diff --git a/.browserslistrc b/.browserslistrc index 54dd3aaf34..0376af4bcc 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,7 +1,9 @@ [production] defaults -not IE 11 +> 0.2% +ios >= 15.6 not dead +not OperaMini all [development] supports es6-module diff --git a/.bundler-audit.yml b/.bundler-audit.yml deleted file mode 100644 index 0671df390f..0000000000 --- a/.bundler-audit.yml +++ /dev/null @@ -1,6 +0,0 @@ ---- -ignore: - # devise-two-factor advisory about brute-forcing TOTP - # We have rate-limits on authentication endpoints in place (including second - # factor verification) since Mastodon v3.2.0 - - CVE-2024-0227 diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index b5e72a0973..c6dcc4d46a 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,20 +1,15 @@ # For details, see https://github.com/devcontainers/images/tree/main/src/ruby -FROM mcr.microsoft.com/devcontainers/ruby:1-3.2-bullseye +FROM mcr.microsoft.com/devcontainers/ruby:1-3.3-bookworm -# Install Rails -# RUN gem install rails webdrivers +# Install node version from .nvmrc +WORKDIR /app +COPY .nvmrc . +RUN /bin/bash --login -i -c "nvm install" -ARG NODE_VERSION="20" -RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1" +# Install additional OS packages +RUN apt-get update && \ + export DEBIAN_FRONTEND=noninteractive && \ + apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev -# [Optional] Uncomment this section to install additional OS packages. -RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ - && apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libpam-dev - -# [Optional] Uncomment this line to install additional gems. -RUN gem install foreman - -# [Optional] Uncomment this line to install global node packages. -RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && corepack enable" 2>&1 - -COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt +# Move welcome message to where VS Code expects it +COPY .devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt diff --git a/.devcontainer/codespaces/devcontainer.json b/.devcontainer/codespaces/devcontainer.json index b32e4026d2..d2358657f6 100644 --- a/.devcontainer/codespaces/devcontainer.json +++ b/.devcontainer/codespaces/devcontainer.json @@ -1,11 +1,11 @@ { "name": "Mastodon on GitHub Codespaces", - "dockerComposeFile": "../docker-compose.yml", + "dockerComposeFile": "../compose.yaml", "service": "app", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { - "ghcr.io/devcontainers/features/sshd:1": {}, + "ghcr.io/devcontainers/features/sshd:1": {} }, "runServices": ["app", "db", "redis"], @@ -15,16 +15,18 @@ "portsAttributes": { "3000": { "label": "web", - "onAutoForward": "notify", + "onAutoForward": "notify" }, "4000": { "label": "stream", - "onAutoForward": "silent", - }, + "onAutoForward": "silent" + } }, + "remoteUser": "root", + "otherPortsAttributes": { - "onAutoForward": "silent", + "onAutoForward": "silent" }, "remoteEnv": { @@ -33,17 +35,17 @@ "STREAMING_API_BASE_URL": "https://${localEnv:CODESPACE_NAME}-4000.app.github.dev", "DISABLE_FORGERY_REQUEST_PROTECTION": "true", "ES_ENABLED": "", - "LIBRE_TRANSLATE_ENDPOINT": "", + "LIBRE_TRANSLATE_ENDPOINT": "" }, "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", - "postCreateCommand": ".devcontainer/post-create.sh", + "postCreateCommand": "bin/setup", "waitFor": "postCreateCommand", "customizations": { "vscode": { "settings": {}, - "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"], - }, - }, + "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] + } + } } diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/compose.yaml similarity index 90% rename from .devcontainer/docker-compose.yml rename to .devcontainer/compose.yaml index ecdf9f5f53..1e2e1ba7de 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/compose.yaml @@ -1,12 +1,11 @@ -version: '3' - services: app: + working_dir: /workspaces/mastodon/ build: - context: . - dockerfile: Dockerfile + context: .. + dockerfile: .devcontainer/Dockerfile volumes: - - ../..:/workspaces:cached + - ..:/workspaces/mastodon:cached environment: RAILS_ENV: development NODE_ENV: development @@ -70,7 +69,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.5.5 + image: libretranslate/libretranslate:v1.5.7 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ed71235b3b..fb88f7801f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,11 @@ { "name": "Mastodon on local machine", - "dockerComposeFile": "docker-compose.yml", + "dockerComposeFile": "compose.yaml", "service": "app", "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", "features": { - "ghcr.io/devcontainers/features/sshd:1": {}, + "ghcr.io/devcontainers/features/sshd:1": {} }, "forwardPorts": [3000, 4000], @@ -14,27 +14,29 @@ "3000": { "label": "web", "onAutoForward": "notify", - "requireLocalPort": true, + "requireLocalPort": true }, "4000": { "label": "stream", "onAutoForward": "silent", - "requireLocalPort": true, - }, + "requireLocalPort": true + } }, + "remoteUser": "root", + "otherPortsAttributes": { - "onAutoForward": "silent", + "onAutoForward": "silent" }, "onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}", - "postCreateCommand": ".devcontainer/post-create.sh", + "postCreateCommand": "bin/setup", "waitFor": "postCreateCommand", "customizations": { "vscode": { "settings": {}, - "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"], - }, - }, + "extensions": ["EditorConfig.EditorConfig", "webben.browserslist"] + } + } } diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh deleted file mode 100755 index 82a2ccbb6c..0000000000 --- a/.devcontainer/post-create.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -set -e # Fail the whole script on first error - -# Fetch Ruby gem dependencies -bundle config path 'vendor/bundle' -bundle config with 'development test' -bundle install - -# Make Gemfile.lock pristine again -git checkout -- Gemfile.lock - -# Fetch Javascript dependencies -corepack prepare -yarn install --immutable - -# [re]create, migrate, and seed the test database -RAILS_ENV=test ./bin/rails db:setup - -# [re]create, migrate, and seed the development database -RAILS_ENV=development ./bin/rails db:setup - -# Precompile assets for development -RAILS_ENV=development ./bin/rails assets:precompile - -# Precompile assets for test -RAILS_ENV=test ./bin/rails assets:precompile diff --git a/.devcontainer/welcome-message.txt b/.devcontainer/welcome-message.txt index 488cf92857..dbc19c910c 100644 --- a/.devcontainer/welcome-message.txt +++ b/.devcontainer/welcome-message.txt @@ -1,8 +1,7 @@ -๐Ÿ‘‹ Welcome to "Mastodon" in GitHub Codespaces! +๐Ÿ‘‹ Welcome to your Mastodon Dev Container! -๐Ÿ› ๏ธ Your environment is fully setup with all the required software. +๐Ÿ› ๏ธ Your environment is fully setup with all the required software. -๐Ÿ” To explore VS Code to its fullest, search using the Command Palette (Cmd/Ctrl + Shift + P or F1). - -๐Ÿ“ Edit away, run your app as usual, and we'll automatically make it available for you to access. +๐Ÿ’ฅ Run `bin/dev` to start the application processes. +๐Ÿฅผ Run `RAILS_ENV=test bin/rails assets:precompile && RAILS_ENV=test bin/rspec` to run the test suite. diff --git a/.env.development b/.env.development new file mode 100644 index 0000000000..0330da8377 --- /dev/null +++ b/.env.development @@ -0,0 +1,4 @@ +# Required by ActiveRecord encryption feature +ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=fkSxKD2bF396kdQbrP1EJ7WbU7ZgNokR +ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=r0hvVmzBVsjxC7AMlwhOzmtc36ZCOS1E +ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=PhdFyyfy5xJ7WVd2lWBpcPScRQHzRTNr diff --git a/.env.test b/.env.test index 2f8c1afd6e..d2763e582a 100644 --- a/.env.test +++ b/.env.test @@ -3,3 +3,9 @@ NODE_ENV=production # Federation LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_HTTPS=true + +# Secret values required by ActiveRecord encryption feature +# Use `bin/rails db:encryption:init` to generate fresh secrets +ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=test_determinist_key_DO_NOT_USE_IN_PRODUCTION +ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=test_salt_DO_NOT_USE_IN_PRODUCTION +ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=test_primary_key_DO_NOT_USE_IN_PRODUCTION diff --git a/.eslintrc.js b/.eslintrc.js index ebe07f6e79..d118262826 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -20,10 +20,6 @@ module.exports = defineConfig({ es6: true, }, - globals: { - ATTACHMENT_HOST: false, - }, - parser: '@typescript-eslint/parser', plugins: [ @@ -79,7 +75,7 @@ module.exports = defineConfig({ ], }, ], - 'no-empty': 'off', + 'no-empty': ['error', { "allowEmptyCatch": true }], 'no-restricted-properties': [ 'error', { property: 'substring', message: 'Use .slice instead of .substring.' }, @@ -94,7 +90,6 @@ module.exports = defineConfig({ message: "Use 'ยท' (middle dot) instead of 'โ€ข' (bullet)", }, ], - 'no-self-assign': 'off', 'no-unused-expressions': 'error', 'no-unused-vars': 'off', '@typescript-eslint/no-unused-vars': [ @@ -119,12 +114,10 @@ module.exports = defineConfig({ 'react/jsx-tag-spacing': 'error', 'react/jsx-uses-react': 'off', // not needed with new JSX transform 'react/jsx-wrap-multilines': 'error', - 'react/no-deprecated': 'off', 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform 'react/self-closing-comp': 'error', - // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js - 'jsx-a11y/accessible-emoji': 'warn', + // recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46 'jsx-a11y/click-events-have-key-events': 'off', 'jsx-a11y/label-has-associated-control': 'off', 'jsx-a11y/media-has-caption': 'off', @@ -139,23 +132,6 @@ module.exports = defineConfig({ // ], 'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off', // recommended rule is: - // 'jsx-a11y/no-noninteractive-element-interactions': [ - // 'error', - // { - // body: ['onError', 'onLoad'], - // iframe: ['onError', 'onLoad'], - // img: ['onError', 'onLoad'], - // }, - // ], - 'jsx-a11y/no-noninteractive-element-interactions': [ - 'warn', - { - handlers: [ - 'onClick', - ], - }, - ], - // recommended rule is: // 'jsx-a11y/no-noninteractive-tabindex': [ // 'error', // { @@ -165,7 +141,6 @@ module.exports = defineConfig({ // }, // ], 'jsx-a11y/no-noninteractive-tabindex': 'off', - 'jsx-a11y/no-onchange': 'off', // recommended is full 'error' 'jsx-a11y/no-static-element-interactions': [ 'warn', @@ -176,7 +151,7 @@ module.exports = defineConfig({ }, ], - // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js + // See https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/config/recommended.js 'import/extensions': [ 'error', 'always', @@ -338,7 +313,6 @@ module.exports = defineConfig({ 'plugin:import/typescript', 'plugin:promise/recommended', 'plugin:jsdoc/recommended-typescript', - 'plugin:prettier/recommended', ], parserOptions: { @@ -347,6 +321,12 @@ module.exports = defineConfig({ }, rules: { + // Disable formatting rules that have been enabled in the base config + 'indent': 'off', + + // This is not needed as we use noImplicitReturns, which handles this in addition to understanding types + 'consistent-return': 'off', + 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], '@typescript-eslint/consistent-type-definitions': ['warn', 'interface'], @@ -361,6 +341,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/actions/setup-ruby/action.yml b/.github/actions/setup-ruby/action.yml index 3a6fba9402..3e232f134c 100644 --- a/.github/actions/setup-ruby/action.yml +++ b/.github/actions/setup-ruby/action.yml @@ -14,7 +14,7 @@ runs: shell: bash run: | sudo apt-get update - sudo apt-get install -y libicu-dev libidn11-dev ${{ inputs.additional-system-dependencies }} + sudo apt-get install -y libicu-dev libidn11-dev libvips42 ${{ inputs.additional-system-dependencies }} - name: Set up Ruby uses: ruby/setup-ruby@v1 diff --git a/.github/codecov.yml b/.github/codecov.yml index 5532c49618..701ba3af8f 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -1,13 +1,11 @@ +comment: false # Do not leave PR comments coverage: status: project: default: - # Github status check is not blocking + # GitHub status check is not blocking informational: true patch: default: - # Github status check is not blocking + # GitHub status check is not blocking informational: true -comment: - # Only write a comment in PR if there are changes - require_changes: true diff --git a/.github/renovate.json5 b/.github/renovate.json5 index dab99829a1..03787dfac6 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -2,6 +2,7 @@ $schema: 'https://docs.renovatebot.com/renovate-schema.json', extends: [ 'config:recommended', + 'customManagers:dockerfileVersions', ':labels(dependencies)', ':prConcurrentLimitNone', // Remove limit for open PRs at any time. ':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour. @@ -13,6 +14,9 @@ // to `null` after any other rule set it to something. dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).', postUpdateOptions: ['yarnDedupeHighest'], + lockFileMaintenance: { + enabled: true, + }, packageRules: [ { // Require Dependency Dashboard Approval for major version bumps of these node packages @@ -59,7 +63,7 @@ dependencyDashboardApproval: true, }, { - // Update Github Actions and Docker images weekly + // Update GitHub Actions and Docker images weekly matchManagers: ['github-actions', 'dockerfile', 'docker-compose'], extends: ['schedule:weekly'], }, @@ -125,6 +129,29 @@ ], groupName: null, // We dont want them to belong to any group }, + { + // Group all RuboCop packages with `rubocop` in the same PR + matchManagers: ['bundler'], + matchPackageNames: ['rubocop'], + matchPackagePrefixes: ['rubocop-'], + matchUpdateTypes: ['patch', 'minor'], + groupName: 'RuboCop (non-major)', + }, + { + // Group all RSpec packages with `rspec` in the same PR + matchManagers: ['bundler'], + matchPackageNames: ['rspec'], + matchPackagePrefixes: ['rspec-'], + matchUpdateTypes: ['patch', 'minor'], + groupName: 'RSpec (non-major)', + }, + { + // Group all opentelemetry-ruby packages in the same PR + matchManagers: ['bundler'], + matchPackagePrefixes: ['opentelemetry-'], + matchUpdateTypes: ['patch', 'minor'], + groupName: 'opentelemetry-ruby (non-major)', + }, // Add labels depending on package manager { matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] }, { matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] }, diff --git a/.github/stylelint-matcher.json b/.github/stylelint-matcher.json deleted file mode 100644 index cdfd4086bd..0000000000 --- a/.github/stylelint-matcher.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "problemMatcher": [ - { - "owner": "stylelint", - "pattern": [ - { - "regexp": "^([^\\s].*)$", - "file": 1 - }, - { - "regexp": "^\\s+((\\d+):(\\d+))?\\s+(โœ–|ร—)\\s+(.*)\\s{2,}(.*)$", - "line": 2, - "column": 3, - "message": 5, - "code": 6, - "loop": true - } - ] - } - ] -} diff --git a/.github/workflows/build-container-image.yml b/.github/workflows/build-container-image.yml index e100e15821..dbb32af9bf 100644 --- a/.github/workflows/build-container-image.yml +++ b/.github/workflows/build-container-image.yml @@ -68,7 +68,7 @@ jobs: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Log in to the Github Container registry + - name: Log in to the GitHub Container registry if: contains(inputs.push_to_images, 'ghcr.io') uses: docker/login-action@v3 with: diff --git a/.github/workflows/bundler-audit.yml b/.github/workflows/bundler-audit.yml index bbc31598c7..e3e2da0c78 100644 --- a/.github/workflows/bundler-audit.yml +++ b/.github/workflows/bundler-audit.yml @@ -6,14 +6,12 @@ on: paths: - 'Gemfile*' - '.ruby-version' - - '.bundler-audit.yml' - '.github/workflows/bundler-audit.yml' pull_request: paths: - 'Gemfile*' - '.ruby-version' - - '.bundler-audit.yml' - '.github/workflows/bundler-audit.yml' schedule: @@ -23,12 +21,17 @@ jobs: security: runs-on: ubuntu-latest + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Run bundler-audit - run: bundle exec bundler-audit + run: bundle exec bundler-audit check --update diff --git a/.github/workflows/crowdin-download.yml b/.github/workflows/crowdin-download.yml index a676ff12fc..e9da7cb26f 100644 --- a/.github/workflows/crowdin-download.yml +++ b/.github/workflows/crowdin-download.yml @@ -52,19 +52,19 @@ jobs: # Create or update the pull request - name: Create Pull Request - uses: peter-evans/create-pull-request@v6.0.0 + uses: peter-evans/create-pull-request@v6.0.5 with: commit-message: 'New Crowdin translations' title: 'New Crowdin Translations (automated)' author: 'GitHub Actions ' body: | - New Crowdin translations, automated with Github Actions + New Crowdin translations, automated with GitHub Actions See `.github/workflows/crowdin-download.yml` This PR will be updated every day with new translations. - Due to a limitation in Github Actions, checks are not running on this PR without manual action. + Due to a limitation in GitHub Actions, checks are not running on this PR without manual action. If you want to run the checks, then close and re-open it. branch: i18n/crowdin/translations base: main diff --git a/.github/workflows/format-check.yml b/.github/workflows/format-check.yml new file mode 100644 index 0000000000..2d483b5022 --- /dev/null +++ b/.github/workflows/format-check.yml @@ -0,0 +1,18 @@ +name: Check formatting +on: + push: + pull_request: + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Set up Javascript environment + uses: ./.github/actions/setup-javascript + + - name: Check formatting with Prettier + run: yarn format:check diff --git a/.github/workflows/lint-css.yml b/.github/workflows/lint-css.yml index 7229bec582..d3b8035cd8 100644 --- a/.github/workflows/lint-css.yml +++ b/.github/workflows/lint-css.yml @@ -38,9 +38,5 @@ jobs: - name: Set up Javascript environment uses: ./.github/actions/setup-javascript - - uses: xt0rted/stylelint-problem-matcher@v1 - - - run: echo "::add-matcher::.github/stylelint-matcher.json" - - name: Stylelint - run: yarn lint:sass + run: yarn lint:css -f github diff --git a/.github/workflows/lint-haml.yml b/.github/workflows/lint-haml.yml index 8dcab845ee..ca4b0c80bf 100644 --- a/.github/workflows/lint-haml.yml +++ b/.github/workflows/lint-haml.yml @@ -26,14 +26,20 @@ on: jobs: lint: runs-on: ubuntu-latest + + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Run haml-lint run: | echo "::add-matcher::.github/workflows/haml-lint-problem-matcher.json" - bundle exec haml-lint + bundle exec haml-lint --reporter github diff --git a/.github/workflows/lint-json.yml b/.github/workflows/lint-json.yml deleted file mode 100644 index 7796bf92c4..0000000000 --- a/.github/workflows/lint-json.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: JSON Linting -on: - push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' - paths: - - 'package.json' - - 'yarn.lock' - - '.nvmrc' - - '.prettier*' - - '**/*.json' - - '.github/workflows/lint-json.yml' - - '!app/javascript/mastodon/locales/*.json' - - pull_request: - paths: - - 'package.json' - - 'yarn.lock' - - '.nvmrc' - - '.prettier*' - - '**/*.json' - - '.github/workflows/lint-json.yml' - - '!app/javascript/mastodon/locales/*.json' - -jobs: - lint: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v4 - - - name: Set up Javascript environment - uses: ./.github/actions/setup-javascript - - - name: Prettier - run: yarn lint:json diff --git a/.github/workflows/lint-md.yml b/.github/workflows/lint-md.yml deleted file mode 100644 index 51c59937a3..0000000000 --- a/.github/workflows/lint-md.yml +++ /dev/null @@ -1,38 +0,0 @@ -name: Markdown Linting -on: - push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' - paths: - - '.github/workflows/lint-md.yml' - - '.nvmrc' - - '.prettier*' - - '**/*.md' - - '!AUTHORS.md' - - 'package.json' - - 'yarn.lock' - - pull_request: - paths: - - '.github/workflows/lint-md.yml' - - '.nvmrc' - - '.prettier*' - - '**/*.md' - - '!AUTHORS.md' - - 'package.json' - - 'yarn.lock' - -jobs: - lint: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v4 - - - name: Set up Javascript environment - uses: ./.github/actions/setup-javascript - - - name: Prettier - run: yarn lint:md diff --git a/.github/workflows/lint-ruby.yml b/.github/workflows/lint-ruby.yml index 411b323486..b3a89c3caf 100644 --- a/.github/workflows/lint-ruby.yml +++ b/.github/workflows/lint-ruby.yml @@ -27,19 +27,24 @@ jobs: lint: runs-on: ubuntu-latest + env: + BUNDLE_ONLY: development + steps: - name: Clone repository uses: actions/checkout@v4 - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true - name: Set-up RuboCop Problem Matcher uses: r7kamura/rubocop-problem-matchers-action@v1 - name: Run rubocop - run: bundle exec rubocop + run: bin/rubocop - name: Run brakeman if: always() # Run both checks, even if the first failed - run: bundle exec brakeman + run: bin/brakeman diff --git a/.github/workflows/lint-yml.yml b/.github/workflows/lint-yml.yml deleted file mode 100644 index 908bdef5cc..0000000000 --- a/.github/workflows/lint-yml.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: YML Linting -on: - push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' - paths: - - 'package.json' - - 'yarn.lock' - - '.nvmrc' - - '.prettier*' - - '**/*.yaml' - - '**/*.yml' - - '.github/workflows/lint-yml.yml' - - '!config/locales/*.yml' - - pull_request: - paths: - - 'package.json' - - 'yarn.lock' - - '.nvmrc' - - '.prettier*' - - '**/*.yaml' - - '**/*.yml' - - '.github/workflows/lint-yml.yml' - - '!config/locales/*.yml' - -jobs: - lint: - runs-on: ubuntu-latest - - steps: - - name: Clone repository - uses: actions/checkout@v4 - - - name: Set up Javascript environment - uses: ./.github/actions/setup-javascript - - - name: Prettier - run: yarn lint:yml diff --git a/.github/workflows/rebase-needed.yml b/.github/workflows/rebase-needed.yml index 06d835c090..8784397a8f 100644 --- a/.github/workflows/rebase-needed.yml +++ b/.github/workflows/rebase-needed.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Check for merge conflicts - uses: eps1lon/actions-label-merge-conflict@releases/2.x + uses: eps1lon/actions-label-merge-conflict@v3 with: dirtyLabel: 'rebase needed :construction:' repoToken: '${{ secrets.GITHUB_TOKEN }}' diff --git a/.github/workflows/test-js.yml b/.github/workflows/test-js.yml index 79622b6c1f..481afdba30 100644 --- a/.github/workflows/test-js.yml +++ b/.github/workflows/test-js.yml @@ -38,5 +38,5 @@ jobs: - name: Set up Javascript environment uses: ./.github/actions/setup-javascript - - name: Jest testing + - name: JavaScript testing run: yarn jest --reporters github-actions summary diff --git a/.github/workflows/test-migrations-two-step.yml b/.github/workflows/test-migrations-two-step.yml deleted file mode 100644 index 6698847315..0000000000 --- a/.github/workflows/test-migrations-two-step.yml +++ /dev/null @@ -1,95 +0,0 @@ -name: Test two step migrations -on: - push: - branches-ignore: - - 'dependabot/**' - - 'renovate/**' - pull_request: - -jobs: - pre_job: - runs-on: ubuntu-latest - - outputs: - should_skip: ${{ steps.skip_check.outputs.should_skip }} - - steps: - - id: skip_check - uses: fkirc/skip-duplicate-actions@v5 - with: - paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-two-step.yml", "lib/tasks/tests.rake"]' - - test: - runs-on: ubuntu-latest - needs: pre_job - if: needs.pre_job.outputs.should_skip != 'true' - - strategy: - fail-fast: false - - matrix: - postgres: - - 14-alpine - - 15-alpine - - services: - postgres: - image: postgres:${{ matrix.postgres}} - env: - POSTGRES_PASSWORD: postgres - POSTGRES_USER: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - redis: - image: redis:7-alpine - options: >- - --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 6379:6379 - - env: - CONTINUOUS_INTEGRATION: true - DB_HOST: localhost - DB_USER: postgres - DB_PASS: postgres - DISABLE_SIMPLECOV: true - RAILS_ENV: test - BUNDLE_CLEAN: true - BUNDLE_FROZEN: true - BUNDLE_WITHOUT: 'development production' - BUNDLE_JOBS: 3 - BUNDLE_RETRY: 3 - - steps: - - uses: actions/checkout@v4 - - - name: Set up Ruby environment - uses: ./.github/actions/setup-ruby - - - name: Create database - run: './bin/rails db:create' - - - name: Run historical migrations with data population - run: './bin/rails tests:migrations:prepare_database' - env: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - - name: Run all remaining pre-deployment migrations - run: './bin/rails db:migrate' - env: - SKIP_POST_DEPLOYMENT_MIGRATIONS: true - - - name: Run all post-deployment migrations - run: './bin/rails db:migrate' - - - name: Check migration result - run: './bin/rails tests:migrations:check_database' diff --git a/.github/workflows/test-migrations-one-step.yml b/.github/workflows/test-migrations.yml similarity index 58% rename from .github/workflows/test-migrations-one-step.yml rename to .github/workflows/test-migrations.yml index 1ff5cc06b9..3eaf2c2d74 100644 --- a/.github/workflows/test-migrations-one-step.yml +++ b/.github/workflows/test-migrations.yml @@ -1,4 +1,5 @@ -name: Test one step migrations +name: Historical data migration test + on: push: branches-ignore: @@ -17,7 +18,7 @@ jobs: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 with: - paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations-one-step.yml", "lib/tasks/tests.rake"]' + paths: '["Gemfile*", ".ruby-version", "**/*.rb", ".github/workflows/test-migrations.yml", "lib/tasks/tests.rake"]' test: runs-on: ubuntu-latest @@ -40,9 +41,9 @@ jobs: POSTGRES_USER: postgres options: >- --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 5432:5432 @@ -50,14 +51,13 @@ jobs: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 6379:6379 env: - CONTINUOUS_INTEGRATION: true DB_HOST: localhost DB_USER: postgres DB_PASS: postgres @@ -65,7 +65,7 @@ jobs: RAILS_ENV: test BUNDLE_CLEAN: true BUNDLE_FROZEN: true - BUNDLE_WITHOUT: 'development production' + BUNDLE_WITHOUT: 'development:production' BUNDLE_JOBS: 3 BUNDLE_RETRY: 3 @@ -75,14 +75,19 @@ jobs: - name: Set up Ruby environment uses: ./.github/actions/setup-ruby - - name: Create database - run: './bin/rails db:create' + - name: Test "one step migration" flow + run: | + bin/rails db:drop + bin/rails db:create + bin/rails tests:migrations:prepare_database + bin/rails db:migrate + bin/rails tests:migrations:check_database - - name: Run historical migrations with data population - run: './bin/rails tests:migrations:prepare_database' - - - name: Run all remaining migrations - run: './bin/rails db:migrate' - - - name: Check migration result - run: './bin/rails tests:migrations:check_database' + - name: Test "two step migration" flow + run: | + bin/rails db:drop + bin/rails db:create + SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails tests:migrations:prepare_database + SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails db:migrate + bin/rails db:migrate + bin/rails tests:migrations:check_database diff --git a/.github/workflows/test-ruby.yml b/.github/workflows/test-ruby.yml index 7fd259ae01..dd71fd253b 100644 --- a/.github/workflows/test-ruby.yml +++ b/.github/workflows/test-ruby.yml @@ -28,8 +28,7 @@ jobs: env: RAILS_ENV: ${{ matrix.mode }} BUNDLE_WITH: ${{ matrix.mode }} - OTP_SECRET: precompile_placeholder - SECRET_KEY_BASE: precompile_placeholder + SECRET_KEY_BASE_DUMMY: 1 steps: - uses: actions/checkout@v4 @@ -74,9 +73,9 @@ jobs: POSTGRES_USER: postgres options: >- --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 5432:5432 @@ -84,9 +83,9 @@ jobs: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 6379:6379 @@ -111,8 +110,8 @@ jobs: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' + - '3.2' - '.ruby-version' steps: - uses: actions/checkout@v4 @@ -130,7 +129,7 @@ jobs: uses: ./.github/actions/setup-ruby with: ruby-version: ${{ matrix.ruby-version}} - additional-system-dependencies: ffmpeg imagemagick libpam-dev + additional-system-dependencies: ffmpeg libpam-dev - name: Load database schema run: './bin/rails db:create db:schema:load db:seed' @@ -142,6 +141,95 @@ jobs: uses: codecov/codecov-action@v4 with: files: coverage/lcov/mastodon.lcov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + test-libvips: + name: Libvips tests + runs-on: ubuntu-24.04 + + needs: + - build + + services: + postgres: + image: postgres:14-alpine + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + options: >- + --health-cmd pg_isready + --health-interval 10ms + --health-timeout 3s + --health-retries 50 + ports: + - 5432:5432 + + redis: + image: redis:7-alpine + options: >- + --health-cmd "redis-cli ping" + --health-interval 10ms + --health-timeout 3s + --health-retries 50 + ports: + - 6379:6379 + + env: + DB_HOST: localhost + DB_USER: postgres + DB_PASS: postgres + DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }} + RAILS_ENV: test + ALLOW_NOPAM: true + PAM_ENABLED: true + PAM_DEFAULT_SERVICE: pam_test + PAM_CONTROLLED_SERVICE: pam_test_controlled + OIDC_ENABLED: true + OIDC_SCOPE: read + SAML_ENABLED: true + CAS_ENABLED: true + BUNDLE_WITH: 'pam_authentication test' + GITHUB_RSPEC: ${{ matrix.ruby-version == '.ruby-version' && github.event.pull_request && 'true' }} + MASTODON_USE_LIBVIPS: true + + strategy: + fail-fast: false + matrix: + ruby-version: + - '3.1' + - '3.2' + - '.ruby-version' + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + with: + path: './' + name: ${{ github.sha }} + + - name: Expand archived asset artifacts + run: | + tar xvzf artifacts.tar.gz + + - name: Set up Ruby environment + uses: ./.github/actions/setup-ruby + with: + ruby-version: ${{ matrix.ruby-version}} + additional-system-dependencies: ffmpeg libpam-dev libyaml-dev + + - name: Load database schema + run: './bin/rails db:create db:schema:load db:seed' + + - run: bin/rspec --tag paperclip_processing + + - name: Upload coverage reports to Codecov + if: matrix.ruby-version == '.ruby-version' + uses: codecov/codecov-action@v4 + with: + files: coverage/lcov/mastodon.lcov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} test-e2e: name: End to End testing @@ -158,9 +246,9 @@ jobs: POSTGRES_USER: postgres options: >- --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 5432:5432 @@ -168,9 +256,9 @@ jobs: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 6379:6379 @@ -181,13 +269,15 @@ jobs: DISABLE_SIMPLECOV: true RAILS_ENV: test BUNDLE_WITH: test + LOCAL_DOMAIN: localhost:3000 + LOCAL_HTTPS: false strategy: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' + - '3.2' - '.ruby-version' steps: @@ -195,14 +285,18 @@ jobs: - uses: actions/download-artifact@v4 with: - path: './public' + path: './' name: ${{ github.sha }} + - name: Expand archived asset artifacts + run: | + tar xvzf artifacts.tar.gz + - name: Set up Ruby environment uses: ./.github/actions/setup-ruby with: ruby-version: ${{ matrix.ruby-version}} - additional-system-dependencies: ffmpeg imagemagick + additional-system-dependencies: ffmpeg - name: Set up Javascript environment uses: ./.github/actions/setup-javascript @@ -210,7 +304,7 @@ jobs: - name: Load database schema run: './bin/rails db:create db:schema:load db:seed' - - run: bundle exec rake spec:system + - run: bin/rspec spec/system --tag streaming --tag js - name: Archive logs uses: actions/upload-artifact@v4 @@ -241,9 +335,9 @@ jobs: POSTGRES_USER: postgres options: >- --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 5432:5432 @@ -251,22 +345,36 @@ jobs: image: redis:7-alpine options: >- --health-cmd "redis-cli ping" - --health-interval 10s - --health-timeout 5s - --health-retries 5 + --health-interval 10ms + --health-timeout 3s + --health-retries 50 ports: - 6379:6379 - search: - image: ${{ matrix.search-image }} + elasticsearch: + image: ${{ contains(matrix.search-image, 'elasticsearch') && matrix.search-image || '' }} env: discovery.type: single-node xpack.security.enabled: false options: >- --health-cmd "curl http://localhost:9200/_cluster/health" - --health-interval 10s - --health-timeout 5s - --health-retries 10 + --health-interval 2s + --health-timeout 3s + --health-retries 50 + ports: + - 9200:9200 + + opensearch: + image: ${{ contains(matrix.search-image, 'opensearch') && matrix.search-image || '' }} + env: + discovery.type: single-node + DISABLE_INSTALL_DEMO_CONFIG: true + DISABLE_SECURITY_PLUGIN: true + options: >- + --health-cmd "curl http://localhost:9200/_cluster/health" + --health-interval 2s + --health-timeout 3s + --health-retries 50 ports: - 9200:9200 @@ -285,28 +393,30 @@ jobs: fail-fast: false matrix: ruby-version: - - '3.0' - '3.1' + - '3.2' - '.ruby-version' search-image: - docker.elastic.co/elasticsearch/elasticsearch:7.17.13 include: - ruby-version: '.ruby-version' search-image: docker.elastic.co/elasticsearch/elasticsearch:8.10.2 + - ruby-version: '.ruby-version' + search-image: opensearchproject/opensearch:2 steps: - uses: actions/checkout@v4 - uses: actions/download-artifact@v4 with: - path: './public' + path: './' name: ${{ github.sha }} - name: Set up Ruby environment uses: ./.github/actions/setup-ruby with: ruby-version: ${{ matrix.ruby-version}} - additional-system-dependencies: ffmpeg imagemagick + additional-system-dependencies: ffmpeg - name: Set up Javascript environment uses: ./.github/actions/setup-javascript diff --git a/.gitignore b/.gitignore index c5af8eb67f..a70f30f952 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,6 @@ /public/packs-test .env .env.production -.env.development /node_modules/ /build/ @@ -69,3 +68,6 @@ yarn-debug.log # Ignore Docker option files docker-compose.override.yml + +# Ignore dotenv .local files +.env*.local diff --git a/.haml-lint.yml b/.haml-lint.yml index 8cfcaec8d9..74d243a3ad 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -1,8 +1,5 @@ -inherits_from: .haml-lint_todo.yml - exclude: - 'vendor/**/*' - - lib/templates/haml/scaffold/_form.html.haml require: - ./lib/linter/haml_middle_dot.rb @@ -13,4 +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/.haml-lint_todo.yml b/.haml-lint_todo.yml deleted file mode 100644 index af2d2e8f4e..0000000000 --- a/.haml-lint_todo.yml +++ /dev/null @@ -1,13 +0,0 @@ -# This configuration was generated by -# `haml-lint --auto-gen-config` -# on 2024-01-09 11:30:07 -0500 using Haml-Lint version 0.53.0. -# The point is for the user to remove these configuration records -# one by one as the lints are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of Haml-Lint, may require this file to be generated again. - -linters: - # Offense count: 1 - LineLength: - exclude: - - 'app/views/admin/roles/_form.html.haml' diff --git a/.husky/pre-commit b/.husky/pre-commit index d2ae35e84b..3723623171 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/bin/sh -. "$(dirname "$0")/_/husky.sh" - yarn lint-staged diff --git a/.nanoignore b/.nanoignore deleted file mode 100644 index 80e9397035..0000000000 --- a/.nanoignore +++ /dev/null @@ -1,19 +0,0 @@ -.DS_Store -.git/ -.gitignore - -.bundle/ -.cache/ -config/deploy/* -coverage -docs/ -.env -log/*.log -neo4j/ -node_modules/ -public/assets/ -public/system/ -spec/ -tmp/ -.vagrant/ -vendor/bundle/ diff --git a/.nvmrc b/.nvmrc index a3597ecbd1..cecb936289 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.11 +20.15 diff --git a/.prettierignore b/.prettierignore index 51850b2b28..6b2f0c1889 100644 --- a/.prettierignore +++ b/.prettierignore @@ -54,6 +54,13 @@ # Ignore Docker option files docker-compose.override.yml +# Ignore public +/public/assets +/public/emoji +/public/packs +/public/packs-test +/public/system + # Ignore emoji map file /app/javascript/mastodon/features/emoji/emoji_map.json @@ -74,4 +81,5 @@ app/javascript/styles/mastodon/reset.scss # Ignore the generated AUTHORS.md AUTHORS.md +# Process a few selected JS files !lint-staged.config.js diff --git a/.rubocop.yml b/.rubocop.yml index dce33eab30..965f56f3e7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,27 @@ -# Can be removed once all rules are addressed or moved to this file as documented overrides -inherit_from: .rubocop_todo.yml +--- +AllCops: + CacheRootDirectory: tmp + DisplayStyleGuide: true + Exclude: + - Vagrantfile + - config/initializers/json_ld* + - lib/mastodon/migration_helpers.rb + ExtraDetails: true + NewCops: enable + TargetRubyVersion: 3.1 # Oldest supported ruby version + +inherit_from: + - .rubocop/layout.yml + - .rubocop/metrics.yml + - .rubocop/naming.yml + - .rubocop/rails.yml + - .rubocop/rspec_rails.yml + - .rubocop/rspec.yml + - .rubocop/style.yml + - .rubocop/custom.yml + - .rubocop_todo.yml + - .rubocop/strict.yml -# Used for merging with exclude lists with .rubocop_todo.yml inherit_mode: merge: - Exclude @@ -9,226 +29,6 @@ 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 - DisplayCopNames: true - DisplayStyleGuide: true - ExtraDetails: true - UseCache: true - CacheRootDirectory: tmp - NewCops: enable # Opt-in to newly added rules - Exclude: - - db/schema.rb - - 'bin/*' - - 'node_modules/**/*' - - 'Vagrantfile' - - 'vendor/**/*' - - 'config/initializers/json_ld*' # Generated files - - 'lib/mastodon/migration_helpers.rb' # Vendored from GitLab - - 'lib/templates/**/*' - -# Reason: Prefer Hashes without extreme indentation -# https://docs.rubocop.org/rubocop/cops_layout.html#layoutfirsthashelementindentation -Layout/FirstHashElementIndentation: - EnforcedStyle: consistent - -# 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 - -## Disable most Metrics/*Length cops -# Reason: those are often triggered and force significant refactors when this happend -# but the team feel they are not really improving the code quality. - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsblocklength -Metrics/BlockLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsclasslength -Metrics/ClassLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmethodlength -Metrics/MethodLength: - Enabled: false - -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsmodulelength -Metrics/ModuleLength: - Enabled: false - -## End Disable Metrics/*Length cops - -# Reason: Currently disabled in .rubocop_todo.yml -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize -Metrics/AbcSize: - Exclude: - - 'lib/mastodon/cli/*.rb' - -# Reason: Currently disabled in .rubocop_todo.yml -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricscyclomaticcomplexity -Metrics/CyclomaticComplexity: - Exclude: - - lib/mastodon/cli/*.rb - -# Reason: -# https://docs.rubocop.org/rubocop/cops_metrics.html#metricsparameterlists -Metrics/ParameterLists: - CountKeywordArgs: false - -# Reason: Prevailing style is argument file paths -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsfilepath -Rails/FilePath: - EnforcedStyle: arguments - -# Reason: Prevailing style uses numeric status codes, matches RSpec/Rails/HttpStatus -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railshttpstatus -Rails/HttpStatus: - EnforcedStyle: numeric - -# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter -Rails/LexicallyScopedActionFilter: - Exclude: - - 'app/controllers/auth/*' - -# Reason: These tasks are doing local work which do not need full env loaded -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsrakeenvironment -Rails/RakeEnvironment: - Exclude: - - 'lib/tasks/auto_annotate_models.rake' - - 'lib/tasks/emojis.rake' - - 'lib/tasks/mastodon.rake' - - 'lib/tasks/repo.rake' - - 'lib/tasks/statistics.rake' - -# Reason: There are appropriate times to use these features -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsskipsmodelvalidations -Rails/SkipsModelValidations: - Enabled: false - -# Reason: We want to preserve the ability to migrate from arbitrary old versions, -# and cannot guarantee that every installation has run every migration as they upgrade. -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns -Rails/UnusedIgnoredColumns: - Enabled: false - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude -Rails/NegateInclude: - Enabled: false - -# Reason: Enforce default limit, but allow some elements to span lines -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecexamplelength -RSpec/ExampleLength: - CountAsOne: ['array', 'heredoc', 'method_call'] - -# Reason: Deprecated cop, will be removed in 3.0, replaced by SpecFilePathFormat -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath -RSpec/FilePath: - Enabled: false - -# Reason: -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnamedsubject -RSpec/NamedSubject: - EnforcedStyle: named_only - -# Reason: Prevailing style choice -# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecnottonot -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: - CustomTransform: - ActivityPub: activitypub - DeepL: deepl - FetchOEmbedService: fetch_oembed_service - OEmbedController: oembed_controller - OStatus: ostatus - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styleclassandmodulechildren -Style/ClassAndModuleChildren: - Enabled: false - -# Reason: Classes mostly self-document with their names -# https://docs.rubocop.org/rubocop/cops_style.html#styledocumentation -Style/Documentation: - Enabled: false - -# Reason: Route redirects are not token-formatted and must be skipped -# https://docs.rubocop.org/rubocop/cops_style.html#styleformatstringtoken -Style/FormatStringToken: - inherit_mode: - merge: - - AllowedMethods # The rubocop-rails config adds `redirect` - AllowedMethods: - - redirect_with_vary - -# Reason: Enforce modern Ruby style -# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax -Style/HashSyntax: - EnforcedStyle: ruby19_no_mixed_keys - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#stylenumericliterals -Style/NumericLiterals: - AllowedPatterns: - - \d{4}_\d{2}_\d{2}_\d{6} # For DB migration date version number readability - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#stylepercentliteraldelimiters -Style/PercentLiteralDelimiters: - PreferredDelimiters: - '%i': '()' - '%w': '()' - -# Reason: Prefer less indentation in conditional assignments -# https://docs.rubocop.org/rubocop/cops_style.html#styleredundantbegin -Style/RedundantBegin: - Enabled: false - -# Reason: Overridden to reduce implicit StandardError rescues -# https://docs.rubocop.org/rubocop/cops_style.html#stylerescuestandarderror -Style/RescueStandardError: - EnforcedStyle: implicit - -# Reason: Simplify some spec layouts -# https://docs.rubocop.org/rubocop/cops_style.html#stylesemicolon -Style/Semicolon: - AllowAsExpressionSeparator: true - -# Reason: Originally disabled for CodeClimate, and no config consensus has been found -# https://docs.rubocop.org/rubocop/cops_style.html#stylesymbolarray -Style/SymbolArray: - Enabled: false - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainarrayliteral -Style/TrailingCommaInArrayLiteral: - EnforcedStyleForMultiline: 'comma' - -# Reason: -# https://docs.rubocop.org/rubocop/cops_style.html#styletrailingcommainhashliteral -Style/TrailingCommaInHashLiteral: - EnforcedStyleForMultiline: 'comma' - -Style/MiddleDot: - Enabled: true diff --git a/.rubocop/custom.yml b/.rubocop/custom.yml new file mode 100644 index 0000000000..63035837f8 --- /dev/null +++ b/.rubocop/custom.yml @@ -0,0 +1,6 @@ +--- +require: + - ../lib/linter/rubocop_middle_dot + +Style/MiddleDot: + Enabled: true diff --git a/.rubocop/layout.yml b/.rubocop/layout.yml new file mode 100644 index 0000000000..487879ca2c --- /dev/null +++ b/.rubocop/layout.yml @@ -0,0 +1,6 @@ +--- +Layout/FirstHashElementIndentation: + EnforcedStyle: consistent + +Layout/LineLength: + Max: 300 # Default of 120 causes a duplicate entry in generated todo file diff --git a/.rubocop/metrics.yml b/.rubocop/metrics.yml new file mode 100644 index 0000000000..89532af42a --- /dev/null +++ b/.rubocop/metrics.yml @@ -0,0 +1,23 @@ +--- +Metrics/AbcSize: + Exclude: + - lib/mastodon/cli/*.rb + +Metrics/BlockLength: + Enabled: false + +Metrics/ClassLength: + Enabled: false + +Metrics/CyclomaticComplexity: + Exclude: + - lib/mastodon/cli/*.rb + +Metrics/MethodLength: + Enabled: false + +Metrics/ModuleLength: + Enabled: false + +Metrics/ParameterLists: + CountKeywordArgs: false diff --git a/.rubocop/naming.yml b/.rubocop/naming.yml new file mode 100644 index 0000000000..da6ad4ac57 --- /dev/null +++ b/.rubocop/naming.yml @@ -0,0 +1,3 @@ +--- +Naming/BlockForwarding: + EnforcedStyle: explicit diff --git a/.rubocop/rails.yml b/.rubocop/rails.yml new file mode 100644 index 0000000000..4e08f1ab91 --- /dev/null +++ b/.rubocop/rails.yml @@ -0,0 +1,23 @@ +--- +Rails/FilePath: + EnforcedStyle: arguments + +Rails/HttpStatus: + EnforcedStyle: numeric + +Rails/NegateInclude: + Enabled: false + +Rails/RakeEnvironment: + Exclude: # Tasks are doing local work which do not need full env loaded + - lib/tasks/auto_annotate_models.rake + - lib/tasks/emojis.rake + - lib/tasks/mastodon.rake + - lib/tasks/repo.rake + - lib/tasks/statistics.rake + +Rails/SkipsModelValidations: + Enabled: false + +Rails/UnusedIgnoredColumns: + Enabled: false # Preserve ability to migrate from arbitrary old versions diff --git a/.rubocop/rspec.yml b/.rubocop/rspec.yml new file mode 100644 index 0000000000..d2d2f8325d --- /dev/null +++ b/.rubocop/rspec.yml @@ -0,0 +1,27 @@ +--- +RSpec/ExampleLength: + CountAsOne: ['array', 'heredoc', 'method_call'] + Max: 20 # Override default of 5 + +RSpec/MultipleExpectations: + Max: 10 # Overrides default of 1 + +RSpec/MultipleMemoizedHelpers: + Max: 20 # Overrides default of 5 + +RSpec/NamedSubject: + EnforcedStyle: named_only + +RSpec/NestedGroups: + Max: 10 # Overrides default of 3 + +RSpec/NotToNot: + EnforcedStyle: to_not + +RSpec/SpecFilePathFormat: + CustomTransform: + ActivityPub: activitypub + DeepL: deepl + FetchOEmbedService: fetch_oembed_service + OEmbedController: oembed_controller + OStatus: ostatus diff --git a/.rubocop/rspec_rails.yml b/.rubocop/rspec_rails.yml new file mode 100644 index 0000000000..993a5689ad --- /dev/null +++ b/.rubocop/rspec_rails.yml @@ -0,0 +1,3 @@ +--- +RSpecRails/HttpStatus: + EnforcedStyle: numeric diff --git a/.rubocop/strict.yml b/.rubocop/strict.yml new file mode 100644 index 0000000000..2222c6d8b9 --- /dev/null +++ b/.rubocop/strict.yml @@ -0,0 +1,19 @@ +Lint/Debugger: # Remove any `binding.pry` + Enabled: true + Exclude: [] + +RSpec/Focus: # Require full spec run on CI + Enabled: true + Exclude: [] + +Rails/Output: # Remove any `puts` debugging + Enabled: true + Exclude: [] + +Rails/FindEach: # Using `each` could impact performance, use `find_each` + Enabled: true + Exclude: [] + +Rails/UniqBeforePluck: # Require `uniq.pluck` and not `pluck.uniq` + Enabled: true + Exclude: [] diff --git a/.rubocop/style.yml b/.rubocop/style.yml new file mode 100644 index 0000000000..03e35a70ac --- /dev/null +++ b/.rubocop/style.yml @@ -0,0 +1,47 @@ +--- +Style/ClassAndModuleChildren: + Enabled: false + +Style/Documentation: + Enabled: false + +Style/FormatStringToken: + AllowedMethods: + - redirect_with_vary # Route redirects are not token-formatted + inherit_mode: + merge: + - AllowedMethods + +Style/HashAsLastArrayItem: + Enabled: false + +Style/HashSyntax: + EnforcedShorthandSyntax: either + EnforcedStyle: ruby19_no_mixed_keys + +Style/NumericLiterals: + AllowedPatterns: + - \d{4}_\d{2}_\d{2}_\d{6} + +Style/PercentLiteralDelimiters: + PreferredDelimiters: + '%i': () + '%w': () + +Style/RedundantBegin: + Enabled: false + +Style/RedundantFetchBlock: + Enabled: false + +Style/RescueStandardError: + EnforcedStyle: implicit + +Style/SymbolArray: + Enabled: false + +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma + +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 11ac570836..b05d1bc6bd 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. +# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp` +# using RuboCop version 1.64.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' @@ -34,61 +27,16 @@ Metrics/CyclomaticComplexity: Metrics/PerceivedComplexity: Max: 27 -# Configuration parameters: CountAsOne. -RSpec/ExampleLength: - Max: 20 # Override default of 5 - -RSpec/MultipleExpectations: - Max: 7 - -# Configuration parameters: AllowSubject. -RSpec/MultipleMemoizedHelpers: - Max: 17 - -# Configuration parameters: AllowedGroups. -RSpec/NestedGroups: - Max: 6 - -# Configuration parameters: Include. -# Include: app/models/**/*.rb -Rails/HasAndBelongsToMany: - Exclude: - - 'app/models/concerns/account/associations.rb' - - 'app/models/status.rb' - - 'app/models/tag.rb' - 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? -Style/ClassEqualityComparison: - Exclude: - - 'app/helpers/jsonld_helper.rb' - - 'app/serializers/activitypub/outbox_serializer.rb' - -Style/ClassVars: - Exclude: - - 'config/initializers/devise.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: AllowedVars. 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,9 +46,7 @@ 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' # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns. @@ -111,54 +57,10 @@ Style/FormatStringToken: - 'config/initializers/devise.rb' - 'lib/paperclip/color_extractor.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -Style/GlobalStdStream: - Exclude: - - 'config/environments/development.rb' - - 'config/environments/production.rb' - # This cop supports safe autocorrection (--autocorrect). # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. Style/GuardClause: - Exclude: - - 'app/lib/activitypub/activity/block.rb' - - 'app/lib/request.rb' - - 'app/lib/request_pool.rb' - - 'app/lib/webfinger.rb' - - 'app/lib/webfinger_resource.rb' - - 'app/models/concerns/account/counters.rb' - - 'app/models/concerns/user/ldap_authenticable.rb' - - 'app/models/tag.rb' - - 'app/models/user.rb' - - 'app/services/fan_out_on_write_service.rb' - - 'app/services/post_status_service.rb' - - 'app/services/process_hashtags_service.rb' - - 'app/workers/move_worker.rb' - - 'app/workers/redownload_avatar_worker.rb' - - 'app/workers/redownload_header_worker.rb' - - 'app/workers/redownload_media_worker.rb' - - 'app/workers/remote_account_refresh_worker.rb' - - 'config/initializers/devise.rb' - - 'lib/devise/strategies/two_factor_ldap_authenticatable.rb' - - 'lib/devise/strategies/two_factor_pam_authenticatable.rb' - - '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' + Enabled: false # This cop supports unsafe autocorrection (--autocorrect-all). Style/HashTransformValues: @@ -166,13 +68,6 @@ Style/HashTransformValues: - 'app/serializers/rest/web_push_subscription_serializer.rb' - 'app/services/import_service.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/IfUnlessModifier: - Exclude: - - 'config/environments/production.rb' - - 'config/initializers/devise.rb' - - 'config/initializers/ffmpeg.rb' - # This cop supports unsafe autocorrection (--autocorrect-all). Style/MapToHash: Exclude: @@ -187,16 +82,10 @@ Style/MutableConstant: - 'app/services/delete_account_service.rb' - 'lib/mastodon/migration_warning.rb' -# This cop supports safe autocorrection (--autocorrect). -Style/NilLambda: - Exclude: - - 'config/initializers/paperclip.rb' - # Configuration parameters: AllowedMethods. # AllowedMethods: respond_to_missing? Style/OptionalBooleanParameter: Exclude: - - 'app/helpers/admin/account_moderation_notes_helper.rb' - 'app/helpers/jsonld_helper.rb' - 'app/lib/admin/system_check/message.rb' - 'app/lib/request.rb' @@ -207,13 +96,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 @@ -227,69 +109,6 @@ Style/RedundantConstantBase: - 'config/environments/production.rb' - 'config/initializers/sidekiq.rb' -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: SafeForConstants. -Style/RedundantFetchBlock: - Exclude: - - 'config/initializers/1_hosts.rb' - - 'config/initializers/chewy.rb' - - 'config/initializers/devise.rb' - - 'config/initializers/paperclip.rb' - - 'config/puma.rb' - -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength. -# AllowedMethods: present?, blank?, presence, try, try! -Style/SafeNavigation: - Exclude: - - 'app/models/concerns/account/finder_concern.rb' - -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: only_raise, only_fail, semantic -Style/SignalException: - Exclude: - - '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 b347b11eac..619b537668 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.3 +3.3.3 diff --git a/.simplecov b/.simplecov deleted file mode 100644 index fbd0207bec..0000000000 --- a/.simplecov +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -if ENV['CI'] - require 'simplecov-lcov' - SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true - SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter -else - SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter -end - -SimpleCov.start 'rails' do - enable_coverage :branch - - add_filter 'lib/linter' - - add_group 'Libraries', 'lib' - add_group 'Policies', 'app/policies' - add_group 'Presenters', 'app/presenters' - add_group 'Serializers', 'app/serializers' - add_group 'Services', 'app/services' - add_group 'Validators', 'app/validators' -end diff --git a/CHANGELOG.md b/CHANGELOG.md index a53790afaf..c9b24d6f15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,61 @@ All notable changes to this project will be documented in this file. +## [4.2.9] - 2024-05-30 + +### Security + +- Update dependencies +- Fix private mention filtering ([GHSA-5fq7-3p3j-9vrf](https://github.com/mastodon/mastodon/security/advisories/GHSA-5fq7-3p3j-9vrf)) +- Fix password change endpoint not being rate-limited ([GHSA-q3rg-xx5v-4mxh](https://github.com/mastodon/mastodon/security/advisories/GHSA-q3rg-xx5v-4mxh)) +- Add hardening around rate-limit bypass ([GHSA-c2r5-cfqr-c553](https://github.com/mastodon/mastodon/security/advisories/GHSA-c2r5-cfqr-c553)) + +### Added + +- Add rate-limit on OAuth application registration ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316)) +- Add fallback redirection when getting a webfinger query `WEB_DOMAIN@WEB_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/28592)) +- Add `digest` attribute to `Admin::DomainBlock` entity in REST API ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/29092)) + +### Removed + +- Remove superfluous application-level caching in some controllers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29862)) +- Remove aggressive OAuth application vacuuming ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30316)) + +### Fixed + +- Fix leaking Elasticsearch connections in Sidekiq processes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30450)) +- Fix language of remote posts not being recognized when using unusual casing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30403)) +- Fix off-by-one in `tootctl media` commands ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30306)) +- Fix removal of allowed domains (in `LIMITED_FEDERATION_MODE`) not being recorded in the audit log ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/30125)) +- Fix not being able to block a subdomain of an already-blocked domain through the API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30119)) +- Fix `Idempotency-Key` being ignored when scheduling a post ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30084)) +- Fix crash when supplying the `FFMPEG_BINARY` environment variable ([timothyjrogers](https://github.com/mastodon/mastodon/pull/30022)) +- Fix improper email address validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29838)) +- Fix results/query in `api/v1/featured_tags/suggestions` ([mjankowski](https://github.com/mastodon/mastodon/pull/29597)) +- Fix unblocking internationalized domain names under certain conditions ([tribela](https://github.com/mastodon/mastodon/pull/29530)) +- Fix admin account created by `mastodon:setup` not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29379)) +- Fix reference to non-existent var in CLI maintenance command ([mjankowski](https://github.com/mastodon/mastodon/pull/28363)) + +## [4.2.8] - 2024-02-23 + +### Added + +- Add hourly task to automatically require approval for new registrations in the absence of moderators ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29318), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/29355)) + In order to prevent future abandoned Mastodon servers from being used for spam, harassment and other malicious activity, Mastodon will now automatically switch new user registrations to require moderator approval whenever they are left open and no activity (including non-moderation actions from apps) from any logged-in user with permission to access moderation reports has been detected in a full week. + When this happens, users with the permission to change server settings will receive an email notification. + This feature is disabled when `EMAIL_DOMAIN_ALLOWLIST` is used, and can also be disabled with `DISABLE_AUTOMATIC_SWITCHING_TO_APPROVED_REGISTRATIONS=true`. + +### Changed + +- Change registrations to be closed by default on new installations ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29280)) + If you are running a server and never changed your registrations mode from the default, updating will automatically close your registrations. + Simply re-enable them through the administration interface or using `tootctl settings registrations open` if you want to enable them again. + +### Fixed + +- Fix processing of remote ActivityPub actors making use of `Link` objects as `Image` `url` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29335)) +- Fix link verifications when page size exceeds 1MB ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29358)) + ## [4.2.7] - 2024-02-16 ### Fixed diff --git a/Dockerfile b/Dockerfile index 119c266b89..c3e43dac8d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,7 @@ -# syntax=docker/dockerfile:1.4 +# syntax=docker/dockerfile:1.8 + +# This file is designed for production server deployment, not local development work +# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker # Please see https://docs.docker.com/engine/reference/builder for information about # the extended buildx capabilities used in this file. @@ -7,29 +10,31 @@ 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.3.x"] +# renovate: datasource=docker depName=docker.io/ruby +ARG RUBY_VERSION="3.3.3" # # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"] +# renovate: datasource=node-version depName=node 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.3.x-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 -# Example: v4.2.0-nightly.2023.11.09+something -# Overwrite existance of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"] +# Example: v4.3.0-nightly.2023.11.09+pr-123456 +# Overwrite existence of 'alpha.X' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"] ARG MASTODON_VERSION_PRERELEASE="" -# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="something"] +# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"] ARG MASTODON_VERSION_METADATA="" # Allow Ruby on Rails to serve static files # 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/master/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" @@ -60,7 +65,9 @@ ENV \ DEBIAN_FRONTEND="noninteractive" \ PATH="${PATH}:/opt/ruby/bin:/opt/mastodon/bin" \ # Optimize jemalloc 5.x performance - MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" + MALLOC_CONF="narenas:2,background_thread:true,thp:never,dirty_decay_ms:1000,muzzy_decay_ms:0" \ +# Enable libvips, should not be changed + MASTODON_USE_LIBVIPS=true # Set default shell used for running commands SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-c"] @@ -93,11 +100,8 @@ RUN \ apt-get dist-upgrade -yq; \ # Install jemalloc, curl and other necessary components apt-get install -y --no-install-recommends \ - ca-certificates \ curl \ - ffmpeg \ file \ - imagemagick \ libjemalloc2 \ patchelf \ procps \ @@ -131,18 +135,47 @@ RUN \ --mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \ # Install build tools and bundler dependencies from APT apt-get install -y --no-install-recommends \ - g++ \ - gcc \ + autoconf \ + automake \ + build-essential \ + cmake \ git \ libgdbm-dev \ + libglib2.0-dev \ libgmp-dev \ libicu-dev \ libidn-dev \ libpq-dev \ libssl-dev \ - make \ + libtool \ + meson \ + nasm \ + pkg-config \ shared-mime-info \ - zlib1g-dev \ + xz-utils \ + # libvips components + libcgif-dev \ + libexif-dev \ + libexpat1-dev \ + libgirepository1.0-dev \ + libheif-dev \ + libimagequant-dev \ + libjpeg62-turbo-dev \ + liblcms2-dev \ + liborc-dev \ + libspng-dev \ + libtiff-dev \ + libwebp-dev \ + # ffmpeg components + libdav1d-dev \ + liblzma-dev \ + libmp3lame-dev \ + libopus-dev \ + libsnappy-dev \ + libvorbis-dev \ + libvpx-dev \ + libx264-dev \ + libx265-dev \ ; RUN \ @@ -151,6 +184,68 @@ RUN \ corepack enable; \ corepack prepare --activate; +# Create temporary libvips specific build layer from build layer +FROM build as libvips + +# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"] +# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips +ARG VIPS_VERSION=8.15.2 +# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"] +ARG VIPS_URL=https://github.com/libvips/libvips/releases/download + +WORKDIR /usr/local/libvips/src + +RUN \ + curl -sSL -o vips-${VIPS_VERSION}.tar.xz ${VIPS_URL}/v${VIPS_VERSION}/vips-${VIPS_VERSION}.tar.xz; \ + tar xf vips-${VIPS_VERSION}.tar.xz; \ + cd vips-${VIPS_VERSION}; \ + meson setup build --prefix /usr/local/libvips --libdir=lib -Ddeprecated=false -Dintrospection=disabled -Dmodules=disabled -Dexamples=false; \ + cd build; \ + ninja; \ + ninja install; + +# Create temporary ffmpeg specific build layer from build layer +FROM build as ffmpeg + +# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"] +# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg +ARG FFMPEG_VERSION=7.0.1 +# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"] +ARG FFMPEG_URL=https://ffmpeg.org/releases + +WORKDIR /usr/local/ffmpeg/src + +RUN \ + curl -sSL -o ffmpeg-${FFMPEG_VERSION}.tar.xz ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz; \ + tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz; \ + cd ffmpeg-${FFMPEG_VERSION}; \ + ./configure \ + --prefix=/usr/local/ffmpeg \ + --toolchain=hardened \ + --disable-debug \ + --disable-devices \ + --disable-doc \ + --disable-ffplay \ + --disable-network \ + --disable-static \ + --enable-ffmpeg \ + --enable-ffprobe \ + --enable-gpl \ + --enable-libdav1d \ + --enable-libmp3lame \ + --enable-libopus \ + --enable-libsnappy \ + --enable-libvorbis \ + --enable-libvpx \ + --enable-libwebp \ + --enable-libx264 \ + --enable-libx265 \ + --enable-shared \ + --enable-version3 \ + ; \ + make -j$(nproc); \ + make install; + # Create temporary bundler specific build layer from build layer FROM build as bundler @@ -200,12 +295,17 @@ COPY . /opt/mastodon/ COPY --from=yarn /opt/mastodon /opt/mastodon/ COPY --from=bundler /opt/mastodon /opt/mastodon/ COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/ +# Copy libvips components to layer for precompiler +COPY --from=libvips /usr/local/libvips/bin /usr/local/bin +COPY --from=libvips /usr/local/libvips/lib /usr/local/lib ARG TARGETPLATFORM RUN \ + ldconfig; \ # Use Ruby on Rails to create Mastodon assets - OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder bundle exec rails assets:precompile; \ + SECRET_KEY_BASE_DUMMY=1 \ + bundle exec rails assets:precompile; \ # Cleanup temporary files rm -fr /opt/mastodon/tmp; @@ -224,12 +324,41 @@ RUN \ --mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \ # Apt update install non-dev versions of necessary components apt-get install -y --no-install-recommends \ - libssl3 \ - libpq5 \ + libexpat1 \ + libglib2.0-0 \ libicu72 \ libidn12 \ + libpq5 \ libreadline8 \ + libssl3 \ libyaml-0-2 \ + # libvips components + libcgif0 \ + libexif12 \ + libheif1 \ + libimagequant0 \ + libjpeg62-turbo \ + liblcms2-2 \ + liborc-0.4-0 \ + libspng0 \ + libtiff6 \ + libwebp7 \ + libwebpdemux2 \ + libwebpmux3 \ + # ffmpeg components + libdav1d6 \ + libmp3lame0 \ + libopencore-amrnb0 \ + libopencore-amrwb0 \ + libopus0 \ + libsnappy1v5 \ + libtheora0 \ + libvorbis0a \ + libvorbisenc2 \ + libvorbisfile3 \ + libvpx7 \ + libx264-164 \ + libx265-199 \ ; # Copy Mastodon sources into final layer @@ -240,9 +369,22 @@ COPY --from=precompiler /opt/mastodon/public/packs /opt/mastodon/public/packs COPY --from=precompiler /opt/mastodon/public/assets /opt/mastodon/public/assets # Copy bundler components to layer COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/ +# Copy libvips components to layer +COPY --from=libvips /usr/local/libvips/bin /usr/local/bin +COPY --from=libvips /usr/local/libvips/lib /usr/local/lib +# Copy ffpmeg components to layer +COPY --from=ffmpeg /usr/local/ffmpeg/bin /usr/local/bin +COPY --from=ffmpeg /usr/local/ffmpeg/lib /usr/local/lib RUN \ -# Precompile bootsnap code for faster Rails startup + ldconfig; \ +# Smoketest media processors + vips -v; \ + ffmpeg -version; \ + ffprobe -version; + +RUN \ + # Precompile bootsnap code for faster Rails startup bundle exec bootsnap precompile --gemfile app/ lib/; RUN \ @@ -257,4 +399,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 355e69b0c4..f2d7d098d5 100644 --- a/Gemfile +++ b/Gemfile @@ -1,28 +1,26 @@ # 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 'ruby-vips', '~> 2.2', require: false gem 'active_model_serializers', '~> 0.10' gem 'addressable', '~> 2.8' @@ -31,7 +29,7 @@ gem 'browser' gem 'charlock_holmes', '~> 0.7.7' gem 'chewy', '~> 7.3' gem 'devise', '~> 4.9' -gem 'devise-two-factor', '~> 4.1' +gem 'devise-two-factor' group :pam_authentication, optional: true do gem 'devise_pam_authenticatable2', '~> 9.2' @@ -39,11 +37,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,48 +51,50 @@ 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 'httplog', '~> 1.7.0' +gem 'i18n' gem 'idn-ruby', require: 'idn' +gem 'inline_svg' +gem 'irb', '~> 1.8' 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 'public_suffix', '~> 5.0' -gem 'pundit', '~> 2.3' gem 'premailer-rails' +gem 'public_suffix', '~> 6.0' +gem 'pundit', '~> 2.3' 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 'strong_migrations', '1.7.0' +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' @@ -102,6 +102,26 @@ gem 'rdf-normalize', '~> 0.5' gem 'private_address_check', '~> 0.5' +gem 'opentelemetry-api', '~> 1.2.5' + +group :opentelemetry do + gem 'opentelemetry-exporter-otlp', '~> 0.28.0', require: false + gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false + gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false + gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false + gem 'opentelemetry-instrumentation-excon', '~> 0.22.0', require: false + gem 'opentelemetry-instrumentation-faraday', '~> 0.24.1', require: false + gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false + gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false + gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false + gem 'opentelemetry-instrumentation-pg', '~> 0.27.1', require: false + gem 'opentelemetry-instrumentation-rack', '~> 0.24.1', require: false + gem 'opentelemetry-instrumentation-rails', '~> 0.30.0', require: false + gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false + gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false + gem 'opentelemetry-sdk', '~> 1.4', require: false +end + group :test do # Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab gem 'rspec-github', '~> 2.4', require: false @@ -112,8 +132,8 @@ group :test do # RSpec helpers for email specs gem 'email_spec' - # Extra RSpec extenion methods and helpers for sidekiq - gem 'rspec-sidekiq', '~> 4.0' + # Extra RSpec extension methods and helpers for sidekiq + gem 'rspec-sidekiq', '~> 5.0' # Browser integration testing gem 'capybara', '~> 3.39' @@ -149,6 +169,7 @@ group :development do gem 'rubocop-performance', require: false gem 'rubocop-rails', require: false gem 'rubocop-rspec', require: false + gem 'rubocop-rspec_rails', require: false # Annotates modules with schema gem 'annotate', '~> 3.2' @@ -159,7 +180,7 @@ group :development do # Preview mail in the browser gem 'letter_opener', '~> 1.8' - gem 'letter_opener_web', '~> 2.0' + gem 'letter_opener_web', '~> 3.0' # Security analysis CLI tools gem 'brakeman', '~> 6.0', require: false @@ -196,12 +217,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 79d3b1e637..0fe1c03b25 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -10,35 +10,35 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) + actioncable (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) + actionmailbox (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.3) - actionpack (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activesupport (= 7.1.3) + actionmailer (7.1.3.4) + actionpack (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activesupport (= 7.1.3.4) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.3) - actionview (= 7.1.3) - activesupport (= 7.1.3) + actionpack (7.1.3.4) + actionview (= 7.1.3.4) + activesupport (= 7.1.3.4) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -46,15 +46,15 @@ GEM rack-test (>= 0.6.3) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - actiontext (7.1.3) - actionpack (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) + actiontext (7.1.3.4) + actionpack (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.3) - activesupport (= 7.1.3) + actionview (7.1.3.4) + activesupport (= 7.1.3.4) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -64,22 +64,22 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.1.3) - activesupport (= 7.1.3) + activejob (7.1.3.4) + activesupport (= 7.1.3.4) globalid (>= 0.3.6) - activemodel (7.1.3) - activesupport (= 7.1.3) - activerecord (7.1.3) - activemodel (= 7.1.3) - activesupport (= 7.1.3) + activemodel (7.1.3.4) + activesupport (= 7.1.3.4) + activerecord (7.1.3.4) + activemodel (= 7.1.3.4) + activesupport (= 7.1.3.4) timeout (>= 0.4.0) - activestorage (7.1.3) - actionpack (= 7.1.3) - activejob (= 7.1.3) - activerecord (= 7.1.3) - activesupport (= 7.1.3) + activestorage (7.1.3.4) + actionpack (= 7.1.3.4) + activejob (= 7.1.3.4) + activerecord (= 7.1.3.4) + activesupport (= 7.1.3.4) marcel (~> 1.0) - activesupport (7.1.3) + activesupport (7.1.3.4) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) @@ -89,30 +89,28 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.6) - public_suffix (>= 2.0.2, < 6.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) aes_key_wrap (1.1.0) android_key_attestation (0.3.0) annotate (3.2.0) activerecord (>= 3.2, < 8.0) rake (>= 10.4, < 14.0) 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.940.0) + aws-sdk-core (3.197.0) 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.83.0) + aws-sdk-core (~> 3, >= 3.197.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.142.0) - aws-sdk-core (~> 3, >= 3.189.0) + aws-sdk-s3 (1.152.3) + aws-sdk-core (~> 3, >= 3.197.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.8) aws-sigv4 (1.8.0) @@ -132,17 +130,10 @@ GEM erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - better_html (2.0.2) - actionview (>= 6.0) - activesupport (>= 6.0) - ast (~> 2.0) - erubi (~> 1.4) - parser (>= 2.4) - smart_properties - bigdecimal (3.1.6) - bindata (2.4.15) - binding_of_caller (1.0.0) - debug_inspector (>= 0.0.1) + bigdecimal (3.1.8) + 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) @@ -152,7 +143,7 @@ GEM brpoplpush-redis_script (0.1.3) concurrent-ruby (~> 1.0, >= 1.0.5) redis (>= 1.0, < 6) - builder (3.2.4) + builder (3.3.0) bundler-audit (0.9.1) bundler (>= 1.2.0, < 3) thor (~> 1.0) @@ -167,87 +158,80 @@ 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) + chewy (7.6.0) activesupport (>= 5.2) - elasticsearch (>= 7.12.0, < 7.14.0) + elasticsearch (>= 7.14.0, < 8) elasticsearch-dsl chunky_png (1.4.0) climate_control (1.2.0) cocoon (1.2.15) color_diff (0.1) - concurrent-ruby (1.2.3) + concurrent-ruby (1.3.3) connection_pool (2.4.1) 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) responders warden (~> 1.2.3) - devise-two-factor (4.1.1) + devise-two-factor (5.1.0) activesupport (~> 7.0) - attr_encrypted (>= 1.3, < 5, != 2) devise (~> 4.0) railties (~> 7.0) rotp (~> 6.0) devise_pam_authenticatable2 (9.2.0) devise (>= 4.0.0) rpam2 (~> 4.0) - diff-lcs (1.5.0) + diff-lcs (1.5.1) 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) - drb (2.2.0) - ruby2_keywords + dotenv (3.1.2) + drb (2.2.1) ed25519 (1.3.0) - elasticsearch (7.13.3) - elasticsearch-api (= 7.13.3) - elasticsearch-transport (= 7.13.3) - elasticsearch-api (7.13.3) + elasticsearch (7.17.10) + elasticsearch-api (= 7.17.10) + elasticsearch-transport (= 7.17.10) + elasticsearch-api (7.17.10) multi_json elasticsearch-dsl (0.1.10) - elasticsearch-transport (7.13.3) - faraday (~> 1) + elasticsearch-transport (7.17.10) + faraday (>= 1, < 3) multi_json email_spec (2.2.2) htmlentities (~> 4.3.3) launchy (~> 2.1) mail (~> 2.7) - encryptor (3.0.0) - erubi (1.12.0) - et-orbi (1.2.7) + erubi (1.13.0) + et-orbi (1.2.11) tzinfo - excon (0.109.0) + excon (0.110.0) fabrication (2.31.0) - faker (3.2.3) + faker (3.4.1) i18n (>= 1.8.11, < 2) faraday (1.10.3) faraday-em_http (~> 1.0) @@ -275,10 +259,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 @@ -288,11 +272,11 @@ GEM fog-json (1.2.0) fog-core multi_json (~> 1.10) - fog-openstack (1.1.0) + fog-openstack (1.1.3) 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) @@ -300,6 +284,9 @@ GEM ruby-progressbar (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) + google-protobuf (3.25.3) + googleapis-common-protos-types (1.14.0) + google-protobuf (~> 3.18) haml (6.3.0) temple (>= 0.8.2) thor @@ -309,7 +296,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.56.0) + haml_lint (0.58.0) haml (>= 5.0) parallel (~> 1.10) rainbow @@ -319,29 +306,29 @@ 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) http_accept_language (2.1.1) httpclient (2.8.3) - httplog (1.6.2) + httplog (1.7.0) rack (>= 2.0) rainbow (>= 2.0.0) - i18n (1.14.1) + i18n (1.14.5) concurrent-ruby (~> 1.0) - i18n-tasks (1.0.13) + i18n-tasks (1.0.14) activesupport (>= 4.0.2) ast (>= 2.1.0) - better_html (>= 1.0, < 3.0) erubi highline (>= 2.0.0) i18n @@ -350,14 +337,17 @@ GEM rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) idn-ruby (0.1.5) + inline_svg (1.9.0) + activesupport (>= 3.0) + nokogiri (>= 1.6) io-console (0.7.2) - irb (1.11.2) - rdoc + irb (1.13.2) + rdoc (>= 4.0.0) 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) + json-jwt (1.15.3.1) activesupport (>= 4.2) aes_key_wrap bindata @@ -372,7 +362,7 @@ GEM json-ld-preloaded (3.3.0) json-ld (~> 3.3) rdf (~> 3.3) - json-schema (4.1.1) + json-schema (4.3.0) addressable (>= 2.8) jsonapi-renderer (0.2.2) jwt (2.7.1) @@ -397,17 +387,18 @@ 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_web (2.0.0) - actionmailer (>= 5.2) - letter_opener (~> 1.7) - railties (>= 5.2) + letter_opener (1.10.0) + launchy (>= 2.2, < 4) + letter_opener_web (3.0.0) + actionmailer (>= 6.1) + letter_opener (~> 1.9) + railties (>= 6.1) rexml link_header (0.0.8) - llhttp-ffi (0.4.0) + llhttp-ffi (0.5.0) ffi-compiler (~> 1.0) rake (~> 13.0) + logger (1.6.0) lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) @@ -421,7 +412,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) @@ -429,22 +420,22 @@ GEM addressable (~> 2.5) azure-storage-blob (~> 2.0.1) hashie (~> 5.0) - memory_profiler (1.0.1) + memory_profiler (1.0.2) mime-types (3.5.2) mime-types-data (~> 3.2015) - mime-types-data (3.2023.1205) + mime-types-data (3.2024.0604) mini_mime (1.1.5) - mini_portile2 (2.8.5) - minitest (5.21.2) + mini_portile2 (2.8.7) + minitest (5.23.1) 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 net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.4.9.1) + net-imap (0.4.12) date net-protocol net-ldap (0.19.0) @@ -452,10 +443,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.2) + nio4r (2.7.3) + nokogiri (1.16.6) mini_portile2 (~> 2.8.2) racc (~> 1.4) nsa (0.3.0) @@ -463,13 +454,13 @@ GEM concurrent-ruby (~> 1.0, >= 1.0.2) sidekiq (>= 3.5) statsd-ruby (~> 1.4, >= 1.4.0) - oj (3.16.3) + oj (3.16.4) bigdecimal (>= 3.0) - omniauth (2.1.1) + omniauth (2.1.2) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection - omniauth-cas (3.0.0.beta.1) + omniauth-cas (3.0.0) addressable (~> 2.8) nokogiri (~> 1.12) omniauth (~> 2.1) @@ -496,20 +487,107 @@ GEM openssl (3.2.0) openssl-signature_algorithm (1.3.0) openssl (> 2.0) + opentelemetry-api (1.2.5) + opentelemetry-common (0.20.1) + opentelemetry-api (~> 1.0) + opentelemetry-exporter-otlp (0.28.0) + google-protobuf (>= 3.18) + googleapis-common-protos-types (~> 1.3) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-sdk (~> 1.2) + opentelemetry-semantic_conventions + opentelemetry-helpers-sql-obfuscation (0.1.0) + opentelemetry-common (~> 0.20) + opentelemetry-instrumentation-action_mailer (0.1.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.1) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-action_pack (0.9.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-rack (~> 0.21) + opentelemetry-instrumentation-action_view (0.7.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.1) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-active_job (0.7.1) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-active_model_serializers (0.20.1) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-active_record (0.7.2) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-active_support (0.5.1) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-base (0.22.3) + opentelemetry-api (~> 1.0) + opentelemetry-registry (~> 0.1) + opentelemetry-instrumentation-concurrent_ruby (0.21.3) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-excon (0.22.3) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-faraday (0.24.4) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-http (0.23.3) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-http_client (0.22.6) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-net_http (0.22.6) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-pg (0.27.3) + opentelemetry-api (~> 1.0) + opentelemetry-helpers-sql-obfuscation + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-rack (0.24.5) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-rails (0.30.2) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-action_mailer (~> 0.1.0) + opentelemetry-instrumentation-action_pack (~> 0.9.0) + opentelemetry-instrumentation-action_view (~> 0.7.0) + opentelemetry-instrumentation-active_job (~> 0.7.0) + opentelemetry-instrumentation-active_record (~> 0.7.0) + opentelemetry-instrumentation-active_support (~> 0.5.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-redis (0.25.6) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-sidekiq (0.25.5) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-registry (0.3.1) + opentelemetry-api (~> 1.1) + opentelemetry-sdk (1.4.1) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-registry (~> 0.2) + opentelemetry-semantic_conventions + opentelemetry-semantic_conventions (1.10.0) + opentelemetry-api (~> 1.0) orm_adapter (0.5.0) - ox (2.14.17) - parallel (1.24.0) - parser (3.3.0.5) + ox (2.14.18) + parallel (1.25.1) + parser (3.3.3.0) ast (~> 2.4.1) racc parslet (2.0.0) pastel (0.8.0) tty-color (~> 0.5) - pg (1.5.5) - pghero (3.4.1) + pg (1.5.6) + pghero (3.5.0) 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) @@ -518,24 +596,24 @@ GEM net-smtp premailer (~> 1.7, >= 1.7.9) private_address_check (0.5.0) - propshaft (0.8.0) + propshaft (0.9.0) actionpack (>= 7.0.0) activesupport (>= 7.0.0) rack railties (>= 7.0.0) psych (5.1.2) stringio - public_suffix (5.0.4) + public_suffix (6.0.0) puma (6.4.2) nio4r (~> 2.0) - pundit (2.3.1) + pundit (2.3.2) activesupport (>= 3.0.0) raabro (1.4.0) - racc (1.7.3) - rack (2.2.8) + racc (1.8.0) + rack (2.2.9) rack-attack (6.7.0) rack (>= 1.0, < 4) - rack-cors (2.0.1) + rack-cors (2.0.2) rack (>= 2.0.0) rack-oauth2 (1.21.3) activesupport @@ -543,9 +621,10 @@ GEM httpclient json-jwt (>= 1.11.0) rack (>= 2.1.0) - rack-protection (3.0.5) - rack - rack-proxy (0.7.6) + rack-protection (3.2.0) + base64 (>= 0.1.0) + rack (~> 2.2, >= 2.2.4) + rack-proxy (0.7.7) rack rack-session (1.0.2) rack (< 3) @@ -554,20 +633,20 @@ GEM rackup (1.0.0) rack (< 3) webrick - rails (7.1.3) - actioncable (= 7.1.3) - actionmailbox (= 7.1.3) - actionmailer (= 7.1.3) - actionpack (= 7.1.3) - actiontext (= 7.1.3) - actionview (= 7.1.3) - activejob (= 7.1.3) - activemodel (= 7.1.3) - activerecord (= 7.1.3) - activestorage (= 7.1.3) - activesupport (= 7.1.3) + rails (7.1.3.4) + actioncable (= 7.1.3.4) + actionmailbox (= 7.1.3.4) + actionmailer (= 7.1.3.4) + actionpack (= 7.1.3.4) + actiontext (= 7.1.3.4) + actionview (= 7.1.3.4) + activejob (= 7.1.3.4) + activemodel (= 7.1.3.4) + activerecord (= 7.1.3.4) + activestorage (= 7.1.3.4) + activesupport (= 7.1.3.4) bundler (>= 1.15.0) - railties (= 7.1.3) + railties (= 7.1.3.4) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -579,25 +658,25 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - rails-i18n (7.0.8) + rails-i18n (7.0.9) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.3) - actionpack (= 7.1.3) - activesupport (= 7.1.3) + railties (7.1.3.4) + actionpack (= 7.1.3.4) + activesupport (= 7.1.3.4) irb rackup (>= 1.0.0) rake (>= 12.2) 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) rdf-normalize (0.7.0) rdf (~> 3.3) - rdoc (6.6.2) + rdoc (6.7.0) psych (>= 4.0.0) redcarpet (3.6.0) redis (4.8.1) @@ -605,47 +684,48 @@ GEM redis (>= 4) redlock (1.3.2) redis (>= 3.0.0, < 6.0) - regexp_parser (2.9.0) - reline (0.4.2) + regexp_parser (2.9.2) + reline (0.5.9) 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) + rexml (3.3.0) + strscan rotp (6.3.0) - rouge (4.1.2) + rouge (4.2.1) rpam2 (4.0.2) rqrcode (2.2.0) chunky_png (~> 1.0) rqrcode_core (~> 1.0) rqrcode_core (1.2.0) - rspec-core (3.12.2) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.3) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) + rspec-support (~> 3.13.0) rspec-github (2.4.0) rspec-core (~> 3.0) - rspec-mocks (3.12.6) + rspec-mocks (3.13.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-rails (6.1.1) + rspec-support (~> 3.13.0) + rspec-rails (6.1.3) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) - rspec-core (~> 3.12) - rspec-expectations (~> 3.12) - rspec-mocks (~> 3.12) - rspec-support (~> 3.12) - rspec-sidekiq (4.1.0) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-sidekiq (5.0.0) rspec-core (~> 3.0) rspec-expectations (~> 3.0) rspec-mocks (~> 3.0) sidekiq (>= 5, < 8) - rspec-support (3.12.1) - rubocop (1.60.2) + rspec-support (3.13.1) + rubocop (1.64.1) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -653,46 +733,48 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.30.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.30.0) - parser (>= 3.2.1.0) - rubocop-capybara (2.20.0) + rubocop-ast (1.31.3) + parser (>= 3.3.1.0) + rubocop-capybara (2.21.0) rubocop (~> 1.41) - rubocop-factory_bot (2.25.0) - rubocop (~> 1.33) - rubocop-performance (1.20.2) + rubocop-performance (1.21.1) rubocop (>= 1.48.1, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rails (2.23.1) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rails (2.25.0) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) - rubocop-ast (>= 1.30.0, < 2.0) - rubocop-rspec (2.26.1) - rubocop (~> 1.40) - rubocop-capybara (~> 2.17) - rubocop-factory_bot (~> 2.22) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (3.0.1) + rubocop (~> 1.61) + rubocop-rspec_rails (2.30.0) + rubocop (~> 1.61) + rubocop-rspec (~> 3, >= 3.0.1) 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 + ruby-vips (2.2.1) + ffi (~> 1.12) ruby2_keywords (0.0.5) rubyzip (2.3.2) rufus-scheduler (3.9.1) fugit (~> 1.1, >= 1.1.6) safety_net_attestation (0.4.0) jwt (~> 2.0) - sanitize (6.1.0) + sanitize (6.1.1) 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.17.0) + selenium-webdriver (4.22.0) base64 (~> 0.2) + logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) @@ -715,7 +797,7 @@ GEM thor (>= 0.20, < 3.0) simple-navigation (4.4.0) activesupport (>= 2.3.2) - simple_form (5.3.0) + simple_form (5.3.1) actionpack (>= 5.2) activemodel (>= 5.2) simplecov (0.22.0) @@ -725,14 +807,14 @@ GEM simplecov-html (0.12.3) simplecov-lcov (0.8.0) simplecov_json_formatter (0.1.4) - 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.7.0) + stringio (3.1.1) + strong_migrations (1.8.0) activerecord (>= 5.2) + strscan (3.1.0) swd (1.3.0) activesupport (>= 3) attr_required (>= 0.0.5) @@ -743,8 +825,8 @@ GEM unicode-display_width (>= 1.1.1, < 3) terrapin (1.0.1) climate_control - test-prof (1.3.1) - thor (1.3.0) + test-prof (1.3.3) + thor (1.3.1) tilt (2.3.0) timeout (0.4.1) tpm-key_attestation (0.12.0) @@ -760,7 +842,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) @@ -770,9 +852,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) @@ -793,7 +875,7 @@ GEM webfinger (1.2.0) activesupport httpclient (>= 2.4) - webmock (3.20.0) + webmock (3.23.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -811,7 +893,7 @@ GEM xorcist (1.1.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.13) + zeitwerk (2.6.16) PLATFORMS ruby @@ -840,11 +922,11 @@ DEPENDENCIES database_cleaner-active_record debug (~> 1.8) devise (~> 4.9) - devise-two-factor (~> 4.1) + devise-two-factor devise_pam_authenticatable2 (~> 9.2) discard (~> 1.2) doorkeeper (~> 5.6) - dotenv-rails (~> 2.8) + dotenv ed25519 (~> 1.3) email_spec fabrication (~> 2.30) @@ -859,11 +941,13 @@ 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) + httplog (~> 1.7.0) + i18n i18n-tasks (~> 1.0) idn-ruby + inline_svg irb (~> 1.8) json-ld json-ld-preloaded (~> 3.2) @@ -871,9 +955,10 @@ DEPENDENCIES kaminari (~> 1.2) kt-paperclip (~> 7.2) letter_opener (~> 1.8) - letter_opener_web (~> 2.0) + letter_opener_web (~> 3.0) link_header (~> 0.0) lograge (~> 0.12) + mail (~> 2.8) mario-redis-lock (~> 1.2) md-paperclip-azure (~> 2.2) memory_profiler @@ -888,15 +973,30 @@ DEPENDENCIES omniauth-rails_csrf_protection (~> 1.0) omniauth-saml (~> 2.0) omniauth_openid_connect (~> 0.6.1) + opentelemetry-api (~> 1.2.5) + opentelemetry-exporter-otlp (~> 0.28.0) + opentelemetry-instrumentation-active_job (~> 0.7.1) + opentelemetry-instrumentation-active_model_serializers (~> 0.20.1) + opentelemetry-instrumentation-concurrent_ruby (~> 0.21.2) + opentelemetry-instrumentation-excon (~> 0.22.0) + opentelemetry-instrumentation-faraday (~> 0.24.1) + opentelemetry-instrumentation-http (~> 0.23.2) + opentelemetry-instrumentation-http_client (~> 0.22.3) + opentelemetry-instrumentation-net_http (~> 0.22.4) + opentelemetry-instrumentation-pg (~> 0.27.1) + opentelemetry-instrumentation-rack (~> 0.24.1) + opentelemetry-instrumentation-rails (~> 0.30.0) + opentelemetry-instrumentation-redis (~> 0.25.3) + opentelemetry-instrumentation-sidekiq (~> 0.25.2) + opentelemetry-sdk (~> 1.4) ox (~> 2.14) parslet pg (~> 1.5) pghero - posix-spawn premailer-rails private_address_check (~> 0.5) propshaft - public_suffix (~> 5.0) + public_suffix (~> 6.0) puma (~> 6.3) pundit (~> 2.3) rack (~> 2.2.7) @@ -913,14 +1013,16 @@ DEPENDENCIES rqrcode (~> 2.2) rspec-github (~> 2.4) rspec-rails (~> 6.0) - rspec-sidekiq (~> 4.0) + rspec-sidekiq (~> 5.0) rubocop rubocop-capybara rubocop-performance rubocop-rails rubocop-rspec + rubocop-rspec_rails ruby-prof ruby-progressbar (~> 1.13) + ruby-vips (~> 2.2) rubyzip (~> 2.3) sanitize (~> 6.0) scenic (~> 1.7) @@ -934,8 +1036,8 @@ DEPENDENCIES simplecov (~> 0.22) simplecov-lcov (~> 0.8) stackprof - stoplight (~> 3.0.1) - strong_migrations (= 1.7.0) + stoplight (~> 4.1) + strong_migrations (= 1.8.0) test-prof thor (~> 1.2) tty-prompt (~> 0.23) @@ -948,7 +1050,7 @@ DEPENDENCIES xorcist (~> 1.1) RUBY VERSION - ruby 3.2.2p53 + ruby 3.3.2p78 BUNDLED WITH - 2.5.4 + 2.5.11 diff --git a/README.md b/README.md index 6cf722b355..9c0b0d20ed 100644 --- a/README.md +++ b/README.md @@ -62,17 +62,17 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre ### Tech stack - **Ruby on Rails** powers the REST API and other web pages -- **React.js** and Redux are used for the dynamic parts of the interface +- **React.js** and **Redux** are used for the dynamic parts of the interface - **Node.js** powers the streaming API ### Requirements - **PostgreSQL** 12+ - **Redis** 4+ -- **Ruby** 3.0+ -- **Node.js** 16+ +- **Ruby** 3.1+ +- **Node.js** 18+ -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. +The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. 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. ## Development @@ -83,45 +83,54 @@ A **Vagrant** configuration is included for development purposes. To use it, com - Install Vagrant and Virtualbox - Install the `vagrant-hostsupdater` plugin: `vagrant plugin install vagrant-hostsupdater` - Run `vagrant up` -- Run `vagrant ssh -c "cd /vagrant && foreman start"` +- Run `vagrant ssh -c "cd /vagrant && bin/dev"` - Open `http://mastodon.local` in your browser -### MacOS +### macOS -To set up **MacOS** for native development, complete the following steps: +To set up **macOS** for native development, complete the following steps: -- Install the latest stable Ruby version (use a Ruby version manager for easy installation and management of Ruby versions) -- Run `brew install postgresql@14` -- Run `brew install redis` -- Run `brew install imagemagick` -- Run `brew install libidn` -- Install Foreman or a similar tool (such as [overmind](https://github.com/DarthSim/overmind)) to handle multiple process launching. -- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from .nvmrc -- Run `corepack enable && corepack prepare` -- Run `bundle exec rails db:setup` (optionally prepend `RAILS_ENV=development` to target the dev environment) -- Finally, run `overmind start -f Procfile.dev` +- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick +libidn nvm` to install the required project dependencies +- Use a Ruby version manager to activate the ruby in `.ruby-version` and run + `nvm use` to activate the node version from `.nvmrc` +- Run the `bin/setup` script, which will install the required ruby gems and node + packages and prepare the database for local development +- Finally, run the `bin/dev` script which will launch services via `overmind` + (if installed) or `foreman` ### Docker -For development with **Docker**, complete the following steps: +For production hosting and deployment with **Docker**, use the `Dockerfile` and +`docker-compose.yml` in the project root directory. -- Install Docker Desktop -- Run `docker compose -f .devcontainer/docker-compose.yml up -d` -- Run `docker compose -f .devcontainer/docker-compose.yml exec app .devcontainer/post-create.sh` -- Finally, run `docker compose -f .devcontainer/docker-compose.yml exec app foreman start -f Procfile.dev` +For local development, install and launch [Docker], and run: -If you are using an IDE with [support for the Development Container specification](https://containers.dev/supporting), it will run the above `docker compose` commands automatically. For **Visual Studio Code** this requires the [Dev Container extension](https://containers.dev/supporting#dev-containers). +```shell +docker compose -f .devcontainer/compose.yaml up -d +docker compose -f .devcontainer/compose.yaml exec app bin/setup +docker compose -f .devcontainer/compose.yaml exec app bin/dev +``` + +### Dev Containers + +Within IDEs that support the [Development Containers] specification, start the +"Mastodon on local machine" container from the editor. The necessary `docker +compose` commands to build and setup the container should run automatically. For +**Visual Studio Code** this requires installing the [Dev Container extension]. ### GitHub Codespaces -To get you coding in just a few minutes, GitHub Codespaces provides a web-based version of Visual Studio Code and a cloud-hosted development environment fully configured with the software needed for this project.. +[GitHub Codespaces] provides a web-based version of VS Code and a cloud hosted +development environment configured with the software needed for this project. -- Click this button to create a new codespace:
- [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json) -- Wait for the environment to build. This will take a few minutes. -- When the editor is ready, run `foreman start -f Procfile.dev` in the terminal. -- After a few seconds, a popup will appear with a button labeled _Open in Browser_. This will open Mastodon. -- On the _Ports_ tab, right click on the โ€œstreamโ€ row and select _Port visibility_ โ†’ _Public_. +[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)][codespace] + +- Click the button to create a new codespace, and confirm the options +- Wait for the environment to build (takes a few minutes) +- When the editor is ready, run `bin/dev` in the terminal +- Wait for an _Open in Browser_ prompt. This will open Mastodon +- On the _Ports_ tab "stream" setting change _Port visibility_ โ†’ _Public_ ## Contributing @@ -140,3 +149,10 @@ This program is free software: you can redistribute it and/or modify it under th This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . + +[codespace]: https://codespaces.new/mastodon/mastodon?quickstart=1&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json +[Dev Container extension]: https://containers.dev/supporting#dev-containers +[Development Containers]: https://containers.dev/supporting +[Docker]: https://docs.docker.com +[GitHub Codespaces]: https://docs.github.com/en/codespaces +[Homebrew]: https://brew.sh diff --git a/SECURITY.md b/SECURITY.md index 81472b01b4..156954ce02 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either: -- open a [Github security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new) +- open a [GitHub security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new) - reach us at You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk. diff --git a/Vagrantfile b/Vagrantfile index 6f0f511095..89f5536edc 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -151,6 +151,12 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| vb.customize ["modifyvm", :id, "--nictype2", "virtio"] end + config.vm.provider :libvirt do |libvirt| + libvirt.cpus = 3 + libvirt.memory = 8192 + end + + # This uses the vagrant-hostsupdater plugin, and lets you # access the development site at http://mastodon.local. # If you change it, also change it in .env.vagrant before provisioning @@ -173,6 +179,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 @@ -188,7 +195,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.post_up_message = < { 'Signature' if authorized_fetch_mode? } before_action :require_account_signature!, if: :authorized_fetch_mode? @@ -21,7 +18,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController def set_items case params[:id] when 'featured' - @items = for_signed_account { cache_collection(@account.pinned_statuses, Status) } + @items = for_signed_account { preload_collection(@account.pinned_statuses, Status) } @items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) } when 'tags' @items = for_signed_account { @account.featured_tags } diff --git a/app/controllers/activitypub/followers_synchronizations_controller.rb b/app/controllers/activitypub/followers_synchronizations_controller.rb index d2942104e5..392dd36bcd 100644 --- a/app/controllers/activitypub/followers_synchronizations_controller.rb +++ b/app/controllers/activitypub/followers_synchronizations_controller.rb @@ -1,9 +1,6 @@ # frozen_string_literal: true class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseController - include SignatureVerification - include AccountOwnedConcern - vary_by -> { 'Signature' if authorized_fetch_mode? } before_action :require_account_signature! diff --git a/app/controllers/activitypub/inboxes_controller.rb b/app/controllers/activitypub/inboxes_controller.rb index e8b0f47cde..49cfc8ad1c 100644 --- a/app/controllers/activitypub/inboxes_controller.rb +++ b/app/controllers/activitypub/inboxes_controller.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class ActivityPub::InboxesController < ActivityPub::BaseController - include SignatureVerification include JsonLdHelper - include AccountOwnedConcern before_action :skip_unknown_actor_activity before_action :require_actor_signature! diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb index bf10ba762a..b8baf64e1a 100644 --- a/app/controllers/activitypub/outboxes_controller.rb +++ b/app/controllers/activitypub/outboxes_controller.rb @@ -3,9 +3,6 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController LIMIT = 20 - include SignatureVerification - include AccountOwnedConcern - vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? } before_action :require_account_signature!, if: :authorized_fetch_mode? @@ -63,7 +60,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController def set_statuses return unless page_requested? - @statuses = cache_collection_paginated_by_id( + @statuses = preload_collection_paginated_by_id( AccountStatusesFilter.new(@account, signed_request_account).results, Status, LIMIT, diff --git a/app/controllers/activitypub/replies_controller.rb b/app/controllers/activitypub/replies_controller.rb index c38ff89d1c..11aac48c9c 100644 --- a/app/controllers/activitypub/replies_controller.rb +++ b/app/controllers/activitypub/replies_controller.rb @@ -1,9 +1,7 @@ # frozen_string_literal: true class ActivityPub::RepliesController < ActivityPub::BaseController - include SignatureVerification include Authorization - include AccountOwnedConcern DESCENDANTS_LIMIT = 60 @@ -33,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/admin/domain_allows_controller.rb b/app/controllers/admin/domain_allows_controller.rb index 31be1978bb..b0f139e3a8 100644 --- a/app/controllers/admin/domain_allows_controller.rb +++ b/app/controllers/admin/domain_allows_controller.rb @@ -25,6 +25,8 @@ class Admin::DomainAllowsController < Admin::BaseController def destroy authorize @domain_allow, :destroy? UnallowDomainService.new.call(@domain_allow) + log_action :destroy, @domain_allow + redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg') end diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 325b33df80..16a8cb9eea 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -4,6 +4,18 @@ module Admin class DomainBlocksController < BaseController before_action :set_domain_block, only: [:destroy, :edit, :update] + PERMITTED_PARAMS = %i( + domain + obfuscate + private_comment + public_comment + reject_media + reject_reports + severity + ).freeze + + PERMITTED_UPDATE_PARAMS = PERMITTED_PARAMS.without(:domain).freeze + def batch authorize :domain_block, :create? @form = Form::DomainBlockBatch.new(form_domain_block_batch_params.merge(current_account: current_account, action: action_from_button)) @@ -88,11 +100,17 @@ module Admin end def update_params - params.require(:domain_block).permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) + params + .require(:domain_block) + .slice(*PERMITTED_UPDATE_PARAMS) + .permit(*PERMITTED_UPDATE_PARAMS) end def resource_params - params.require(:domain_block).permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) + params + .require(:domain_block) + .slice(*PERMITTED_PARAMS) + .permit(*PERMITTED_PARAMS) end def form_domain_block_batch_params diff --git a/app/controllers/admin/rules_controller.rb b/app/controllers/admin/rules_controller.rb index d31aec6ea8..b8def22ba3 100644 --- a/app/controllers/admin/rules_controller.rb +++ b/app/controllers/admin/rules_controller.rb @@ -53,7 +53,7 @@ module Admin end def resource_params - params.require(:rule).permit(:text, :priority) + params.require(:rule).permit(:text, :hint, :priority) end end end diff --git a/app/controllers/admin/site_uploads_controller.rb b/app/controllers/admin/site_uploads_controller.rb index a5d2cf41cf..96e61cf6bb 100644 --- a/app/controllers/admin/site_uploads_controller.rb +++ b/app/controllers/admin/site_uploads_controller.rb @@ -9,7 +9,7 @@ module Admin @site_upload.destroy! - redirect_to admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg') + redirect_back fallback_location: admin_settings_path, notice: I18n.t('admin.site_uploads.destroyed_msg') end private diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 98fa1897ef..c1a5e43f88 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -8,6 +8,8 @@ class Api::BaseController < ApplicationController include Api::AccessTokenTrackingConcern include Api::CachingConcern include Api::ContentSecurityPolicy + include Api::ErrorHandling + include Api::Pagination skip_before_action :require_functional!, unless: :limited_federation_mode? @@ -18,51 +20,6 @@ class Api::BaseController < ApplicationController protect_from_forgery with: :null_session - rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e| - render json: { error: e.to_s }, status: 422 - end - - rescue_from ActiveRecord::RecordNotUnique do - render json: { error: 'Duplicate record' }, status: 422 - end - - rescue_from Date::Error do - render json: { error: 'Invalid date supplied' }, status: 422 - end - - rescue_from ActiveRecord::RecordNotFound do - render json: { error: 'Record not found' }, status: 404 - end - - rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do - render json: { error: 'Remote data could not be fetched' }, status: 503 - end - - rescue_from OpenSSL::SSL::SSLError do - render json: { error: 'Remote SSL certificate could not be verified' }, status: 503 - end - - rescue_from Mastodon::NotPermittedError do - render json: { error: 'This action is not allowed' }, status: 403 - end - - rescue_from Seahorse::Client::NetworkingError do |e| - Rails.logger.warn "Storage server error: #{e}" - render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503 - end - - rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do - render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503 - end - - rescue_from Mastodon::RateLimitExceededError do - render json: { error: I18n.t('errors.429') }, status: 429 - end - - rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e| - render json: { error: e.to_s }, status: 400 - end - def doorkeeper_unauthorized_render_options(error: nil) { json: { error: error.try(:description) || 'Not authorized' } } end @@ -73,13 +30,6 @@ class Api::BaseController < ApplicationController protected - 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] @@ -108,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 @@ -140,10 +86,6 @@ class Api::BaseController < ApplicationController private - 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 8f31336b9f..a378425183 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! :profile, :read, :'read:accounts' }, except: [:update] before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:update] before_action :require_user! diff --git a/app/controllers/api/v1/accounts/follower_accounts_controller.rb b/app/controllers/api/v1/accounts/follower_accounts_controller.rb index f60181f1eb..3f2ecb892d 100644 --- a/app/controllers/api/v1/accounts/follower_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/follower_accounts_controller.rb @@ -41,10 +41,6 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_account_followers_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -64,8 +60,4 @@ class Api::V1::Accounts::FollowerAccountsController < Api::BaseController def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/accounts/following_accounts_controller.rb b/app/controllers/api/v1/accounts/following_accounts_controller.rb index 3ab8c1efd6..7c16a3487e 100644 --- a/app/controllers/api/v1/accounts/following_accounts_controller.rb +++ b/app/controllers/api/v1/accounts/following_accounts_controller.rb @@ -41,10 +41,6 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_account_following_index_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -64,8 +60,4 @@ class Api::V1::Accounts::FollowingAccountsController < Api::BaseController def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/accounts/statuses_controller.rb b/app/controllers/api/v1/accounts/statuses_controller.rb index fe4279302f..c42f27776c 100644 --- a/app/controllers/api/v1/accounts/statuses_controller.rb +++ b/app/controllers/api/v1/accounts/statuses_controller.rb @@ -4,7 +4,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController before_action -> { authorize_if_got_token! :read, :'read:statuses' } before_action :set_account - after_action :insert_pagination_headers, unless: -> { truthy_param?(:pinned) } + after_action :insert_pagination_headers def index cache_if_unauthenticated! @@ -19,11 +19,11 @@ class Api::V1::Accounts::StatusesController < Api::BaseController end def load_statuses - @account.unavailable? ? [] : cached_account_statuses + @account.unavailable? ? [] : preloaded_account_statuses end - def cached_account_statuses - cache_collection_paginated_by_id( + def preloaded_account_statuses + preload_collection_paginated_by_id( AccountStatusesFilter.new(@account, current_account, params).results, Status, limit_param(DEFAULT_STATUSES_LIMIT), @@ -35,10 +35,6 @@ class Api::V1::Accounts::StatusesController < Api::BaseController params.slice(:limit, *AccountStatusesFilter::KEYS).permit(:limit, *AccountStatusesFilter::KEYS).merge(core_params) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_account_statuses_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -51,11 +47,7 @@ class Api::V1::Accounts::StatusesController < Api::BaseController @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT) end - def pagination_max_id - @statuses.last.id - end - - def pagination_since_id - @statuses.first.id + def pagination_collection + @statuses end end diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 23fc85b475..84b604b305 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -9,16 +9,22 @@ class Api::V1::AccountsController < Api::BaseController before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, only: [:block, :unblock] before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create] - before_action :require_user!, except: [:show, :create] - before_action :set_account, except: [:create] - before_action :check_account_approval, except: [:create] - before_action :check_account_confirmation, except: [:create] + before_action :require_user!, except: [:index, :show, :create] + before_action :set_account, except: [:index, :create] + before_action :set_accounts, only: [:index] + before_action :check_account_approval, except: [:index, :create] + before_action :check_account_confirmation, except: [:index, :create] before_action :check_enabled_registrations, only: [:create] + before_action :check_accounts_limit, only: [:index] skip_before_action :require_authenticated_user!, only: :create override_rate_limit_headers :follow, family: :follows + def index + render json: @accounts, each_serializer: REST::AccountSerializer + end + def show cache_if_unauthenticated! render json: @account, serializer: REST::AccountSerializer @@ -79,6 +85,10 @@ class Api::V1::AccountsController < Api::BaseController @account = Account.find(params[:id]) end + def set_accounts + @accounts = Account.where(id: account_ids).without_unapproved + end + def check_account_approval raise(ActiveRecord::RecordNotFound) if @account.local? && @account.user_pending? end @@ -87,10 +97,22 @@ class Api::V1::AccountsController < Api::BaseController raise(ActiveRecord::RecordNotFound) if @account.local? && !@account.user_confirmed? end + def check_accounts_limit + raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT + end + def relationships(**options) AccountRelationshipsPresenter.new([@account], current_user.account_id, **options) end + def account_ids + Array(accounts_params[:id]).uniq.map(&:to_i) + end + + def accounts_params + params.permit(id: []) + end + def account_params params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code) end diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb index ff9cae6398..ff6f41e01d 100644 --- a/app/controllers/api/v1/admin/accounts_controller.rb +++ b/app/controllers/api/v1/admin/accounts_controller.rb @@ -125,10 +125,6 @@ class Api::V1::Admin::AccountsController < Api::BaseController translated_params end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_accounts_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -137,12 +133,8 @@ class Api::V1::Admin::AccountsController < Api::BaseController api_v1_admin_accounts_url(pagination_params(min_id: pagination_since_id)) unless @accounts.empty? end - def pagination_max_id - @accounts.last.id - end - - def pagination_since_id - @accounts.first.id + def pagination_collection + @accounts end def records_continue? diff --git a/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb b/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb index 7b192b979f..c144a9e0f9 100644 --- a/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb +++ b/app/controllers/api/v1/admin/canonical_email_blocks_controller.rb @@ -16,8 +16,6 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i(limit).freeze - def index authorize :canonical_email_block, :index? render json: @canonical_email_blocks, each_serializer: REST::Admin::CanonicalEmailBlockSerializer @@ -65,10 +63,6 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController @canonical_email_block = CanonicalEmailBlock.find(params[:id]) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_canonical_email_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -77,19 +71,11 @@ class Api::V1::Admin::CanonicalEmailBlocksController < Api::BaseController api_v1_admin_canonical_email_blocks_url(pagination_params(min_id: pagination_since_id)) unless @canonical_email_blocks.empty? end - def pagination_max_id - @canonical_email_blocks.last.id - end - - def pagination_since_id - @canonical_email_blocks.first.id + def pagination_collection + @canonical_email_blocks end def records_continue? @canonical_email_blocks.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end end diff --git a/app/controllers/api/v1/admin/domain_allows_controller.rb b/app/controllers/api/v1/admin/domain_allows_controller.rb index dd54d67106..9801d832b8 100644 --- a/app/controllers/api/v1/admin/domain_allows_controller.rb +++ b/app/controllers/api/v1/admin/domain_allows_controller.rb @@ -14,8 +14,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i(limit).freeze - def index authorize :domain_allow, :index? render json: @domain_allows, each_serializer: REST::Admin::DomainAllowSerializer @@ -61,10 +59,6 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController DomainAllow.all end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_domain_allows_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -73,22 +67,14 @@ class Api::V1::Admin::DomainAllowsController < Api::BaseController api_v1_admin_domain_allows_url(pagination_params(min_id: pagination_since_id)) unless @domain_allows.empty? end - def pagination_max_id - @domain_allows.last.id - end - - def pagination_since_id - @domain_allows.first.id + def pagination_collection + @domain_allows end def records_continue? @domain_allows.size == limit_param(LIMIT) end - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end - def resource_params params.permit(:domain) end diff --git a/app/controllers/api/v1/admin/domain_blocks_controller.rb b/app/controllers/api/v1/admin/domain_blocks_controller.rb index 2538c7c7c2..a20a4a9c7f 100644 --- a/app/controllers/api/v1/admin/domain_blocks_controller.rb +++ b/app/controllers/api/v1/admin/domain_blocks_controller.rb @@ -14,8 +14,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i(limit).freeze - def index authorize :domain_block, :index? render json: @domain_blocks, each_serializer: REST::Admin::DomainBlockSerializer @@ -29,10 +27,11 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController def create authorize :domain_block, :create? + @domain_block = DomainBlock.new(resource_params) existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil - return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present? + return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block) - @domain_block = DomainBlock.create!(resource_params) + @domain_block.save! DomainBlockWorker.perform_async(@domain_block.id) log_action :create, @domain_block render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer @@ -55,6 +54,10 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController private + def conflicts_with_existing_block?(domain_block, existing_domain_block) + existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block)) + end + def set_domain_blocks @domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) end @@ -72,10 +75,6 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_domain_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -84,22 +83,14 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController api_v1_admin_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @domain_blocks.empty? end - def pagination_max_id - @domain_blocks.last.id - end - - def pagination_since_id - @domain_blocks.first.id + def pagination_collection + @domain_blocks end def records_continue? @domain_blocks.size == limit_param(LIMIT) end - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end - def resource_params params.permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate) end diff --git a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb index df54b9f0a4..e7bd804e36 100644 --- a/app/controllers/api/v1/admin/email_domain_blocks_controller.rb +++ b/app/controllers/api/v1/admin/email_domain_blocks_controller.rb @@ -14,10 +14,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i( - limit - ).freeze - def index authorize :email_domain_block, :index? render json: @email_domain_blocks, each_serializer: REST::Admin::EmailDomainBlockSerializer @@ -58,10 +54,6 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController params.permit(:domain, :allow_with_approval) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_email_domain_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -70,19 +62,11 @@ class Api::V1::Admin::EmailDomainBlocksController < Api::BaseController api_v1_admin_email_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @email_domain_blocks.empty? end - def pagination_max_id - @email_domain_blocks.last.id - end - - def pagination_since_id - @email_domain_blocks.first.id + def pagination_collection + @email_domain_blocks end def records_continue? @email_domain_blocks.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end end diff --git a/app/controllers/api/v1/admin/ip_blocks_controller.rb b/app/controllers/api/v1/admin/ip_blocks_controller.rb index 61c1912344..e132a3a87d 100644 --- a/app/controllers/api/v1/admin/ip_blocks_controller.rb +++ b/app/controllers/api/v1/admin/ip_blocks_controller.rb @@ -14,10 +14,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i( - limit - ).freeze - def index authorize :ip_block, :index? render json: @ip_blocks, each_serializer: REST::Admin::IpBlockSerializer @@ -63,10 +59,6 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController params.permit(:ip, :severity, :comment, :expires_in) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_ip_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -75,19 +67,11 @@ class Api::V1::Admin::IpBlocksController < Api::BaseController api_v1_admin_ip_blocks_url(pagination_params(min_id: pagination_since_id)) unless @ip_blocks.empty? end - def pagination_max_id - @ip_blocks.last.id - end - - def pagination_since_id - @ip_blocks.first.id + def pagination_collection + @ip_blocks end def records_continue? @ip_blocks.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end end diff --git a/app/controllers/api/v1/admin/reports_controller.rb b/app/controllers/api/v1/admin/reports_controller.rb index 7129a5f6ca..9b5beeab67 100644 --- a/app/controllers/api/v1/admin/reports_controller.rb +++ b/app/controllers/api/v1/admin/reports_controller.rb @@ -89,10 +89,6 @@ class Api::V1::Admin::ReportsController < Api::BaseController params.permit(*FILTER_PARAMS) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_reports_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -101,12 +97,8 @@ class Api::V1::Admin::ReportsController < Api::BaseController api_v1_admin_reports_url(pagination_params(min_id: pagination_since_id)) unless @reports.empty? end - def pagination_max_id - @reports.last.id - end - - def pagination_since_id - @reports.first.id + def pagination_collection + @reports end def records_continue? diff --git a/app/controllers/api/v1/admin/tags_controller.rb b/app/controllers/api/v1/admin/tags_controller.rb index 6a7c9f5bf3..283383acb4 100644 --- a/app/controllers/api/v1/admin/tags_controller.rb +++ b/app/controllers/api/v1/admin/tags_controller.rb @@ -12,7 +12,13 @@ class Api::V1::Admin::TagsController < Api::BaseController after_action :verify_authorized LIMIT = 100 - PAGINATION_PARAMS = %i(limit).freeze + + PERMITTED_PARAMS = %i( + display_name + listable + trendable + usable + ).freeze def index authorize :tag, :index? @@ -41,11 +47,9 @@ class Api::V1::Admin::TagsController < Api::BaseController end def tag_params - params.permit(:display_name, :trendable, :usable, :listable) - end - - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) + params + .slice(*PERMITTED_PARAMS) + .permit(*PERMITTED_PARAMS) end def next_path @@ -56,19 +60,11 @@ class Api::V1::Admin::TagsController < Api::BaseController api_v1_admin_tags_url(pagination_params(min_id: pagination_since_id)) unless @tags.empty? end - def pagination_max_id - @tags.last.id - end - - def pagination_since_id - @tags.first.id + def pagination_collection + @tags end def records_continue? @tags.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end end diff --git a/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb b/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb index 5d9fcc82c0..2b0f39b98f 100644 --- a/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb +++ b/app/controllers/api/v1/admin/trends/links/preview_card_providers_controller.rb @@ -12,8 +12,6 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC after_action :verify_authorized after_action :insert_pagination_headers, only: :index - PAGINATION_PARAMS = %i(limit).freeze - def index authorize :preview_card_provider, :index? @@ -42,10 +40,6 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC @providers = PreviewCardProvider.all.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_admin_trends_links_preview_card_providers_url(pagination_params(max_id: pagination_max_id)) if records_continue? end @@ -54,19 +48,11 @@ class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseC api_v1_admin_trends_links_preview_card_providers_url(pagination_params(min_id: pagination_since_id)) unless @providers.empty? end - def pagination_max_id - @providers.last.id - end - - def pagination_since_id - @providers.first.id + def pagination_collection + @providers end def records_continue? @providers.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params) - end end diff --git a/app/controllers/api/v1/apps/credentials_controller.rb b/app/controllers/api/v1/apps/credentials_controller.rb index 6256bed64c..29ab920383 100644 --- a/app/controllers/api/v1/apps/credentials_controller.rb +++ b/app/controllers/api/v1/apps/credentials_controller.rb @@ -4,6 +4,6 @@ class Api::V1::Apps::CredentialsController < Api::BaseController def show return doorkeeper_render_error unless valid_doorkeeper_token? - render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer, fields: %i(name website vapid_key client_id scopes) + render json: doorkeeper_token.application, serializer: REST::ApplicationSerializer end end diff --git a/app/controllers/api/v1/apps_controller.rb b/app/controllers/api/v1/apps_controller.rb index 97177547a2..50feaf1854 100644 --- a/app/controllers/api/v1/apps_controller.rb +++ b/app/controllers/api/v1/apps_controller.rb @@ -5,7 +5,7 @@ class Api::V1::AppsController < Api::BaseController def create @app = Doorkeeper::Application.create!(application_options) - render json: @app, serializer: REST::ApplicationSerializer + render json: @app, serializer: REST::CredentialApplicationSerializer end private @@ -24,6 +24,6 @@ class Api::V1::AppsController < Api::BaseController end def app_params - params.permit(:client_name, :redirect_uris, :scopes, :website) + params.permit(:client_name, :scopes, :website, :redirect_uris, redirect_uris: []) end end diff --git a/app/controllers/api/v1/blocks_controller.rb b/app/controllers/api/v1/blocks_controller.rb index 0934622f88..d7516c927b 100644 --- a/app/controllers/api/v1/blocks_controller.rb +++ b/app/controllers/api/v1/blocks_controller.rb @@ -28,10 +28,6 @@ class Api::V1::BlocksController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_blocks_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -40,19 +36,11 @@ class Api::V1::BlocksController < Api::BaseController api_v1_blocks_url pagination_params(since_id: pagination_since_id) unless paginated_blocks.empty? end - def pagination_max_id - paginated_blocks.last.id - end - - def pagination_since_id - paginated_blocks.first.id + def pagination_collection + paginated_blocks end def records_continue? paginated_blocks.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/bookmarks_controller.rb b/app/controllers/api/v1/bookmarks_controller.rb index 498eb16f44..29f08e81d2 100644 --- a/app/controllers/api/v1/bookmarks_controller.rb +++ b/app/controllers/api/v1/bookmarks_controller.rb @@ -13,11 +13,11 @@ class Api::V1::BookmarksController < Api::BaseController private def load_statuses - cached_bookmarks + preloaded_bookmarks end - def cached_bookmarks - cache_collection(results.map(&:status), Status) + def preloaded_bookmarks + preload_collection(results.map(&:status), Status) end def results @@ -31,10 +31,6 @@ class Api::V1::BookmarksController < Api::BaseController current_account.bookmarks end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_bookmarks_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -43,19 +39,11 @@ class Api::V1::BookmarksController < Api::BaseController api_v1_bookmarks_url pagination_params(min_id: pagination_since_id) unless results.empty? end - def pagination_max_id - results.last.id - end - - def pagination_since_id - results.first.id + def pagination_collection + results end def records_continue? results.size == limit_param(DEFAULT_STATUSES_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/conversations_controller.rb b/app/controllers/api/v1/conversations_controller.rb index 6a3567e624..60db082a8e 100644 --- a/app/controllers/api/v1/conversations_controller.rb +++ b/app/controllers/api/v1/conversations_controller.rb @@ -38,25 +38,21 @@ class Api::V1::ConversationsController < Api::BaseController def paginated_conversations AccountConversation.where(account: current_account) .includes( - account: :account_stat, + account: [:account_stat, user: :role], last_status: [ :media_attachments, :status_stat, :tags, { - preview_cards_status: :preview_card, - active_mentions: [account: :account_stat], - account: :account_stat, + preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } }, + active_mentions: :account, + account: [:account_stat, user: :role], }, ] ) .to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_conversations_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -76,8 +72,4 @@ class Api::V1::ConversationsController < Api::BaseController def records_continue? @conversations.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb index 68cf4384f7..93ae0e7771 100644 --- a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb +++ b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb @@ -29,10 +29,6 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController @encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_crypto_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -41,19 +37,11 @@ class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty? end - def pagination_max_id - @encrypted_messages.last.id - end - - def pagination_since_id - @encrypted_messages.first.id + def pagination_collection + @encrypted_messages end def records_continue? @encrypted_messages.size == limit_param(LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/domain_blocks_controller.rb b/app/controllers/api/v1/domain_blocks_controller.rb index 34def3c44a..780ecbf189 100644 --- a/app/controllers/api/v1/domain_blocks_controller.rb +++ b/app/controllers/api/v1/domain_blocks_controller.rb @@ -38,10 +38,6 @@ class Api::V1::DomainBlocksController < Api::BaseController current_account.domain_blocks end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_domain_blocks_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -50,22 +46,14 @@ class Api::V1::DomainBlocksController < Api::BaseController api_v1_domain_blocks_url pagination_params(since_id: pagination_since_id) unless @blocks.empty? end - def pagination_max_id - @blocks.last.id - end - - def pagination_since_id - @blocks.first.id + def pagination_collection + @blocks end def records_continue? @blocks.size == limit_param(BLOCK_LIMIT) end - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def domain_block_params params.permit(:domain) end diff --git a/app/controllers/api/v1/endorsements_controller.rb b/app/controllers/api/v1/endorsements_controller.rb index 2216a9860d..09bafe0231 100644 --- a/app/controllers/api/v1/endorsements_controller.rb +++ b/app/controllers/api/v1/endorsements_controller.rb @@ -28,10 +28,6 @@ class Api::V1::EndorsementsController < Api::BaseController current_account.endorsed_accounts.includes(:account_stat, :user).without_suspended end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path return if unlimited? @@ -44,22 +40,14 @@ class Api::V1::EndorsementsController < Api::BaseController api_v1_endorsements_url pagination_params(since_id: pagination_since_id) unless @accounts.empty? end - def pagination_max_id - @accounts.last.id - end - - def pagination_since_id - @accounts.first.id + def pagination_collection + @accounts end def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def unlimited? params[:limit] == '0' end diff --git a/app/controllers/api/v1/favourites_controller.rb b/app/controllers/api/v1/favourites_controller.rb index faf1bda96a..a4454e4ded 100644 --- a/app/controllers/api/v1/favourites_controller.rb +++ b/app/controllers/api/v1/favourites_controller.rb @@ -13,11 +13,11 @@ class Api::V1::FavouritesController < Api::BaseController private def load_statuses - cached_favourites + preloaded_favourites end - def cached_favourites - cache_collection(results.map(&:status), Status) + def preloaded_favourites + preload_collection(results.map(&:status), Status) end def results @@ -31,10 +31,6 @@ class Api::V1::FavouritesController < Api::BaseController current_account.favourites end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_favourites_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -43,19 +39,11 @@ class Api::V1::FavouritesController < Api::BaseController api_v1_favourites_url pagination_params(min_id: pagination_since_id) unless results.empty? end - def pagination_max_id - results.last.id - end - - def pagination_since_id - results.first.id + def pagination_collection + results end def records_continue? results.size == limit_param(DEFAULT_STATUSES_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb index 76633210a1..9c72e4380d 100644 --- a/app/controllers/api/v1/featured_tags/suggestions_controller.rb +++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb @@ -12,6 +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: current_account.featured_tags).limit(10) + @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10) end end diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb index 87f6df5f94..29a09fceef 100644 --- a/app/controllers/api/v1/follow_requests_controller.rb +++ b/app/controllers/api/v1/follow_requests_controller.rb @@ -48,10 +48,6 @@ class Api::V1::FollowRequestsController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_follow_requests_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -71,8 +67,4 @@ class Api::V1::FollowRequestsController < Api::BaseController def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/followed_tags_controller.rb b/app/controllers/api/v1/followed_tags_controller.rb index eae2bdc010..7d8f0eda1e 100644 --- a/app/controllers/api/v1/followed_tags_controller.rb +++ b/app/controllers/api/v1/followed_tags_controller.rb @@ -22,10 +22,6 @@ class Api::V1::FollowedTagsController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_followed_tags_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -34,19 +30,11 @@ class Api::V1::FollowedTagsController < Api::BaseController api_v1_followed_tags_url pagination_params(since_id: pagination_since_id) unless @results.empty? end - def pagination_max_id - @results.last.id - end - - def pagination_since_id - @results.first.id + def pagination_collection + @results end def records_continue? @results.size == limit_param(TAGS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/instances/extended_descriptions_controller.rb b/app/controllers/api/v1/instances/extended_descriptions_controller.rb index 73d2248117..db3d082f61 100644 --- a/app/controllers/api/v1/instances/extended_descriptions_controller.rb +++ b/app/controllers/api/v1/instances/extended_descriptions_controller.rb @@ -5,7 +5,7 @@ class Api::V1::Instances::ExtendedDescriptionsController < Api::V1::Instances::B before_action :set_extended_description - # Override `current_user` to avoid reading session cookies unless in whitelist mode + # Override `current_user` to avoid reading session cookies unless in limited federation mode def current_user super if limited_federation_mode? end diff --git a/app/controllers/api/v1/instances/peers_controller.rb b/app/controllers/api/v1/instances/peers_controller.rb index 83116472bb..fac763b405 100644 --- a/app/controllers/api/v1/instances/peers_controller.rb +++ b/app/controllers/api/v1/instances/peers_controller.rb @@ -5,7 +5,7 @@ class Api::V1::Instances::PeersController < Api::V1::Instances::BaseController skip_around_action :set_locale - # Override `current_user` to avoid reading session cookies unless in whitelist mode + # Override `current_user` to avoid reading session cookies unless in limited federation mode def current_user super if limited_federation_mode? end diff --git a/app/controllers/api/v1/instances/rules_controller.rb b/app/controllers/api/v1/instances/rules_controller.rb index d240d72464..3930eec0dd 100644 --- a/app/controllers/api/v1/instances/rules_controller.rb +++ b/app/controllers/api/v1/instances/rules_controller.rb @@ -5,7 +5,7 @@ class Api::V1::Instances::RulesController < Api::V1::Instances::BaseController before_action :set_rules - # Override `current_user` to avoid reading session cookies unless in whitelist mode + # Override `current_user` to avoid reading session cookies unless in limited federation mode def current_user super if limited_federation_mode? end diff --git a/app/controllers/api/v1/instances_controller.rb b/app/controllers/api/v1/instances_controller.rb index df4a14af15..49da75ed28 100644 --- a/app/controllers/api/v1/instances_controller.rb +++ b/app/controllers/api/v1/instances_controller.rb @@ -6,7 +6,7 @@ class Api::V1::InstancesController < Api::BaseController vary_by '' - # Override `current_user` to avoid reading session cookies unless in whitelist mode + # Override `current_user` to avoid reading session cookies unless in limited federation mode def current_user super if limited_federation_mode? end diff --git a/app/controllers/api/v1/lists/accounts_controller.rb b/app/controllers/api/v1/lists/accounts_controller.rb index 0604ad60fc..b1c0e609d0 100644 --- a/app/controllers/api/v1/lists/accounts_controller.rb +++ b/app/controllers/api/v1/lists/accounts_controller.rb @@ -55,10 +55,6 @@ class Api::V1::Lists::AccountsController < Api::BaseController params.permit(account_ids: []) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path return if unlimited? @@ -71,22 +67,14 @@ class Api::V1::Lists::AccountsController < Api::BaseController api_v1_list_accounts_url pagination_params(since_id: pagination_since_id) unless @accounts.empty? end - def pagination_max_id - @accounts.last.id - end - - def pagination_since_id - @accounts.first.id + def pagination_collection + @accounts end def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def unlimited? params[:limit] == '0' end diff --git a/app/controllers/api/v1/mutes_controller.rb b/app/controllers/api/v1/mutes_controller.rb index 2fb685ac39..d2b50e3336 100644 --- a/app/controllers/api/v1/mutes_controller.rb +++ b/app/controllers/api/v1/mutes_controller.rb @@ -28,10 +28,6 @@ class Api::V1::MutesController < Api::BaseController ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_mutes_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -40,19 +36,11 @@ class Api::V1::MutesController < Api::BaseController api_v1_mutes_url pagination_params(since_id: pagination_since_id) unless paginated_mutes.empty? end - def pagination_max_id - paginated_mutes.last.id - end - - def pagination_since_id - paginated_mutes.first.id + def pagination_collection + paginated_mutes end def records_continue? paginated_mutes.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/notifications/policies_controller.rb b/app/controllers/api/v1/notifications/policies_controller.rb new file mode 100644 index 0000000000..1ec336f9a5 --- /dev/null +++ b/app/controllers/api/v1/notifications/policies_controller.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class Api::V1::Notifications::PoliciesController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :show + before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: :update + + before_action :require_user! + before_action :set_policy + + def show + render json: @policy, serializer: REST::NotificationPolicySerializer + end + + def update + @policy.update!(resource_params) + render json: @policy, serializer: REST::NotificationPolicySerializer + end + + private + + def set_policy + @policy = NotificationPolicy.find_or_initialize_by(account: current_account) + + with_read_replica do + @policy.summarize! + end + end + + def resource_params + params.permit( + :filter_not_following, + :filter_not_followers, + :filter_new_accounts, + :filter_private_mentions + ) + end +end diff --git a/app/controllers/api/v1/notifications/requests_controller.rb b/app/controllers/api/v1/notifications/requests_controller.rb new file mode 100644 index 0000000000..0e58379a38 --- /dev/null +++ b/app/controllers/api/v1/notifications/requests_controller.rb @@ -0,0 +1,75 @@ +# frozen_string_literal: true + +class Api::V1::Notifications::RequestsController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, only: :index + before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, except: :index + + before_action :require_user! + before_action :set_request, except: :index + + after_action :insert_pagination_headers, only: :index + + def index + with_read_replica do + @requests = load_requests + @relationships = relationships + end + + render json: @requests, each_serializer: REST::NotificationRequestSerializer, relationships: @relationships + end + + def show + render json: @request, serializer: REST::NotificationRequestSerializer + end + + def accept + AcceptNotificationRequestService.new.call(@request) + render_empty + end + + def dismiss + @request.update!(dismissed: true) + render_empty + end + + private + + def load_requests + requests = NotificationRequest.where(account: current_account).where(dismissed: truthy_param?(:dismissed) || false).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id( + limit_param(DEFAULT_ACCOUNTS_LIMIT), + params_slice(:max_id, :since_id, :min_id) + ) + + NotificationRequest.preload_cache_collection(requests) do |statuses| + preload_collection(statuses, Status) + end + end + + def relationships + StatusRelationshipsPresenter.new(@requests.map(&:last_status), current_user&.account_id) + end + + def set_request + @request = NotificationRequest.where(account: current_account).find(params[:id]) + end + + def next_path + api_v1_notifications_requests_url pagination_params(max_id: pagination_max_id) unless @requests.empty? + end + + def prev_path + api_v1_notifications_requests_url pagination_params(min_id: pagination_since_id) unless @requests.empty? + end + + def pagination_max_id + @requests.last.id + end + + def pagination_since_id + @requests.first.id + end + + def pagination_params(core_params) + params.slice(:dismissed).permit(:dismissed).merge(core_params) + end +end diff --git a/app/controllers/api/v1/notifications_controller.rb b/app/controllers/api/v1/notifications_controller.rb index 406ab97538..1d0aa10d2e 100644 --- a/app/controllers/api/v1/notifications_controller.rb +++ b/app/controllers/api/v1/notifications_controller.rb @@ -41,7 +41,7 @@ class Api::V1::NotificationsController < Api::BaseController ) Notification.preload_cache_collection_target_statuses(notifications) do |target_statuses| - cache_collection(target_statuses, Status) + preload_collection(target_statuses, Status) end end @@ -49,7 +49,8 @@ class Api::V1::NotificationsController < Api::BaseController current_account.notifications.without_suspended.browserable( types: Array(browserable_params[:types]), exclude_types: Array(browserable_params[:exclude_types]), - from_account_id: browserable_params[:account_id] + from_account_id: browserable_params[:account_id], + include_filtered: truthy_param?(:include_filtered) ) end @@ -57,10 +58,6 @@ class Api::V1::NotificationsController < Api::BaseController @notifications.reject { |notification| notification.target_status.nil? }.map(&:target_status) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_notifications_url pagination_params(max_id: pagination_max_id) unless @notifications.empty? end @@ -69,19 +66,15 @@ class Api::V1::NotificationsController < Api::BaseController api_v1_notifications_url pagination_params(min_id: pagination_since_id) unless @notifications.empty? end - def pagination_max_id - @notifications.last.id - end - - def pagination_since_id - @notifications.first.id + def pagination_collection + @notifications end def browserable_params - params.permit(:account_id, types: [], exclude_types: []) + params.permit(:account_id, :include_filtered, types: [], exclude_types: []) end def pagination_params(core_params) - params.slice(:limit, :account_id, :types, :exclude_types).permit(:limit, :account_id, types: [], exclude_types: []).merge(core_params) + params.slice(:limit, :account_id, :types, :exclude_types, :include_filtered).permit(:limit, :account_id, :include_filtered, types: [], exclude_types: []).merge(core_params) end end diff --git a/app/controllers/api/v1/push/subscriptions_controller.rb b/app/controllers/api/v1/push/subscriptions_controller.rb index 3634acf956..e1ad89ee3e 100644 --- a/app/controllers/api/v1/push/subscriptions_controller.rb +++ b/app/controllers/api/v1/push/subscriptions_controller.rb @@ -1,9 +1,12 @@ # frozen_string_literal: true class Api::V1::Push::SubscriptionsController < Api::BaseController + include Redisable + include Lockable + before_action -> { doorkeeper_authorize! :push } before_action :require_user! - before_action :set_push_subscription + before_action :set_push_subscription, only: [:show, :update] before_action :check_push_subscription, only: [:show, :update] def show @@ -11,16 +14,18 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController end def create - @push_subscription&.destroy! + with_redis_lock("push_subscription:#{current_user.id}") do + destroy_web_push_subscriptions! - @push_subscription = Web::PushSubscription.create!( - endpoint: subscription_params[:endpoint], - key_p256dh: subscription_params[:keys][:p256dh], - key_auth: subscription_params[:keys][:auth], - data: data_params, - user_id: current_user.id, - access_token_id: doorkeeper_token.id - ) + @push_subscription = Web::PushSubscription.create!( + endpoint: subscription_params[:endpoint], + key_p256dh: subscription_params[:keys][:p256dh], + key_auth: subscription_params[:keys][:auth], + data: data_params, + user_id: current_user.id, + access_token_id: doorkeeper_token.id + ) + end render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer end @@ -31,14 +36,18 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController end def destroy - @push_subscription&.destroy! + destroy_web_push_subscriptions! render_empty end private + def destroy_web_push_subscriptions! + doorkeeper_token.web_push_subscriptions.destroy_all + end + def set_push_subscription - @push_subscription = Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id) + @push_subscription = doorkeeper_token.web_push_subscriptions.first end def check_push_subscription diff --git a/app/controllers/api/v1/scheduled_statuses_controller.rb b/app/controllers/api/v1/scheduled_statuses_controller.rb index 2220b6d22e..45ee586518 100644 --- a/app/controllers/api/v1/scheduled_statuses_controller.rb +++ b/app/controllers/api/v1/scheduled_statuses_controller.rb @@ -43,14 +43,6 @@ class Api::V1::ScheduledStatusesController < Api::BaseController params.permit(:scheduled_at) end - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -63,11 +55,7 @@ class Api::V1::ScheduledStatusesController < Api::BaseController @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT) end - def pagination_max_id - @statuses.last.id - end - - def pagination_since_id - @statuses.first.id + def pagination_collection + @statuses end end diff --git a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb index 069ad37cb2..5a5c2fdc97 100644 --- a/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/favourited_by_accounts_controller.rb @@ -34,10 +34,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::V1::Statuses::Bas ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_status_favourited_by_index_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -57,8 +53,4 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::V1::Statuses::Bas def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - 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 b8a997518d..0eba4fae32 100644 --- a/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb +++ b/app/controllers/api/v1/statuses/reblogged_by_accounts_controller.rb @@ -23,17 +23,13 @@ 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] ) end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - def next_path api_v1_status_reblogged_by_index_url pagination_params(max_id: pagination_max_id) if records_continue? end @@ -53,8 +49,4 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::Base def records_continue? @accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 01c3718763..19cc71ae58 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -5,9 +5,11 @@ class Api::V1::StatusesController < Api::BaseController before_action -> { authorize_if_got_token! :read, :'read:statuses' }, except: [:create, :update, :destroy] before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:create, :update, :destroy] - before_action :require_user!, except: [:show, :context] - before_action :set_status, only: [:show, :context] - before_action :set_thread, only: [:create] + before_action :require_user!, except: [:index, :show, :context] + before_action :set_statuses, only: [:index] + before_action :set_status, only: [:show, :context] + before_action :set_thread, only: [:create] + before_action :check_statuses_limit, only: [:index] override_rate_limit_headers :create, family: :statuses override_rate_limit_headers :update, family: :statuses @@ -23,9 +25,14 @@ class Api::V1::StatusesController < Api::BaseController DESCENDANTS_LIMIT = 60 DESCENDANTS_DEPTH_LIMIT = 20 + def index + @statuses = preload_collection(@statuses, Status) + render json: @statuses, each_serializer: REST::StatusSerializer + end + def show cache_if_unauthenticated! - @status = cache_collection([@status], Status).first + @status = preload_collection([@status], Status).first render json: @status, serializer: REST::StatusSerializer end @@ -44,8 +51,8 @@ class Api::V1::StatusesController < Api::BaseController ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(ancestors_limit, current_account) descendants_results = @status.descendants(descendants_limit, current_account, descendants_depth_limit) - loaded_ancestors = cache_collection(ancestors_results, Status) - loaded_descendants = cache_collection(descendants_results, Status) + loaded_ancestors = preload_collection(ancestors_results, Status) + loaded_descendants = preload_collection(descendants_results, Status) @context = Context.new(ancestors: loaded_ancestors, descendants: loaded_descendants) statuses = [@status] + @context.ancestors + @context.descendants @@ -111,6 +118,10 @@ class Api::V1::StatusesController < Api::BaseController private + def set_statuses + @statuses = Status.permitted_statuses_from_ids(status_ids, current_account) + end + def set_status @status = Status.find(params[:id]) authorize @status, :show? @@ -125,6 +136,18 @@ class Api::V1::StatusesController < Api::BaseController render json: { error: I18n.t('statuses.errors.in_reply_not_found') }, status: 404 end + def check_statuses_limit + raise(Mastodon::ValidationError) if status_ids.size > DEFAULT_STATUSES_LIMIT + end + + def status_ids + Array(statuses_params[:id]).uniq.map(&:to_i) + end + + def statuses_params + params.permit(id: []) + end + def status_params params.permit( :status, @@ -165,8 +188,4 @@ class Api::V1::StatusesController < Api::BaseController def serialized_accounts(accounts) ActiveModel::Serializer::CollectionSerializer.new(accounts, serializer: REST::AccountSerializer) end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end end diff --git a/app/controllers/api/v1/timelines/base_controller.rb b/app/controllers/api/v1/timelines/base_controller.rb index 173e173cc9..e79eba79ee 100644 --- a/app/controllers/api/v1/timelines/base_controller.rb +++ b/app/controllers/api/v1/timelines/base_controller.rb @@ -5,16 +5,8 @@ class Api::V1::Timelines::BaseController < Api::BaseController private - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_max_id - @statuses.last.id - end - - def pagination_since_id - @statuses.first.id + def pagination_collection + @statuses end def next_path_params diff --git a/app/controllers/api/v1/timelines/home_controller.rb b/app/controllers/api/v1/timelines/home_controller.rb index 36fdbea647..d5d1828666 100644 --- a/app/controllers/api/v1/timelines/home_controller.rb +++ b/app/controllers/api/v1/timelines/home_controller.rb @@ -21,11 +21,11 @@ class Api::V1::Timelines::HomeController < Api::V1::Timelines::BaseController private def load_statuses - cached_home_statuses + preloaded_home_statuses end - def cached_home_statuses - cache_collection home_statuses, Status + def preloaded_home_statuses + preload_collection home_statuses, Status end def home_statuses diff --git a/app/controllers/api/v1/timelines/link_controller.rb b/app/controllers/api/v1/timelines/link_controller.rb new file mode 100644 index 0000000000..af962c430f --- /dev/null +++ b/app/controllers/api/v1/timelines/link_controller.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class Api::V1::Timelines::LinkController < Api::V1::Timelines::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth? + before_action :set_preview_card + before_action :set_statuses + + PERMITTED_PARAMS = %i( + url + limit + ).freeze + + def show + cache_if_unauthenticated! + render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) + end + + private + + def require_auth? + !Setting.timeline_preview + end + + def set_preview_card + @preview_card = PreviewCard.joins(:trend).merge(PreviewCardTrend.allowed).find_by!(url: params[:url]) + end + + def set_statuses + @statuses = @preview_card.nil? ? [] : preload_collection(link_timeline_statuses, Status) + end + + def link_timeline_statuses + link_feed.get( + limit_param(DEFAULT_STATUSES_LIMIT), + params[:max_id], + params[:since_id], + params[:min_id] + ) + end + + def link_feed + LinkFeed.new(@preview_card, current_account) + end + + def next_path + api_v1_timelines_link_url next_path_params + end + + def prev_path + api_v1_timelines_link_url prev_path_params + end +end diff --git a/app/controllers/api/v1/timelines/list_controller.rb b/app/controllers/api/v1/timelines/list_controller.rb index 14b884ecd9..d8cdbdb74c 100644 --- a/app/controllers/api/v1/timelines/list_controller.rb +++ b/app/controllers/api/v1/timelines/list_controller.rb @@ -21,11 +21,11 @@ class Api::V1::Timelines::ListController < Api::V1::Timelines::BaseController end def set_statuses - @statuses = cached_list_statuses + @statuses = preloaded_list_statuses end - def cached_list_statuses - cache_collection list_statuses, Status + def preloaded_list_statuses + preload_collection list_statuses, Status end def list_statuses diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 35af8dc4b5..d164854d6a 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -18,11 +18,11 @@ class Api::V1::Timelines::PublicController < Api::V1::Timelines::BaseController end def load_statuses - cached_public_statuses_page + preloaded_public_statuses_page end - def cached_public_statuses_page - cache_collection(public_statuses, Status) + def preloaded_public_statuses_page + preload_collection(public_statuses, Status) end def public_statuses diff --git a/app/controllers/api/v1/timelines/tag_controller.rb b/app/controllers/api/v1/timelines/tag_controller.rb index 4ba439dbb2..3bf8f374e1 100644 --- a/app/controllers/api/v1/timelines/tag_controller.rb +++ b/app/controllers/api/v1/timelines/tag_controller.rb @@ -23,11 +23,11 @@ class Api::V1::Timelines::TagController < Api::V1::Timelines::BaseController end def load_statuses - cached_tagged_statuses + preloaded_tagged_statuses end - def cached_tagged_statuses - @tag.nil? ? [] : cache_collection(tag_timeline_statuses, Status) + def preloaded_tagged_statuses + @tag.nil? ? [] : preload_collection(tag_timeline_statuses, Status) end def tag_timeline_statuses diff --git a/app/controllers/api/v1/trends/links_controller.rb b/app/controllers/api/v1/trends/links_controller.rb index 57cfa0b7e4..3c5aecff43 100644 --- a/app/controllers/api/v1/trends/links_controller.rb +++ b/app/controllers/api/v1/trends/links_controller.rb @@ -34,14 +34,6 @@ class Api::V1::Trends::LinksController < Api::BaseController scope end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def next_path api_v1_trends_links_url pagination_params(offset: offset_param + limit_param(DEFAULT_LINKS_LIMIT)) if records_continue? end diff --git a/app/controllers/api/v1/trends/statuses_controller.rb b/app/controllers/api/v1/trends/statuses_controller.rb index c186864c3b..cdbfce0685 100644 --- a/app/controllers/api/v1/trends/statuses_controller.rb +++ b/app/controllers/api/v1/trends/statuses_controller.rb @@ -20,7 +20,7 @@ class Api::V1::Trends::StatusesController < Api::BaseController def set_statuses @statuses = if enabled? - cache_collection(statuses_from_trends.offset(offset_param).limit(limit_param(DEFAULT_STATUSES_LIMIT)), Status) + preload_collection(statuses_from_trends.offset(offset_param).limit(limit_param(DEFAULT_STATUSES_LIMIT)), Status) else [] end @@ -32,14 +32,6 @@ class Api::V1::Trends::StatusesController < Api::BaseController scope end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def next_path api_v1_trends_statuses_url pagination_params(offset: offset_param + limit_param(DEFAULT_STATUSES_LIMIT)) if records_continue? end diff --git a/app/controllers/api/v1/trends/tags_controller.rb b/app/controllers/api/v1/trends/tags_controller.rb index aca3dd7089..b15dd50131 100644 --- a/app/controllers/api/v1/trends/tags_controller.rb +++ b/app/controllers/api/v1/trends/tags_controller.rb @@ -30,14 +30,6 @@ class Api::V1::Trends::TagsController < Api::BaseController Trends.tags.query.allowed end - def insert_pagination_headers - set_pagination_headers(next_path, prev_path) - end - - def pagination_params(core_params) - params.slice(:limit).permit(:limit).merge(core_params) - end - def next_path api_v1_trends_tags_url pagination_params(offset: offset_param + limit_param(DEFAULT_TAGS_LIMIT)) if records_continue? end diff --git a/app/controllers/api/v2_alpha/notifications_controller.rb b/app/controllers/api/v2_alpha/notifications_controller.rb new file mode 100644 index 0000000000..edba23ab4a --- /dev/null +++ b/app/controllers/api/v2_alpha/notifications_controller.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +class Api::V2Alpha::NotificationsController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:notifications' }, except: [:clear, :dismiss] + before_action -> { doorkeeper_authorize! :write, :'write:notifications' }, only: [:clear, :dismiss] + before_action :require_user! + after_action :insert_pagination_headers, only: :index + + DEFAULT_NOTIFICATIONS_LIMIT = 40 + + def index + with_read_replica do + @notifications = load_notifications + @group_metadata = load_group_metadata + @relationships = StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id) + end + + render json: @notifications.map { |notification| NotificationGroup.from_notification(notification, max_id: @group_metadata.dig(notification.group_key, :max_id)) }, each_serializer: REST::NotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata + end + + def show + @notification = current_account.notifications.without_suspended.find_by!(group_key: params[:id]) + render json: NotificationGroup.from_notification(@notification), serializer: REST::NotificationGroupSerializer + end + + def clear + current_account.notifications.delete_all + render_empty + end + + def dismiss + current_account.notifications.where(group_key: params[:id]).destroy_all + render_empty + end + + private + + def load_notifications + notifications = browserable_account_notifications.includes(from_account: [:account_stat, :user]).to_a_grouped_paginated_by_id( + limit_param(DEFAULT_NOTIFICATIONS_LIMIT), + params_slice(:max_id, :since_id, :min_id) + ) + + Notification.preload_cache_collection_target_statuses(notifications) do |target_statuses| + preload_collection(target_statuses, Status) + end + end + + def load_group_metadata + return {} if @notifications.empty? + + browserable_account_notifications + .where(group_key: @notifications.filter_map(&:group_key)) + .where(id: (@notifications.last.id)..(@notifications.first.id)) + .group(:group_key) + .pluck(:group_key, 'min(notifications.id) as min_id', 'max(notifications.id) as max_id', 'max(notifications.created_at) as latest_notification_at') + .to_h { |group_key, min_id, max_id, latest_notification_at| [group_key, { min_id: min_id, max_id: max_id, latest_notification_at: latest_notification_at }] } + end + + def browserable_account_notifications + current_account.notifications.without_suspended.browserable( + types: Array(browserable_params[:types]), + exclude_types: Array(browserable_params[:exclude_types]), + include_filtered: truthy_param?(:include_filtered) + ) + end + + def target_statuses_from_notifications + @notifications.filter_map(&:target_status) + end + + def next_path + api_v2_alpha_notifications_url pagination_params(max_id: pagination_max_id) unless @notifications.empty? + end + + def prev_path + api_v2_alpha_notifications_url pagination_params(min_id: pagination_since_id) unless @notifications.empty? + end + + def pagination_collection + @notifications + end + + def browserable_params + params.permit(:include_filtered, types: [], exclude_types: []) + end + + def pagination_params(core_params) + params.slice(:limit, :types, :exclude_types, :include_filtered).permit(:limit, :include_filtered, types: [], exclude_types: []).merge(core_params) + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5f8725f6fc..66e0f7e305 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base include UserTrackingConcern include SessionTrackingConcern include CacheConcern + include PreloadingConcern include DomainControlHelper include DatabaseHelper include AuthorizedFetchHelper @@ -129,7 +130,7 @@ class ApplicationController < ActionController::Base end def single_user_mode? - @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.where('id > 0').exists? + @single_user_mode ||= Rails.configuration.x.single_user_mode && Account.without_internal.exists? end def use_seamless_external_login? @@ -178,7 +179,7 @@ class ApplicationController < ActionController::Base respond_to do |format| format.any { render 'errors/self_destruct', layout: 'auth', status: 410, formats: [:html] } - format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: code } + format.json { render json: { error: Rack::Utils::HTTP_STATUS_CODES[410] }, status: 410 } end end diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index acfc0af0d9..e5a2ac0270 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -25,6 +25,14 @@ class Auth::RegistrationsController < Devise::RegistrationsController super(&:build_invite_request) end + def edit # rubocop:disable Lint/UselessMethodDefinition + super + end + + def create # rubocop:disable Lint/UselessMethodDefinition + super + end + def update super do |resource| resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password? @@ -44,7 +52,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def build_resource(hash = nil) - super(hash) + super resource.locale = I18n.locale resource.invite_code = @invite&.code if resource.invite_code.blank? diff --git a/app/controllers/concerns/api/error_handling.rb b/app/controllers/concerns/api/error_handling.rb new file mode 100644 index 0000000000..ad559fe2d7 --- /dev/null +++ b/app/controllers/concerns/api/error_handling.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Api::ErrorHandling + extend ActiveSupport::Concern + + included do + rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e| + render json: { error: e.to_s }, status: 422 + end + + rescue_from ActiveRecord::RecordNotUnique do + render json: { error: 'Duplicate record' }, status: 422 + end + + rescue_from Date::Error do + render json: { error: 'Invalid date supplied' }, status: 422 + end + + rescue_from ActiveRecord::RecordNotFound do + render json: { error: 'Record not found' }, status: 404 + end + + rescue_from HTTP::Error, Mastodon::UnexpectedResponseError do + render json: { error: 'Remote data could not be fetched' }, status: 503 + end + + rescue_from OpenSSL::SSL::SSLError do + render json: { error: 'Remote SSL certificate could not be verified' }, status: 503 + end + + rescue_from Mastodon::NotPermittedError do + render json: { error: 'This action is not allowed' }, status: 403 + end + + rescue_from Seahorse::Client::NetworkingError do |e| + Rails.logger.warn "Storage server error: #{e}" + render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503 + end + + rescue_from Mastodon::RaceConditionError, Stoplight::Error::RedLight do + render json: { error: 'There was a temporary problem serving your request, please try again' }, status: 503 + end + + rescue_from Mastodon::RateLimitExceededError do + render json: { error: I18n.t('errors.429') }, status: 429 + end + + rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e| + render json: { error: e.to_s }, status: 400 + end + end +end diff --git a/app/controllers/concerns/api/pagination.rb b/app/controllers/concerns/api/pagination.rb new file mode 100644 index 0000000000..7f06dc0202 --- /dev/null +++ b/app/controllers/concerns/api/pagination.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module Api::Pagination + extend ActiveSupport::Concern + + PAGINATION_PARAMS = %i(limit).freeze + + 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 + + def pagination_params(core_params) + params + .slice(*PAGINATION_PARAMS) + .permit(*PAGINATION_PARAMS) + .merge(core_params) + 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 62f763fe2f..1823b5b8ed 100644 --- a/app/controllers/concerns/cache_concern.rb +++ b/app/controllers/concerns/cache_concern.rb @@ -45,28 +45,4 @@ module CacheConcern Rails.cache.write(key, response.body, expires_in: expires_in, raw: true) end end - - def cache_collection(raw, klass) - return raw unless klass.respond_to?(:with_includes) - - raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) - return [] if raw.empty? - - cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) - - 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] } - end - - def cache_collection_paginated_by_id(raw, klass, limit, options) - cache_collection raw.cache_ids.to_a_paginated_by_id(limit, options), klass - end end diff --git a/app/controllers/concerns/preloading_concern.rb b/app/controllers/concerns/preloading_concern.rb new file mode 100644 index 0000000000..61e2213649 --- /dev/null +++ b/app/controllers/concerns/preloading_concern.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module PreloadingConcern + extend ActiveSupport::Concern + + def preload_collection(scope, klass) + return scope unless klass.respond_to?(:preload_cacheable_associations) + + scope.to_a.tap do |records| + klass.preload_cacheable_associations(records) + end + end + + def preload_collection_paginated_by_id(scope, klass, limit, options) + preload_collection scope.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 3155866271..68f09ee023 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/custom_css_controller.rb b/app/controllers/custom_css_controller.rb index 62f8e0d772..eb6417698a 100644 --- a/app/controllers/custom_css_controller.rb +++ b/app/controllers/custom_css_controller.rb @@ -16,6 +16,6 @@ class CustomCssController < ActionController::Base # rubocop:disable Rails/Appli helper_method :custom_css_styles def set_user_roles - @user_roles = UserRole.where(highlighted: true).where.not(color: [nil, '']) + @user_roles = UserRole.providing_styles end end diff --git a/app/controllers/instance_actors_controller.rb b/app/controllers/instance_actors_controller.rb index 8422d74bc3..f2b1eaa3e7 100644 --- a/app/controllers/instance_actors_controller.rb +++ b/app/controllers/instance_actors_controller.rb @@ -6,6 +6,8 @@ class InstanceActorsController < ActivityPub::BaseController serialization_scope nil before_action :set_account + + skip_before_action :authenticate_user! # From `AccountOwnedConcern` skip_before_action :require_functional! skip_before_action :update_user_sign_in @@ -16,6 +18,11 @@ class InstanceActorsController < ActivityPub::BaseController private + # Skips various `before_action` from `AccountOwnedConcern` + def account_required? + false + end + def set_account @account = Account.representative end diff --git a/app/controllers/settings/applications_controller.rb b/app/controllers/settings/applications_controller.rb index d4b7205681..d6573f9b49 100644 --- a/app/controllers/settings/applications_controller.rb +++ b/app/controllers/settings/applications_controller.rb @@ -13,7 +13,7 @@ class Settings::ApplicationsController < Settings::BaseController def new @application = Doorkeeper::Application.new( redirect_uri: Doorkeeper.configuration.native_redirect_uri, - scopes: 'read write follow' + scopes: 'profile' ) end diff --git a/app/controllers/settings/featured_tags_controller.rb b/app/controllers/settings/featured_tags_controller.rb index c384402650..90c112e219 100644 --- a/app/controllers/settings/featured_tags_controller.rb +++ b/app/controllers/settings/featured_tags_controller.rb @@ -38,7 +38,7 @@ class Settings::FeaturedTagsController < Settings::BaseController end def set_recently_used_tags - @recently_used_tags = Tag.recently_used(current_account).where.not(id: @featured_tags.map(&:id)).limit(10) + @recently_used_tags = Tag.suggestions_for_account(current_account).limit(10) end def featured_tag_params diff --git a/app/controllers/settings/imports_controller.rb b/app/controllers/settings/imports_controller.rb index 983caf22fa..569aa07c53 100644 --- a/app/controllers/settings/imports_controller.rb +++ b/app/controllers/settings/imports_controller.rb @@ -31,7 +31,7 @@ class Settings::ImportsController < Settings::BaseController def show; end def failures - @bulk_import = current_account.bulk_imports.where(state: :finished).find(params[:id]) + @bulk_import = current_account.bulk_imports.state_finished.find(params[:id]) respond_to do |format| format.csv do @@ -92,7 +92,7 @@ class Settings::ImportsController < Settings::BaseController end def set_bulk_import - @bulk_import = current_account.bulk_imports.where(state: :unconfirmed).find(params[:id]) + @bulk_import = current_account.bulk_imports.state_unconfirmed.find(params[:id]) end def set_recent_imports diff --git a/app/controllers/severed_relationships_controller.rb b/app/controllers/severed_relationships_controller.rb new file mode 100644 index 0000000000..168e85e3fe --- /dev/null +++ b/app/controllers/severed_relationships_controller.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +class SeveredRelationshipsController < ApplicationController + layout 'admin' + + before_action :authenticate_user! + before_action :set_body_classes + before_action :set_cache_headers + + before_action :set_event, only: [:following, :followers] + + def index + @events = AccountRelationshipSeveranceEvent.where(account: current_account) + end + + def following + respond_to do |format| + format.csv { send_data following_data, filename: "following-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" } + end + end + + def followers + respond_to do |format| + format.csv { send_data followers_data, filename: "followers-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" } + end + end + + private + + def set_event + @event = AccountRelationshipSeveranceEvent.find(params[:id]) + end + + def following_data + CSV.generate(headers: ['Account address', 'Show boosts', 'Notify on new posts', 'Languages'], write_headers: true) do |csv| + @event.severed_relationships.active.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow| + csv << [acct(follow.target_account), follow.show_reblogs, follow.notify, follow.languages&.join(', ')] + end + end + end + + def followers_data + CSV.generate(headers: ['Account address'], write_headers: true) do |csv| + @event.severed_relationships.passive.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow| + csv << [acct(follow.account)] + end + end + end + + def acct(account) + account.local? ? account.local_username_and_domain : account.acct + end + + def set_body_classes + @body_classes = 'admin' + end + + def set_cache_headers + response.cache_control.replace(private: true, no_store: true) + end +end diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index b0bdbde956..d6c0d872c8 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -45,7 +45,7 @@ class TagsController < ApplicationController end def set_statuses - @statuses = cache_collection(TagFeed.new(@tag, nil, local: @local).get(limit_param), Status) + @statuses = preload_collection(TagFeed.new(@tag, nil, local: @local).get(limit_param), Status) end def limit_param diff --git a/app/controllers/well_known/oauth_metadata_controller.rb b/app/controllers/well_known/oauth_metadata_controller.rb new file mode 100644 index 0000000000..c80be2d652 --- /dev/null +++ b/app/controllers/well_known/oauth_metadata_controller.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module WellKnown + class OauthMetadataController < ActionController::Base # rubocop:disable Rails/ApplicationController + include CacheConcern + + # Prevent `active_model_serializer`'s `ActionController::Serialization` from calling `current_user` + # and thus re-issuing session cookies + serialization_scope nil + + def show + # Due to this document potentially changing between Mastodon versions (as + # new OAuth scopes are added), we don't use expires_in to cache upstream, + # instead just caching in the rails cache: + render_with_cache( + json: ::OauthMetadataPresenter.new, + serializer: ::OauthMetadataSerializer, + content_type: 'application/json', + expires_in: 15.minutes + ) + end + end +end diff --git a/app/helpers/admin/account_moderation_notes_helper.rb b/app/helpers/admin/account_moderation_notes_helper.rb index 3b9d580499..2a3d954a35 100644 --- a/app/helpers/admin/account_moderation_notes_helper.rb +++ b/app/helpers/admin/account_moderation_notes_helper.rb @@ -4,27 +4,42 @@ module Admin::AccountModerationNotesHelper def admin_account_link_to(account, path: nil) return if account.nil? - link_to path || admin_account_path(account.id), class: name_tag_classes(account), title: account.acct do - safe_join([ - image_tag(account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar'), - content_tag(:span, account.acct, class: 'username'), - ], ' ') - end + link_to( + labeled_account_avatar(account), + path || admin_account_path(account.id), + class: class_names('name-tag', suspended: suspended_account?(account)), + title: account.acct + ) end def admin_account_inline_link_to(account) return if account.nil? - link_to admin_account_path(account.id), class: name_tag_classes(account, true), title: account.acct do - content_tag(:span, account.acct, class: 'username') - end + link_to( + account_inline_text(account), + admin_account_path(account.id), + class: class_names('inline-name-tag', suspended: suspended_account?(account)), + title: account.acct + ) end private - def name_tag_classes(account, inline = false) - classes = [inline ? 'inline-name-tag' : 'name-tag'] - classes << 'suspended' if account.suspended? || (account.local? && account.user.nil?) - classes.join(' ') + def labeled_account_avatar(account) + safe_join( + [ + image_tag(account.avatar.url, width: 15, height: 15, alt: '', class: 'avatar'), + account_inline_text(account), + ], + ' ' + ) + end + + def account_inline_text(account) + content_tag(:span, account.acct, class: 'username') + end + + def suspended_account?(account) + account.suspended? || (account.local? && account.user.nil?) end end diff --git a/app/helpers/admin/action_logs_helper.rb b/app/helpers/admin/action_logs_helper.rb index 4018ef6b1c..e8d5634126 100644 --- a/app/helpers/admin/action_logs_helper.rb +++ b/app/helpers/admin/action_logs_helper.rb @@ -15,15 +15,15 @@ module Admin::ActionLogsHelper link_to log.human_identifier, admin_roles_path(log.target_id) when 'Report' link_to "##{log.human_identifier.presence || log.target_id}", admin_report_path(log.target_id) - when 'DomainBlock', 'DomainAllow', 'EmailDomainBlock', 'UnavailableDomain' - link_to log.human_identifier, "https://#{log.human_identifier.presence}" + when 'Instance', 'DomainBlock', 'DomainAllow', 'UnavailableDomain' + log.human_identifier.present? ? link_to(log.human_identifier, admin_instance_path(log.human_identifier)) : I18n.t('admin.action_logs.unavailable_instance') when 'Status' link_to log.human_identifier, log.permalink when 'AccountWarning' link_to log.human_identifier, disputes_strike_path(log.target_id) when 'Announcement' link_to truncate(log.human_identifier), edit_admin_announcement_path(log.target_id) - when 'IpBlock', 'Instance', 'CustomEmoji' + when 'IpBlock', 'EmailDomainBlock', 'CustomEmoji' log.human_identifier when 'CanonicalEmailBlock' content_tag(:samp, (log.human_identifier.presence || '')[0...7], title: log.human_identifier) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 4f7f66985d..7e9cfee3f6 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -28,14 +28,6 @@ module ApplicationHelper number_to_human(number, **options) end - def active_nav_class(*paths) - paths.any? { |path| current_page?(path) } ? 'active' : '' - end - - def show_landing_strip? - !user_signed_in? && !single_user_mode? - end - def open_registrations? Setting.registrations_mode == 'open' end @@ -121,8 +113,16 @@ 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 - content_tag(:svg, tag.path('fill-rule': 'evenodd', 'clip-rule': 'evenodd', d: 'M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z'), xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 20 20', fill: 'currentColor') + inline_svg_tag 'check.svg' end def visibility_icon(status) @@ -213,7 +213,7 @@ module ApplicationHelper state_params[:moved_to_account] = current_account.moved_to_account end - state_params[:owner] = Account.local.without_suspended.where('id > 0').first if single_user_mode? + state_params[:owner] = Account.local.without_suspended.without_internal.first if single_user_mode? json = ActiveModelSerializers::SerializableResource.new(InitialStatePresenter.new(state_params), serializer: InitialStateSerializer).to_json # rubocop:disable Rails/OutputSafety @@ -240,6 +240,26 @@ module ApplicationHelper EmojiFormatter.new(html, custom_emojis, other_options.merge(animate: prefers_autoplay?)).to_s end + def mascot_url + full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg')) + end + + def instance_presenter + @instance_presenter ||= InstancePresenter.new + end + + def favicon_path(size = '48') + instance_presenter.favicon&.file&.url(size) + end + + def app_icon_path(size = '48') + instance_presenter.app_icon&.file&.url(size) + end + + def use_mask_icon? + instance_presenter.app_icon.blank? + end + private def storage_host_var diff --git a/app/helpers/branding_helper.rb b/app/helpers/branding_helper.rb index 2b9c233c23..8201f36e3c 100644 --- a/app/helpers/branding_helper.rb +++ b/app/helpers/branding_helper.rb @@ -19,17 +19,6 @@ module BrandingHelper end def render_logo - image_pack_tag('logo.svg', alt: 'Mastodon', class: 'logo logo--icon') - end - - def render_symbol(version = :icon) - path = case version - when :icon - 'logo-symbol-icon.svg' - when :wordmark - 'logo-symbol-wordmark.svg' - end - - render(file: Rails.root.join('app', 'javascript', 'images', path)).html_safe # rubocop:disable Rails/OutputSafety + 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 945ef9b91a..cbefe0fe53 100644 --- a/app/helpers/context_helper.rb +++ b/app/helpers/context_helper.rb @@ -24,12 +24,21 @@ module ContextHelper memorial: { 'toot' => 'http://joinmastodon.org/ns#', 'memorial' => 'toot:memorial' }, voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' }, olm: { - 'toot' => 'http://joinmastodon.org/ns#', 'Device' => 'toot:Device', 'Ed25519Signature' => 'toot:Ed25519Signature', 'Ed25519Key' => 'toot:Ed25519Key', 'Curve25519Key' => 'toot:Curve25519Key', 'EncryptedMessage' => 'toot:EncryptedMessage', 'publicKeyBase64' => 'toot:publicKeyBase64', 'deviceId' => 'toot:deviceId', + 'toot' => 'http://joinmastodon.org/ns#', + 'Device' => 'toot:Device', + 'Ed25519Signature' => 'toot:Ed25519Signature', + 'Ed25519Key' => 'toot:Ed25519Key', + 'Curve25519Key' => 'toot:Curve25519Key', + 'EncryptedMessage' => 'toot:EncryptedMessage', + 'publicKeyBase64' => 'toot:publicKeyBase64', + 'deviceId' => 'toot:deviceId', 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, - 'messageFranking' => 'toot:messageFranking', 'messageType' => 'toot:messageType', 'cipherText' => 'toot:cipherText' + 'messageFranking' => 'toot:messageFranking', + 'messageType' => 'toot:messageType', + 'cipherText' => 'toot:cipherText', }, suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' }, }.freeze @@ -39,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/jsonld_helper.rb b/app/helpers/jsonld_helper.rb index b0f2077db0..932a3420db 100644 --- a/app/helpers/jsonld_helper.rb +++ b/app/helpers/jsonld_helper.rb @@ -141,7 +141,7 @@ module JsonLdHelper def safe_for_forwarding?(original, compacted) original.without('@context', 'signature').all? do |key, value| compacted_value = compacted[key] - return false unless value.class == compacted_value.class + return false unless value.instance_of?(compacted_value.class) if value.is_a?(Hash) safe_for_forwarding?(value, compacted_value) diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index 87f0f288d3..9e1c0a7db1 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -109,6 +109,7 @@ module LanguagesHelper mn: ['Mongolian', 'ะœะพะฝะณะพะป ั…ัะป'].freeze, mr: ['Marathi', 'เคฎเคฐเคพเค เฅ€'].freeze, ms: ['Malay', 'Bahasa Melayu'].freeze, + 'ms-Arab': ['Jawi Malay', 'ุจู‡ุงุณ ู…ู„ุงูŠูˆ'].freeze, mt: ['Maltese', 'Malti'].freeze, my: ['Burmese', 'แ€—แ€™แ€ฌแ€…แ€ฌ'].freeze, na: ['Nauru', 'Ekakairลฉ Naoero'].freeze, @@ -127,7 +128,7 @@ module LanguagesHelper om: ['Oromo', 'Afaan Oromoo'].freeze, or: ['Oriya', 'เฌ“เฌกเฌผเฌฟเฌ†'].freeze, os: ['Ossetian', 'ะธั€ะพะฝ รฆะฒะทะฐะณ'].freeze, - pa: ['Panjabi', 'เจชเฉฐเจœเจพเจฌเฉ€'].freeze, + pa: ['Punjabi', 'เจชเฉฐเจœเจพเจฌเฉ€'].freeze, pi: ['Pฤli', 'เคชเคพเคดเคฟ'].freeze, pl: ['Polish', 'Polski'].freeze, ps: ['Pashto', 'ูพฺšุชูˆ'].freeze, @@ -191,15 +192,20 @@ module LanguagesHelper chr: ['Cherokee', 'แฃแŽณแŽฉ แŽฆแฌแ‚แŽฏแแ—'].freeze, ckb: ['Sorani (Kurdish)', 'ุณ†ุฑุงู†Œ'].freeze, cnr: ['Montenegrin', 'crnogorski'].freeze, + csb: ['Kashubian', 'Kaszรซbsczi'].freeze, jbo: ['Lojban', 'la .lojban.'].freeze, kab: ['Kabyle', 'Taqbaylit'].freeze, ldn: ['Lรกadan', 'Lรกadan'].freeze, lfn: ['Lingua Franca Nova', 'lingua franca nova'].freeze, + moh: ['Mohawk', 'Kanienสผkรฉha'].freeze, + nds: ['Low German', 'Plattdรผรผtsch'].freeze, + pdc: ['Pennsylvania Dutch', 'Pennsilfaani-Deitsch'].freeze, sco: ['Scots', 'Scots'].freeze, sma: ['Southern Sami', 'ร…arjelsaemien Gรฏele'].freeze, smj: ['Lule Sami', 'Julevsรกmegiella'].freeze, szl: ['Silesian', 'ล›lลฏnsko godka'].freeze, tok: ['Toki Pona', 'toki pona'].freeze, + vai: ['Vai', '๊•™๊”ค'].freeze, xal: ['Kalmyk', 'ะฅะฐะปัŒะผะณ ะบะตะปะฝ'].freeze, zba: ['Balaibalan', 'ุจุงู„ูŠุจู„ู†'].freeze, zgh: ['Standard Moroccan Tamazight', 'โตœโดฐโตŽโดฐโตฃโต‰โต–โตœ'].freeze, diff --git a/app/helpers/mascot_helper.rb b/app/helpers/mascot_helper.rb deleted file mode 100644 index 34b656411e..0000000000 --- a/app/helpers/mascot_helper.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module MascotHelper - def mascot_url - full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg')) - end - - def instance_presenter - @instance_presenter ||= InstancePresenter.new - end -end diff --git a/app/helpers/statuses_helper.rb b/app/helpers/statuses_helper.rb index 286c53d834..ca693a8a78 100644 --- a/app/helpers/statuses_helper.rb +++ b/app/helpers/statuses_helper.rb @@ -4,14 +4,6 @@ module StatusesHelper EMBEDDED_CONTROLLER = 'statuses' EMBEDDED_ACTION = 'embed' - def link_to_newer(url) - link_to t('statuses.show_newer'), url, class: 'load-more load-gap' - end - - def link_to_older(url) - link_to t('statuses.show_older'), url, class: 'load-more load-gap' - end - def nothing_here(extra_classes = '') content_tag(:div, class: "nothing-here #{extra_classes}") do t('accounts.nothing_here') diff --git a/app/helpers/theme_helper.rb b/app/helpers/theme_helper.rb new file mode 100644 index 0000000000..d15259851c --- /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/entrypoints/admin.tsx b/app/javascript/entrypoints/admin.tsx new file mode 100644 index 0000000000..225cb16330 --- /dev/null +++ b/app/javascript/entrypoints/admin.tsx @@ -0,0 +1,368 @@ +import './public-path'; +import { createRoot } from 'react-dom/client'; + +import Rails from '@rails/ujs'; + +import ready from '../mastodon/ready'; + +const setAnnouncementEndsAttributes = (target: HTMLInputElement) => { + const valid = target.value && target.validity.valid; + const element = document.querySelector( + 'input[type="datetime-local"]#announcement_ends_at', + ); + + if (!element) return; + + if (valid) { + element.classList.remove('optional'); + element.required = true; + element.min = target.value; + } else { + element.classList.add('optional'); + element.removeAttribute('required'); + element.removeAttribute('min'); + } +}; + +Rails.delegate( + document, + 'input[type="datetime-local"]#announcement_starts_at', + 'change', + ({ target }) => { + if (target instanceof HTMLInputElement) + setAnnouncementEndsAttributes(target); + }, +); + +const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]'; + +const showSelectAll = () => { + const selectAllMatchingElement = document.querySelector( + '.batch-table__select-all', + ); + selectAllMatchingElement?.classList.add('active'); +}; + +const hideSelectAll = () => { + const selectAllMatchingElement = document.querySelector( + '.batch-table__select-all', + ); + const hiddenField = document.querySelector( + 'input#select_all_matching', + ); + const selectedMsg = document.querySelector( + '.batch-table__select-all .selected', + ); + const notSelectedMsg = document.querySelector( + '.batch-table__select-all .not-selected', + ); + + selectAllMatchingElement?.classList.remove('active'); + selectedMsg?.classList.remove('active'); + notSelectedMsg?.classList.add('active'); + if (hiddenField) hiddenField.value = '0'; +}; + +Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => { + if (!(target instanceof HTMLInputElement)) return; + + const selectAllMatchingElement = document.querySelector( + '.batch-table__select-all', + ); + + document + .querySelectorAll(batchCheckboxClassName) + .forEach((content) => { + content.checked = target.checked; + }); + + if (selectAllMatchingElement) { + if (target.checked) { + showSelectAll(); + } else { + hideSelectAll(); + } + } +}); + +Rails.delegate(document, '.batch-table__select-all button', 'click', () => { + const hiddenField = document.querySelector( + '#select_all_matching', + ); + + if (!hiddenField) return; + + const active = hiddenField.value === '1'; + const selectedMsg = document.querySelector( + '.batch-table__select-all .selected', + ); + const notSelectedMsg = document.querySelector( + '.batch-table__select-all .not-selected', + ); + + if (!selectedMsg || !notSelectedMsg) return; + + if (active) { + hiddenField.value = '0'; + selectedMsg.classList.remove('active'); + notSelectedMsg.classList.add('active'); + } else { + hiddenField.value = '1'; + notSelectedMsg.classList.remove('active'); + selectedMsg.classList.add('active'); + } +}); + +Rails.delegate(document, batchCheckboxClassName, 'change', () => { + const checkAllElement = document.querySelector( + 'input#batch_checkbox_all', + ); + const selectAllMatchingElement = document.querySelector( + '.batch-table__select-all', + ); + + if (checkAllElement) { + const allCheckboxes = Array.from( + document.querySelectorAll(batchCheckboxClassName), + ); + checkAllElement.checked = allCheckboxes.every((content) => content.checked); + checkAllElement.indeterminate = + !checkAllElement.checked && + allCheckboxes.some((content) => content.checked); + + if (selectAllMatchingElement) { + if (checkAllElement.checked) { + showSelectAll(); + } else { + hideSelectAll(); + } + } + } +}); + +Rails.delegate( + document, + '.filter-subset--with-select select', + 'change', + ({ target }) => { + if (target instanceof HTMLSelectElement) target.form?.submit(); + }, +); + +const onDomainBlockSeverityChange = (target: HTMLSelectElement) => { + const rejectMediaDiv = document.querySelector( + '.input.with_label.domain_block_reject_media', + ); + const rejectReportsDiv = document.querySelector( + '.input.with_label.domain_block_reject_reports', + ); + + if (rejectMediaDiv && rejectMediaDiv instanceof HTMLElement) { + rejectMediaDiv.style.display = + target.value === 'suspend' ? 'none' : 'block'; + } + + if (rejectReportsDiv && rejectReportsDiv instanceof HTMLElement) { + rejectReportsDiv.style.display = + target.value === 'suspend' ? 'none' : 'block'; + } +}; + +Rails.delegate(document, '#domain_block_severity', 'change', ({ target }) => { + if (target instanceof HTMLSelectElement) onDomainBlockSeverityChange(target); +}); + +const onEnableBootstrapTimelineAccountsChange = (target: HTMLInputElement) => { + const bootstrapTimelineAccountsField = + document.querySelector( + '#form_admin_settings_bootstrap_timeline_accounts', + ); + + if (bootstrapTimelineAccountsField) { + bootstrapTimelineAccountsField.disabled = !target.checked; + if (target.checked) { + bootstrapTimelineAccountsField.parentElement?.classList.remove( + 'disabled', + ); + bootstrapTimelineAccountsField.parentElement?.parentElement?.classList.remove( + 'disabled', + ); + } else { + bootstrapTimelineAccountsField.parentElement?.classList.add('disabled'); + bootstrapTimelineAccountsField.parentElement?.parentElement?.classList.add( + 'disabled', + ); + } + } +}; + +Rails.delegate( + document, + '#form_admin_settings_enable_bootstrap_timeline_accounts', + 'change', + ({ target }) => { + if (target instanceof HTMLInputElement) + onEnableBootstrapTimelineAccountsChange(target); + }, +); + +const onChangeRegistrationMode = (target: HTMLSelectElement) => { + const enabled = target.value === 'approved'; + + document + .querySelectorAll( + '.form_admin_settings_registrations_mode .warning-hint', + ) + .forEach((warning_hint) => { + warning_hint.style.display = target.value === 'open' ? 'inline' : 'none'; + }); + + document + .querySelectorAll( + 'input#form_admin_settings_require_invite_text', + ) + .forEach((input) => { + input.disabled = !enabled; + if (enabled) { + let element: HTMLElement | null = input; + do { + element.classList.remove('disabled'); + element = element.parentElement; + } while (element && !element.classList.contains('fields-group')); + } else { + let element: HTMLElement | null = input; + do { + element.classList.add('disabled'); + element = element.parentElement; + } while (element && !element.classList.contains('fields-group')); + } + }); +}; + +const convertUTCDateTimeToLocal = (value: string) => { + const date = new Date(value + 'Z'); + const twoChars = (x: number) => x.toString().padStart(2, '0'); + return `${date.getFullYear()}-${twoChars(date.getMonth() + 1)}-${twoChars(date.getDate())}T${twoChars(date.getHours())}:${twoChars(date.getMinutes())}`; +}; + +function convertLocalDatetimeToUTC(value: string) { + const date = new Date(value); + const fullISO8601 = date.toISOString(); + return fullISO8601.slice(0, fullISO8601.indexOf('T') + 6); +} + +Rails.delegate( + document, + '#form_admin_settings_registrations_mode', + 'change', + ({ target }) => { + if (target instanceof HTMLSelectElement) onChangeRegistrationMode(target); + }, +); + +async function mountReactComponent(element: Element) { + const componentName = element.getAttribute('data-admin-component'); + const stringProps = element.getAttribute('data-props'); + + if (!stringProps) return; + + const componentProps = JSON.parse(stringProps) as object; + + const { default: AdminComponent } = await import( + '@/mastodon/containers/admin_component' + ); + + const { default: Component } = (await import( + `@/mastodon/components/admin/${componentName}` + )) as { default: React.ComponentType }; + + const root = createRoot(element); + + root.render( + + + , + ); +} + +ready(() => { + const domainBlockSeveritySelect = document.querySelector( + 'select#domain_block_severity', + ); + if (domainBlockSeveritySelect) + onDomainBlockSeverityChange(domainBlockSeveritySelect); + + const enableBootstrapTimelineAccounts = + document.querySelector( + 'input#form_admin_settings_enable_bootstrap_timeline_accounts', + ); + if (enableBootstrapTimelineAccounts) + onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts); + + const registrationMode = document.querySelector( + 'select#form_admin_settings_registrations_mode', + ); + if (registrationMode) onChangeRegistrationMode(registrationMode); + + const checkAllElement = document.querySelector( + 'input#batch_checkbox_all', + ); + if (checkAllElement) { + const allCheckboxes = Array.from( + document.querySelectorAll(batchCheckboxClassName), + ); + checkAllElement.checked = allCheckboxes.every((content) => content.checked); + checkAllElement.indeterminate = + !checkAllElement.checked && + allCheckboxes.some((content) => content.checked); + } + + document + .querySelector('a#add-instance-button') + ?.addEventListener('click', (e) => { + const domain = document.querySelector( + 'input[type="text"]#by_domain', + )?.value; + + if (domain && e.target instanceof HTMLAnchorElement) { + const url = new URL(e.target.href); + url.searchParams.set('_domain', domain); + e.target.href = url.toString(); + } + }); + + document + .querySelectorAll('input[type="datetime-local"]') + .forEach((element) => { + if (element.value) { + element.value = convertUTCDateTimeToLocal(element.value); + } + if (element.placeholder) { + element.placeholder = convertUTCDateTimeToLocal(element.placeholder); + } + }); + + Rails.delegate(document, 'form', 'submit', ({ target }) => { + if (target instanceof HTMLFormElement) + target + .querySelectorAll('input[type="datetime-local"]') + .forEach((element) => { + if (element.value && element.validity.valid) { + element.value = convertLocalDatetimeToUTC(element.value); + } + }); + }); + + const announcementStartsAt = document.querySelector( + 'input[type="datetime-local"]#announcement_starts_at', + ); + if (announcementStartsAt) { + setAnnouncementEndsAttributes(announcementStartsAt); + } + + document.querySelectorAll('[data-admin-component]').forEach((element) => { + void mountReactComponent(element); + }); +}).catch((reason: unknown) => { + throw reason; +}); diff --git a/app/javascript/packs/application.js b/app/javascript/entrypoints/application.ts similarity index 81% rename from app/javascript/packs/application.js rename to app/javascript/entrypoints/application.ts index d13388b479..1087b1c4cb 100644 --- a/app/javascript/packs/application.js +++ b/app/javascript/entrypoints/application.ts @@ -1,5 +1,5 @@ import './public-path'; -import main from "mastodon/main"; +import main from 'mastodon/main'; import { start } from '../mastodon/common'; import { loadLocale } from '../mastodon/locales'; @@ -10,6 +10,6 @@ start(); loadPolyfills() .then(loadLocale) .then(main) - .catch(e => { + .catch((e: unknown) => { console.error(e); }); diff --git a/app/javascript/packs/error.js b/app/javascript/entrypoints/error.ts similarity index 64% rename from app/javascript/packs/error.js rename to app/javascript/entrypoints/error.ts index 6376dc2f5d..db68484f3a 100644 --- a/app/javascript/packs/error.js +++ b/app/javascript/entrypoints/error.ts @@ -2,7 +2,9 @@ import './public-path'; import ready from '../mastodon/ready'; ready(() => { - const image = document.querySelector('img'); + const image = document.querySelector('img'); + + if (!image) return; image.addEventListener('mouseenter', () => { image.src = '/oops.gif'; @@ -11,4 +13,6 @@ ready(() => { image.addEventListener('mouseleave', () => { image.src = '/oops.png'; }); +}).catch((e: unknown) => { + console.error(e); }); diff --git a/app/javascript/packs/inert.js b/app/javascript/entrypoints/inert.ts similarity index 100% rename from app/javascript/packs/inert.js rename to app/javascript/entrypoints/inert.ts diff --git a/app/javascript/packs/mailer.js b/app/javascript/entrypoints/mailer.ts similarity index 100% rename from app/javascript/packs/mailer.js rename to app/javascript/entrypoints/mailer.ts diff --git a/app/javascript/packs/public-path.js b/app/javascript/entrypoints/public-path.ts similarity index 69% rename from app/javascript/packs/public-path.js rename to app/javascript/entrypoints/public-path.ts index f4d166a771..ac4b9355b9 100644 --- a/app/javascript/packs/public-path.js +++ b/app/javascript/entrypoints/public-path.ts @@ -2,7 +2,7 @@ // to share the same assets regardless of instance configuration. // See https://webpack.js.org/guides/public-path/#on-the-fly -function removeOuterSlashes(string) { +function removeOuterSlashes(string: string) { return string.replace(/^\/*/, '').replace(/\/*$/, ''); } @@ -15,7 +15,9 @@ function formatPublicPath(host = '', path = '') { return `${formattedHost}/${formattedPath}/`; } -const cdnHost = document.querySelector('meta[name=cdn-host]'); +const cdnHost = document.querySelector('meta[name=cdn-host]'); -// eslint-disable-next-line no-undef -__webpack_public_path__ = formatPublicPath(cdnHost ? cdnHost.content : '', process.env.PUBLIC_OUTPUT_PATH); +__webpack_public_path__ = formatPublicPath( + cdnHost ? cdnHost.content : '', + process.env.PUBLIC_OUTPUT_PATH, +); diff --git a/app/javascript/entrypoints/public.tsx b/app/javascript/entrypoints/public.tsx new file mode 100644 index 0000000000..40a9b7c0ca --- /dev/null +++ b/app/javascript/entrypoints/public.tsx @@ -0,0 +1,462 @@ +import { createRoot } from 'react-dom/client'; + +import './public-path'; + +import { IntlMessageFormat } from 'intl-messageformat'; +import type { MessageDescriptor, PrimitiveType } from 'react-intl'; +import { defineMessages } from 'react-intl'; + +import Rails from '@rails/ujs'; +import axios from 'axios'; +import { throttle } from 'lodash'; + +import { start } from '../mastodon/common'; +import { timeAgoString } from '../mastodon/components/relative_timestamp'; +import emojify from '../mastodon/features/emoji/emoji'; +import loadKeyboardExtensions from '../mastodon/load_keyboard_extensions'; +import { loadLocale, getLocale } from '../mastodon/locales'; +import { loadPolyfills } from '../mastodon/polyfills'; +import ready from '../mastodon/ready'; + +import 'cocoon-js-vanilla'; + +start(); + +const messages = defineMessages({ + usernameTaken: { + id: 'username.taken', + defaultMessage: 'That username is taken. Try another', + }, + passwordExceedsLength: { + id: 'password_confirmation.exceeds_maxlength', + defaultMessage: 'Password confirmation exceeds the maximum password length', + }, + passwordDoesNotMatch: { + id: 'password_confirmation.mismatching', + defaultMessage: 'Password confirmation does not match', + }, +}); + +interface SetHeightMessage { + type: 'setHeight'; + id: string; + height: number; +} + +function isSetHeightMessage(data: unknown): data is SetHeightMessage { + if ( + data && + typeof data === 'object' && + 'type' in data && + data.type === 'setHeight' + ) + return true; + else return false; +} + +window.addEventListener('message', (e) => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- typings are not correct, it can be null in very rare cases + if (!e.data || !isSetHeightMessage(e.data) || !window.parent) return; + + const data = e.data; + + ready(() => { + window.parent.postMessage( + { + type: 'setHeight', + id: data.id, + height: document.getElementsByTagName('html')[0]?.scrollHeight, + }, + '*', + ); + }).catch((e: unknown) => { + console.error('Error in setHeightMessage postMessage', e); + }); +}); + +function loaded() { + const { messages: localeData } = getLocale(); + + const locale = document.documentElement.lang; + + const dateTimeFormat = new Intl.DateTimeFormat(locale, { + year: 'numeric', + month: 'long', + day: 'numeric', + hour: 'numeric', + minute: 'numeric', + }); + + const dateFormat = new Intl.DateTimeFormat(locale, { + year: 'numeric', + month: 'short', + day: 'numeric', + }); + + const timeFormat = new Intl.DateTimeFormat(locale, { + timeStyle: 'short', + }); + + const formatMessage = ( + { id, defaultMessage }: MessageDescriptor, + values?: Record, + ) => { + let message: string | undefined = undefined; + + if (id) message = localeData[id]; + + if (!message) message = defaultMessage as string; + + const messageFormat = new IntlMessageFormat(message, locale); + return messageFormat.format(values) as string; + }; + + document.querySelectorAll('.emojify').forEach((content) => { + content.innerHTML = emojify(content.innerHTML); + }); + + document + .querySelectorAll('time.formatted') + .forEach((content) => { + const datetime = new Date(content.dateTime); + const formattedDate = dateTimeFormat.format(datetime); + + content.title = formattedDate; + content.textContent = formattedDate; + }); + + const isToday = (date: Date) => { + const today = new Date(); + + return ( + date.getDate() === today.getDate() && + date.getMonth() === today.getMonth() && + date.getFullYear() === today.getFullYear() + ); + }; + const todayFormat = new IntlMessageFormat( + localeData['relative_format.today'] ?? 'Today at {time}', + locale, + ); + + document + .querySelectorAll('time.relative-formatted') + .forEach((content) => { + const datetime = new Date(content.dateTime); + + let formattedContent: string; + + if (isToday(datetime)) { + const formattedTime = timeFormat.format(datetime); + + formattedContent = todayFormat.format({ + time: formattedTime, + }) as string; + } else { + formattedContent = dateFormat.format(datetime); + } + + content.title = formattedContent; + content.textContent = formattedContent; + }); + + document + .querySelectorAll('time.time-ago') + .forEach((content) => { + const datetime = new Date(content.dateTime); + const now = new Date(); + + const timeGiven = content.dateTime.includes('T'); + content.title = timeGiven + ? dateTimeFormat.format(datetime) + : dateFormat.format(datetime); + content.textContent = timeAgoString( + { + formatMessage, + formatDate: (date: Date, options) => + new Intl.DateTimeFormat(locale, options).format(date), + }, + datetime, + now.getTime(), + now.getFullYear(), + timeGiven, + ); + }); + + const reactComponents = document.querySelectorAll('[data-component]'); + + if (reactComponents.length > 0) { + import( + /* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container' + ) + .then(({ default: MediaContainer }) => { + reactComponents.forEach((component) => { + Array.from(component.children).forEach((child) => { + component.removeChild(child); + }); + }); + + const content = document.createElement('div'); + + const root = createRoot(content); + root.render( + , + ); + document.body.appendChild(content); + + return true; + }) + .catch((error: unknown) => { + console.error(error); + }); + } + + Rails.delegate( + document, + 'input#user_account_attributes_username', + 'input', + throttle( + ({ target }) => { + if (!(target instanceof HTMLInputElement)) return; + + if (target.value && target.value.length > 0) { + axios + .get('/api/v1/accounts/lookup', { params: { acct: target.value } }) + .then(() => { + target.setCustomValidity(formatMessage(messages.usernameTaken)); + return true; + }) + .catch(() => { + target.setCustomValidity(''); + }); + } else { + target.setCustomValidity(''); + } + }, + 500, + { leading: false, trailing: true }, + ), + ); + + Rails.delegate( + document, + '#user_password,#user_password_confirmation', + 'input', + () => { + const password = document.querySelector( + 'input#user_password', + ); + const confirmation = document.querySelector( + 'input#user_password_confirmation', + ); + if (!confirmation || !password) return; + + if ( + confirmation.value && + confirmation.value.length > password.maxLength + ) { + confirmation.setCustomValidity( + formatMessage(messages.passwordExceedsLength), + ); + } else if (password.value && password.value !== confirmation.value) { + confirmation.setCustomValidity( + formatMessage(messages.passwordDoesNotMatch), + ); + } else { + confirmation.setCustomValidity(''); + } + }, + ); + + Rails.delegate( + document, + 'button.status__content__spoiler-link', + 'click', + function () { + if (!(this instanceof HTMLButtonElement)) return; + + const statusEl = this.parentNode?.parentNode; + + if ( + !( + statusEl instanceof HTMLDivElement && + statusEl.classList.contains('.status__content') + ) + ) + return; + + if (statusEl.dataset.spoiler === 'expanded') { + statusEl.dataset.spoiler = 'folded'; + this.textContent = new IntlMessageFormat( + localeData['status.show_more'] ?? 'Show more', + locale, + ).format() as string; + } else { + statusEl.dataset.spoiler = 'expanded'; + this.textContent = new IntlMessageFormat( + localeData['status.show_less'] ?? 'Show less', + locale, + ).format() as string; + } + }, + ); + + document + .querySelectorAll('button.status__content__spoiler-link') + .forEach((spoilerLink) => { + const statusEl = spoilerLink.parentNode?.parentNode; + + if ( + !( + statusEl instanceof HTMLDivElement && + statusEl.classList.contains('.status__content') + ) + ) + return; + + const message = + statusEl.dataset.spoiler === 'expanded' + ? localeData['status.show_less'] ?? 'Show less' + : localeData['status.show_more'] ?? 'Show more'; + spoilerLink.textContent = new IntlMessageFormat( + message, + locale, + ).format() as string; + }); +} + +Rails.delegate( + document, + '#edit_profile input[type=file]', + 'change', + ({ target }) => { + if (!(target instanceof HTMLInputElement)) return; + + const avatar = document.querySelector( + `img#${target.id}-preview`, + ); + + if (!avatar) return; + + let file: File | undefined; + if (target.files) file = target.files[0]; + + const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc; + + if (url) avatar.src = url; + }, +); + +Rails.delegate(document, '.input-copy input', 'click', ({ target }) => { + if (!(target instanceof HTMLInputElement)) return; + + target.focus(); + target.select(); + target.setSelectionRange(0, target.value.length); +}); + +Rails.delegate(document, '.input-copy button', 'click', ({ target }) => { + if (!(target instanceof HTMLButtonElement)) return; + + const input = target.parentNode?.querySelector( + '.input-copy__wrapper input', + ); + + if (!input) return; + + const oldReadOnly = input.readOnly; + + input.readOnly = false; + input.focus(); + input.select(); + input.setSelectionRange(0, input.value.length); + + try { + if (document.execCommand('copy')) { + input.blur(); + + const parent = target.parentElement; + + if (!parent) return; + parent.classList.add('copied'); + + setTimeout(() => { + parent.classList.remove('copied'); + }, 700); + } + } catch (err) { + console.error(err); + } + + input.readOnly = oldReadOnly; +}); + +const toggleSidebar = () => { + const sidebar = document.querySelector('.sidebar ul'); + const toggleButton = document.querySelector( + 'a.sidebar__toggle__icon', + ); + + if (!sidebar || !toggleButton) return; + + if (sidebar.classList.contains('visible')) { + document.body.style.overflow = ''; + toggleButton.setAttribute('aria-expanded', 'false'); + } else { + document.body.style.overflow = 'hidden'; + toggleButton.setAttribute('aria-expanded', 'true'); + } + + toggleButton.classList.toggle('active'); + sidebar.classList.toggle('visible'); +}; + +Rails.delegate(document, '.sidebar__toggle__icon', 'click', () => { + toggleSidebar(); +}); + +Rails.delegate(document, '.sidebar__toggle__icon', 'keydown', (e) => { + if (e.key === ' ' || e.key === 'Enter') { + e.preventDefault(); + toggleSidebar(); + } +}); + +Rails.delegate(document, 'img.custom-emoji', 'mouseover', ({ target }) => { + if (target instanceof HTMLImageElement && target.dataset.original) + target.src = target.dataset.original; +}); +Rails.delegate(document, 'img.custom-emoji', 'mouseout', ({ target }) => { + if (target instanceof HTMLImageElement && target.dataset.static) + target.src = target.dataset.static; +}); + +// Empty the honeypot fields in JS in case something like an extension +// automatically filled them. +Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => { + [ + 'user_website', + 'user_confirm_password', + 'registration_user_website', + 'registration_user_confirm_password', + ].forEach((id) => { + const field = document.querySelector(`input#${id}`); + if (field) { + field.value = ''; + } + }); +}); + +function main() { + ready(loaded).catch((error: unknown) => { + console.error(error); + }); +} + +loadPolyfills() + .then(loadLocale) + .then(main) + .then(loadKeyboardExtensions) + .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 96% rename from app/javascript/packs/remote_interaction_helper.ts rename to app/javascript/entrypoints/remote_interaction_helper.ts index d5834c6c3d..419571c896 100644 --- a/app/javascript/packs/remote_interaction_helper.ts +++ b/app/javascript/entrypoints/remote_interaction_helper.ts @@ -67,7 +67,9 @@ const fetchInteractionURLFailure = () => { ); }; -const isValidDomain = (value: string) => { +const isValidDomain = (value: unknown) => { + if (typeof value !== 'string') return false; + const url = new URL('https:///path'); url.hostname = value; return url.hostname === value; @@ -124,6 +126,11 @@ const fromAcct = (acct: string) => { const domain = segments[1]; const fallbackTemplate = `https://${domain}/authorize_interaction?uri={uri}`; + if (!domain) { + fetchInteractionURLFailure(); + return; + } + axios .get(`https://${domain}/.well-known/webfinger`, { params: { resource: `acct:${acct}` }, diff --git a/app/javascript/packs/share.jsx b/app/javascript/entrypoints/share.tsx similarity index 64% rename from app/javascript/packs/share.jsx rename to app/javascript/entrypoints/share.tsx index 7b5723091c..7926250851 100644 --- a/app/javascript/packs/share.jsx +++ b/app/javascript/entrypoints/share.tsx @@ -2,7 +2,7 @@ import './public-path'; import { createRoot } from 'react-dom/client'; import { start } from '../mastodon/common'; -import ComposeContainer from '../mastodon/containers/compose_container'; +import ComposeContainer from '../mastodon/containers/compose_container'; import { loadPolyfills } from '../mastodon/polyfills'; import ready from '../mastodon/ready'; @@ -16,7 +16,7 @@ function loaded() { if (!attr) return; - const props = JSON.parse(attr); + const props = JSON.parse(attr) as object; const root = createRoot(mountNode); root.render(); @@ -24,9 +24,13 @@ function loaded() { } function main() { - ready(loaded); + ready(loaded).catch((error: unknown) => { + console.error(error); + }); } -loadPolyfills().then(main).catch(error => { - console.error(error); -}); +loadPolyfills() + .then(main) + .catch((error: unknown) => { + console.error(error); + }); diff --git a/app/javascript/entrypoints/sign_up.ts b/app/javascript/entrypoints/sign_up.ts new file mode 100644 index 0000000000..880738fcb7 --- /dev/null +++ b/app/javascript/entrypoints/sign_up.ts @@ -0,0 +1,48 @@ +import './public-path'; +import axios from 'axios'; + +import ready from '../mastodon/ready'; + +async function checkConfirmation() { + const response = await axios.get('/api/v1/emails/check_confirmation'); + + if (response.data) { + window.location.href = '/start'; + } +} + +ready(() => { + setInterval(() => { + void checkConfirmation(); + }, 5000); + + document + .querySelectorAll('button.timer-button') + .forEach((button) => { + let counter = 30; + + const container = document.createElement('span'); + + const updateCounter = () => { + container.innerText = ` (${counter})`; + }; + + updateCounter(); + + const countdown = setInterval(() => { + counter--; + + if (counter === 0) { + button.disabled = false; + button.removeChild(container); + clearInterval(countdown); + } else { + updateCounter(); + } + }, 1000); + + button.appendChild(container); + }); +}).catch((e: unknown) => { + throw e; +}); diff --git a/app/javascript/entrypoints/two_factor_authentication.ts b/app/javascript/entrypoints/two_factor_authentication.ts new file mode 100644 index 0000000000..981481694b --- /dev/null +++ b/app/javascript/entrypoints/two_factor_authentication.ts @@ -0,0 +1,197 @@ +import * as WebAuthnJSON from '@github/webauthn-json'; +import axios, { AxiosError } from 'axios'; + +import ready from '../mastodon/ready'; + +import 'regenerator-runtime/runtime'; + +type PublicKeyCredentialCreationOptionsJSON = + WebAuthnJSON.CredentialCreationOptionsJSON['publicKey']; + +function exceptionHasAxiosError( + error: unknown, +): error is AxiosError<{ error: unknown }> { + return ( + error instanceof AxiosError && + typeof error.response?.data === 'object' && + 'error' in error.response.data + ); +} + +function logAxiosResponseError(error: unknown) { + if (exceptionHasAxiosError(error)) console.error(error); +} + +function getCSRFToken() { + return document + .querySelector('meta[name="csrf-token"]') + ?.getAttribute('content'); +} + +function hideFlashMessages() { + document.querySelectorAll('.flash-message').forEach((flashMessage) => { + flashMessage.classList.add('hidden'); + }); +} + +async function callback( + url: string, + body: + | { + credential: WebAuthnJSON.PublicKeyCredentialWithAttestationJSON; + nickname: string; + } + | { + user: { credential: WebAuthnJSON.PublicKeyCredentialWithAssertionJSON }; + }, +) { + try { + const response = await axios.post<{ redirect_path: string }>( + url, + JSON.stringify(body), + { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + 'X-CSRF-Token': getCSRFToken(), + }, + }, + ); + + window.location.replace(response.data.redirect_path); + } catch (error) { + if (error instanceof AxiosError && error.response?.status === 422) { + const errorMessage = document.getElementById( + 'security-key-error-message', + ); + errorMessage?.classList.remove('hidden'); + + logAxiosResponseError(error); + } else { + console.error(error); + } + } +} + +async function handleWebauthnCredentialRegistration(nickname: string) { + try { + const response = await axios.get( + '/settings/security_keys/options', + ); + + const credentialOptions = response.data; + + try { + const credential = await WebAuthnJSON.create({ + publicKey: credentialOptions, + }); + + const params = { + credential: credential, + nickname: nickname, + }; + + await callback('/settings/security_keys', params); + } catch (error) { + const errorMessage = document.getElementById( + 'security-key-error-message', + ); + errorMessage?.classList.remove('hidden'); + console.error(error); + } + } catch (error) { + logAxiosResponseError(error); + } +} + +async function handleWebauthnCredentialAuthentication() { + try { + const response = await axios.get( + 'sessions/security_key_options', + ); + + const credentialOptions = response.data; + + try { + const credential = await WebAuthnJSON.get({ + publicKey: credentialOptions, + }); + + const params = { user: { credential: credential } }; + void callback('sign_in', params); + } catch (error) { + const errorMessage = document.getElementById( + 'security-key-error-message', + ); + errorMessage?.classList.remove('hidden'); + console.error(error); + } + } catch (error) { + logAxiosResponseError(error); + } +} + +ready(() => { + if (!WebAuthnJSON.supported()) { + const unsupported_browser_message = document.getElementById( + 'unsupported-browser-message', + ); + if (unsupported_browser_message) { + unsupported_browser_message.classList.remove('hidden'); + const button = document.querySelector( + 'button.btn.js-webauthn', + ); + if (button) button.disabled = true; + } + } + + const webAuthnCredentialRegistrationForm = + document.querySelector('form#new_webauthn_credential'); + if (webAuthnCredentialRegistrationForm) { + webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => { + event.preventDefault(); + + if (!(event.target instanceof HTMLFormElement)) return; + + const nickname = event.target.querySelector( + 'input[name="new_webauthn_credential[nickname]"]', + ); + + if (nickname?.value) { + void handleWebauthnCredentialRegistration(nickname.value); + } else { + nickname?.focus(); + } + }); + } + + const webAuthnCredentialAuthenticationForm = + document.getElementById('webauthn-form'); + if (webAuthnCredentialAuthenticationForm) { + webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => { + event.preventDefault(); + void handleWebauthnCredentialAuthentication(); + }); + + const otpAuthenticationForm = document.getElementById( + 'otp-authentication-form', + ); + + const linkToOtp = document.getElementById('link-to-otp'); + + linkToOtp?.addEventListener('click', () => { + webAuthnCredentialAuthenticationForm.classList.add('hidden'); + otpAuthenticationForm?.classList.remove('hidden'); + hideFlashMessages(); + }); + + const linkToWebAuthn = document.getElementById('link-to-webauthn'); + linkToWebAuthn?.addEventListener('click', () => { + otpAuthenticationForm?.classList.add('hidden'); + webAuthnCredentialAuthenticationForm.classList.remove('hidden'); + hideFlashMessages(); + }); + } +}).catch((e: unknown) => { + throw e; +}); diff --git a/app/javascript/images/check.svg b/app/javascript/images/check.svg new file mode 100644 index 0000000000..8a0ebe878d --- /dev/null +++ b/app/javascript/images/check.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/app/javascript/images/mailer-new/heading/LICENSE b/app/javascript/images/mailer-new/heading/LICENSE new file mode 100644 index 0000000000..974db1ac4b --- /dev/null +++ b/app/javascript/images/mailer-new/heading/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2024 Paweล‚ Kuna + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/javascript/images/mailer-new/heading/README.md b/app/javascript/images/mailer-new/heading/README.md new file mode 100644 index 0000000000..ecd4b949e7 --- /dev/null +++ b/app/javascript/images/mailer-new/heading/README.md @@ -0,0 +1 @@ +Images in this folder are based on [Tabler.io icons](https://tabler.io/icons). diff --git a/app/javascript/images/mailer-new/store-icons/btn-app-store.png b/app/javascript/images/mailer-new/store-icons/btn-app-store.png new file mode 100644 index 0000000000..ee3bd9385c Binary files /dev/null and b/app/javascript/images/mailer-new/store-icons/btn-app-store.png differ diff --git a/app/javascript/images/mailer-new/store-icons/btn-google-play.png b/app/javascript/images/mailer-new/store-icons/btn-google-play.png new file mode 100644 index 0000000000..ed43ff29aa Binary files /dev/null and b/app/javascript/images/mailer-new/store-icons/btn-google-play.png differ diff --git a/app/javascript/images/mailer-new/welcome-icons/LICENSE b/app/javascript/images/mailer-new/welcome-icons/LICENSE new file mode 100644 index 0000000000..974db1ac4b --- /dev/null +++ b/app/javascript/images/mailer-new/welcome-icons/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-2024 Paweล‚ Kuna + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/javascript/images/mailer-new/welcome-icons/README.md b/app/javascript/images/mailer-new/welcome-icons/README.md new file mode 100644 index 0000000000..ecd4b949e7 --- /dev/null +++ b/app/javascript/images/mailer-new/welcome-icons/README.md @@ -0,0 +1 @@ +Images in this folder are based on [Tabler.io icons](https://tabler.io/icons). diff --git a/app/javascript/images/mailer-new/welcome/step5-off.png b/app/javascript/images/mailer-new/welcome-icons/apps_step-off.png similarity index 100% rename from app/javascript/images/mailer-new/welcome/step5-off.png rename to app/javascript/images/mailer-new/welcome-icons/apps_step-off.png diff --git a/app/javascript/images/mailer-new/welcome-icons/apps_step-on.png b/app/javascript/images/mailer-new/welcome-icons/apps_step-on.png new file mode 100644 index 0000000000..fd631bf97e Binary files /dev/null and b/app/javascript/images/mailer-new/welcome-icons/apps_step-on.png differ diff --git a/app/javascript/images/mailer-new/welcome-icons/edit_profile_step-off.png b/app/javascript/images/mailer-new/welcome-icons/edit_profile_step-off.png new file mode 100644 index 0000000000..dfcdd04e16 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome-icons/edit_profile_step-off.png differ diff --git a/app/javascript/images/mailer-new/welcome/step1-on.png b/app/javascript/images/mailer-new/welcome-icons/edit_profile_step-on.png similarity index 100% rename from app/javascript/images/mailer-new/welcome/step1-on.png rename to app/javascript/images/mailer-new/welcome-icons/edit_profile_step-on.png diff --git a/app/javascript/images/mailer-new/welcome/step2-off.png b/app/javascript/images/mailer-new/welcome-icons/follow_step-off.png similarity index 100% rename from app/javascript/images/mailer-new/welcome/step2-off.png rename to app/javascript/images/mailer-new/welcome-icons/follow_step-off.png diff --git a/app/javascript/images/mailer-new/welcome-icons/follow_step-on.png b/app/javascript/images/mailer-new/welcome-icons/follow_step-on.png new file mode 100644 index 0000000000..3ac011539b Binary files /dev/null and b/app/javascript/images/mailer-new/welcome-icons/follow_step-on.png differ diff --git a/app/javascript/images/mailer-new/welcome/step3-off.png b/app/javascript/images/mailer-new/welcome-icons/post_step-off.png similarity index 100% rename from app/javascript/images/mailer-new/welcome/step3-off.png rename to app/javascript/images/mailer-new/welcome-icons/post_step-off.png diff --git a/app/javascript/images/mailer-new/welcome-icons/post_step-on.png b/app/javascript/images/mailer-new/welcome-icons/post_step-on.png new file mode 100644 index 0000000000..aa318e66c8 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome-icons/post_step-on.png differ diff --git a/app/javascript/images/mailer-new/welcome/step4-off.png b/app/javascript/images/mailer-new/welcome-icons/share_step-off.png similarity index 100% rename from app/javascript/images/mailer-new/welcome/step4-off.png rename to app/javascript/images/mailer-new/welcome-icons/share_step-off.png diff --git a/app/javascript/images/mailer-new/welcome-icons/share_step-on.png b/app/javascript/images/mailer-new/welcome-icons/share_step-on.png new file mode 100644 index 0000000000..98782d9317 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome-icons/share_step-on.png differ diff --git a/app/javascript/images/mailer-new/welcome/feature_audience.png b/app/javascript/images/mailer-new/welcome/feature_audience.png new file mode 100644 index 0000000000..902de133b4 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/feature_audience.png differ diff --git a/app/javascript/images/mailer-new/welcome/feature_control.png b/app/javascript/images/mailer-new/welcome/feature_control.png new file mode 100644 index 0000000000..1afb6c238c Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/feature_control.png differ diff --git a/app/javascript/images/mailer-new/welcome/feature_creativity.png b/app/javascript/images/mailer-new/welcome/feature_creativity.png new file mode 100644 index 0000000000..3365856699 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/feature_creativity.png differ diff --git a/app/javascript/images/mailer-new/welcome/feature_moderation.png b/app/javascript/images/mailer-new/welcome/feature_moderation.png new file mode 100644 index 0000000000..7cee9b29b8 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/feature_moderation.png differ diff --git a/app/javascript/images/mailer-new/welcome/purple-extra-soft-spacer.png b/app/javascript/images/mailer-new/welcome/purple-extra-soft-spacer.png new file mode 100644 index 0000000000..ec1ad5c957 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/purple-extra-soft-spacer.png differ diff --git a/app/javascript/images/mailer-new/welcome/purple-extra-soft-wave.png b/app/javascript/images/mailer-new/welcome/purple-extra-soft-wave.png new file mode 100644 index 0000000000..ba8f6dd3d9 Binary files /dev/null and b/app/javascript/images/mailer-new/welcome/purple-extra-soft-wave.png differ diff --git a/app/javascript/mastodon/actions/account_notes.ts b/app/javascript/mastodon/actions/account_notes.ts index e524e5235b..c2ebaf54a4 100644 --- a/app/javascript/mastodon/actions/account_notes.ts +++ b/app/javascript/mastodon/actions/account_notes.ts @@ -1,18 +1,10 @@ -import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships'; -import { createAppAsyncThunk } from 'mastodon/store/typed_functions'; +import { apiSubmitAccountNote } from 'mastodon/api/accounts'; +import { createDataLoadingThunk } from 'mastodon/store/typed_functions'; -import api from '../api'; - -export const submitAccountNote = createAppAsyncThunk( +export const submitAccountNote = createDataLoadingThunk( 'account_note/submit', - async (args: { id: string; value: string }, { getState }) => { - const response = await api(getState).post( - `/api/v1/accounts/${args.id}/note`, - { - comment: args.value, - }, - ); - - return { relationship: response.data }; - }, + ({ accountId, note }: { accountId: string; note: string }) => + apiSubmitAccountNote(accountId, note), + (relationship) => ({ relationship }), + { skipLoading: true }, ); diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js index 9f3bbba033..cea915e5f1 100644 --- a/app/javascript/mastodon/actions/accounts.js +++ b/app/javascript/mastodon/actions/accounts.js @@ -76,11 +76,11 @@ export const ACCOUNT_REVEAL = 'ACCOUNT_REVEAL'; export * from './accounts_typed'; export function fetchAccount(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchRelationships([id])); dispatch(fetchAccountRequest(id)); - api(getState).get(`/api/v1/accounts/${id}`).then(response => { + api().get(`/api/v1/accounts/${id}`).then(response => { dispatch(importFetchedAccount(response.data)); dispatch(fetchAccountSuccess()); }).catch(error => { @@ -89,10 +89,10 @@ export function fetchAccount(id) { }; } -export const lookupAccount = acct => (dispatch, getState) => { +export const lookupAccount = acct => (dispatch) => { dispatch(lookupAccountRequest(acct)); - api(getState).get('/api/v1/accounts/lookup', { params: { acct } }).then(response => { + api().get('/api/v1/accounts/lookup', { params: { acct } }).then(response => { dispatch(fetchRelationships([response.data.id])); dispatch(importFetchedAccount(response.data)); dispatch(lookupAccountSuccess()); @@ -146,7 +146,7 @@ export function followAccount(id, options = { reblogs: true }) { dispatch(followAccountRequest({ id, locked })); - api(getState).post(`/api/v1/accounts/${id}/follow`, options).then(response => { + api().post(`/api/v1/accounts/${id}/follow`, options).then(response => { dispatch(followAccountSuccess({relationship: response.data, alreadyFollowing})); }).catch(error => { dispatch(followAccountFail({ id, error, locked })); @@ -158,7 +158,7 @@ export function unfollowAccount(id) { return (dispatch, getState) => { dispatch(unfollowAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/unfollow`).then(response => { + api().post(`/api/v1/accounts/${id}/unfollow`).then(response => { dispatch(unfollowAccountSuccess({relationship: response.data, statuses: getState().get('statuses')})); }).catch(error => { dispatch(unfollowAccountFail({ id, error })); @@ -170,7 +170,7 @@ export function blockAccount(id) { return (dispatch, getState) => { dispatch(blockAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/block`).then(response => { + api().post(`/api/v1/accounts/${id}/block`).then(response => { // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers dispatch(blockAccountSuccess({ relationship: response.data, statuses: getState().get('statuses') })); }).catch(error => { @@ -180,10 +180,10 @@ export function blockAccount(id) { } export function unblockAccount(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unblockAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/unblock`).then(response => { + api().post(`/api/v1/accounts/${id}/unblock`).then(response => { dispatch(unblockAccountSuccess({ relationship: response.data })); }).catch(error => { dispatch(unblockAccountFail({ id, error })); @@ -223,7 +223,7 @@ export function muteAccount(id, notifications, duration=0) { return (dispatch, getState) => { dispatch(muteAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/mute`, { notifications, duration }).then(response => { + api().post(`/api/v1/accounts/${id}/mute`, { notifications, duration }).then(response => { // Pass in entire statuses map so we can use it to filter stuff in different parts of the reducers dispatch(muteAccountSuccess({ relationship: response.data, statuses: getState().get('statuses') })); }).catch(error => { @@ -233,10 +233,10 @@ export function muteAccount(id, notifications, duration=0) { } export function unmuteAccount(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unmuteAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/unmute`).then(response => { + api().post(`/api/v1/accounts/${id}/unmute`).then(response => { dispatch(unmuteAccountSuccess({ relationship: response.data })); }).catch(error => { dispatch(unmuteAccountFail({ id, error })); @@ -274,10 +274,10 @@ export function unmuteAccountFail(error) { export function fetchFollowers(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchFollowersRequest(id)); - api(getState).get(`/api/v1/accounts/${id}/followers`).then(response => { + api().get(`/api/v1/accounts/${id}/followers`).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -324,7 +324,7 @@ export function expandFollowers(id) { dispatch(expandFollowersRequest(id)); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -361,10 +361,10 @@ export function expandFollowersFail(id, error) { } export function fetchFollowing(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchFollowingRequest(id)); - api(getState).get(`/api/v1/accounts/${id}/following`).then(response => { + api().get(`/api/v1/accounts/${id}/following`).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -411,7 +411,7 @@ export function expandFollowing(id) { dispatch(expandFollowingRequest(id)); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -460,7 +460,7 @@ export function fetchRelationships(accountIds) { dispatch(fetchRelationshipsRequest(newAccountIds)); - api(getState).get(`/api/v1/accounts/relationships?with_suspended=true&${newAccountIds.map(id => `id[]=${id}`).join('&')}`).then(response => { + api().get(`/api/v1/accounts/relationships?with_suspended=true&${newAccountIds.map(id => `id[]=${id}`).join('&')}`).then(response => { dispatch(fetchRelationshipsSuccess({ relationships: response.data })); }).catch(error => { dispatch(fetchRelationshipsFail(error)); @@ -486,10 +486,10 @@ export function fetchRelationshipsFail(error) { } export function fetchFollowRequests() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchFollowRequestsRequest()); - api(getState).get('/api/v1/follow_requests').then(response => { + api().get('/api/v1/follow_requests').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null)); @@ -528,7 +528,7 @@ export function expandFollowRequests() { dispatch(expandFollowRequestsRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null)); @@ -558,10 +558,10 @@ export function expandFollowRequestsFail(error) { } export function authorizeFollowRequest(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(authorizeFollowRequestRequest(id)); - api(getState) + api() .post(`/api/v1/follow_requests/${id}/authorize`) .then(() => dispatch(authorizeFollowRequestSuccess({ id }))) .catch(error => dispatch(authorizeFollowRequestFail(id, error))); @@ -585,10 +585,10 @@ export function authorizeFollowRequestFail(id, error) { export function rejectFollowRequest(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(rejectFollowRequestRequest(id)); - api(getState) + api() .post(`/api/v1/follow_requests/${id}/reject`) .then(() => dispatch(rejectFollowRequestSuccess({ id }))) .catch(error => dispatch(rejectFollowRequestFail(id, error))); @@ -611,10 +611,10 @@ export function rejectFollowRequestFail(id, error) { } export function pinAccount(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(pinAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/pin`).then(response => { + api().post(`/api/v1/accounts/${id}/pin`).then(response => { dispatch(pinAccountSuccess({ relationship: response.data })); }).catch(error => { dispatch(pinAccountFail(error)); @@ -623,10 +623,10 @@ export function pinAccount(id) { } export function unpinAccount(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unpinAccountRequest(id)); - api(getState).post(`/api/v1/accounts/${id}/unpin`).then(response => { + api().post(`/api/v1/accounts/${id}/unpin`).then(response => { dispatch(unpinAccountSuccess({ relationship: response.data })); }).catch(error => { dispatch(unpinAccountFail(error)); @@ -662,7 +662,7 @@ export function unpinAccountFail(error) { }; } -export const updateAccount = ({ displayName, note, avatar, header, discoverable, indexable }) => (dispatch, getState) => { +export const updateAccount = ({ displayName, note, avatar, header, discoverable, indexable }) => (dispatch) => { const data = new FormData(); data.append('display_name', displayName); @@ -672,7 +672,7 @@ export const updateAccount = ({ displayName, note, avatar, header, discoverable, data.append('discoverable', discoverable); data.append('indexable', indexable); - return api(getState).patch('/api/v1/accounts/update_credentials', data).then(response => { + return api().patch('/api/v1/accounts/update_credentials', data).then(response => { dispatch(importFetchedAccount(response.data)); }); }; diff --git a/app/javascript/mastodon/actions/announcements.js b/app/javascript/mastodon/actions/announcements.js index 339c5f3adc..7657b05dc4 100644 --- a/app/javascript/mastodon/actions/announcements.js +++ b/app/javascript/mastodon/actions/announcements.js @@ -26,10 +26,10 @@ export const ANNOUNCEMENTS_TOGGLE_SHOW = 'ANNOUNCEMENTS_TOGGLE_SHOW'; const noOp = () => {}; -export const fetchAnnouncements = (done = noOp) => (dispatch, getState) => { +export const fetchAnnouncements = (done = noOp) => (dispatch) => { dispatch(fetchAnnouncementsRequest()); - api(getState).get('/api/v1/announcements').then(response => { + api().get('/api/v1/announcements').then(response => { dispatch(fetchAnnouncementsSuccess(response.data.map(x => normalizeAnnouncement(x)))); }).catch(error => { dispatch(fetchAnnouncementsFail(error)); @@ -61,10 +61,10 @@ export const updateAnnouncements = announcement => ({ announcement: normalizeAnnouncement(announcement), }); -export const dismissAnnouncement = announcementId => (dispatch, getState) => { +export const dismissAnnouncement = announcementId => (dispatch) => { dispatch(dismissAnnouncementRequest(announcementId)); - api(getState).post(`/api/v1/announcements/${announcementId}/dismiss`).then(() => { + api().post(`/api/v1/announcements/${announcementId}/dismiss`).then(() => { dispatch(dismissAnnouncementSuccess(announcementId)); }).catch(error => { dispatch(dismissAnnouncementFail(announcementId, error)); @@ -103,7 +103,7 @@ export const addReaction = (announcementId, name) => (dispatch, getState) => { dispatch(addReactionRequest(announcementId, name, alreadyAdded)); } - api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => { + api().put(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => { dispatch(addReactionSuccess(announcementId, name, alreadyAdded)); }).catch(err => { if (!alreadyAdded) { @@ -134,10 +134,10 @@ export const addReactionFail = (announcementId, name, error) => ({ skipLoading: true, }); -export const removeReaction = (announcementId, name) => (dispatch, getState) => { +export const removeReaction = (announcementId, name) => (dispatch) => { dispatch(removeReactionRequest(announcementId, name)); - api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => { + api().delete(`/api/v1/announcements/${announcementId}/reactions/${encodeURIComponent(name)}`).then(() => { dispatch(removeReactionSuccess(announcementId, name)); }).catch(err => { dispatch(removeReactionFail(announcementId, name, err)); diff --git a/app/javascript/mastodon/actions/blocks.js b/app/javascript/mastodon/actions/blocks.js index e293657ad3..5c66e27bec 100644 --- a/app/javascript/mastodon/actions/blocks.js +++ b/app/javascript/mastodon/actions/blocks.js @@ -12,13 +12,11 @@ export const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST'; export const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS'; export const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL'; -export const BLOCKS_INIT_MODAL = 'BLOCKS_INIT_MODAL'; - export function fetchBlocks() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchBlocksRequest()); - api(getState).get('/api/v1/blocks').then(response => { + api().get('/api/v1/blocks').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null)); @@ -58,7 +56,7 @@ export function expandBlocks() { dispatch(expandBlocksRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(expandBlocksSuccess(response.data, next ? next.uri : null)); @@ -90,11 +88,12 @@ export function expandBlocksFail(error) { export function initBlockModal(account) { return dispatch => { - dispatch({ - type: BLOCKS_INIT_MODAL, - account, - }); - - dispatch(openModal({ modalType: 'BLOCK' })); + dispatch(openModal({ + modalType: 'BLOCK', + modalProps: { + accountId: account.get('id'), + acct: account.get('acct'), + }, + })); }; } diff --git a/app/javascript/mastodon/actions/bookmarks.js b/app/javascript/mastodon/actions/bookmarks.js index 0b16f61e63..89716b224c 100644 --- a/app/javascript/mastodon/actions/bookmarks.js +++ b/app/javascript/mastodon/actions/bookmarks.js @@ -18,7 +18,7 @@ export function fetchBookmarkedStatuses() { dispatch(fetchBookmarkedStatusesRequest()); - api(getState).get('/api/v1/bookmarks').then(response => { + api().get('/api/v1/bookmarks').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(fetchBookmarkedStatusesSuccess(response.data, next ? next.uri : null)); @@ -59,7 +59,7 @@ export function expandBookmarkedStatuses() { dispatch(expandBookmarkedStatusesRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(expandBookmarkedStatusesSuccess(response.data, next ? next.uri : null)); diff --git a/app/javascript/mastodon/actions/boosts.js b/app/javascript/mastodon/actions/boosts.js deleted file mode 100644 index 1fc2e391e2..0000000000 --- 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/compose.js b/app/javascript/mastodon/actions/compose.js index 6abfd6157e..b07dff182a 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -75,6 +75,7 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL'; export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION'; export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS'; +export const COMPOSE_CHANGE_MEDIA_ORDER = 'COMPOSE_CHANGE_MEDIA_ORDER'; export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS'; export const COMPOSE_FOCUS = 'COMPOSE_FOCUS'; @@ -195,7 +196,7 @@ export function submitCompose(routerHistory) { }); } - api(getState).request({ + api().request({ url: statusId === null ? '/api/v1/statuses' : `/api/v1/statuses/${statusId}`, method: statusId === null ? 'post' : 'put', data: { @@ -303,7 +304,7 @@ export function uploadCompose(files) { const data = new FormData(); data.append('file', file); - api(getState).post('/api/v2/media', data, { + api().post('/api/v2/media', data, { onUploadProgress: function({ loaded }){ progress[i] = loaded; dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total)); @@ -320,7 +321,7 @@ export function uploadCompose(files) { let tryCount = 1; const poll = () => { - api(getState).get(`/api/v1/media/${data.id}`).then(response => { + api().get(`/api/v1/media/${data.id}`).then(response => { if (response.status === 200) { dispatch(uploadComposeSuccess(response.data, file)); } else if (response.status === 206) { @@ -342,7 +343,7 @@ export const uploadComposeProcessing = () => ({ type: COMPOSE_UPLOAD_PROCESSING, }); -export const uploadThumbnail = (id, file) => (dispatch, getState) => { +export const uploadThumbnail = (id, file) => (dispatch) => { dispatch(uploadThumbnailRequest()); const total = file.size; @@ -350,7 +351,7 @@ export const uploadThumbnail = (id, file) => (dispatch, getState) => { data.append('thumbnail', file); - api(getState).put(`/api/v1/media/${id}`, data, { + api().put(`/api/v1/media/${id}`, data, { onUploadProgress: ({ loaded }) => { dispatch(uploadThumbnailProgress(loaded, total)); }, @@ -433,7 +434,7 @@ export function changeUploadCompose(id, params) { dispatch(changeUploadComposeSuccess(data, true)); } else { - api(getState).put(`/api/v1/media/${id}`, params).then(response => { + api().put(`/api/v1/media/${id}`, params).then(response => { dispatch(changeUploadComposeSuccess(response.data, false)); }).catch(error => { dispatch(changeUploadComposeFail(id, error)); @@ -521,7 +522,7 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) => fetchComposeSuggestionsAccountsController = new AbortController(); - api(getState).get('/api/v1/accounts/search', { + api().get('/api/v1/accounts/search', { signal: fetchComposeSuggestionsAccountsController.signal, params: { @@ -555,7 +556,7 @@ const fetchComposeSuggestionsTags = throttle((dispatch, getState, token) => { fetchComposeSuggestionsTagsController = new AbortController(); - api(getState).get('/api/v2/search', { + api().get('/api/v2/search', { signal: fetchComposeSuggestionsTagsController.signal, params: { @@ -786,11 +787,12 @@ export function addPollOption(title) { }; } -export function changePollOption(index, title) { +export function changePollOption(index, title, maxOptions) { return { type: COMPOSE_POLL_OPTION_CHANGE, index, title, + maxOptions, }; } @@ -808,3 +810,9 @@ export function changePollSettings(expiresIn, isMultiple) { isMultiple, }; } + +export const changeMediaOrder = (a, b) => ({ + type: COMPOSE_CHANGE_MEDIA_ORDER, + a, + b, +}); diff --git a/app/javascript/mastodon/actions/conversations.js b/app/javascript/mastodon/actions/conversations.js index 8c4c4529fb..03174c485d 100644 --- a/app/javascript/mastodon/actions/conversations.js +++ b/app/javascript/mastodon/actions/conversations.js @@ -28,13 +28,13 @@ export const unmountConversations = () => ({ type: CONVERSATIONS_UNMOUNT, }); -export const markConversationRead = conversationId => (dispatch, getState) => { +export const markConversationRead = conversationId => (dispatch) => { dispatch({ type: CONVERSATIONS_READ, id: conversationId, }); - api(getState).post(`/api/v1/conversations/${conversationId}/read`); + api().post(`/api/v1/conversations/${conversationId}/read`); }; export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => { @@ -48,7 +48,7 @@ export const expandConversations = ({ maxId } = {}) => (dispatch, getState) => { const isLoadingRecent = !!params.since_id; - api(getState).get('/api/v1/conversations', { params }) + api().get('/api/v1/conversations', { params }) .then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); @@ -88,10 +88,10 @@ export const updateConversations = conversation => dispatch => { }); }; -export const deleteConversation = conversationId => (dispatch, getState) => { +export const deleteConversation = conversationId => (dispatch) => { dispatch(deleteConversationRequest(conversationId)); - api(getState).delete(`/api/v1/conversations/${conversationId}`) + api().delete(`/api/v1/conversations/${conversationId}`) .then(() => dispatch(deleteConversationSuccess(conversationId))) .catch(error => dispatch(deleteConversationFail(conversationId, error))); }; diff --git a/app/javascript/mastodon/actions/custom_emojis.js b/app/javascript/mastodon/actions/custom_emojis.js index 9ec8156b17..fb65f072dc 100644 --- a/app/javascript/mastodon/actions/custom_emojis.js +++ b/app/javascript/mastodon/actions/custom_emojis.js @@ -5,10 +5,10 @@ export const CUSTOM_EMOJIS_FETCH_SUCCESS = 'CUSTOM_EMOJIS_FETCH_SUCCESS'; export const CUSTOM_EMOJIS_FETCH_FAIL = 'CUSTOM_EMOJIS_FETCH_FAIL'; export function fetchCustomEmojis() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchCustomEmojisRequest()); - api(getState).get('/api/v1/custom_emojis').then(response => { + api().get('/api/v1/custom_emojis').then(response => { dispatch(fetchCustomEmojisSuccess(response.data)); }).catch(error => { dispatch(fetchCustomEmojisFail(error)); diff --git a/app/javascript/mastodon/actions/directory.js b/app/javascript/mastodon/actions/directory.js index cda63f2b5a..7a0748029d 100644 --- a/app/javascript/mastodon/actions/directory.js +++ b/app/javascript/mastodon/actions/directory.js @@ -11,10 +11,10 @@ export const DIRECTORY_EXPAND_REQUEST = 'DIRECTORY_EXPAND_REQUEST'; export const DIRECTORY_EXPAND_SUCCESS = 'DIRECTORY_EXPAND_SUCCESS'; export const DIRECTORY_EXPAND_FAIL = 'DIRECTORY_EXPAND_FAIL'; -export const fetchDirectory = params => (dispatch, getState) => { +export const fetchDirectory = params => (dispatch) => { dispatch(fetchDirectoryRequest()); - api(getState).get('/api/v1/directory', { params: { ...params, limit: 20 } }).then(({ data }) => { + api().get('/api/v1/directory', { params: { ...params, limit: 20 } }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(fetchDirectorySuccess(data)); dispatch(fetchRelationships(data.map(x => x.id))); @@ -40,7 +40,7 @@ export const expandDirectory = params => (dispatch, getState) => { const loadedItems = getState().getIn(['user_lists', 'directory', 'items']).size; - api(getState).get('/api/v1/directory', { params: { ...params, offset: loadedItems, limit: 20 } }).then(({ data }) => { + api().get('/api/v1/directory', { params: { ...params, offset: loadedItems, limit: 20 } }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(expandDirectorySuccess(data)); dispatch(fetchRelationships(data.map(x => x.id))); diff --git a/app/javascript/mastodon/actions/domain_blocks.js b/app/javascript/mastodon/actions/domain_blocks.js index 718002613f..727f800af3 100644 --- a/app/javascript/mastodon/actions/domain_blocks.js +++ b/app/javascript/mastodon/actions/domain_blocks.js @@ -1,6 +1,8 @@ import api, { getLinks } from '../api'; import { blockDomainSuccess, unblockDomainSuccess } from "./domain_blocks_typed"; +import { openModal } from './modal'; + export * from "./domain_blocks_typed"; @@ -22,7 +24,7 @@ export function blockDomain(domain) { return (dispatch, getState) => { dispatch(blockDomainRequest(domain)); - api(getState).post('/api/v1/domain_blocks', { domain }).then(() => { + api().post('/api/v1/domain_blocks', { domain }).then(() => { const at_domain = '@' + domain; const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id')); @@ -52,7 +54,7 @@ export function unblockDomain(domain) { return (dispatch, getState) => { dispatch(unblockDomainRequest(domain)); - api(getState).delete('/api/v1/domain_blocks', { params: { domain } }).then(() => { + api().delete('/api/v1/domain_blocks', { params: { domain } }).then(() => { const at_domain = '@' + domain; const accounts = getState().get('accounts').filter(item => item.get('acct').endsWith(at_domain)).valueSeq().map(item => item.get('id')); dispatch(unblockDomainSuccess({ domain, accounts })); @@ -78,10 +80,10 @@ export function unblockDomainFail(domain, error) { } export function fetchDomainBlocks() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchDomainBlocksRequest()); - api(getState).get('/api/v1/domain_blocks').then(response => { + api().get('/api/v1/domain_blocks').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(fetchDomainBlocksSuccess(response.data, next ? next.uri : null)); }).catch(err => { @@ -121,7 +123,7 @@ export function expandDomainBlocks() { dispatch(expandDomainBlocksRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(expandDomainBlocksSuccess(response.data, next ? next.uri : null)); }).catch(err => { @@ -150,3 +152,12 @@ export function expandDomainBlocksFail(error) { error, }; } + +export const initDomainBlockModal = account => dispatch => dispatch(openModal({ + modalType: 'DOMAIN_BLOCK', + modalProps: { + domain: account.get('acct').split('@')[1], + acct: account.get('acct'), + accountId: account.get('id'), + }, +})); diff --git a/app/javascript/mastodon/actions/favourites.js b/app/javascript/mastodon/actions/favourites.js index 2d4d4e6206..ff475c82be 100644 --- a/app/javascript/mastodon/actions/favourites.js +++ b/app/javascript/mastodon/actions/favourites.js @@ -18,7 +18,7 @@ export function fetchFavouritedStatuses() { dispatch(fetchFavouritedStatusesRequest()); - api(getState).get('/api/v1/favourites').then(response => { + api().get('/api/v1/favourites').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(fetchFavouritedStatusesSuccess(response.data, next ? next.uri : null)); @@ -62,7 +62,7 @@ export function expandFavouritedStatuses() { dispatch(expandFavouritedStatusesRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(expandFavouritedStatusesSuccess(response.data, next ? next.uri : null)); diff --git a/app/javascript/mastodon/actions/featured_tags.js b/app/javascript/mastodon/actions/featured_tags.js index 18bb615394..6ee4dee2bc 100644 --- a/app/javascript/mastodon/actions/featured_tags.js +++ b/app/javascript/mastodon/actions/featured_tags.js @@ -11,7 +11,7 @@ export const fetchFeaturedTags = (id) => (dispatch, getState) => { dispatch(fetchFeaturedTagsRequest(id)); - api(getState).get(`/api/v1/accounts/${id}/featured_tags`) + api().get(`/api/v1/accounts/${id}/featured_tags`) .then(({ data }) => dispatch(fetchFeaturedTagsSuccess(id, data))) .catch(err => dispatch(fetchFeaturedTagsFail(id, err))); }; diff --git a/app/javascript/mastodon/actions/filters.js b/app/javascript/mastodon/actions/filters.js index a11956ac56..588e390f0a 100644 --- a/app/javascript/mastodon/actions/filters.js +++ b/app/javascript/mastodon/actions/filters.js @@ -23,13 +23,13 @@ export const initAddFilter = (status, { contextType }) => dispatch => }, })); -export const fetchFilters = () => (dispatch, getState) => { +export const fetchFilters = () => (dispatch) => { dispatch({ type: FILTERS_FETCH_REQUEST, skipLoading: true, }); - api(getState) + api() .get('/api/v2/filters') .then(({ data }) => dispatch({ type: FILTERS_FETCH_SUCCESS, @@ -44,10 +44,10 @@ export const fetchFilters = () => (dispatch, getState) => { })); }; -export const createFilterStatus = (params, onSuccess, onFail) => (dispatch, getState) => { +export const createFilterStatus = (params, onSuccess, onFail) => (dispatch) => { dispatch(createFilterStatusRequest()); - api(getState).post(`/api/v2/filters/${params.filter_id}/statuses`, params).then(response => { + api().post(`/api/v2/filters/${params.filter_id}/statuses`, params).then(response => { dispatch(createFilterStatusSuccess(response.data)); if (onSuccess) onSuccess(); }).catch(error => { @@ -70,10 +70,10 @@ export const createFilterStatusFail = error => ({ error, }); -export const createFilter = (params, onSuccess, onFail) => (dispatch, getState) => { +export const createFilter = (params, onSuccess, onFail) => (dispatch) => { dispatch(createFilterRequest()); - api(getState).post('/api/v2/filters', params).then(response => { + api().post('/api/v2/filters', params).then(response => { dispatch(createFilterSuccess(response.data)); if (onSuccess) onSuccess(response.data); }).catch(error => { diff --git a/app/javascript/mastodon/actions/history.js b/app/javascript/mastodon/actions/history.js index 52401b7dce..07732ea187 100644 --- a/app/javascript/mastodon/actions/history.js +++ b/app/javascript/mastodon/actions/history.js @@ -15,7 +15,7 @@ export const fetchHistory = statusId => (dispatch, getState) => { dispatch(fetchHistoryRequest(statusId)); - api(getState).get(`/api/v1/statuses/${statusId}/history`).then(({ data }) => { + api().get(`/api/v1/statuses/${statusId}/history`).then(({ data }) => { dispatch(importFetchedAccounts(data.map(x => x.account))); dispatch(fetchHistorySuccess(statusId, data)); }).catch(error => dispatch(fetchHistoryFail(error))); diff --git a/app/javascript/mastodon/actions/importer/index.js b/app/javascript/mastodon/actions/importer/index.js index 16f191b584..d906bdfb14 100644 --- a/app/javascript/mastodon/actions/importer/index.js +++ b/app/javascript/mastodon/actions/importer/index.js @@ -68,13 +68,17 @@ export function importFetchedStatuses(statuses) { status.filtered.forEach(result => pushUnique(filters, result.filter)); } - if (status.reblog && status.reblog.id) { + if (status.reblog?.id) { processStatus(status.reblog); } - if (status.poll && status.poll.id) { + if (status.poll?.id) { pushUnique(polls, normalizePoll(status.poll, getState().getIn(['polls', status.poll.id]))); } + + if (status.card?.author_account) { + pushUnique(accounts, status.card.author_account); + } } statuses.forEach(processStatus); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index b5a30343e4..be76b0f391 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -36,6 +36,10 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.poll = status.poll.id; } + if (status.card?.author_account) { + normalStatus.card = { ...status.card, author_account: status.card.author_account.id }; + } + if (status.filtered) { normalStatus.filtered = status.filtered.map(normalizeFilterResult); } diff --git a/app/javascript/mastodon/actions/interactions.js b/app/javascript/mastodon/actions/interactions.js index 7d0144438a..57f2459c01 100644 --- a/app/javascript/mastodon/actions/interactions.js +++ b/app/javascript/mastodon/actions/interactions.js @@ -3,10 +3,6 @@ import api, { getLinks } from '../api'; import { fetchRelationships } from './accounts'; import { importFetchedAccounts, importFetchedStatus } from './importer'; -export const REBLOG_REQUEST = 'REBLOG_REQUEST'; -export const REBLOG_SUCCESS = 'REBLOG_SUCCESS'; -export const REBLOG_FAIL = 'REBLOG_FAIL'; - export const REBLOGS_EXPAND_REQUEST = 'REBLOGS_EXPAND_REQUEST'; export const REBLOGS_EXPAND_SUCCESS = 'REBLOGS_EXPAND_SUCCESS'; export const REBLOGS_EXPAND_FAIL = 'REBLOGS_EXPAND_FAIL'; @@ -15,10 +11,6 @@ export const FAVOURITE_REQUEST = 'FAVOURITE_REQUEST'; export const FAVOURITE_SUCCESS = 'FAVOURITE_SUCCESS'; export const FAVOURITE_FAIL = 'FAVOURITE_FAIL'; -export const UNREBLOG_REQUEST = 'UNREBLOG_REQUEST'; -export const UNREBLOG_SUCCESS = 'UNREBLOG_SUCCESS'; -export const UNREBLOG_FAIL = 'UNREBLOG_FAIL'; - export const UNFAVOURITE_REQUEST = 'UNFAVOURITE_REQUEST'; export const UNFAVOURITE_SUCCESS = 'UNFAVOURITE_SUCCESS'; export const UNFAVOURITE_FAIL = 'UNFAVOURITE_FAIL'; @@ -51,89 +43,13 @@ export const UNBOOKMARK_REQUEST = 'UNBOOKMARKED_REQUEST'; export const UNBOOKMARK_SUCCESS = 'UNBOOKMARKED_SUCCESS'; export const UNBOOKMARK_FAIL = 'UNBOOKMARKED_FAIL'; -export function reblog(status, visibility) { - return function (dispatch, getState) { - dispatch(reblogRequest(status)); - - api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`, { visibility }).then(function (response) { - // The reblog API method returns a new status wrapped around the original. In this case we are only - // interested in how the original is modified, hence passing it skipping the wrapper - dispatch(importFetchedStatus(response.data.reblog)); - dispatch(reblogSuccess(status)); - }).catch(function (error) { - dispatch(reblogFail(status, error)); - }); - }; -} - -export function unreblog(status) { - return (dispatch, getState) => { - dispatch(unreblogRequest(status)); - - api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then(response => { - dispatch(importFetchedStatus(response.data)); - dispatch(unreblogSuccess(status)); - }).catch(error => { - dispatch(unreblogFail(status, error)); - }); - }; -} - -export function reblogRequest(status) { - return { - type: REBLOG_REQUEST, - status: status, - skipLoading: true, - }; -} - -export function reblogSuccess(status) { - return { - type: REBLOG_SUCCESS, - status: status, - skipLoading: true, - }; -} - -export function reblogFail(status, error) { - return { - type: REBLOG_FAIL, - status: status, - error: error, - skipLoading: true, - }; -} - -export function unreblogRequest(status) { - return { - type: UNREBLOG_REQUEST, - status: status, - skipLoading: true, - }; -} - -export function unreblogSuccess(status) { - return { - type: UNREBLOG_SUCCESS, - status: status, - skipLoading: true, - }; -} - -export function unreblogFail(status, error) { - return { - type: UNREBLOG_FAIL, - status: status, - error: error, - skipLoading: true, - }; -} +export * from "./interactions_typed"; export function favourite(status) { - return function (dispatch, getState) { + return function (dispatch) { dispatch(favouriteRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function (response) { + api().post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function (response) { dispatch(importFetchedStatus(response.data)); dispatch(favouriteSuccess(status)); }).catch(function (error) { @@ -143,10 +59,10 @@ export function favourite(status) { } export function unfavourite(status) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unfavouriteRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(response => { + api().post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(unfavouriteSuccess(status)); }).catch(error => { @@ -206,10 +122,10 @@ export function unfavouriteFail(status, error) { } export function bookmark(status) { - return function (dispatch, getState) { + return function (dispatch) { dispatch(bookmarkRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function (response) { + api().post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function (response) { dispatch(importFetchedStatus(response.data)); dispatch(bookmarkSuccess(status, response.data)); }).catch(function (error) { @@ -219,10 +135,10 @@ export function bookmark(status) { } export function unbookmark(status) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unbookmarkRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => { + api().post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(unbookmarkSuccess(status, response.data)); }).catch(error => { @@ -278,10 +194,10 @@ export function unbookmarkFail(status, error) { } export function fetchReblogs(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchReblogsRequest(id)); - api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => { + api().get(`/api/v1/statuses/${id}/reblogged_by`).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(fetchReblogsSuccess(id, response.data, next ? next.uri : null)); @@ -325,7 +241,7 @@ export function expandReblogs(id) { dispatch(expandReblogsRequest(id)); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -360,10 +276,10 @@ export function expandReblogsFail(id, error) { } export function fetchFavourites(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchFavouritesRequest(id)); - api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => { + api().get(`/api/v1/statuses/${id}/favourited_by`).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(fetchFavouritesSuccess(id, response.data, next ? next.uri : null)); @@ -407,7 +323,7 @@ export function expandFavourites(id) { dispatch(expandFavouritesRequest(id)); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); @@ -442,10 +358,10 @@ export function expandFavouritesFail(id, error) { } export function pin(status) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(pinRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => { + api().post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(pinSuccess(status)); }).catch(error => { @@ -480,10 +396,10 @@ export function pinFail(status, error) { } export function unpin (status) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unpinRequest(status)); - api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => { + api().post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(unpinSuccess(status)); }).catch(error => { diff --git a/app/javascript/mastodon/actions/interactions_typed.ts b/app/javascript/mastodon/actions/interactions_typed.ts new file mode 100644 index 0000000000..f58faffa86 --- /dev/null +++ b/app/javascript/mastodon/actions/interactions_typed.ts @@ -0,0 +1,35 @@ +import { apiReblog, apiUnreblog } from 'mastodon/api/interactions'; +import type { StatusVisibility } from 'mastodon/models/status'; +import { createDataLoadingThunk } from 'mastodon/store/typed_functions'; + +import { importFetchedStatus } from './importer'; + +export const reblog = createDataLoadingThunk( + 'status/reblog', + ({ + statusId, + visibility, + }: { + statusId: string; + visibility: StatusVisibility; + }) => apiReblog(statusId, visibility), + (data, { dispatch, discardLoadData }) => { + // The reblog API method returns a new status wrapped around the original. In this case we are only + // interested in how the original is modified, hence passing it skipping the wrapper + dispatch(importFetchedStatus(data.reblog)); + + // The payload is not used in any actions + return discardLoadData; + }, +); + +export const unreblog = createDataLoadingThunk( + 'status/unreblog', + ({ statusId }: { statusId: string }) => apiUnreblog(statusId), + (data, { dispatch, discardLoadData }) => { + dispatch(importFetchedStatus(data)); + + // The payload is not used in any actions + return discardLoadData; + }, +); diff --git a/app/javascript/mastodon/actions/lists.js b/app/javascript/mastodon/actions/lists.js index b0789cd426..9956059387 100644 --- a/app/javascript/mastodon/actions/lists.js +++ b/app/javascript/mastodon/actions/lists.js @@ -57,7 +57,7 @@ export const fetchList = id => (dispatch, getState) => { dispatch(fetchListRequest(id)); - api(getState).get(`/api/v1/lists/${id}`) + api().get(`/api/v1/lists/${id}`) .then(({ data }) => dispatch(fetchListSuccess(data))) .catch(err => dispatch(fetchListFail(id, err))); }; @@ -78,10 +78,10 @@ export const fetchListFail = (id, error) => ({ error, }); -export const fetchLists = () => (dispatch, getState) => { +export const fetchLists = () => (dispatch) => { dispatch(fetchListsRequest()); - api(getState).get('/api/v1/lists') + api().get('/api/v1/lists') .then(({ data }) => dispatch(fetchListsSuccess(data))) .catch(err => dispatch(fetchListsFail(err))); }; @@ -125,10 +125,10 @@ export const changeListEditorTitle = value => ({ value, }); -export const createList = (title, shouldReset) => (dispatch, getState) => { +export const createList = (title, shouldReset) => (dispatch) => { dispatch(createListRequest()); - api(getState).post('/api/v1/lists', { title }).then(({ data }) => { + api().post('/api/v1/lists', { title }).then(({ data }) => { dispatch(createListSuccess(data)); if (shouldReset) { @@ -151,10 +151,10 @@ export const createListFail = error => ({ error, }); -export const updateList = (id, title, shouldReset, isExclusive, replies_policy) => (dispatch, getState) => { +export const updateList = (id, title, shouldReset, isExclusive, replies_policy) => (dispatch) => { dispatch(updateListRequest(id)); - api(getState).put(`/api/v1/lists/${id}`, { title, replies_policy, exclusive: typeof isExclusive === 'undefined' ? undefined : !!isExclusive }).then(({ data }) => { + api().put(`/api/v1/lists/${id}`, { title, replies_policy, exclusive: typeof isExclusive === 'undefined' ? undefined : !!isExclusive }).then(({ data }) => { dispatch(updateListSuccess(data)); if (shouldReset) { @@ -183,10 +183,10 @@ export const resetListEditor = () => ({ type: LIST_EDITOR_RESET, }); -export const deleteList = id => (dispatch, getState) => { +export const deleteList = id => (dispatch) => { dispatch(deleteListRequest(id)); - api(getState).delete(`/api/v1/lists/${id}`) + api().delete(`/api/v1/lists/${id}`) .then(() => dispatch(deleteListSuccess(id))) .catch(err => dispatch(deleteListFail(id, err))); }; @@ -207,10 +207,10 @@ export const deleteListFail = (id, error) => ({ error, }); -export const fetchListAccounts = listId => (dispatch, getState) => { +export const fetchListAccounts = listId => (dispatch) => { dispatch(fetchListAccountsRequest(listId)); - api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => { + api().get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(fetchListAccountsSuccess(listId, data)); }).catch(err => dispatch(fetchListAccountsFail(listId, err))); @@ -234,7 +234,7 @@ export const fetchListAccountsFail = (id, error) => ({ error, }); -export const fetchListSuggestions = q => (dispatch, getState) => { +export const fetchListSuggestions = q => (dispatch) => { const params = { q, resolve: false, @@ -242,7 +242,7 @@ export const fetchListSuggestions = q => (dispatch, getState) => { following: true, }; - api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => { + api().get('/api/v1/accounts/search', { params }).then(({ data }) => { dispatch(importFetchedAccounts(data)); dispatch(fetchListSuggestionsReady(q, data)); }).catch(error => dispatch(showAlertForError(error))); @@ -267,10 +267,10 @@ export const addToListEditor = accountId => (dispatch, getState) => { dispatch(addToList(getState().getIn(['listEditor', 'listId']), accountId)); }; -export const addToList = (listId, accountId) => (dispatch, getState) => { +export const addToList = (listId, accountId) => (dispatch) => { dispatch(addToListRequest(listId, accountId)); - api(getState).post(`/api/v1/lists/${listId}/accounts`, { account_ids: [accountId] }) + api().post(`/api/v1/lists/${listId}/accounts`, { account_ids: [accountId] }) .then(() => dispatch(addToListSuccess(listId, accountId))) .catch(err => dispatch(addToListFail(listId, accountId, err))); }; @@ -298,10 +298,10 @@ export const removeFromListEditor = accountId => (dispatch, getState) => { dispatch(removeFromList(getState().getIn(['listEditor', 'listId']), accountId)); }; -export const removeFromList = (listId, accountId) => (dispatch, getState) => { +export const removeFromList = (listId, accountId) => (dispatch) => { dispatch(removeFromListRequest(listId, accountId)); - api(getState).delete(`/api/v1/lists/${listId}/accounts`, { params: { account_ids: [accountId] } }) + api().delete(`/api/v1/lists/${listId}/accounts`, { params: { account_ids: [accountId] } }) .then(() => dispatch(removeFromListSuccess(listId, accountId))) .catch(err => dispatch(removeFromListFail(listId, accountId, err))); }; @@ -338,10 +338,10 @@ export const setupListAdder = accountId => (dispatch, getState) => { dispatch(fetchAccountLists(accountId)); }; -export const fetchAccountLists = accountId => (dispatch, getState) => { +export const fetchAccountLists = accountId => (dispatch) => { dispatch(fetchAccountListsRequest(accountId)); - api(getState).get(`/api/v1/accounts/${accountId}/lists`) + api().get(`/api/v1/accounts/${accountId}/lists`) .then(({ data }) => dispatch(fetchAccountListsSuccess(accountId, data))) .catch(err => dispatch(fetchAccountListsFail(accountId, err))); }; @@ -370,4 +370,3 @@ export const addToListAdder = listId => (dispatch, getState) => { export const removeFromListAdder = listId => (dispatch, getState) => { dispatch(removeFromList(listId, getState().getIn(['listAdder', 'accountId']))); }; - diff --git a/app/javascript/mastodon/actions/markers.js b/app/javascript/mastodon/actions/markers.js deleted file mode 100644 index cfc329a8b7..0000000000 --- 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 0000000000..03f577c540 --- /dev/null +++ b/app/javascript/mastodon/actions/markers.ts @@ -0,0 +1,148 @@ +import { debounce } from 'lodash'; + +import type { MarkerJSON } from 'mastodon/api_types/markers'; +import { getAccessToken } from 'mastodon/initial_state'; +import type { AppDispatch, RootState } from 'mastodon/store'; +import { createAppAsyncThunk } from 'mastodon/store/typed_functions'; + +import api from '../api'; +import { compareId } from '../compare_id'; + +export const synchronouslySubmitMarkers = createAppAsyncThunk( + 'markers/submit', + async (_args, { getState }) => { + const accessToken = getAccessToken(); + const params = buildPostMarkersParams(getState()); + + if ( + Object.keys(params).length === 0 || + !accessToken || + 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 getLastNotificationId(state: RootState): string | undefined { + // @ts-expect-error state.notifications is not yet typed + // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call + return state.getIn(['notifications', 'lastReadId']); +} + +const buildPostMarkersParams = (state: RootState) => { + const params = {} as { home?: MarkerParam; notifications?: MarkerParam }; + + const lastNotificationId = getLastNotificationId(state); + + 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 = getAccessToken(); + const params = buildPostMarkersParams(getState()); + + if (Object.keys(params).length === 0 || !accessToken || accessToken === '') { + return { home: undefined, notifications: undefined }; + } + + await api().post('/api/v1/markers', params); + + return { + home: params.home?.last_read_id, + notifications: params.notifications?.last_read_id, + }; +}); + +const debouncedSubmitMarkers = debounce( + (dispatch: AppDispatch) => { + void 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 () => { + const response = await api().get>( + `/api/v1/markers`, + { params: { timeline: ['notifications'] } }, + ); + + return { markers: response.data }; +}); diff --git a/app/javascript/mastodon/actions/mutes.js b/app/javascript/mastodon/actions/mutes.js index fb041078b8..3676748cf3 100644 --- a/app/javascript/mastodon/actions/mutes.js +++ b/app/javascript/mastodon/actions/mutes.js @@ -12,15 +12,11 @@ export const MUTES_EXPAND_REQUEST = 'MUTES_EXPAND_REQUEST'; export const MUTES_EXPAND_SUCCESS = 'MUTES_EXPAND_SUCCESS'; export const MUTES_EXPAND_FAIL = 'MUTES_EXPAND_FAIL'; -export const MUTES_INIT_MODAL = 'MUTES_INIT_MODAL'; -export const MUTES_TOGGLE_HIDE_NOTIFICATIONS = 'MUTES_TOGGLE_HIDE_NOTIFICATIONS'; -export const MUTES_CHANGE_DURATION = 'MUTES_CHANGE_DURATION'; - export function fetchMutes() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchMutesRequest()); - api(getState).get('/api/v1/mutes').then(response => { + api().get('/api/v1/mutes').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(fetchMutesSuccess(response.data, next ? next.uri : null)); @@ -60,7 +56,7 @@ export function expandMutes() { dispatch(expandMutesRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data)); dispatch(expandMutesSuccess(response.data, next ? next.uri : null)); @@ -92,26 +88,12 @@ export function expandMutesFail(error) { export function initMuteModal(account) { return dispatch => { - dispatch({ - type: MUTES_INIT_MODAL, - account, - }); - - dispatch(openModal({ modalType: 'MUTE' })); - }; -} - -export function toggleHideNotifications() { - return dispatch => { - dispatch({ type: MUTES_TOGGLE_HIDE_NOTIFICATIONS }); - }; -} - -export function changeMuteDuration(duration) { - return dispatch => { - dispatch({ - type: MUTES_CHANGE_DURATION, - duration, - }); + dispatch(openModal({ + modalType: 'MUTE', + modalProps: { + accountId: account.get('id'), + acct: account.get('acct'), + }, + })); }; } diff --git a/app/javascript/mastodon/actions/notification_policies.ts b/app/javascript/mastodon/actions/notification_policies.ts new file mode 100644 index 0000000000..fcc9919c49 --- /dev/null +++ b/app/javascript/mastodon/actions/notification_policies.ts @@ -0,0 +1,16 @@ +import { + apiGetNotificationPolicy, + apiUpdateNotificationsPolicy, +} from 'mastodon/api/notification_policies'; +import type { NotificationPolicy } from 'mastodon/models/notification_policy'; +import { createDataLoadingThunk } from 'mastodon/store/typed_functions'; + +export const fetchNotificationPolicy = createDataLoadingThunk( + 'notificationPolicy/fetch', + () => apiGetNotificationPolicy(), +); + +export const updateNotificationsPolicy = createDataLoadingThunk( + 'notificationPolicy/update', + (policy: Partial) => apiUpdateNotificationsPolicy(policy), +); diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index eafbf42d1b..6a59d5624e 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -44,6 +44,34 @@ export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ'; export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT'; export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION'; +export const NOTIFICATION_REQUESTS_FETCH_REQUEST = 'NOTIFICATION_REQUESTS_FETCH_REQUEST'; +export const NOTIFICATION_REQUESTS_FETCH_SUCCESS = 'NOTIFICATION_REQUESTS_FETCH_SUCCESS'; +export const NOTIFICATION_REQUESTS_FETCH_FAIL = 'NOTIFICATION_REQUESTS_FETCH_FAIL'; + +export const NOTIFICATION_REQUESTS_EXPAND_REQUEST = 'NOTIFICATION_REQUESTS_EXPAND_REQUEST'; +export const NOTIFICATION_REQUESTS_EXPAND_SUCCESS = 'NOTIFICATION_REQUESTS_EXPAND_SUCCESS'; +export const NOTIFICATION_REQUESTS_EXPAND_FAIL = 'NOTIFICATION_REQUESTS_EXPAND_FAIL'; + +export const NOTIFICATION_REQUEST_FETCH_REQUEST = 'NOTIFICATION_REQUEST_FETCH_REQUEST'; +export const NOTIFICATION_REQUEST_FETCH_SUCCESS = 'NOTIFICATION_REQUEST_FETCH_SUCCESS'; +export const NOTIFICATION_REQUEST_FETCH_FAIL = 'NOTIFICATION_REQUEST_FETCH_FAIL'; + +export const NOTIFICATION_REQUEST_ACCEPT_REQUEST = 'NOTIFICATION_REQUEST_ACCEPT_REQUEST'; +export const NOTIFICATION_REQUEST_ACCEPT_SUCCESS = 'NOTIFICATION_REQUEST_ACCEPT_SUCCESS'; +export const NOTIFICATION_REQUEST_ACCEPT_FAIL = 'NOTIFICATION_REQUEST_ACCEPT_FAIL'; + +export const NOTIFICATION_REQUEST_DISMISS_REQUEST = 'NOTIFICATION_REQUEST_DISMISS_REQUEST'; +export const NOTIFICATION_REQUEST_DISMISS_SUCCESS = 'NOTIFICATION_REQUEST_DISMISS_SUCCESS'; +export const NOTIFICATION_REQUEST_DISMISS_FAIL = 'NOTIFICATION_REQUEST_DISMISS_FAIL'; + +export const NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST'; +export const NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS'; +export const NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL = 'NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL'; + +export const NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST'; +export const NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS'; +export const NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL = 'NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL'; + defineMessages({ mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' }, group: { id: 'notifications.group', defaultMessage: '{count} notifications' }, @@ -184,7 +212,7 @@ export function expandNotifications({ maxId, forceLoad } = {}, done = noOp) { dispatch(expandNotificationsRequest(isLoadingMore)); - api(getState).get('/api/v1/notifications', { params, signal: expandNotificationsController.signal }).then(response => { + api().get('/api/v1/notifications', { params, signal: expandNotificationsController.signal }).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedAccounts(response.data.map(item => item.account))); @@ -230,12 +258,12 @@ export function expandNotificationsFail(error, isLoadingMore) { } export function clearNotifications() { - return (dispatch, getState) => { + return (dispatch) => { dispatch({ type: NOTIFICATIONS_CLEAR, }); - api(getState).post('/api/v1/notifications/clear'); + api().post('/api/v1/notifications/clear'); }; } @@ -313,3 +341,236 @@ export function setBrowserPermission (value) { value, }; } + +export const fetchNotificationRequests = () => (dispatch, getState) => { + const params = {}; + + if (getState().getIn(['notificationRequests', 'isLoading'])) { + return; + } + + if (getState().getIn(['notificationRequests', 'items'])?.size > 0) { + params.since_id = getState().getIn(['notificationRequests', 'items', 0, 'id']); + } + + dispatch(fetchNotificationRequestsRequest()); + + api().get('/api/v1/notifications/requests', { params }).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + dispatch(importFetchedAccounts(response.data.map(x => x.account))); + dispatch(fetchNotificationRequestsSuccess(response.data, next ? next.uri : null)); + }).catch(err => { + dispatch(fetchNotificationRequestsFail(err)); + }); +}; + +export const fetchNotificationRequestsRequest = () => ({ + type: NOTIFICATION_REQUESTS_FETCH_REQUEST, +}); + +export const fetchNotificationRequestsSuccess = (requests, next) => ({ + type: NOTIFICATION_REQUESTS_FETCH_SUCCESS, + requests, + next, +}); + +export const fetchNotificationRequestsFail = error => ({ + type: NOTIFICATION_REQUESTS_FETCH_FAIL, + error, +}); + +export const expandNotificationRequests = () => (dispatch, getState) => { + const url = getState().getIn(['notificationRequests', 'next']); + + if (!url || getState().getIn(['notificationRequests', 'isLoading'])) { + return; + } + + dispatch(expandNotificationRequestsRequest()); + + api().get(url).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + dispatch(importFetchedAccounts(response.data.map(x => x.account))); + dispatch(expandNotificationRequestsSuccess(response.data, next?.uri)); + }).catch(err => { + dispatch(expandNotificationRequestsFail(err)); + }); +}; + +export const expandNotificationRequestsRequest = () => ({ + type: NOTIFICATION_REQUESTS_EXPAND_REQUEST, +}); + +export const expandNotificationRequestsSuccess = (requests, next) => ({ + type: NOTIFICATION_REQUESTS_EXPAND_SUCCESS, + requests, + next, +}); + +export const expandNotificationRequestsFail = error => ({ + type: NOTIFICATION_REQUESTS_EXPAND_FAIL, + error, +}); + +export const fetchNotificationRequest = id => (dispatch, getState) => { + const current = getState().getIn(['notificationRequests', 'current']); + + if (current.getIn(['item', 'id']) === id || current.get('isLoading')) { + return; + } + + dispatch(fetchNotificationRequestRequest(id)); + + api().get(`/api/v1/notifications/requests/${id}`).then(({ data }) => { + dispatch(fetchNotificationRequestSuccess(data)); + }).catch(err => { + dispatch(fetchNotificationRequestFail(id, err)); + }); +}; + +export const fetchNotificationRequestRequest = id => ({ + type: NOTIFICATION_REQUEST_FETCH_REQUEST, + id, +}); + +export const fetchNotificationRequestSuccess = request => ({ + type: NOTIFICATION_REQUEST_FETCH_SUCCESS, + request, +}); + +export const fetchNotificationRequestFail = (id, error) => ({ + type: NOTIFICATION_REQUEST_FETCH_FAIL, + id, + error, +}); + +export const acceptNotificationRequest = id => (dispatch) => { + dispatch(acceptNotificationRequestRequest(id)); + + api().post(`/api/v1/notifications/requests/${id}/accept`).then(() => { + dispatch(acceptNotificationRequestSuccess(id)); + }).catch(err => { + dispatch(acceptNotificationRequestFail(id, err)); + }); +}; + +export const acceptNotificationRequestRequest = id => ({ + type: NOTIFICATION_REQUEST_ACCEPT_REQUEST, + id, +}); + +export const acceptNotificationRequestSuccess = id => ({ + type: NOTIFICATION_REQUEST_ACCEPT_SUCCESS, + id, +}); + +export const acceptNotificationRequestFail = (id, error) => ({ + type: NOTIFICATION_REQUEST_ACCEPT_FAIL, + id, + error, +}); + +export const dismissNotificationRequest = id => (dispatch) => { + dispatch(dismissNotificationRequestRequest(id)); + + api().post(`/api/v1/notifications/requests/${id}/dismiss`).then(() =>{ + dispatch(dismissNotificationRequestSuccess(id)); + }).catch(err => { + dispatch(dismissNotificationRequestFail(id, err)); + }); +}; + +export const dismissNotificationRequestRequest = id => ({ + type: NOTIFICATION_REQUEST_DISMISS_REQUEST, + id, +}); + +export const dismissNotificationRequestSuccess = id => ({ + type: NOTIFICATION_REQUEST_DISMISS_SUCCESS, + id, +}); + +export const dismissNotificationRequestFail = (id, error) => ({ + type: NOTIFICATION_REQUEST_DISMISS_FAIL, + id, + error, +}); + +export const fetchNotificationsForRequest = accountId => (dispatch, getState) => { + const current = getState().getIn(['notificationRequests', 'current']); + const params = { account_id: accountId }; + + if (current.getIn(['item', 'account']) === accountId) { + if (current.getIn(['notifications', 'isLoading'])) { + return; + } + + if (current.getIn(['notifications', 'items'])?.size > 0) { + params.since_id = current.getIn(['notifications', 'items', 0, 'id']); + } + } + + dispatch(fetchNotificationsForRequestRequest()); + + api().get('/api/v1/notifications', { params }).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + dispatch(importFetchedAccounts(response.data.map(item => item.account))); + dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status))); + dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account))); + + dispatch(fetchNotificationsForRequestSuccess(response.data, next?.uri)); + }).catch(err => { + dispatch(fetchNotificationsForRequestFail(err)); + }); +}; + +export const fetchNotificationsForRequestRequest = () => ({ + type: NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST, +}); + +export const fetchNotificationsForRequestSuccess = (notifications, next) => ({ + type: NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS, + notifications, + next, +}); + +export const fetchNotificationsForRequestFail = (error) => ({ + type: NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL, + error, +}); + +export const expandNotificationsForRequest = () => (dispatch, getState) => { + const url = getState().getIn(['notificationRequests', 'current', 'notifications', 'next']); + + if (!url || getState().getIn(['notificationRequests', 'current', 'notifications', 'isLoading'])) { + return; + } + + dispatch(expandNotificationsForRequestRequest()); + + api().get(url).then(response => { + const next = getLinks(response).refs.find(link => link.rel === 'next'); + dispatch(importFetchedAccounts(response.data.map(item => item.account))); + dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status))); + dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account))); + + dispatch(expandNotificationsForRequestSuccess(response.data, next?.uri)); + }).catch(err => { + dispatch(expandNotificationsForRequestFail(err)); + }); +}; + +export const expandNotificationsForRequestRequest = () => ({ + type: NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST, +}); + +export const expandNotificationsForRequestSuccess = (notifications, next) => ({ + type: NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS, + notifications, + next, +}); + +export const expandNotificationsForRequestFail = (error) => ({ + type: NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL, + error, +}); 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 898375abeb..0000000000 --- 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 0000000000..d34b508a33 --- /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/actions/pin_statuses.js b/app/javascript/mastodon/actions/pin_statuses.js index baa10d1562..d583eab573 100644 --- a/app/javascript/mastodon/actions/pin_statuses.js +++ b/app/javascript/mastodon/actions/pin_statuses.js @@ -8,10 +8,10 @@ export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS'; export const PINNED_STATUSES_FETCH_FAIL = 'PINNED_STATUSES_FETCH_FAIL'; export function fetchPinnedStatuses() { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchPinnedStatusesRequest()); - api(getState).get(`/api/v1/accounts/${me}/statuses`, { params: { pinned: true } }).then(response => { + api().get(`/api/v1/accounts/${me}/statuses`, { params: { pinned: true } }).then(response => { dispatch(importFetchedStatuses(response.data)); dispatch(fetchPinnedStatusesSuccess(response.data, null)); }).catch(error => { diff --git a/app/javascript/mastodon/actions/polls.js b/app/javascript/mastodon/actions/polls.js index a37410dc90..aa49341444 100644 --- a/app/javascript/mastodon/actions/polls.js +++ b/app/javascript/mastodon/actions/polls.js @@ -10,10 +10,10 @@ export const POLL_FETCH_REQUEST = 'POLL_FETCH_REQUEST'; export const POLL_FETCH_SUCCESS = 'POLL_FETCH_SUCCESS'; export const POLL_FETCH_FAIL = 'POLL_FETCH_FAIL'; -export const vote = (pollId, choices) => (dispatch, getState) => { +export const vote = (pollId, choices) => (dispatch) => { dispatch(voteRequest()); - api(getState).post(`/api/v1/polls/${pollId}/votes`, { choices }) + api().post(`/api/v1/polls/${pollId}/votes`, { choices }) .then(({ data }) => { dispatch(importFetchedPoll(data)); dispatch(voteSuccess(data)); @@ -21,10 +21,10 @@ export const vote = (pollId, choices) => (dispatch, getState) => { .catch(err => dispatch(voteFail(err))); }; -export const fetchPoll = pollId => (dispatch, getState) => { +export const fetchPoll = pollId => (dispatch) => { dispatch(fetchPollRequest()); - api(getState).get(`/api/v1/polls/${pollId}`) + api().get(`/api/v1/polls/${pollId}`) .then(({ data }) => { dispatch(importFetchedPoll(data)); dispatch(fetchPollSuccess(data)); diff --git a/app/javascript/mastodon/actions/reports.js b/app/javascript/mastodon/actions/reports.js index 756b8cd05e..49b89b0d13 100644 --- a/app/javascript/mastodon/actions/reports.js +++ b/app/javascript/mastodon/actions/reports.js @@ -15,10 +15,10 @@ export const initReport = (account, status) => dispatch => }, })); -export const submitReport = (params, onSuccess, onFail) => (dispatch, getState) => { +export const submitReport = (params, onSuccess, onFail) => (dispatch) => { dispatch(submitReportRequest()); - api(getState).post('/api/v1/reports', params).then(response => { + api().post('/api/v1/reports', params).then(response => { dispatch(submitReportSuccess(response.data)); if (onSuccess) onSuccess(); }).catch(error => { diff --git a/app/javascript/mastodon/actions/search.js b/app/javascript/mastodon/actions/search.js index a34a490e76..bde17ae0db 100644 --- a/app/javascript/mastodon/actions/search.js +++ b/app/javascript/mastodon/actions/search.js @@ -46,7 +46,7 @@ export function submitSearch(type) { dispatch(fetchSearchRequest(type)); - api(getState).get('/api/v2/search', { + api().get('/api/v2/search', { params: { q: value, resolve: signedIn, @@ -99,7 +99,7 @@ export const expandSearch = type => (dispatch, getState) => { dispatch(expandSearchRequest(type)); - api(getState).get('/api/v2/search', { + api().get('/api/v2/search', { params: { q: value, type, @@ -156,7 +156,7 @@ export const openURL = (value, history, onFailure) => (dispatch, getState) => { dispatch(fetchSearchRequest()); - api(getState).get('/api/v2/search', { params: { q: value, resolve: true } }).then(response => { + api().get('/api/v2/search', { params: { q: value, resolve: true } }).then(response => { if (response.data.accounts?.length > 0) { dispatch(importFetchedAccounts(response.data.accounts)); history.push(`/@${response.data.accounts[0].acct}`); diff --git a/app/javascript/mastodon/actions/server.js b/app/javascript/mastodon/actions/server.js index 65f3efc3a7..32ee093afa 100644 --- a/app/javascript/mastodon/actions/server.js +++ b/app/javascript/mastodon/actions/server.js @@ -25,7 +25,7 @@ export const fetchServer = () => (dispatch, getState) => { dispatch(fetchServerRequest()); - api(getState) + api() .get('/api/v2/instance').then(({ data }) => { if (data.contact.account) dispatch(importFetchedAccount(data.contact.account)); dispatch(fetchServerSuccess(data)); @@ -46,10 +46,10 @@ const fetchServerFail = error => ({ error, }); -export const fetchServerTranslationLanguages = () => (dispatch, getState) => { +export const fetchServerTranslationLanguages = () => (dispatch) => { dispatch(fetchServerTranslationLanguagesRequest()); - api(getState) + api() .get('/api/v1/instance/translation_languages').then(({ data }) => { dispatch(fetchServerTranslationLanguagesSuccess(data)); }).catch(err => dispatch(fetchServerTranslationLanguagesFail(err))); @@ -76,7 +76,7 @@ export const fetchExtendedDescription = () => (dispatch, getState) => { dispatch(fetchExtendedDescriptionRequest()); - api(getState) + api() .get('/api/v1/instance/extended_description') .then(({ data }) => dispatch(fetchExtendedDescriptionSuccess(data))) .catch(err => dispatch(fetchExtendedDescriptionFail(err))); @@ -103,7 +103,7 @@ export const fetchDomainBlocks = () => (dispatch, getState) => { dispatch(fetchDomainBlocksRequest()); - api(getState) + api() .get('/api/v1/instance/domain_blocks') .then(({ data }) => dispatch(fetchDomainBlocksSuccess(true, data))) .catch(err => { diff --git a/app/javascript/mastodon/actions/settings.js b/app/javascript/mastodon/actions/settings.js index 3685b0684e..fbd89f9d4b 100644 --- a/app/javascript/mastodon/actions/settings.js +++ b/app/javascript/mastodon/actions/settings.js @@ -20,7 +20,7 @@ export function changeSetting(path, value) { } const debouncedSave = debounce((dispatch, getState) => { - if (getState().getIn(['settings', 'saved'])) { + if (getState().getIn(['settings', 'saved']) || !getState().getIn(['meta', 'me'])) { return; } diff --git a/app/javascript/mastodon/actions/statuses.js b/app/javascript/mastodon/actions/statuses.js index 3aed807358..a60b80dc2c 100644 --- a/app/javascript/mastodon/actions/statuses.js +++ b/app/javascript/mastodon/actions/statuses.js @@ -59,7 +59,7 @@ export function fetchStatus(id, forceFetch = false) { dispatch(fetchStatusRequest(id, skipLoading)); - api(getState).get(`/api/v1/statuses/${id}`).then(response => { + api().get(`/api/v1/statuses/${id}`).then(response => { dispatch(importFetchedStatus(response.data)); dispatch(fetchStatusSuccess(skipLoading)); }).catch(error => { @@ -102,7 +102,7 @@ export const editStatus = (id, routerHistory) => (dispatch, getState) => { dispatch(fetchStatusSourceRequest()); - api(getState).get(`/api/v1/statuses/${id}/source`).then(response => { + api().get(`/api/v1/statuses/${id}/source`).then(response => { dispatch(fetchStatusSourceSuccess()); ensureComposeIsVisible(getState, routerHistory); dispatch(setComposeToStatus(status, response.data.text, response.data.spoiler_text)); @@ -134,7 +134,7 @@ export function deleteStatus(id, routerHistory, withRedraft = false) { dispatch(deleteStatusRequest(id)); - api(getState).delete(`/api/v1/statuses/${id}`).then(response => { + api().delete(`/api/v1/statuses/${id}`).then(response => { dispatch(deleteStatusSuccess(id)); dispatch(deleteFromTimelines(id)); dispatch(importFetchedAccount(response.data.account)); @@ -175,10 +175,10 @@ export const updateStatus = status => dispatch => dispatch(importFetchedStatus(status)); export function fetchContext(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchContextRequest(id)); - api(getState).get(`/api/v1/statuses/${id}/context`).then(response => { + api().get(`/api/v1/statuses/${id}/context`).then(response => { dispatch(importFetchedStatuses(response.data.ancestors.concat(response.data.descendants))); dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants)); @@ -219,10 +219,10 @@ export function fetchContextFail(id, error) { } export function muteStatus(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(muteStatusRequest(id)); - api(getState).post(`/api/v1/statuses/${id}/mute`).then(() => { + api().post(`/api/v1/statuses/${id}/mute`).then(() => { dispatch(muteStatusSuccess(id)); }).catch(error => { dispatch(muteStatusFail(id, error)); @@ -253,10 +253,10 @@ export function muteStatusFail(id, error) { } export function unmuteStatus(id) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(unmuteStatusRequest(id)); - api(getState).post(`/api/v1/statuses/${id}/unmute`).then(() => { + api().post(`/api/v1/statuses/${id}/unmute`).then(() => { dispatch(unmuteStatusSuccess(id)); }).catch(error => { dispatch(unmuteStatusFail(id, error)); @@ -316,10 +316,10 @@ export function toggleStatusCollapse(id, isCollapsed) { }; } -export const translateStatus = id => (dispatch, getState) => { +export const translateStatus = id => (dispatch) => { dispatch(translateStatusRequest(id)); - api(getState).post(`/api/v1/statuses/${id}/translate`).then(response => { + api().post(`/api/v1/statuses/${id}/translate`).then(response => { dispatch(translateStatusSuccess(id, response.data)); }).catch(error => { dispatch(translateStatusFail(id, error)); diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js index 9daeb3c60f..e7fe1c53ed 100644 --- a/app/javascript/mastodon/actions/streaming.js +++ b/app/javascript/mastodon/actions/streaming.js @@ -77,7 +77,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti }, onDisconnect() { - dispatch(disconnectTimeline(timelineId)); + dispatch(disconnectTimeline({ timeline: timelineId })); if (options.fallback) { // @ts-expect-error diff --git a/app/javascript/mastodon/actions/suggestions.js b/app/javascript/mastodon/actions/suggestions.js index 8eafe38b21..258ffa901d 100644 --- a/app/javascript/mastodon/actions/suggestions.js +++ b/app/javascript/mastodon/actions/suggestions.js @@ -10,10 +10,10 @@ export const SUGGESTIONS_FETCH_FAIL = 'SUGGESTIONS_FETCH_FAIL'; export const SUGGESTIONS_DISMISS = 'SUGGESTIONS_DISMISS'; export function fetchSuggestions(withRelationships = false) { - return (dispatch, getState) => { + return (dispatch) => { dispatch(fetchSuggestionsRequest()); - api(getState).get('/api/v2/suggestions', { params: { limit: 20 } }).then(response => { + api().get('/api/v2/suggestions', { params: { limit: 20 } }).then(response => { dispatch(importFetchedAccounts(response.data.map(x => x.account))); dispatch(fetchSuggestionsSuccess(response.data)); @@ -48,11 +48,11 @@ export function fetchSuggestionsFail(error) { }; } -export const dismissSuggestion = accountId => (dispatch, getState) => { +export const dismissSuggestion = accountId => (dispatch) => { dispatch({ type: SUGGESTIONS_DISMISS, id: accountId, }); - api(getState).delete(`/api/v1/suggestions/${accountId}`).catch(() => {}); + api().delete(`/api/v1/suggestions/${accountId}`).catch(() => {}); }; diff --git a/app/javascript/mastodon/actions/tags.js b/app/javascript/mastodon/actions/tags.js index dda8c924bb..d18d7e514f 100644 --- a/app/javascript/mastodon/actions/tags.js +++ b/app/javascript/mastodon/actions/tags.js @@ -20,10 +20,10 @@ export const HASHTAG_UNFOLLOW_REQUEST = 'HASHTAG_UNFOLLOW_REQUEST'; export const HASHTAG_UNFOLLOW_SUCCESS = 'HASHTAG_UNFOLLOW_SUCCESS'; export const HASHTAG_UNFOLLOW_FAIL = 'HASHTAG_UNFOLLOW_FAIL'; -export const fetchHashtag = name => (dispatch, getState) => { +export const fetchHashtag = name => (dispatch) => { dispatch(fetchHashtagRequest()); - api(getState).get(`/api/v1/tags/${name}`).then(({ data }) => { + api().get(`/api/v1/tags/${name}`).then(({ data }) => { dispatch(fetchHashtagSuccess(name, data)); }).catch(err => { dispatch(fetchHashtagFail(err)); @@ -45,10 +45,10 @@ export const fetchHashtagFail = error => ({ error, }); -export const fetchFollowedHashtags = () => (dispatch, getState) => { +export const fetchFollowedHashtags = () => (dispatch) => { dispatch(fetchFollowedHashtagsRequest()); - api(getState).get('/api/v1/followed_tags').then(response => { + api().get('/api/v1/followed_tags').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(fetchFollowedHashtagsSuccess(response.data, next ? next.uri : null)); }).catch(err => { @@ -87,7 +87,7 @@ export function expandFollowedHashtags() { dispatch(expandFollowedHashtagsRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(expandFollowedHashtagsSuccess(response.data, next ? next.uri : null)); }).catch(error => { @@ -117,10 +117,10 @@ export function expandFollowedHashtagsFail(error) { }; } -export const followHashtag = name => (dispatch, getState) => { +export const followHashtag = name => (dispatch) => { dispatch(followHashtagRequest(name)); - api(getState).post(`/api/v1/tags/${name}/follow`).then(({ data }) => { + api().post(`/api/v1/tags/${name}/follow`).then(({ data }) => { dispatch(followHashtagSuccess(name, data)); }).catch(err => { dispatch(followHashtagFail(name, err)); @@ -144,10 +144,10 @@ export const followHashtagFail = (name, error) => ({ error, }); -export const unfollowHashtag = name => (dispatch, getState) => { +export const unfollowHashtag = name => (dispatch) => { dispatch(unfollowHashtagRequest(name)); - api(getState).post(`/api/v1/tags/${name}/unfollow`).then(({ data }) => { + api().post(`/api/v1/tags/${name}/unfollow`).then(({ data }) => { dispatch(unfollowHashtagSuccess(name, data)); }).catch(err => { dispatch(unfollowHashtagFail(name, err)); diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js index 4ce7c3cf84..4ca3c3a151 100644 --- a/app/javascript/mastodon/actions/timelines.js +++ b/app/javascript/mastodon/actions/timelines.js @@ -6,9 +6,11 @@ import { usePendingItems as preferPendingItems } from 'mastodon/initial_state'; import { importFetchedStatus, importFetchedStatuses } from './importer'; import { submitMarkers } from './markers'; +import {timelineDelete} from './timelines_typed'; + +export { disconnectTimeline } from './timelines_typed'; export const TIMELINE_UPDATE = 'TIMELINE_UPDATE'; -export const TIMELINE_DELETE = 'TIMELINE_DELETE'; export const TIMELINE_CLEAR = 'TIMELINE_CLEAR'; export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST'; @@ -17,7 +19,6 @@ export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL'; export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP'; export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING'; -export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT'; export const TIMELINE_CONNECT = 'TIMELINE_CONNECT'; export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL'; @@ -62,16 +63,10 @@ export function updateTimeline(timeline, status, accept) { export function deleteFromTimelines(id) { return (dispatch, getState) => { const accountId = getState().getIn(['statuses', id, 'account']); - const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id')); + const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id')).valueSeq().toJSON(); const reblogOf = getState().getIn(['statuses', id, 'reblog'], null); - dispatch({ - type: TIMELINE_DELETE, - id, - accountId, - references, - reblogOf, - }); + dispatch(timelineDelete({ statusId: id, accountId, references, reblogOf })); }; } @@ -114,7 +109,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) { dispatch(expandTimelineRequest(timelineId, isLoadingMore)); - api(getState).get(path, { params }).then(response => { + api().get(path, { params }).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); @@ -225,12 +220,6 @@ export function connectTimeline(timeline) { }; } -export const disconnectTimeline = timeline => ({ - type: TIMELINE_DISCONNECT, - timeline, - usePendingItems: preferPendingItems, -}); - export const markAsPartial = timeline => ({ type: TIMELINE_MARK_AS_PARTIAL, timeline, diff --git a/app/javascript/mastodon/actions/timelines_typed.ts b/app/javascript/mastodon/actions/timelines_typed.ts new file mode 100644 index 0000000000..07d82b2f01 --- /dev/null +++ b/app/javascript/mastodon/actions/timelines_typed.ts @@ -0,0 +1,20 @@ +import { createAction } from '@reduxjs/toolkit'; + +import { usePendingItems as preferPendingItems } from 'mastodon/initial_state'; + +export const disconnectTimeline = createAction( + 'timeline/disconnect', + ({ timeline }: { timeline: string }) => ({ + payload: { + timeline, + usePendingItems: preferPendingItems, + }, + }), +); + +export const timelineDelete = createAction<{ + statusId: string; + accountId: string; + references: string[]; + reblogOf: string | null; +}>('timelines/delete'); diff --git a/app/javascript/mastodon/actions/trends.js b/app/javascript/mastodon/actions/trends.js index d314423884..01089fccbb 100644 --- a/app/javascript/mastodon/actions/trends.js +++ b/app/javascript/mastodon/actions/trends.js @@ -1,6 +1,6 @@ import api, { getLinks } from '../api'; -import { importFetchedStatuses } from './importer'; +import { importFetchedStatuses, importFetchedAccounts } from './importer'; export const TRENDS_TAGS_FETCH_REQUEST = 'TRENDS_TAGS_FETCH_REQUEST'; export const TRENDS_TAGS_FETCH_SUCCESS = 'TRENDS_TAGS_FETCH_SUCCESS'; @@ -18,10 +18,10 @@ export const TRENDS_STATUSES_EXPAND_REQUEST = 'TRENDS_STATUSES_EXPAND_REQUEST'; export const TRENDS_STATUSES_EXPAND_SUCCESS = 'TRENDS_STATUSES_EXPAND_SUCCESS'; export const TRENDS_STATUSES_EXPAND_FAIL = 'TRENDS_STATUSES_EXPAND_FAIL'; -export const fetchTrendingHashtags = () => (dispatch, getState) => { +export const fetchTrendingHashtags = () => (dispatch) => { dispatch(fetchTrendingHashtagsRequest()); - api(getState) + api() .get('/api/v1/trends/tags') .then(({ data }) => dispatch(fetchTrendingHashtagsSuccess(data))) .catch(err => dispatch(fetchTrendingHashtagsFail(err))); @@ -45,12 +45,15 @@ export const fetchTrendingHashtagsFail = error => ({ skipAlert: true, }); -export const fetchTrendingLinks = () => (dispatch, getState) => { +export const fetchTrendingLinks = () => (dispatch) => { dispatch(fetchTrendingLinksRequest()); - api(getState) - .get('/api/v1/trends/links') - .then(({ data }) => dispatch(fetchTrendingLinksSuccess(data))) + api() + .get('/api/v1/trends/links', { params: { limit: 20 } }) + .then(({ data }) => { + dispatch(importFetchedAccounts(data.map(link => link.author_account).filter(account => !!account))); + dispatch(fetchTrendingLinksSuccess(data)); + }) .catch(err => dispatch(fetchTrendingLinksFail(err))); }; @@ -79,7 +82,7 @@ export const fetchTrendingStatuses = () => (dispatch, getState) => { dispatch(fetchTrendingStatusesRequest()); - api(getState).get('/api/v1/trends/statuses').then(response => { + api().get('/api/v1/trends/statuses').then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(fetchTrendingStatusesSuccess(response.data, next ? next.uri : null)); @@ -115,7 +118,7 @@ export const expandTrendingStatuses = () => (dispatch, getState) => { dispatch(expandTrendingStatusesRequest()); - api(getState).get(url).then(response => { + api().get(url).then(response => { const next = getLinks(response).refs.find(link => link.rel === 'next'); dispatch(importFetchedStatuses(response.data)); dispatch(expandTrendingStatusesSuccess(response.data, next ? next.uri : null)); diff --git a/app/javascript/mastodon/api.ts b/app/javascript/mastodon/api.ts index f262fd8570..e133125a29 100644 --- a/app/javascript/mastodon/api.ts +++ b/app/javascript/mastodon/api.ts @@ -1,9 +1,9 @@ -import type { AxiosResponse, RawAxiosRequestHeaders } from 'axios'; +import type { AxiosResponse, Method, RawAxiosRequestHeaders } from 'axios'; import axios from 'axios'; import LinkHeader from 'http-link-header'; +import { getAccessToken } from './initial_state'; import ready from './ready'; -import type { GetState } from './store'; export const getLinks = (response: AxiosResponse) => { const value = response.headers.link as string | undefined; @@ -29,25 +29,22 @@ const setCSRFHeader = () => { void ready(setCSRFHeader); -const authorizationHeaderFromState = (getState?: GetState) => { - const accessToken = - getState && (getState().meta.get('access_token', '') as string); +const authorizationTokenFromInitialState = (): RawAxiosRequestHeaders => { + const accessToken = getAccessToken(); - if (!accessToken) { - return {}; - } + if (!accessToken) return {}; return { Authorization: `Bearer ${accessToken}`, - } as RawAxiosRequestHeaders; + }; }; // eslint-disable-next-line import/no-default-export -export default function api(getState: GetState) { +export default function api(withAuthorization = true) { return axios.create({ headers: { ...csrfHeader, - ...authorizationHeaderFromState(getState), + ...(withAuthorization ? authorizationTokenFromInitialState() : {}), }, transformResponse: [ @@ -61,3 +58,17 @@ export default function api(getState: GetState) { ], }); } + +export async function apiRequest( + method: Method, + url: string, + params?: Record, +) { + const { data } = await api().request({ + method, + url: '/api/' + url, + data: params, + }); + + return data; +} diff --git a/app/javascript/mastodon/api/accounts.ts b/app/javascript/mastodon/api/accounts.ts new file mode 100644 index 0000000000..3d89e44b26 --- /dev/null +++ b/app/javascript/mastodon/api/accounts.ts @@ -0,0 +1,7 @@ +import { apiRequest } from 'mastodon/api'; +import type { ApiRelationshipJSON } from 'mastodon/api_types/relationships'; + +export const apiSubmitAccountNote = (id: string, value: string) => + apiRequest('post', `v1/accounts/${id}/note`, { + comment: value, + }); diff --git a/app/javascript/mastodon/api/interactions.ts b/app/javascript/mastodon/api/interactions.ts new file mode 100644 index 0000000000..4c466a1b46 --- /dev/null +++ b/app/javascript/mastodon/api/interactions.ts @@ -0,0 +1,10 @@ +import { apiRequest } from 'mastodon/api'; +import type { Status, StatusVisibility } from 'mastodon/models/status'; + +export const apiReblog = (statusId: string, visibility: StatusVisibility) => + apiRequest<{ reblog: Status }>('post', `v1/statuses/${statusId}/reblog`, { + visibility, + }); + +export const apiUnreblog = (statusId: string) => + apiRequest('post', `v1/statuses/${statusId}/unreblog`); diff --git a/app/javascript/mastodon/api/notification_policies.ts b/app/javascript/mastodon/api/notification_policies.ts new file mode 100644 index 0000000000..b2a1e5ac31 --- /dev/null +++ b/app/javascript/mastodon/api/notification_policies.ts @@ -0,0 +1,10 @@ +import { apiRequest } from 'mastodon/api'; +import type { NotificationPolicyJSON } from 'mastodon/api_types/notification_policies'; + +export const apiGetNotificationPolicy = () => + apiRequest('GET', '/v1/notifications/policy'); + +export const apiUpdateNotificationsPolicy = ( + policy: Partial, +) => + apiRequest('PUT', '/v1/notifications/policy', policy); diff --git a/app/javascript/mastodon/api_types/markers.ts b/app/javascript/mastodon/api_types/markers.ts new file mode 100644 index 0000000000..f7664fd7c1 --- /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 0000000000..fc027ccd2a --- /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/notification_policies.ts b/app/javascript/mastodon/api_types/notification_policies.ts new file mode 100644 index 0000000000..0f4a2d132e --- /dev/null +++ b/app/javascript/mastodon/api_types/notification_policies.ts @@ -0,0 +1,12 @@ +// See app/serializers/rest/notification_policy_serializer.rb + +export interface NotificationPolicyJSON { + filter_not_following: boolean; + filter_not_followers: boolean; + filter_new_accounts: boolean; + filter_private_mentions: boolean; + summary: { + pending_requests_count: number; + pending_notifications_count: number; + }; +} diff --git a/app/javascript/mastodon/api_types/polls.ts b/app/javascript/mastodon/api_types/polls.ts new file mode 100644 index 0000000000..8181f7b813 --- /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 0000000000..c7dd33b5da --- /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 0ec8449343..511568aa0f 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 4a99dd0bbf..18a31cba24 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,150 @@ 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 = ); - + return ( + + ); }; BackButton.propTypes = { - pinned: PropTypes.bool, - show: PropTypes.bool, + onlyIcon: PropTypes.bool, }; class ColumnHeader extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, intl: PropTypes.object.isRequired, title: PropTypes.node, icon: PropTypes.string, @@ -114,7 +109,7 @@ class ColumnHeader extends PureComponent { }; render () { - const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props; + const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props; const { collapsed, animating } = this.state; const wrapperClassName = classNames('column-header__wrapper', { @@ -145,30 +140,36 @@ class ColumnHeader extends PureComponent { } if (multiColumn && pinned) { - pinButton = ; + pinButton = ; moveButtons = ( -
+
); } else if (multiColumn && this.props.onPin) { - pinButton = ; + pinButton = ; } - backButton = ; + if (history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) { + backButton = ; + } const collapsedContent = [ extraContent, ]; if (multiColumn) { - collapsedContent.push(pinButton); - collapsedContent.push(moveButtons); + collapsedContent.push( +
+ {pinButton} + {moveButtons} +
+ ); } - if (this.context.identity.signedIn && (children || (multiColumn && this.props.onPin))) { + if (this.props.identity.signedIn && (children || (multiColumn && this.props.onPin))) { collapseButton = ( @@ -190,16 +191,19 @@ class ColumnHeader extends PureComponent {

{hasTitle && ( - + <> + {backButton} + + + )} {!hasTitle && backButton}
- {hasTitle && backButton} {extraButton} {collapseButton}
@@ -226,4 +230,4 @@ class ColumnHeader extends PureComponent { } -export default injectIntl(withRouter(ColumnHeader)); +export default injectIntl(withIdentity(withRouter(ColumnHeader))); diff --git a/app/javascript/mastodon/components/dropdown_menu.jsx b/app/javascript/mastodon/components/dropdown_menu.jsx index f6c08dd43b..524dbb927b 100644 --- a/app/javascript/mastodon/components/dropdown_menu.jsx +++ b/app/javascript/mastodon/components/dropdown_menu.jsx @@ -9,7 +9,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { supportsPassiveEvents } from 'detect-passive-events'; import Overlay from 'react-overlays/Overlay'; -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import { CircularProgress } from 'mastodon/components/circular_progress'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -298,7 +297,7 @@ class Dropdown extends PureComponent { }) : ( ); diff --git a/app/javascript/mastodon/components/hashtag_bar.tsx b/app/javascript/mastodon/components/hashtag_bar.tsx index 91fa922198..1642ba6504 100644 --- a/app/javascript/mastodon/components/hashtag_bar.tsx +++ b/app/javascript/mastodon/components/hashtag_bar.tsx @@ -24,7 +24,7 @@ export type StatusLike = Record<{ function normalizeHashtag(hashtag: string) { return ( - hashtag && hashtag.startsWith('#') ? hashtag.slice(1) : hashtag + !!hashtag && hashtag.startsWith('#') ? hashtag.slice(1) : hashtag ).normalize('NFKC'); } @@ -52,7 +52,10 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) { ); return Object.values(groups).map((tags) => { - if (tags.length === 1) return tags[0]; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the array has at least one element + const firstTag = tags[0]!; + + if (tags.length === 1) return firstTag; // The best match is the one where we have the less difference between upper and lower case letter count const best = minBy(tags, (tag) => { @@ -66,7 +69,7 @@ function uniqueHashtagsWithCaseHandling(hashtags: string[]) { return Math.abs(lowerCase - upperCase); }); - return best ?? tags[0]; + return best ?? firstTag; }); } diff --git a/app/javascript/mastodon/components/more_from_author.jsx b/app/javascript/mastodon/components/more_from_author.jsx new file mode 100644 index 0000000000..c20e76ac45 --- /dev/null +++ b/app/javascript/mastodon/components/more_from_author.jsx @@ -0,0 +1,19 @@ +import PropTypes from 'prop-types'; + +import { FormattedMessage } from 'react-intl'; + +import { AuthorLink } from 'mastodon/features/explore/components/author_link'; + +export const MoreFromAuthor = ({ accountId }) => ( +
+ + + + + }} /> +
+); + +MoreFromAuthor.propTypes = { + accountId: PropTypes.string.isRequired, +}; diff --git a/app/javascript/mastodon/components/poll.jsx b/app/javascript/mastodon/components/poll.jsx index c7036d111b..7b836f00b1 100644 --- a/app/javascript/mastodon/components/poll.jsx +++ b/app/javascript/mastodon/components/poll.jsx @@ -14,6 +14,7 @@ import CheckIcon from '@/material-icons/400-24px/check.svg?react'; import { Icon } from 'mastodon/components/icon'; import emojify from 'mastodon/features/emoji/emoji'; import Motion from 'mastodon/features/ui/util/optional_motion'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { RelativeTimestamp } from './relative_timestamp'; @@ -38,12 +39,8 @@ const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => { }, {}); class Poll extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, poll: ImmutablePropTypes.map, lang: PropTypes.string, intl: PropTypes.object.isRequired, @@ -235,7 +232,7 @@ class Poll extends ImmutablePureComponent {
- {!showResults && } + {!showResults && } {!showResults && <> ยท } {showResults && !this.props.disabled && <> ยท } {votesCount} @@ -247,4 +244,4 @@ class Poll extends ImmutablePureComponent { } -export default injectIntl(Poll); +export default injectIntl(withIdentity(Poll)); diff --git a/app/javascript/mastodon/components/relative_timestamp.tsx b/app/javascript/mastodon/components/relative_timestamp.tsx index ac3ab0fb4d..ac385e88c6 100644 --- a/app/javascript/mastodon/components/relative_timestamp.tsx +++ b/app/javascript/mastodon/components/relative_timestamp.tsx @@ -53,7 +53,6 @@ const messages = defineMessages({ }); const dateFormatOptions = { - hour12: false, year: 'numeric', month: 'short', day: '2-digit', @@ -103,7 +102,7 @@ const getUnitDelay = (units: string) => { }; export const timeAgoString = ( - intl: IntlShape, + intl: Pick, date: Date, now: number, year: number, @@ -192,7 +191,7 @@ const timeRemainingString = ( interface Props { intl: IntlShape; timestamp: string; - year: number; + year?: number; futureDate?: boolean; short?: boolean; } @@ -204,11 +203,6 @@ class RelativeTimestamp extends Component { now: Date.now(), }; - static defaultProps = { - year: new Date().getFullYear(), - short: true, - }; - _timer: number | undefined; shouldComponentUpdate(nextProps: Props, nextState: States) { @@ -258,7 +252,13 @@ class RelativeTimestamp extends Component { } render() { - const { timestamp, intl, year, futureDate, short } = this.props; + const { + timestamp, + intl, + futureDate, + year = new Date().getFullYear(), + short = true, + } = this.props; const timeGiven = timestamp.includes('T'); const date = new Date(timestamp); diff --git a/app/javascript/mastodon/components/server_banner.jsx b/app/javascript/mastodon/components/server_banner.jsx index 63eec53492..baa220af5e 100644 --- a/app/javascript/mastodon/components/server_banner.jsx +++ b/app/javascript/mastodon/components/server_banner.jsx @@ -42,10 +42,12 @@ class ServerBanner extends PureComponent { return (
- {domain}, mastodon: Mastodon }} /> + {domain}, mastodon: Mastodon }} />
- + + +
{isLoading ? ( @@ -84,10 +86,6 @@ class ServerBanner extends PureComponent { )}
- -
- -
); } diff --git a/app/javascript/mastodon/components/short_number.tsx b/app/javascript/mastodon/components/short_number.tsx index 74c3c5d75e..a0b523aaad 100644 --- a/app/javascript/mastodon/components/short_number.tsx +++ b/app/javascript/mastodon/components/short_number.tsx @@ -48,7 +48,7 @@ const ShortNumberCounter: React.FC = ({ value }) => { const count = ( ); diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index 1171351c51..7b97e45766 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -22,6 +22,7 @@ import Card from '../features/status/components/card'; // to use the progress bar to show download progress import Bundle from '../features/ui/components/bundle'; import { MediaGallery, Video, Audio } from '../features/ui/util/async-components'; +import { SensitiveMediaContext } from '../features/ui/util/sensitive_media_context'; import { displayMedia } from '../initial_state'; import { Avatar } from './avatar'; @@ -78,6 +79,8 @@ const messages = defineMessages({ class Status extends ImmutablePureComponent { + static contextType = SensitiveMediaContext; + static propTypes = { status: ImmutablePropTypes.map, account: ImmutablePropTypes.record, @@ -133,19 +136,21 @@ class Status extends ImmutablePureComponent { ]; state = { - showMedia: defaultMediaVisibility(this.props.status), - statusId: undefined, + showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault), forceFilter: undefined, }; - static getDerivedStateFromProps(nextProps, prevState) { - if (nextProps.status && nextProps.status.get('id') !== prevState.statusId) { - return { - showMedia: defaultMediaVisibility(nextProps.status), - statusId: nextProps.status.get('id'), - }; - } else { - return null; + componentDidUpdate (prevProps) { + // This will potentially cause a wasteful redraw, but in most cases `Status` components are used + // with a `key` directly depending on their `id`, preventing re-use of the component across + // different IDs. + // But just in case this does change, reset the state on status change. + + if (this.props.status?.get('id') !== prevProps.status?.get('id')) { + this.setState({ + showMedia: defaultMediaVisibility(this.props.status) && !(this.context?.hideMediaByDefault), + forceFilter: undefined, + }); } } @@ -554,7 +559,7 @@ class Status extends ImmutablePureComponent {
- {status.get('edited_at') && *} + {status.get('edited_at') && *} diff --git a/app/javascript/mastodon/components/status_action_bar.jsx b/app/javascript/mastodon/components/status_action_bar.jsx index b111a65385..c79eae8460 100644 --- a/app/javascript/mastodon/components/status_action_bar.jsx +++ b/app/javascript/mastodon/components/status_action_bar.jsx @@ -22,6 +22,7 @@ import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react'; import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react'; import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react'; import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -74,14 +75,10 @@ const mapStateToProps = (state, { status }) => ({ }); class StatusActionBar extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, status: ImmutablePropTypes.map.isRequired, - relationship: ImmutablePropTypes.map, + relationship: ImmutablePropTypes.record, onReply: PropTypes.func, onFavourite: PropTypes.func, onReblog: PropTypes.func, @@ -118,7 +115,7 @@ class StatusActionBar extends ImmutablePureComponent { ]; handleReplyClick = () => { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { this.props.onReply(this.props.status, this.props.history); @@ -136,7 +133,7 @@ class StatusActionBar extends ImmutablePureComponent { }; handleFavouriteClick = () => { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { this.props.onFavourite(this.props.status); @@ -146,7 +143,7 @@ class StatusActionBar extends ImmutablePureComponent { }; handleReblogClick = e => { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { this.props.onReblog(this.props.status, e); @@ -209,7 +206,7 @@ class StatusActionBar extends ImmutablePureComponent { const { status, onBlockDomain } = this.props; const account = status.get('account'); - onBlockDomain(account.get('acct').split('@')[1]); + onBlockDomain(account); }; handleUnblockDomain = () => { @@ -250,7 +247,7 @@ class StatusActionBar extends ImmutablePureComponent { render () { const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props; - const { signedIn, permissions } = this.context.identity; + const { signedIn, permissions } = this.props.identity; const publicStatus = ['public', 'unlisted'].includes(status.get('visibility')); const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility')); @@ -410,4 +407,4 @@ class StatusActionBar extends ImmutablePureComponent { } -export default withRouter(connect(mapStateToProps)(injectIntl(StatusActionBar))); +export default withRouter(withIdentity(connect(mapStateToProps)(injectIntl(StatusActionBar)))); diff --git a/app/javascript/mastodon/components/status_content.jsx b/app/javascript/mastodon/components/status_content.jsx index 4a7ba941eb..24483cf512 100644 --- a/app/javascript/mastodon/components/status_content.jsx +++ b/app/javascript/mastodon/components/status_content.jsx @@ -12,8 +12,10 @@ import { connect } from 'react-redux'; import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import { Icon } from 'mastodon/components/icon'; import PollContainer from 'mastodon/containers/poll_container'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { autoPlayGif, languages as preloadedLanguages } from 'mastodon/initial_state'; + const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) /** @@ -67,12 +69,8 @@ const mapStateToProps = state => ({ }); class StatusContent extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, status: ImmutablePropTypes.map.isRequired, statusContent: PropTypes.string, expanded: PropTypes.bool, @@ -245,7 +243,7 @@ class StatusContent extends PureComponent { const renderReadMore = this.props.onClick && status.get('collapsed'); const contentLocale = intl.locale.replace(/[_-].*/, ''); const targetLanguages = this.props.languages?.get(status.get('language') || 'und'); - const renderTranslate = this.props.onTranslate && this.context.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && targetLanguages?.includes(contentLocale); + const renderTranslate = this.props.onTranslate && this.props.identity.signedIn && ['public', 'unlisted'].includes(status.get('visibility')) && status.get('search_index').trim().length > 0 && targetLanguages?.includes(contentLocale); const content = { __html: statusContent ?? getStatusContent(status) }; const spoilerContent = { __html: status.getIn(['translation', 'spoilerHtml']) || status.get('spoilerHtml') }; @@ -328,4 +326,4 @@ class StatusContent extends PureComponent { } -export default withRouter(connect(mapStateToProps)(injectIntl(StatusContent))); +export default withRouter(withIdentity(connect(mapStateToProps)(injectIntl(StatusContent)))); diff --git a/app/javascript/mastodon/components/visibility_icon.tsx b/app/javascript/mastodon/components/visibility_icon.tsx index 753dc02737..3a310cbae2 100644 --- a/app/javascript/mastodon/components/visibility_icon.tsx +++ b/app/javascript/mastodon/components/visibility_icon.tsx @@ -4,11 +4,10 @@ import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?re import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; +import type { StatusVisibility } from 'mastodon/models/status'; import { Icon } from './icon'; -type Visibility = 'public' | 'unlisted' | 'private' | 'direct'; - const messages = defineMessages({ public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, unlisted_short: { @@ -25,7 +24,7 @@ const messages = defineMessages({ }, }); -export const VisibilityIcon: React.FC<{ visibility: Visibility }> = ({ +export const VisibilityIcon: React.FC<{ visibility: StatusVisibility }> = ({ visibility, }) => { const intl = useIntl(); diff --git a/app/javascript/mastodon/containers/account_container.jsx b/app/javascript/mastodon/containers/account_container.jsx index a134452e77..f171fcc2fe 100644 --- a/app/javascript/mastodon/containers/account_container.jsx +++ b/app/javascript/mastodon/containers/account_container.jsx @@ -13,7 +13,6 @@ import { import { openModal } from '../actions/modal'; import { initMuteModal } from '../actions/mutes'; import Account from '../components/account'; -import { unfollowModal } from '../initial_state'; import { makeGetAccount } from '../selectors'; const messages = defineMessages({ @@ -34,18 +33,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ onFollow (account) { if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) { - if (unfollowModal) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }, - })); - } else { - dispatch(unfollowAccount(account.get('id'))); - } + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.unfollowConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, + })); } else { dispatch(followAccount(account.get('id'))); } diff --git a/app/javascript/mastodon/containers/mastodon.jsx b/app/javascript/mastodon/containers/mastodon.jsx index 87708da191..0b1255c336 100644 --- a/app/javascript/mastodon/containers/mastodon.jsx +++ b/app/javascript/mastodon/containers/mastodon.jsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import { PureComponent } from 'react'; import { Helmet } from 'react-helmet'; @@ -14,6 +13,7 @@ import { connectUserStream } from 'mastodon/actions/streaming'; import ErrorBoundary from 'mastodon/components/error_boundary'; import { Router } from 'mastodon/components/router'; import UI from 'mastodon/features/ui'; +import { IdentityContext, createIdentityContext } from 'mastodon/identity_context'; import initialState, { title as siteTitle } from 'mastodon/initial_state'; import { IntlProvider } from 'mastodon/locales'; import { store } from 'mastodon/store'; @@ -28,33 +28,9 @@ if (initialState.meta.me) { store.dispatch(fetchCustomEmojis()); } -const createIdentityContext = state => ({ - signedIn: !!state.meta.me, - accountId: state.meta.me, - disabledAccountId: state.meta.disabled_account_id, - accessToken: state.meta.access_token, - permissions: state.role ? state.role.permissions : 0, -}); - export default class Mastodon extends PureComponent { - - static childContextTypes = { - identity: PropTypes.shape({ - signedIn: PropTypes.bool.isRequired, - accountId: PropTypes.string, - disabledAccountId: PropTypes.string, - accessToken: PropTypes.string, - }).isRequired, - }; - identity = createIdentityContext(initialState); - getChildContext() { - return { - identity: this.identity, - }; - } - componentDidMount() { if (this.identity.signedIn) { this.disconnect = store.dispatch(connectUserStream()); @@ -74,19 +50,21 @@ export default class Mastodon extends PureComponent { render () { return ( - - - - - - - - + + + + + + + + + - - - - + + + + + ); } diff --git a/app/javascript/mastodon/containers/media_container.jsx b/app/javascript/mastodon/containers/media_container.jsx index fba3c5df78..d18602e3b5 100644 --- a/app/javascript/mastodon/containers/media_container.jsx +++ b/app/javascript/mastodon/containers/media_container.jsx @@ -80,7 +80,7 @@ export default class MediaContainer extends PureComponent { return ( <> - {[].map.call(components, (component, i) => { + {Array.from(components).map((component, i) => { const componentName = component.getAttribute('data-component'); const Component = MEDIA_COMPONENTS[componentName]; const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props')); diff --git a/app/javascript/mastodon/containers/status_container.jsx b/app/javascript/mastodon/containers/status_container.jsx index 7a7cd9880f..4a9b525777 100644 --- a/app/javascript/mastodon/containers/status_container.jsx +++ b/app/javascript/mastodon/containers/status_container.jsx @@ -1,4 +1,4 @@ -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import { connect } from 'react-redux'; @@ -8,14 +8,13 @@ import { } from '../actions/accounts'; import { showAlertForError } from '../actions/alerts'; import { initBlockModal } from '../actions/blocks'; -import { initBoostModal } from '../actions/boosts'; import { replyCompose, mentionCompose, directCompose, } from '../actions/compose'; import { - blockDomain, + initDomainBlockModal, unblockDomain, } from '../actions/domain_blocks'; import { @@ -97,9 +96,9 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ onModalReblog (status, privacy) { if (status.get('reblogged')) { - dispatch(unreblog(status)); + dispatch(unreblog({ statusId: status.get('id') })); } else { - dispatch(reblog(status, privacy)); + dispatch(reblog({ statusId: status.get('id'), visibility: privacy })); } }, @@ -107,7 +106,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ if ((e && e.shiftKey) || !boostModal) { this.onModalReblog(status); } else { - dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); + dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); } }, @@ -253,15 +252,8 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ dispatch(toggleStatusCollapse(status.get('id'), isCollapsed)); }, - onBlockDomain (domain) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: {domain} }} />, - confirm: intl.formatMessage(messages.blockDomainConfirm), - onConfirm: () => dispatch(blockDomain(domain)), - }, - })); + onBlockDomain (account) { + dispatch(initDomainBlockModal(account)); }, onUnblockDomain (domain) { @@ -269,7 +261,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ }, deployPictureInPicture (status, type, mediaProps) { - dispatch(deployPictureInPicture(status.get('id'), status.getIn(['account', 'id']), type, mediaProps)); + dispatch(deployPictureInPicture({statusId: status.get('id'), accountId: status.getIn(['account', 'id']), playerType: type, props: mediaProps})); }, onInteractionModal (type, status) { diff --git a/app/javascript/mastodon/features/about/index.jsx b/app/javascript/mastodon/features/about/index.jsx index 3287631ed1..65a36520d6 100644 --- a/app/javascript/mastodon/features/about/index.jsx +++ b/app/javascript/mastodon/features/about/index.jsx @@ -170,7 +170,8 @@ class About extends PureComponent {
    {server.get('rules').map(rule => (
  1. - {rule.get('text')} +
    {rule.get('text')}
    + {rule.get('hint').length > 0 && (
    {rule.get('hint')}
    )}
  2. ))}
@@ -188,18 +189,20 @@ class About extends PureComponent { <>

-
- {domainBlocks.get('items').map(block => ( -
-
-
{block.get('domain')}
- {intl.formatMessage(severityMessages[block.get('severity')].title)} -
+ {domainBlocks.get('items').size > 0 && ( +
+ {domainBlocks.get('items').map(block => ( +
+
+
{block.get('domain')}
+ {intl.formatMessage(severityMessages[block.get('severity')].title)} +
-

{(block.get('comment') || '').length > 0 ? block.get('comment') : }

-
- ))} -
+

{(block.get('comment') || '').length > 0 ? block.get('comment') : }

+
+ ))} +
+ )} ) : (

diff --git a/app/javascript/mastodon/features/account/components/domain_pill.jsx b/app/javascript/mastodon/features/account/components/domain_pill.jsx new file mode 100644 index 0000000000..0dadb947f9 --- /dev/null +++ b/app/javascript/mastodon/features/account/components/domain_pill.jsx @@ -0,0 +1,86 @@ +import PropTypes from 'prop-types'; +import { useState, useRef, useCallback } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import classNames from 'classnames'; + +import Overlay from 'react-overlays/Overlay'; + + + +import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; +import BadgeIcon from '@/material-icons/400-24px/badge.svg?react'; +import GlobeIcon from '@/material-icons/400-24px/globe.svg?react'; +import { Icon } from 'mastodon/components/icon'; + +export const DomainPill = ({ domain, username, isSelf }) => { + const [open, setOpen] = useState(false); + const [expanded, setExpanded] = useState(false); + const triggerRef = useRef(null); + + const handleClick = useCallback(() => { + setOpen(!open); + }, [open, setOpen]); + + const handleExpandClick = useCallback(() => { + setExpanded(!expanded); + }, [expanded, setExpanded]); + + return ( + <> + + + + {({ props }) => ( +
+
+
+

+
+ +
+
{isSelf ? : }
+
@{username}@{domain}
+
+ +
+
+
+ +
+
+

{isSelf ? : }

+
+
+ +
+
+ +
+
+

{isSelf ? : }

+
+
+
+ +

{isSelf ? }} /> : }} />}

+ + {expanded && ( + <> +

+

+ + )} +
+ )} +
+ + ); +}; + +DomainPill.propTypes = { + username: PropTypes.string.isRequired, + domain: PropTypes.string.isRequired, + isSelf: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index 233d208c64..b10ef6ef76 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -22,15 +22,19 @@ import { CopyIconButton } from 'mastodon/components/copy_icon_button'; import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters'; import { Icon } from 'mastodon/components/icon'; import { IconButton } from 'mastodon/components/icon_button'; +import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import { ShortNumber } from 'mastodon/components/short_number'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; -import { autoPlayGif, me, domain } from 'mastodon/initial_state'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; +import { autoPlayGif, me, domain as localDomain } from 'mastodon/initial_state'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import AccountNoteContainer from '../containers/account_note_container'; import FollowRequestNoteContainer from '../containers/follow_request_note_container'; +import { DomainPill } from './domain_pill'; + const messages = defineMessages({ unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, follow: { id: 'account.follow', defaultMessage: 'Follow' }, @@ -77,7 +81,7 @@ const messages = defineMessages({ const titleFromAccount = account => { const displayName = account.get('display_name'); - const acct = account.get('acct') === account.get('username') ? `${account.get('username')}@${domain}` : account.get('acct'); + const acct = account.get('acct') === account.get('username') ? `${account.get('username')}@${localDomain}` : account.get('acct'); const prefix = displayName.trim().length === 0 ? account.get('username') : displayName; return `${prefix} (@${acct})`; @@ -101,7 +105,6 @@ const dateFormatOptions = { month: 'short', day: 'numeric', year: 'numeric', - hour12: false, hour: '2-digit', minute: '2-digit', }; @@ -109,6 +112,7 @@ const dateFormatOptions = { class Header extends ImmutablePureComponent { static propTypes = { + identity: identityContextPropShape, account: ImmutablePropTypes.record, identity_props: ImmutablePropTypes.list, onFollow: PropTypes.func.isRequired, @@ -134,10 +138,6 @@ class Header extends ImmutablePureComponent { ...WithRouterPropTypes, }; - static contextTypes = { - identity: PropTypes.object, - }; - setRef = c => { this.node = c; }; @@ -252,8 +252,8 @@ class Header extends ImmutablePureComponent { } render () { - const { account, hidden, intl, domain } = this.props; - const { signedIn, permissions } = this.context.identity; + const { account, hidden, intl } = this.props; + const { signedIn, permissions } = this.props.identity; if (!account) { return null; @@ -290,7 +290,7 @@ class Header extends ImmutablePureComponent { if (me !== account.get('id')) { if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded - actionBtn = ''; + actionBtn = ; } else if (account.getIn(['relationship', 'requested'])) { actionBtn =
@@ -443,7 +439,9 @@ class Header extends ImmutablePureComponent {

- @{acct} {lockedIcon} + @{username}@{domain} + + {lockedIcon}

@@ -516,4 +514,4 @@ class Header extends ImmutablePureComponent { } -export default withRouter(injectIntl(Header)); +export default withRouter(withIdentity(injectIntl(Header))); diff --git a/app/javascript/mastodon/features/account/containers/account_note_container.js b/app/javascript/mastodon/features/account/containers/account_note_container.js index 20304a4524..1530242d69 100644 --- a/app/javascript/mastodon/features/account/containers/account_note_container.js +++ b/app/javascript/mastodon/features/account/containers/account_note_container.js @@ -11,7 +11,7 @@ const mapStateToProps = (state, { account }) => ({ const mapDispatchToProps = (dispatch, { account }) => ({ onSave (value) { - dispatch(submitAccountNote({ id: account.get('id'), value})); + dispatch(submitAccountNote({ accountId: account.get('id'), note: value })); }, }); diff --git a/app/javascript/mastodon/features/account_timeline/components/header.jsx b/app/javascript/mastodon/features/account_timeline/components/header.jsx index 7de8d3771b..a2463b8764 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.jsx +++ b/app/javascript/mastodon/features/account_timeline/components/header.jsx @@ -72,11 +72,7 @@ class Header extends ImmutablePureComponent { }; handleBlockDomain = () => { - const domain = this.props.account.get('acct').split('@')[1]; - - if (!domain) return; - - this.props.onBlockDomain(domain); + this.props.onBlockDomain(this.props.account); }; handleUnblockDomain = () => { diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx b/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx index 84a303c37a..73fd62841b 100644 --- a/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx +++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.jsx @@ -17,11 +17,10 @@ import { mentionCompose, directCompose, } from '../../../actions/compose'; -import { blockDomain, unblockDomain } from '../../../actions/domain_blocks'; +import { initDomainBlockModal, unblockDomain } from '../../../actions/domain_blocks'; import { openModal } from '../../../actions/modal'; import { initMuteModal } from '../../../actions/mutes'; import { initReport } from '../../../actions/reports'; -import { unfollowModal } from '../../../initial_state'; import { makeGetAccount, getAccountHidden } from '../../../selectors'; import Header from '../components/header'; @@ -47,31 +46,23 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ onFollow (account) { if (account.getIn(['relationship', 'following'])) { - if (unfollowModal) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }, - })); - } else { - dispatch(unfollowAccount(account.get('id'))); - } + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.unfollowConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, + })); } else if (account.getIn(['relationship', 'requested'])) { - if (unfollowModal) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }, - })); - } else { - dispatch(unfollowAccount(account.get('id'))); - } + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, + })); } else { dispatch(followAccount(account.get('id'))); } @@ -140,15 +131,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, - onBlockDomain (domain) { - dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: {domain} }} />, - confirm: intl.formatMessage(messages.blockDomainConfirm), - onConfirm: () => dispatch(blockDomain(domain)), - }, - })); + onBlockDomain (account) { + dispatch(initDomainBlockModal(account)); }, onUnblockDomain (domain) { diff --git a/app/javascript/mastodon/features/account_timeline/index.jsx b/app/javascript/mastodon/features/account_timeline/index.jsx index 5ec029593d..dc69f83e77 100644 --- a/app/javascript/mastodon/features/account_timeline/index.jsx +++ b/app/javascript/mastodon/features/account_timeline/index.jsx @@ -133,7 +133,7 @@ class AccountTimeline extends ImmutablePureComponent { } if (prevProps.accountId === me && accountId !== me) { - dispatch(disconnectTimeline(`account:${me}`)); + dispatch(disconnectTimeline({ timeline: `account:${me}` })); } } @@ -141,7 +141,7 @@ class AccountTimeline extends ImmutablePureComponent { const { dispatch, accountId } = this.props; if (accountId === me) { - dispatch(disconnectTimeline(`account:${me}`)); + dispatch(disconnectTimeline({ timeline: `account:${me}` })); } } @@ -199,6 +199,7 @@ class AccountTimeline extends ImmutablePureComponent { emptyMessage={emptyMessage} bindToDocument={!multiColumn} timelineId='account' + withCounters /> ); diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx b/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx index 69959c1760..15381b589d 100644 --- a/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx +++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.jsx @@ -20,7 +20,7 @@ class ColumnSettings extends PureComponent { const { settings, onChange } = this.props; return ( -
+
} />
diff --git a/app/javascript/mastodon/features/community_timeline/index.jsx b/app/javascript/mastodon/features/community_timeline/index.jsx index 0aa1f9aa23..5652ea5327 100644 --- a/app/javascript/mastodon/features/community_timeline/index.jsx +++ b/app/javascript/mastodon/features/community_timeline/index.jsx @@ -9,6 +9,7 @@ import { connect } from 'react-redux'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; import { DismissableBanner } from 'mastodon/components/dismissable_banner'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { domain } from 'mastodon/initial_state'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; @@ -38,16 +39,12 @@ const mapStateToProps = (state, { columnId }) => { }; class CommunityTimeline extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static defaultProps = { onlyMedia: false, }; static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, columnId: PropTypes.string, intl: PropTypes.object.isRequired, @@ -77,7 +74,7 @@ class CommunityTimeline extends PureComponent { componentDidMount () { const { dispatch, onlyMedia } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; dispatch(expandCommunityTimeline({ onlyMedia })); @@ -87,7 +84,7 @@ class CommunityTimeline extends PureComponent { } componentDidUpdate (prevProps) { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (prevProps.onlyMedia !== this.props.onlyMedia) { const { dispatch, onlyMedia } = this.props; @@ -161,4 +158,4 @@ class CommunityTimeline extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(CommunityTimeline)); +export default withIdentity(connect(mapStateToProps)(injectIntl(CommunityTimeline))); diff --git a/app/javascript/mastodon/features/compose/components/compose_form.jsx b/app/javascript/mastodon/features/compose/components/compose_form.jsx index b93bac9d19..9b4d3dfeb5 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.jsx +++ b/app/javascript/mastodon/features/compose/components/compose_form.jsx @@ -21,7 +21,6 @@ import PollButtonContainer from '../containers/poll_button_container'; import PrivacyDropdownContainer from '../containers/privacy_dropdown_container'; import SpoilerButtonContainer from '../containers/spoiler_button_container'; import UploadButtonContainer from '../containers/upload_button_container'; -import UploadFormContainer from '../containers/upload_form_container'; import WarningContainer from '../containers/warning_container'; import { countableText } from '../util/counter'; @@ -30,6 +29,7 @@ import { EditIndicator } from './edit_indicator'; import { NavigationBar } from './navigation_bar'; import { PollForm } from "./poll_form"; import { ReplyIndicator } from './reply_indicator'; +import { UploadForm } from './upload_form'; const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d'; @@ -283,7 +283,7 @@ class ComposeForm extends ImmutablePureComponent { />
- +
diff --git a/app/javascript/mastodon/features/compose/components/edit_indicator.jsx b/app/javascript/mastodon/features/compose/components/edit_indicator.jsx index 6cdaaebea5..cc37d2d7d8 100644 --- a/app/javascript/mastodon/features/compose/components/edit_indicator.jsx +++ b/app/javascript/mastodon/features/compose/components/edit_indicator.jsx @@ -6,9 +6,9 @@ import { Link } from 'react-router-dom'; import { useDispatch, useSelector } from 'react-redux'; -import BarChart4BarsIcon from 'mastodon/../material-icons/400-24px/bar_chart_4_bars.svg?react'; -import CloseIcon from 'mastodon/../material-icons/400-24px/close.svg?react'; -import PhotoLibraryIcon from 'mastodon/../material-icons/400-24px/photo_library.svg?react'; +import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; import { cancelReplyCompose } from 'mastodon/actions/compose'; import { Icon } from 'mastodon/components/icon'; import { IconButton } from 'mastodon/components/icon_button'; diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx index 37017f4cc3..43795d030f 100644 --- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx +++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.jsx @@ -10,7 +10,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { supportsPassiveEvents } from 'detect-passive-events'; import Overlay from 'react-overlays/Overlay'; -import MoodIcon from 'mastodon/../material-icons/400-24px/mood.svg?react'; +import MoodIcon from '@/material-icons/400-20px/mood.svg?react'; import { IconButton } from 'mastodon/components/icon_button'; import { assetHost } from 'mastodon/utils/config'; @@ -330,6 +330,7 @@ class EmojiPickerDropdown extends PureComponent { state = { active: false, loading: false, + placement: 'bottom', }; setRef = (c) => { @@ -381,10 +382,14 @@ class EmojiPickerDropdown extends PureComponent { return this.target; }; + handleOverlayEnter = (state) => { + this.setState({ placement: state.placement }); + }; + render () { const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis } = this.props; const title = intl.formatMessage(messages.emoji); - const { active, loading } = this.state; + const { active, loading, placement } = this.state; return (
@@ -397,7 +402,7 @@ class EmojiPickerDropdown extends PureComponent { inverted /> - + {({ props, placement })=> (
diff --git a/app/javascript/mastodon/features/compose/components/language_dropdown.jsx b/app/javascript/mastodon/features/compose/components/language_dropdown.jsx index 2783ca8be2..47e81cf134 100644 --- a/app/javascript/mastodon/features/compose/components/language_dropdown.jsx +++ b/app/javascript/mastodon/features/compose/components/language_dropdown.jsx @@ -9,9 +9,9 @@ import { supportsPassiveEvents } from 'detect-passive-events'; import fuzzysort from 'fuzzysort'; import Overlay from 'react-overlays/Overlay'; -import CancelIcon from 'mastodon/../material-icons/400-24px/cancel-fill.svg?react'; -import SearchIcon from 'mastodon/../material-icons/400-24px/search.svg?react'; -import TranslateIcon from 'mastodon/../material-icons/400-24px/translate.svg?react'; +import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react'; +import SearchIcon from '@/material-icons/400-24px/search.svg?react'; +import TranslateIcon from '@/material-icons/400-24px/translate.svg?react'; import { Icon } from 'mastodon/components/icon'; import { languages as preloadedLanguages } from 'mastodon/initial_state'; @@ -110,18 +110,6 @@ class LanguageDropdownMenu extends PureComponent { }).map(result => result.obj); } - frequentlyUsed () { - const { languages, value } = this.props; - const current = languages.find(lang => lang[0] === value); - const results = []; - - if (current) { - results.push(current); - } - - return results; - } - handleClick = e => { const value = e.currentTarget.getAttribute('data-index'); @@ -141,6 +129,7 @@ class LanguageDropdownMenu extends PureComponent { case 'Escape': onClose(); break; + case ' ': case 'Enter': this.handleClick(e); break; diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.jsx b/app/javascript/mastodon/features/compose/components/navigation_bar.jsx index ebf59e4c83..ec5578eef3 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.jsx +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.jsx @@ -4,7 +4,7 @@ import { useIntl, defineMessages } from 'react-intl'; import { useSelector, useDispatch } from 'react-redux'; -import CloseIcon from 'mastodon/../material-icons/400-24px/close.svg?react'; +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import { cancelReplyCompose } from 'mastodon/actions/compose'; import Account from 'mastodon/components/account'; import { IconButton } from 'mastodon/components/icon_button'; diff --git a/app/javascript/mastodon/features/compose/components/poll_button.jsx b/app/javascript/mastodon/features/compose/components/poll_button.jsx index 345497abd3..cbaa25cb3c 100644 --- a/app/javascript/mastodon/features/compose/components/poll_button.jsx +++ b/app/javascript/mastodon/features/compose/components/poll_button.jsx @@ -3,7 +3,7 @@ import { PureComponent } from 'react'; import { defineMessages, injectIntl } from 'react-intl'; -import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react'; +import BarChart4BarsIcon from '@/material-icons/400-20px/bar_chart_4_bars.svg?react'; import { IconButton } from '../../../components/icon_button'; diff --git a/app/javascript/mastodon/features/compose/components/poll_form.jsx b/app/javascript/mastodon/features/compose/components/poll_form.jsx index b3566fd6f5..d2adc58cc0 100644 --- a/app/javascript/mastodon/features/compose/components/poll_form.jsx +++ b/app/javascript/mastodon/features/compose/components/poll_form.jsx @@ -58,10 +58,11 @@ const Option = ({ multipleChoice, index, title, autoFocus }) => { const dispatch = useDispatch(); const suggestions = useSelector(state => state.getIn(['compose', 'suggestions'])); const lang = useSelector(state => state.getIn(['compose', 'language'])); + const maxOptions = useSelector(state => state.getIn(['server', 'server', 'configuration', 'polls', 'max_options'])); const handleChange = useCallback(({ target: { value } }) => { - dispatch(changePollOption(index, value)); - }, [dispatch, index]); + dispatch(changePollOption(index, value, maxOptions)); + }, [dispatch, index, maxOptions]); const handleSuggestionsFetchRequested = useCallback(token => { dispatch(fetchComposeSuggestions(token)); diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx index 82f9027388..071f0a6fab 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.jsx @@ -5,16 +5,16 @@ import { injectIntl, defineMessages } from 'react-intl'; import classNames from 'classnames'; -import { supportsPassiveEvents } from 'detect-passive-events'; import Overlay from 'react-overlays/Overlay'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; -import InfoIcon from '@/material-icons/400-24px/info.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react'; import { Icon } from 'mastodon/components/icon'; +import { PrivacyDropdownMenu } from './privacy_dropdown_menu'; + const messages = defineMessages({ public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' }, @@ -28,126 +28,6 @@ const messages = defineMessages({ unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' }, }); -const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true; - -class PrivacyDropdownMenu extends PureComponent { - - static propTypes = { - style: PropTypes.object, - items: PropTypes.array.isRequired, - value: PropTypes.string.isRequired, - onClose: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - }; - - handleDocumentClick = e => { - if (this.node && !this.node.contains(e.target)) { - this.props.onClose(); - e.stopPropagation(); - } - }; - - handleKeyDown = e => { - const { items } = this.props; - const value = e.currentTarget.getAttribute('data-index'); - const index = items.findIndex(item => { - return (item.value === value); - }); - let element = null; - - switch(e.key) { - case 'Escape': - this.props.onClose(); - break; - case 'Enter': - this.handleClick(e); - break; - case 'ArrowDown': - element = this.node.childNodes[index + 1] || this.node.firstChild; - break; - case 'ArrowUp': - element = this.node.childNodes[index - 1] || this.node.lastChild; - break; - case 'Tab': - if (e.shiftKey) { - element = this.node.childNodes[index - 1] || this.node.lastChild; - } else { - element = this.node.childNodes[index + 1] || this.node.firstChild; - } - break; - case 'Home': - element = this.node.firstChild; - break; - case 'End': - element = this.node.lastChild; - break; - } - - if (element) { - element.focus(); - this.props.onChange(element.getAttribute('data-index')); - e.preventDefault(); - e.stopPropagation(); - } - }; - - handleClick = e => { - const value = e.currentTarget.getAttribute('data-index'); - - e.preventDefault(); - - this.props.onClose(); - this.props.onChange(value); - }; - - componentDidMount () { - document.addEventListener('click', this.handleDocumentClick, { capture: true }); - document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); - if (this.focusedItem) this.focusedItem.focus({ preventScroll: true }); - } - - componentWillUnmount () { - document.removeEventListener('click', this.handleDocumentClick, { capture: true }); - document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); - } - - setRef = c => { - this.node = c; - }; - - setFocusRef = c => { - this.focusedItem = c; - }; - - render () { - const { style, items, value } = this.props; - - return ( -
- {items.map(item => ( -
-
- -
- -
- {item.text} - {item.meta} -
- - {item.extra && ( -
- -
- )} -
- ))} -
- ); - } - -} - class PrivacyDropdown extends PureComponent { static propTypes = { diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown_menu.jsx b/app/javascript/mastodon/features/compose/components/privacy_dropdown_menu.jsx new file mode 100644 index 0000000000..1a5ff1fa80 --- /dev/null +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown_menu.jsx @@ -0,0 +1,128 @@ +import PropTypes from 'prop-types'; +import { useCallback, useEffect, useRef, useState } from 'react'; + +import classNames from 'classnames'; + +import { supportsPassiveEvents } from 'detect-passive-events'; + +import InfoIcon from '@/material-icons/400-24px/info.svg?react'; +import { Icon } from 'mastodon/components/icon'; + +const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true; + +export const PrivacyDropdownMenu = ({ style, items, value, onClose, onChange }) => { + const nodeRef = useRef(null); + const focusedItemRef = useRef(null); + const [currentValue, setCurrentValue] = useState(value); + + const handleDocumentClick = useCallback((e) => { + if (nodeRef.current && !nodeRef.current.contains(e.target)) { + onClose(); + e.stopPropagation(); + } + }, [nodeRef, onClose]); + + const handleClick = useCallback((e) => { + const value = e.currentTarget.getAttribute('data-index'); + + e.preventDefault(); + + onClose(); + onChange(value); + }, [onClose, onChange]); + + const handleKeyDown = useCallback((e) => { + const value = e.currentTarget.getAttribute('data-index'); + const index = items.findIndex(item => (item.value === value)); + + let element = null; + + switch (e.key) { + case 'Escape': + onClose(); + break; + case ' ': + case 'Enter': + handleClick(e); + break; + case 'ArrowDown': + element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild; + break; + case 'ArrowUp': + element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild; + break; + case 'Tab': + if (e.shiftKey) { + element = nodeRef.current.childNodes[index + 1] || nodeRef.current.firstChild; + } else { + element = nodeRef.current.childNodes[index - 1] || nodeRef.current.lastChild; + } + break; + case 'Home': + element = nodeRef.current.firstChild; + break; + case 'End': + element = nodeRef.current.lastChild; + break; + } + + if (element) { + element.focus(); + setCurrentValue(element.getAttribute('data-index')); + e.preventDefault(); + e.stopPropagation(); + } + }, [nodeRef, items, onClose, handleClick, setCurrentValue]); + + useEffect(() => { + document.addEventListener('click', handleDocumentClick, { capture: true }); + document.addEventListener('touchend', handleDocumentClick, listenerOptions); + focusedItemRef.current?.focus({ preventScroll: true }); + + return () => { + document.removeEventListener('click', handleDocumentClick, { capture: true }); + document.removeEventListener('touchend', handleDocumentClick, listenerOptions); + }; + }, [handleDocumentClick]); + + return ( +
    + {items.map(item => ( +
  • +
    + +
    + +
    + {item.text} + {item.meta} +
    + + {item.extra && ( +
    + +
    + )} +
  • + ))} +
+ ); +}; + +PrivacyDropdownMenu.propTypes = { + style: PropTypes.object, + items: PropTypes.array.isRequired, + value: PropTypes.string.isRequired, + onClose: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, +}; diff --git a/app/javascript/mastodon/features/compose/components/search.jsx b/app/javascript/mastodon/features/compose/components/search.jsx index ca02c23fc4..7fa7ad248b 100644 --- a/app/javascript/mastodon/features/compose/components/search.jsx +++ b/app/javascript/mastodon/features/compose/components/search.jsx @@ -12,6 +12,7 @@ import CancelIcon from '@/material-icons/400-24px/cancel-fill.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react'; import { Icon } from 'mastodon/components/icon'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { domain, searchEnabled } from 'mastodon/initial_state'; import { HASHTAG_REGEX } from 'mastodon/utils/hashtags'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -33,12 +34,8 @@ const labelForRecentSearch = search => { }; class Search extends PureComponent { - - static contextTypes = { - identity: PropTypes.object.isRequired, - }; - static propTypes = { + identity: identityContextPropShape, value: PropTypes.string.isRequired, recent: ImmutablePropTypes.orderedSet, submitted: PropTypes.bool, @@ -276,7 +273,7 @@ class Search extends PureComponent { } _calculateOptions (value) { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const trimmedValue = value.trim(); const options = []; @@ -318,7 +315,7 @@ class Search extends PureComponent { render () { const { intl, value, submitted, recent } = this.props; const { expanded, options, selectedOption } = this.state; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const hasValue = value.length > 0 || submitted; @@ -402,4 +399,4 @@ class Search extends PureComponent { } -export default withRouter(injectIntl(Search)); +export default withRouter(withIdentity(injectIntl(Search))); diff --git a/app/javascript/mastodon/features/compose/components/search_results.jsx b/app/javascript/mastodon/features/compose/components/search_results.jsx index 694deea04e..6a482c8ec2 100644 --- a/app/javascript/mastodon/features/compose/components/search_results.jsx +++ b/app/javascript/mastodon/features/compose/components/search_results.jsx @@ -1,17 +1,16 @@ -import PropTypes from 'prop-types'; +import { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; -import SearchIcon from '@/material-icons/400-24px/search.svg?react'; import TagIcon from '@/material-icons/400-24px/tag.svg?react'; +import { expandSearch } from 'mastodon/actions/search'; import { Icon } from 'mastodon/components/icon'; import { LoadMore } from 'mastodon/components/load_more'; +import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import { SearchSection } from 'mastodon/features/explore/components/search_section'; +import { useAppDispatch, useAppSelector } from 'mastodon/store'; import { ImmutableHashtag as Hashtag } from '../../../components/hashtag'; import AccountContainer from '../../../containers/account_container'; @@ -27,67 +26,68 @@ const withoutLastResult = list => { } }; -class SearchResults extends ImmutablePureComponent { +export const SearchResults = () => { + const results = useAppSelector((state) => state.getIn(['search', 'results'])); + const isLoading = useAppSelector((state) => state.getIn(['search', 'isLoading'])); - static propTypes = { - results: ImmutablePropTypes.map.isRequired, - expandSearch: PropTypes.func.isRequired, - searchTerm: PropTypes.string, - }; + const dispatch = useAppDispatch(); - handleLoadMoreAccounts = () => this.props.expandSearch('accounts'); + const handleLoadMoreAccounts = useCallback(() => { + dispatch(expandSearch('accounts')); + }, [dispatch]); - handleLoadMoreStatuses = () => this.props.expandSearch('statuses'); + const handleLoadMoreStatuses = useCallback(() => { + dispatch(expandSearch('statuses')); + }, [dispatch]); - handleLoadMoreHashtags = () => this.props.expandSearch('hashtags'); + const handleLoadMoreHashtags = useCallback(() => { + dispatch(expandSearch('hashtags')); + }, [dispatch]); - render () { - const { results } = this.props; + let accounts, statuses, hashtags; - let accounts, statuses, hashtags; - - if (results.get('accounts') && results.get('accounts').size > 0) { - accounts = ( - }> - {withoutLastResult(results.get('accounts')).map(accountId => )} - {(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && } - - ); - } - - if (results.get('hashtags') && results.get('hashtags').size > 0) { - hashtags = ( - }> - {withoutLastResult(results.get('hashtags')).map(hashtag => )} - {(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && } - - ); - } - - if (results.get('statuses') && results.get('statuses').size > 0) { - statuses = ( - }> - {withoutLastResult(results.get('statuses')).map(statusId => )} - {(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && } - - ); - } - - - return ( -
-
- - -
- - {accounts} - {hashtags} - {statuses} -
+ if (results.get('accounts') && results.get('accounts').size > 0) { + accounts = ( + }> + {withoutLastResult(results.get('accounts')).map(accountId => )} + {(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && } + ); } -} + if (results.get('hashtags') && results.get('hashtags').size > 0) { + hashtags = ( + }> + {withoutLastResult(results.get('hashtags')).map(hashtag => )} + {(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && } + + ); + } -export default SearchResults; + if (results.get('statuses') && results.get('statuses').size > 0) { + statuses = ( + }> + {withoutLastResult(results.get('statuses')).map(statusId => )} + {(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && } + + ); + } + + return ( +
+ {!accounts && !hashtags && !statuses && ( + isLoading ? ( + + ) : ( +
+ +
+ ) + )} + {accounts} + {hashtags} + {statuses} +
+ ); + +}; diff --git a/app/javascript/mastodon/features/compose/components/upload.jsx b/app/javascript/mastodon/features/compose/components/upload.jsx index 861232d0ec..7f6ef6cfd8 100644 --- a/app/javascript/mastodon/features/compose/components/upload.jsx +++ b/app/javascript/mastodon/features/compose/components/upload.jsx @@ -1,77 +1,81 @@ import PropTypes from 'prop-types'; +import { useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import { useDispatch, useSelector } from 'react-redux'; import spring from 'react-motion/lib/spring'; -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import CloseIcon from '@/material-icons/400-20px/close.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import WarningIcon from '@/material-icons/400-24px/warning.svg?react'; +import { undoUploadCompose, initMediaEditModal } from 'mastodon/actions/compose'; import { Blurhash } from 'mastodon/components/blurhash'; import { Icon } from 'mastodon/components/icon'; +import Motion from 'mastodon/features/ui/util/optional_motion'; -import Motion from '../../ui/util/optional_motion'; +export const Upload = ({ id, onDragStart, onDragEnter, onDragEnd }) => { + const dispatch = useDispatch(); + const media = useSelector(state => state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id)); + const sensitive = useSelector(state => state.getIn(['compose', 'spoiler'])); -export default class Upload extends ImmutablePureComponent { + const handleUndoClick = useCallback(() => { + dispatch(undoUploadCompose(id)); + }, [dispatch, id]); - static propTypes = { - media: ImmutablePropTypes.map.isRequired, - sensitive: PropTypes.bool, - onUndo: PropTypes.func.isRequired, - onOpenFocalPoint: PropTypes.func.isRequired, - }; + const handleFocalPointClick = useCallback(() => { + dispatch(initMediaEditModal(id)); + }, [dispatch, id]); - handleUndoClick = e => { - e.stopPropagation(); - this.props.onUndo(this.props.media.get('id')); - }; + const handleDragStart = useCallback(() => { + onDragStart(id); + }, [onDragStart, id]); - handleFocalPointClick = e => { - e.stopPropagation(); - this.props.onOpenFocalPoint(this.props.media.get('id')); - }; + const handleDragEnter = useCallback(() => { + onDragEnter(id); + }, [onDragEnter, id]); - render () { - const { media, sensitive } = this.props; - - if (!media) { - return null; - } - - const focusX = media.getIn(['meta', 'focus', 'x']); - const focusY = media.getIn(['meta', 'focus', 'y']); - const x = ((focusX / 2) + .5) * 100; - const y = ((focusY / -2) + .5) * 100; - const missingDescription = (media.get('description') || '').length === 0; - - return ( -
- - {({ scale }) => ( -
- {sensitive && } - -
- - -
- -
- -
-
- )} -
-
- ); + if (!media) { + return null; } -} + const focusX = media.getIn(['meta', 'focus', 'x']); + const focusY = media.getIn(['meta', 'focus', 'y']); + const x = ((focusX / 2) + .5) * 100; + const y = ((focusY / -2) + .5) * 100; + const missingDescription = (media.get('description') || '').length === 0; + + return ( +
+ + {({ scale }) => ( +
+ {sensitive && } + +
+ + +
+ +
+ +
+
+ )} +
+
+ ); +}; + +Upload.propTypes = { + id: PropTypes.string, + onDragEnter: PropTypes.func, + onDragStart: PropTypes.func, + onDragEnd: PropTypes.func, +}; diff --git a/app/javascript/mastodon/features/compose/components/upload_button.jsx b/app/javascript/mastodon/features/compose/components/upload_button.jsx index 50c9ad6321..20fb20f092 100644 --- a/app/javascript/mastodon/features/compose/components/upload_button.jsx +++ b/app/javascript/mastodon/features/compose/components/upload_button.jsx @@ -6,7 +6,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; -import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react'; +import PhotoLibraryIcon from '@/material-icons/400-20px/photo_library.svg?react'; import { IconButton } from 'mastodon/components/icon_button'; const messages = defineMessages({ diff --git a/app/javascript/mastodon/features/compose/components/upload_form.jsx b/app/javascript/mastodon/features/compose/components/upload_form.jsx index 46bac7823b..adf5591382 100644 --- a/app/javascript/mastodon/features/compose/components/upload_form.jsx +++ b/app/javascript/mastodon/features/compose/components/upload_form.jsx @@ -1,31 +1,53 @@ -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; +import { useRef, useCallback } from 'react'; -import UploadContainer from '../containers/upload_container'; -import UploadProgressContainer from '../containers/upload_progress_container'; +import { useSelector, useDispatch } from 'react-redux'; -export default class UploadForm extends ImmutablePureComponent { +import { changeMediaOrder } from 'mastodon/actions/compose'; - static propTypes = { - mediaIds: ImmutablePropTypes.list.isRequired, - }; +import { Upload } from './upload'; +import { UploadProgress } from './upload_progress'; - render () { - const { mediaIds } = this.props; +export const UploadForm = () => { + const dispatch = useDispatch(); + const mediaIds = useSelector(state => state.getIn(['compose', 'media_attachments']).map(item => item.get('id'))); + const active = useSelector(state => state.getIn(['compose', 'is_uploading'])); + const progress = useSelector(state => state.getIn(['compose', 'progress'])); + const isProcessing = useSelector(state => state.getIn(['compose', 'is_processing'])); - return ( - <> - + const dragItem = useRef(); + const dragOverItem = useRef(); - {mediaIds.size > 0 && ( -
- {mediaIds.map(id => ( - - ))} -
- )} - - ); - } + const handleDragStart = useCallback(id => { + dragItem.current = id; + }, [dragItem]); -} + const handleDragEnter = useCallback(id => { + dragOverItem.current = id; + }, [dragOverItem]); + + const handleDragEnd = useCallback(() => { + dispatch(changeMediaOrder(dragItem.current, dragOverItem.current)); + dragItem.current = null; + dragOverItem.current = null; + }, [dispatch, dragItem, dragOverItem]); + + return ( + <> + + + {mediaIds.size > 0 && ( +
+ {mediaIds.map(id => ( + + ))} +
+ )} + + ); +}; diff --git a/app/javascript/mastodon/features/compose/components/upload_progress.jsx b/app/javascript/mastodon/features/compose/components/upload_progress.jsx index 1276cded1f..fd0c8f4530 100644 --- a/app/javascript/mastodon/features/compose/components/upload_progress.jsx +++ b/app/javascript/mastodon/features/compose/components/upload_progress.jsx @@ -1,5 +1,4 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; import { FormattedMessage } from 'react-intl'; @@ -10,46 +9,40 @@ import { Icon } from 'mastodon/components/icon'; import Motion from '../../ui/util/optional_motion'; -export default class UploadProgress extends PureComponent { - - static propTypes = { - active: PropTypes.bool, - progress: PropTypes.number, - isProcessing: PropTypes.bool, - }; - - render () { - const { active, progress, isProcessing } = this.props; - - if (!active) { - return null; - } - - let message; - - if (isProcessing) { - message = ; - } else { - message = ; - } - - return ( -
- - -
- {message} - -
- - {({ width }) => -
- } - -
-
-
- ); +export const UploadProgress = ({ active, progress, isProcessing }) => { + if (!active) { + return null; } -} + let message; + + if (isProcessing) { + message = ; + } else { + message = ; + } + + return ( +
+ + +
+ {message} + +
+ + {({ width }) => +
+ } + +
+
+
+ ); +}; + +UploadProgress.propTypes = { + active: PropTypes.bool, + progress: PropTypes.number, + isProcessing: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/compose/containers/search_results_container.js b/app/javascript/mastodon/features/compose/containers/search_results_container.js deleted file mode 100644 index 54c2af3177..0000000000 --- a/app/javascript/mastodon/features/compose/containers/search_results_container.js +++ /dev/null @@ -1,20 +0,0 @@ -import { connect } from 'react-redux'; - -import { expandSearch } from 'mastodon/actions/search'; -import { fetchSuggestions, dismissSuggestion } from 'mastodon/actions/suggestions'; - -import SearchResults from '../components/search_results'; - -const mapStateToProps = state => ({ - results: state.getIn(['search', 'results']), - suggestions: state.getIn(['suggestions', 'items']), - searchTerm: state.getIn(['search', 'searchTerm']), -}); - -const mapDispatchToProps = dispatch => ({ - fetchSuggestions: () => dispatch(fetchSuggestions()), - expandSearch: type => dispatch(expandSearch(type)), - dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(SearchResults); diff --git a/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js b/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js index a241417735..9acc43437b 100644 --- a/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/spoiler_button_container.js @@ -2,7 +2,7 @@ import { injectIntl, defineMessages } from 'react-intl'; import { connect } from 'react-redux'; -import WarningIcon from 'mastodon/../material-icons/400-24px/warning.svg?react'; +import WarningIcon from '@/material-icons/400-20px/warning.svg?react'; import { IconButton } from 'mastodon/components/icon_button'; import { changeComposeSpoilerness } from '../../../actions/compose'; diff --git a/app/javascript/mastodon/features/compose/containers/upload_button_container.js b/app/javascript/mastodon/features/compose/containers/upload_button_container.js index 7c4757b6c3..066e185346 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_button_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_button_container.js @@ -3,14 +3,24 @@ import { connect } from 'react-redux'; import { uploadCompose } from '../../../actions/compose'; import UploadButton from '../components/upload_button'; -const mapStateToProps = state => ({ - disabled: state.getIn(['compose', 'poll']) !== null || state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size + state.getIn(['compose', 'pending_media_attachments']) > 3 || state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type')))), - resetFileKey: state.getIn(['compose', 'resetFileKey']), -}); +const mapStateToProps = state => { + const isPoll = state.getIn(['compose', 'poll']) !== null; + const isUploading = state.getIn(['compose', 'is_uploading']); + const readyAttachmentsSize = state.getIn(['compose', 'media_attachments']).size ?? 0; + const pendingAttachmentsSize = state.getIn(['compose', 'pending_media_attachments']).size ?? 0; + const attachmentsSize = readyAttachmentsSize + pendingAttachmentsSize; + const isOverLimit = attachmentsSize > 3; + const hasVideoOrAudio = state.getIn(['compose', 'media_attachments']).some(m => ['video', 'audio'].includes(m.get('type'))); + + return { + disabled: isPoll || isUploading || isOverLimit || hasVideoOrAudio, + resetFileKey: state.getIn(['compose', 'resetFileKey']), + }; +}; const mapDispatchToProps = dispatch => ({ - onSelectFile (files) { + onSelectFile(files) { dispatch(uploadCompose(files)); }, diff --git a/app/javascript/mastodon/features/compose/containers/upload_container.js b/app/javascript/mastodon/features/compose/containers/upload_container.js deleted file mode 100644 index a17a691444..0000000000 --- a/app/javascript/mastodon/features/compose/containers/upload_container.js +++ /dev/null @@ -1,27 +0,0 @@ -import { connect } from 'react-redux'; - -import { undoUploadCompose, initMediaEditModal, submitCompose } from '../../../actions/compose'; -import Upload from '../components/upload'; - -const mapStateToProps = (state, { id }) => ({ - media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), - sensitive: state.getIn(['compose', 'spoiler']), -}); - -const mapDispatchToProps = dispatch => ({ - - onUndo: id => { - dispatch(undoUploadCompose(id)); - }, - - onOpenFocalPoint: id => { - dispatch(initMediaEditModal(id)); - }, - - onSubmit (router) { - dispatch(submitCompose(router)); - }, - -}); - -export default connect(mapStateToProps, mapDispatchToProps)(Upload); diff --git a/app/javascript/mastodon/features/compose/containers/upload_form_container.js b/app/javascript/mastodon/features/compose/containers/upload_form_container.js deleted file mode 100644 index 336525cf53..0000000000 --- a/app/javascript/mastodon/features/compose/containers/upload_form_container.js +++ /dev/null @@ -1,9 +0,0 @@ -import { connect } from 'react-redux'; - -import UploadForm from '../components/upload_form'; - -const mapStateToProps = state => ({ - mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')), -}); - -export default connect(mapStateToProps)(UploadForm); diff --git a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js b/app/javascript/mastodon/features/compose/containers/upload_progress_container.js deleted file mode 100644 index ffff321c3f..0000000000 --- a/app/javascript/mastodon/features/compose/containers/upload_progress_container.js +++ /dev/null @@ -1,11 +0,0 @@ -import { connect } from 'react-redux'; - -import UploadProgress from '../components/upload_progress'; - -const mapStateToProps = state => ({ - active: state.getIn(['compose', 'is_uploading']), - progress: state.getIn(['compose', 'progress']), - isProcessing: state.getIn(['compose', 'is_processing']), -}); - -export default connect(mapStateToProps)(UploadProgress); diff --git a/app/javascript/mastodon/features/compose/index.jsx b/app/javascript/mastodon/features/compose/index.jsx index ce8eb9e05d..83c741fd19 100644 --- a/app/javascript/mastodon/features/compose/index.jsx +++ b/app/javascript/mastodon/features/compose/index.jsx @@ -29,9 +29,9 @@ import { mascot } from '../../initial_state'; import { isMobile } from '../../is_mobile'; import Motion from '../ui/util/optional_motion'; +import { SearchResults } from './components/search_results'; import ComposeFormContainer from './containers/compose_form_container'; import SearchContainer from './containers/search_container'; -import SearchResultsContainer from './containers/search_results_container'; const messages = defineMessages({ start: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, @@ -138,7 +138,7 @@ class Compose extends PureComponent { {({ x }) => (
- +
)}
diff --git a/app/javascript/mastodon/features/directory/components/account_card.jsx b/app/javascript/mastodon/features/directory/components/account_card.jsx index ff1f8a653b..9c5e688120 100644 --- a/app/javascript/mastodon/features/directory/components/account_card.jsx +++ b/app/javascript/mastodon/features/directory/components/account_card.jsx @@ -20,7 +20,7 @@ import { Avatar } from 'mastodon/components/avatar'; import { Button } from 'mastodon/components/button'; import { DisplayName } from 'mastodon/components/display_name'; import { ShortNumber } from 'mastodon/components/short_number'; -import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state'; +import { autoPlayGif, me } from 'mastodon/initial_state'; import { makeGetAccount } from 'mastodon/selectors'; const messages = defineMessages({ @@ -48,38 +48,30 @@ const makeMapStateToProps = () => { const mapDispatchToProps = (dispatch, { intl }) => ({ onFollow(account) { if (account.getIn(['relationship', 'following'])) { - if (unfollowModal) { - dispatch( - openModal({ - modalType: 'CONFIRM', - modalProps: { - message: ( - @{account.get('acct')} }} - /> - ), - confirm: intl.formatMessage(messages.unfollowConfirm), - onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - } }), - ); - } else { - dispatch(unfollowAccount(account.get('id'))); - } - } else if (account.getIn(['relationship', 'requested'])) { - if (unfollowModal) { - dispatch(openModal({ + dispatch( + openModal({ modalType: 'CONFIRM', modalProps: { - message: @{account.get('acct')} }} />, - confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), + message: ( + @{account.get('acct')} }} + /> + ), + confirm: intl.formatMessage(messages.unfollowConfirm), onConfirm: () => dispatch(unfollowAccount(account.get('id'))), - }, - })); - } else { - dispatch(unfollowAccount(account.get('id'))); - } + } }), + ); + } else if (account.getIn(['relationship', 'requested'])) { + dispatch(openModal({ + modalType: 'CONFIRM', + modalProps: { + message: @{account.get('acct')} }} />, + confirm: intl.formatMessage(messages.cancelFollowRequestConfirm), + onConfirm: () => dispatch(unfollowAccount(account.get('id'))), + }, + })); } else { dispatch(followAccount(account.get('id'))); } diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js index 7b917ac43b..9d6ff5226a 100644 --- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js +++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js @@ -22,23 +22,23 @@ describe('emoji', () => { it('does unicode', () => { expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual( - '๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ'); + '๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆโ€๐Ÿ‘ฆ'); expect(emojify('๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง')).toEqual( - '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง'); - expect(emojify('๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ')).toEqual('๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ'); + '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ง'); + expect(emojify('๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ')).toEqual('๐Ÿ‘ฉโ€๐Ÿ‘ฉโ€๐Ÿ‘ฆ'); expect(emojify('\u2757')).toEqual( - 'โ—'); + 'โ—'); }); it('does multiple unicode', () => { expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual( - 'โ— #๏ธโƒฃ'); + 'โ— #๏ธโƒฃ'); expect(emojify('\u2757#\uFE0F\u20E3')).toEqual( - 'โ—#๏ธโƒฃ'); + 'โ—#๏ธโƒฃ'); expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual( - 'โ— #๏ธโƒฃ โ—'); + 'โ— #๏ธโƒฃ โ—'); expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual( - 'foo โ— #๏ธโƒฃ bar'); + 'foo โ— #๏ธโƒฃ bar'); }); it('ignores unicode inside of tags', () => { @@ -46,16 +46,16 @@ describe('emoji', () => { }); it('does multiple emoji properly (issue 5188)', () => { - expect(emojify('๐Ÿ‘Œ๐ŸŒˆ๐Ÿ’•')).toEqual('๐Ÿ‘Œ๐ŸŒˆ๐Ÿ’•'); - expect(emojify('๐Ÿ‘Œ ๐ŸŒˆ ๐Ÿ’•')).toEqual('๐Ÿ‘Œ ๐ŸŒˆ ๐Ÿ’•'); + expect(emojify('๐Ÿ‘Œ๐ŸŒˆ๐Ÿ’•')).toEqual('๐Ÿ‘Œ๐ŸŒˆ๐Ÿ’•'); + expect(emojify('๐Ÿ‘Œ ๐ŸŒˆ ๐Ÿ’•')).toEqual('๐Ÿ‘Œ ๐ŸŒˆ ๐Ÿ’•'); }); it('does an emoji that has no shortcode', () => { - expect(emojify('๐Ÿ‘โ€๐Ÿ—จ')).toEqual('๐Ÿ‘โ€๐Ÿ—จ'); + expect(emojify('๐Ÿ‘โ€๐Ÿ—จ')).toEqual('๐Ÿ‘โ€๐Ÿ—จ'); }); it('does an emoji whose filename is irregular', () => { - expect(emojify('โ†™๏ธ')).toEqual('โ†™๏ธ'); + expect(emojify('โ†™๏ธ')).toEqual('โ†™๏ธ'); }); it('avoid emojifying on invisible text', () => { @@ -67,11 +67,11 @@ describe('emoji', () => { it('avoid emojifying on invisible text with nested tags', () => { expect(emojify('๐Ÿ˜‡')) - .toEqual('๐Ÿ˜‡'); + .toEqual('๐Ÿ˜‡'); expect(emojify('๐Ÿ˜‡')) - .toEqual('๐Ÿ˜‡'); + .toEqual('๐Ÿ˜‡'); expect(emojify('๐Ÿ˜‡')) - .toEqual('๐Ÿ˜‡'); + .toEqual('๐Ÿ˜‡'); }); it('does not emojify emojis with textual presentation VS15 character', () => { @@ -79,19 +79,19 @@ describe('emoji', () => { .toEqual('โœด๏ธŽ'); }); - it('does an simple emoji properly', () => { + it('does a simple emoji properly', () => { expect(emojify('โ™€โ™‚')) - .toEqual('โ™€โ™‚'); + .toEqual('โ™€โ™‚'); }); it('does an emoji containing ZWJ properly', () => { expect(emojify('๐Ÿ’‚โ€โ™€๏ธ๐Ÿ’‚โ€โ™‚๏ธ')) - .toEqual('๐Ÿ’‚\u200Dโ™€๏ธ๐Ÿ’‚\u200Dโ™‚๏ธ'); + .toEqual('๐Ÿ’‚\u200Dโ™€๏ธ๐Ÿ’‚\u200Dโ™‚๏ธ'); }); it('keeps ordering as expected (issue fixed by PR 20677)', () => { expect(emojify('

๐Ÿ’• #foo test: foo.

')) - .toEqual('

๐Ÿ’• #foo test: foo.

'); + .toEqual('

๐Ÿ’• #foo test: foo.

'); }); }); }); diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index 5918a65ed7..e4aad302f6 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -17,8 +17,13 @@ const emojiFilenames = (emojis) => { const darkEmoji = emojiFilenames(['๐ŸŽฑ', '๐Ÿœ', 'โšซ', '๐Ÿ–ค', 'โฌ›', 'โ—ผ๏ธ', 'โ—พ', 'โ—ผ๏ธ', 'โœ’๏ธ', 'โ–ช๏ธ', '๐Ÿ’ฃ', '๐ŸŽณ', '๐Ÿ“ท', '๐Ÿ“ธ', 'โ™ฃ๏ธ', '๐Ÿ•ถ๏ธ', 'โœด๏ธ', '๐Ÿ”Œ', '๐Ÿ’‚โ€โ™€๏ธ', '๐Ÿ“ฝ๏ธ', '๐Ÿณ', '๐Ÿฆ', '๐Ÿ’‚', '๐Ÿ”ช', '๐Ÿ•ณ๏ธ', '๐Ÿ•น๏ธ', '๐Ÿ•‹', '๐Ÿ–Š๏ธ', '๐Ÿ–‹๏ธ', '๐Ÿ’‚โ€โ™‚๏ธ', '๐ŸŽค', '๐ŸŽ“', '๐ŸŽฅ', '๐ŸŽผ', 'โ™ ๏ธ', '๐ŸŽฉ', '๐Ÿฆƒ', '๐Ÿ“ผ', '๐Ÿ“น', '๐ŸŽฎ', '๐Ÿƒ', '๐Ÿด', '๐Ÿž', '๐Ÿ•บ', '๐Ÿ“ฑ', '๐Ÿ“ฒ', '๐Ÿšฒ', '๐Ÿชฎ', '๐Ÿฆโ€โฌ›']); const lightEmoji = emojiFilenames(['๐Ÿ‘ฝ', 'โšพ', '๐Ÿ”', 'โ˜๏ธ', '๐Ÿ’จ', '๐Ÿ•Š๏ธ', '๐Ÿ‘€', '๐Ÿฅ', '๐Ÿ‘ป', '๐Ÿ', 'โ•', 'โ”', 'โ›ธ๏ธ', '๐ŸŒฉ๏ธ', '๐Ÿ”Š', '๐Ÿ”‡', '๐Ÿ“ƒ', '๐ŸŒง๏ธ', '๐Ÿ', '๐Ÿš', '๐Ÿ™', '๐Ÿ“', '๐Ÿ‘', '๐Ÿ’€', 'โ˜ ๏ธ', '๐ŸŒจ๏ธ', '๐Ÿ”‰', '๐Ÿ”ˆ', '๐Ÿ’ฌ', '๐Ÿ’ญ', '๐Ÿ', '๐Ÿณ๏ธ', 'โšช', 'โฌœ', 'โ—ฝ', 'โ—ป๏ธ', 'โ–ซ๏ธ', '๐Ÿชฝ', '๐Ÿชฟ']); -const emojiFilename = (filename) => { - const borderedEmoji = (document.body && document.body.classList.contains('theme-mastodon-light')) ? lightEmoji : darkEmoji; +/** + * @param {string} filename + * @param {"light" | "dark" } colorScheme + * @returns {string} + */ +const emojiFilename = (filename, colorScheme) => { + const borderedEmoji = colorScheme === "light" ? lightEmoji : darkEmoji; return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; @@ -92,12 +97,30 @@ const emojifyTextNode = (node, customEmojis) => { const { filename, shortCode } = unicodeMapping[unicode_emoji]; const title = shortCode ? `:${shortCode}:` : ''; - replacement = document.createElement('img'); - replacement.setAttribute('draggable', 'false'); - replacement.setAttribute('class', 'emojione'); - replacement.setAttribute('alt', unicode_emoji); - replacement.setAttribute('title', title); - replacement.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename)}.svg`); + replacement = document.createElement('picture'); + + const isSystemTheme = !!document.body?.classList.contains('theme-system'); + + if(isSystemTheme) { + let source = document.createElement('source'); + source.setAttribute('media', '(prefers-color-scheme: dark)'); + source.setAttribute('srcset', `${assetHost}/emoji/${emojiFilename(filename, "dark")}.svg`); + replacement.appendChild(source); + } + + let img = document.createElement('img'); + img.setAttribute('draggable', 'false'); + img.setAttribute('class', 'emojione'); + img.setAttribute('alt', unicode_emoji); + img.setAttribute('title', title); + + let theme = "light"; + + if(!isSystemTheme && !document.body?.classList.contains('theme-mastodon-light')) + theme = "dark"; + + img.setAttribute('src', `${assetHost}/emoji/${emojiFilename(filename, theme)}.svg`); + replacement.appendChild(img); } // Add the processed-up-to-now string and the emoji replacement diff --git a/app/javascript/mastodon/features/emoji/emoji_compressed.js b/app/javascript/mastodon/features/emoji/emoji_compressed.js index a4863566da..ed8e9bbe30 100644 --- a/app/javascript/mastodon/features/emoji/emoji_compressed.js +++ b/app/javascript/mastodon/features/emoji/emoji_compressed.js @@ -36,7 +36,7 @@ Object.keys(emojiIndex.emojis).forEach(key => { let emoji = emojiIndex.emojis[key]; // Emojis with skin tone modifiers are stored like this - if (Object.prototype.hasOwnProperty.call(emoji, '1')) { + if (Object.hasOwn(emoji, '1')) { emoji = emoji['1']; } @@ -88,7 +88,7 @@ Object.keys(emojiIndex.emojis).forEach(key => { let emoji = emojiIndex.emojis[key]; // Emojis with skin tone modifiers are stored like this - if (Object.prototype.hasOwnProperty.call(emoji, '1')) { + if (Object.hasOwn(emoji, '1')) { emoji = emoji['1']; } diff --git a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts index ffca1f8b06..806a3f8927 100644 --- a/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts +++ b/app/javascript/mastodon/features/emoji/emoji_mart_data_light.ts @@ -29,7 +29,10 @@ const emojis: Emojis = {}; // decompress Object.keys(shortCodesToEmojiData).forEach((shortCode) => { - const [_filenameData, searchData] = shortCodesToEmojiData[shortCode]; + const emojiData = shortCodesToEmojiData[shortCode]; + if (!emojiData) return; + + const [_filenameData, searchData] = emojiData; const [native, short_names, search, unified] = searchData; emojis[shortCode] = { diff --git a/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts b/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts index 191419496f..d116c6c62c 100644 --- a/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts +++ b/app/javascript/mastodon/features/emoji/emoji_unicode_mapping_light.ts @@ -46,7 +46,10 @@ function processEmojiMapData( Object.keys(shortCodesToEmojiData).forEach( (shortCode: ShortCodesToEmojiDataKey) => { if (shortCode === undefined) return; - const [filenameData, _searchData] = shortCodesToEmojiData[shortCode]; + + const emojiData = shortCodesToEmojiData[shortCode]; + if (!emojiData) return; + const [filenameData, _searchData] = emojiData; filenameData.forEach((emojiMapData) => { processEmojiMapData(emojiMapData, shortCode); }); diff --git a/app/javascript/mastodon/features/emoji/emoji_utils.js b/app/javascript/mastodon/features/emoji/emoji_utils.js index 83bcc9d82f..c13d250567 100644 --- a/app/javascript/mastodon/features/emoji/emoji_utils.js +++ b/app/javascript/mastodon/features/emoji/emoji_utils.js @@ -135,19 +135,19 @@ function getData(emoji, skin, set) { } } - if (Object.prototype.hasOwnProperty.call(data.short_names, emoji)) { + if (Object.hasOwn(data.short_names, emoji)) { emoji = data.short_names[emoji]; } - if (Object.prototype.hasOwnProperty.call(data.emojis, emoji)) { + if (Object.hasOwn(data.emojis, emoji)) { emojiData = data.emojis[emoji]; } } else if (emoji.id) { - if (Object.prototype.hasOwnProperty.call(data.short_names, emoji.id)) { + if (Object.hasOwn(data.short_names, emoji.id)) { emoji.id = data.short_names[emoji.id]; } - if (Object.prototype.hasOwnProperty.call(data.emojis, emoji.id)) { + if (Object.hasOwn(data.emojis, emoji.id)) { emojiData = data.emojis[emoji.id]; skin = skin || emoji.skin; } @@ -216,7 +216,7 @@ function deepMerge(a, b) { let originalValue = a[key], value = originalValue; - if (Object.prototype.hasOwnProperty.call(b, key)) { + if (Object.hasOwn(b, key)) { value = b[key]; } diff --git a/app/javascript/mastodon/features/explore/components/author_link.jsx b/app/javascript/mastodon/features/explore/components/author_link.jsx new file mode 100644 index 0000000000..b9dec3367e --- /dev/null +++ b/app/javascript/mastodon/features/explore/components/author_link.jsx @@ -0,0 +1,21 @@ +import PropTypes from 'prop-types'; + +import { Link } from 'react-router-dom'; + +import { Avatar } from 'mastodon/components/avatar'; +import { useAppSelector } from 'mastodon/store'; + +export const AuthorLink = ({ accountId }) => { + const account = useAppSelector(state => state.getIn(['accounts', accountId])); + + return ( + + + + + ); +}; + +AuthorLink.propTypes = { + accountId: PropTypes.string.isRequired, +}; diff --git a/app/javascript/mastodon/features/explore/components/card.jsx b/app/javascript/mastodon/features/explore/components/card.jsx new file mode 100644 index 0000000000..316203060a --- /dev/null +++ b/app/javascript/mastodon/features/explore/components/card.jsx @@ -0,0 +1,88 @@ +import PropTypes from 'prop-types'; +import { useCallback } from 'react'; + +import { FormattedMessage, useIntl, defineMessages } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import { useDispatch, useSelector } from 'react-redux'; + +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { followAccount, unfollowAccount } from 'mastodon/actions/accounts'; +import { dismissSuggestion } from 'mastodon/actions/suggestions'; +import { Avatar } from 'mastodon/components/avatar'; +import { Button } from 'mastodon/components/button'; +import { DisplayName } from 'mastodon/components/display_name'; +import { IconButton } from 'mastodon/components/icon_button'; +import { domain } from 'mastodon/initial_state'; + +const messages = defineMessages({ + follow: { id: 'account.follow', defaultMessage: 'Follow' }, + unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, + dismiss: { id: 'follow_suggestions.dismiss', defaultMessage: "Don't show again" }, +}); + +export const Card = ({ id, source }) => { + const intl = useIntl(); + const account = useSelector(state => state.getIn(['accounts', id])); + const relationship = useSelector(state => state.getIn(['relationships', id])); + const dispatch = useDispatch(); + const following = relationship?.get('following') ?? relationship?.get('requested'); + + const handleFollow = useCallback(() => { + if (following) { + dispatch(unfollowAccount(id)); + } else { + dispatch(followAccount(id)); + } + }, [id, following, dispatch]); + + const handleDismiss = useCallback(() => { + dispatch(dismissSuggestion(id)); + }, [id, dispatch]); + + let label; + + switch (source) { + case 'friends_of_friends': + label = ; + break; + case 'similar_to_recently_followed': + label = ; + break; + case 'featured': + label = ; + break; + case 'most_followed': + label = ; + break; + case 'most_interactions': + label = ; + break; + } + + return ( +
+
+ {label} +
+ +
+ + +
+
+ + +
+
+
+
+ ); +}; + +Card.propTypes = { + id: PropTypes.string.isRequired, + source: PropTypes.oneOf(['friends_of_friends', 'similar_to_recently_followed', 'featured', 'most_followed', 'most_interactions']), +}; diff --git a/app/javascript/mastodon/features/explore/components/story.jsx b/app/javascript/mastodon/features/explore/components/story.jsx index 80dd5200fc..a2cae942d4 100644 --- a/app/javascript/mastodon/features/explore/components/story.jsx +++ b/app/javascript/mastodon/features/explore/components/story.jsx @@ -1,61 +1,89 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; +import { useState, useCallback } from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; + import { Blurhash } from 'mastodon/components/blurhash'; -import { accountsCountRenderer } from 'mastodon/components/hashtag'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { ShortNumber } from 'mastodon/components/short_number'; import { Skeleton } from 'mastodon/components/skeleton'; -export default class Story extends PureComponent { +import { AuthorLink } from './author_link'; - static propTypes = { - url: PropTypes.string, - title: PropTypes.string, - lang: PropTypes.string, - publisher: PropTypes.string, - publishedAt: PropTypes.string, - author: PropTypes.string, - sharedTimes: PropTypes.number, - thumbnail: PropTypes.string, - thumbnailDescription: PropTypes.string, - blurhash: PropTypes.string, - expanded: PropTypes.bool, - }; +const sharesCountRenderer = (displayNumber, pluralReady) => ( + {displayNumber}, + }} + /> +); - state = { - thumbnailLoaded: false, - }; +export const Story = ({ + url, + title, + lang, + publisher, + publishedAt, + author, + authorAccount, + sharedTimes, + thumbnail, + thumbnailDescription, + blurhash, + expanded +}) => { + const [thumbnailLoaded, setThumbnailLoaded] = useState(false); - handleImageLoad = () => this.setState({ thumbnailLoaded: true }); + const handleImageLoad = useCallback(() => { + setThumbnailLoaded(true); + }, [setThumbnailLoaded]); - render () { - const { expanded, url, title, lang, publisher, author, publishedAt, sharedTimes, thumbnail, thumbnailDescription, blurhash } = this.props; - - const { thumbnailLoaded } = this.state; - - return ( - -
-
{publisher ? {publisher} : }{publishedAt && <> ยท }
-
{title ? title : }
-
{author && <>{author} }} /> ยท }{typeof sharedTimes === 'number' ? : }
+ return ( +
+ + ); +}; -} +Story.propTypes = { + url: PropTypes.string, + title: PropTypes.string, + lang: PropTypes.string, + publisher: PropTypes.string, + publishedAt: PropTypes.string, + author: PropTypes.string, + authorAccount: PropTypes.string, + sharedTimes: PropTypes.number, + thumbnail: PropTypes.string, + thumbnailDescription: PropTypes.string, + blurhash: PropTypes.string, + expanded: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/explore/index.jsx b/app/javascript/mastodon/features/explore/index.jsx index 8ebaccd013..83e5df22f8 100644 --- a/app/javascript/mastodon/features/explore/index.jsx +++ b/app/javascript/mastodon/features/explore/index.jsx @@ -8,11 +8,12 @@ import { NavLink, Switch, Route } from 'react-router-dom'; import { connect } from 'react-redux'; +import ExploreIcon from '@/material-icons/400-24px/explore.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react'; -import TagIcon from '@/material-icons/400-24px/tag.svg?react'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; import Search from 'mastodon/features/compose/containers/search_container'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { trendsEnabled } from 'mastodon/initial_state'; import Links from './links'; @@ -32,12 +33,8 @@ const mapStateToProps = state => ({ }); class Explore extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, intl: PropTypes.object.isRequired, multiColumn: PropTypes.bool, isSearching: PropTypes.bool, @@ -53,13 +50,13 @@ class Explore extends PureComponent { render() { const { intl, multiColumn, isSearching } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; return ( ({ links: state.getIn(['trends', 'links', 'items']), @@ -75,6 +75,7 @@ class Links extends PureComponent { publisher={link.get('provider_name')} publishedAt={link.get('published_at')} author={link.get('author_name')} + authorAccount={link.getIn(['author_account', 'id'])} sharedTimes={link.getIn(['history', 0, 'accounts']) * 1 + link.getIn(['history', 1, 'accounts']) * 1} thumbnail={link.get('image')} thumbnailDescription={link.get('image_description')} diff --git a/app/javascript/mastodon/features/explore/suggestions.jsx b/app/javascript/mastodon/features/explore/suggestions.jsx index ba33c4d081..101ec0d195 100644 --- a/app/javascript/mastodon/features/explore/suggestions.jsx +++ b/app/javascript/mastodon/features/explore/suggestions.jsx @@ -10,9 +10,10 @@ import { connect } from 'react-redux'; import { fetchSuggestions } from 'mastodon/actions/suggestions'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; -import AccountCard from 'mastodon/features/directory/components/account_card'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; +import { Card } from './components/card'; + const mapStateToProps = state => ({ suggestions: state.getIn(['suggestions', 'items']), isLoading: state.getIn(['suggestions', 'isLoading']), @@ -54,7 +55,11 @@ class Suggestions extends PureComponent { return (
{isLoading ? : suggestions.map(suggestion => ( - + ))}
); diff --git a/app/javascript/mastodon/features/firehose/index.jsx b/app/javascript/mastodon/features/firehose/index.jsx index 6355efbfe0..f65bee45ec 100644 --- a/app/javascript/mastodon/features/firehose/index.jsx +++ b/app/javascript/mastodon/features/firehose/index.jsx @@ -6,13 +6,14 @@ import { useIntl, defineMessages, FormattedMessage } from 'react-intl'; import { Helmet } from 'react-helmet'; import { NavLink } from 'react-router-dom'; +import { useIdentity } from '@/mastodon/identity_context'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import { addColumn } from 'mastodon/actions/columns'; import { changeSetting } from 'mastodon/actions/settings'; import { connectPublicStream, connectCommunityStream } from 'mastodon/actions/streaming'; import { expandPublicTimeline, expandCommunityTimeline } from 'mastodon/actions/timelines'; import { DismissableBanner } from 'mastodon/components/dismissable_banner'; -import initialState, { domain } from 'mastodon/initial_state'; +import { domain } from 'mastodon/initial_state'; import { useAppDispatch, useAppSelector } from 'mastodon/store'; import Column from '../../components/column'; @@ -24,15 +25,6 @@ const messages = defineMessages({ title: { id: 'column.firehose', defaultMessage: 'Live feeds' }, }); -// TODO: use a proper React context later on -const useIdentity = () => ({ - signedIn: !!initialState.meta.me, - accountId: initialState.meta.me, - disabledAccountId: initialState.meta.disabled_account_id, - accessToken: initialState.meta.access_token, - permissions: initialState.role ? initialState.role.permissions : 0, -}); - const ColumnSettings = () => { const dispatch = useAppDispatch(); const settings = useAppSelector((state) => state.getIn(['settings', 'firehose'])); @@ -42,15 +34,17 @@ const ColumnSettings = () => { ); return ( -
-
- } - /> -
+
+
+
+ } + /> +
+
); }; diff --git a/app/javascript/mastodon/features/follow_requests/index.jsx b/app/javascript/mastodon/features/follow_requests/index.jsx index 7d651f2ca6..a8f40a31d0 100644 --- a/app/javascript/mastodon/features/follow_requests/index.jsx +++ b/app/javascript/mastodon/features/follow_requests/index.jsx @@ -68,7 +68,7 @@ class FollowRequests extends ImmutablePureComponent { ); return ( - + - {hasTimeRange && ยท - } + {hasTimeRange && ยท - } diff --git a/app/javascript/mastodon/features/getting_started/index.jsx b/app/javascript/mastodon/features/getting_started/index.jsx index 21a5c2a519..628bbe62bb 100644 --- a/app/javascript/mastodon/features/getting_started/index.jsx +++ b/app/javascript/mastodon/features/getting_started/index.jsx @@ -11,6 +11,7 @@ import { connect } from 'react-redux'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; +import ExploreIcon from '@/material-icons/400-24px/explore.svg?react'; import PeopleIcon from '@/material-icons/400-24px/group.svg?react'; import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; @@ -19,11 +20,11 @@ import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react'; import StarIcon from '@/material-icons/400-24px/star.svg?react'; -import TagIcon from '@/material-icons/400-24px/tag.svg?react'; import { fetchFollowRequests } from 'mastodon/actions/accounts'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; import LinkFooter from 'mastodon/features/ui/components/link_footer'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { me, showTrends } from '../../initial_state'; import { NavigationBar } from '../compose/components/navigation_bar'; @@ -75,14 +76,10 @@ const badgeDisplay = (number, limit) => { }; class GettingStarted extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, intl: PropTypes.object.isRequired, - myAccount: ImmutablePropTypes.map, + myAccount: ImmutablePropTypes.record, multiColumn: PropTypes.bool, fetchFollowRequests: PropTypes.func.isRequired, unreadFollowRequests: PropTypes.number, @@ -91,7 +88,7 @@ class GettingStarted extends ImmutablePureComponent { componentDidMount () { const { fetchFollowRequests } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (!signedIn) { return; @@ -102,7 +99,7 @@ class GettingStarted extends ImmutablePureComponent { render () { const { intl, myAccount, multiColumn, unreadFollowRequests } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const navItems = []; @@ -112,7 +109,7 @@ class GettingStarted extends ImmutablePureComponent { if (showTrends) { navItems.push( - , + , ); } @@ -167,4 +164,4 @@ class GettingStarted extends ImmutablePureComponent { } -export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(GettingStarted)); +export default withIdentity(connect(mapStateToProps, mapDispatchToProps)(injectIntl(GettingStarted))); diff --git a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx index c60de4c518..3412e5d1bd 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx +++ b/app/javascript/mastodon/features/hashtag_timeline/components/column_settings.jsx @@ -107,28 +107,28 @@ class ColumnSettings extends PureComponent { const { settings, onChange } = this.props; return ( -
-
-
- +
+
+
+ } /> - - - +
+ + + + + +
-
- {this.state.open && ( -
- {this.modeSelect('any')} - {this.modeSelect('all')} - {this.modeSelect('none')} -
- )} - -
- } /> -
+ {this.state.open && ( +
+ {this.modeSelect('any')} + {this.modeSelect('all')} + {this.modeSelect('none')} +
+ )} +
); } diff --git a/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js b/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js index be95004cc7..680b44519b 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/hashtag_timeline/containers/column_settings_container.js @@ -15,7 +15,7 @@ const mapStateToProps = (state, { columnId }) => { return { settings: columns.get(index).get('params'), onLoad (value) { - return api(() => state).get('/api/v2/search', { params: { q: value, type: 'hashtags' } }).then(response => { + return api().get('/api/v2/search', { params: { q: value, type: 'hashtags' } }).then(response => { return (response.data.hashtags || []).map((tag) => { return { value: tag.name, label: `#${tag.name}` }; }); diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.jsx b/app/javascript/mastodon/features/hashtag_timeline/index.jsx index f431a7e9b7..42a668859e 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.jsx +++ b/app/javascript/mastodon/features/hashtag_timeline/index.jsx @@ -17,6 +17,7 @@ import { fetchHashtag, followHashtag, unfollowHashtag } from 'mastodon/actions/t import { expandHashtagTimeline, clearTimeline } from 'mastodon/actions/timelines'; import Column from 'mastodon/components/column'; import ColumnHeader from 'mastodon/components/column_header'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import StatusListContainer from '../ui/containers/status_list_container'; @@ -29,14 +30,10 @@ const mapStateToProps = (state, props) => ({ }); class HashtagTimeline extends PureComponent { - disconnects = []; - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, params: PropTypes.object.isRequired, columnId: PropTypes.string, dispatch: PropTypes.func.isRequired, @@ -94,7 +91,7 @@ class HashtagTimeline extends PureComponent { }; _subscribe (dispatch, id, tags = {}, local) { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (!signedIn) { return; @@ -168,7 +165,7 @@ class HashtagTimeline extends PureComponent { handleFollow = () => { const { dispatch, params, tag } = this.props; const { id } = params; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (!signedIn) { return; @@ -185,7 +182,7 @@ class HashtagTimeline extends PureComponent { const { hasUnread, columnId, multiColumn, tag } = this.props; const { id, local } = this.props.params; const pinned = !!columnId; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; return ( @@ -225,4 +222,4 @@ class HashtagTimeline extends PureComponent { } -export default connect(mapStateToProps)(HashtagTimeline); +export default connect(mapStateToProps)(withIdentity(HashtagTimeline)); diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.tsx b/app/javascript/mastodon/features/home_timeline/components/column_settings.tsx index ca09d46c7e..3f0525fe57 100644 --- a/app/javascript/mastodon/features/home_timeline/components/column_settings.tsx +++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.tsx @@ -24,43 +24,36 @@ export const ColumnSettings: React.FC = () => { ); return ( -
- - - +
+
+
+ + } + /> -
- - } - /> -
- -
- - } - /> -
+ + } + /> +
+
); }; diff --git a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx index f76526e045..c39b43bade 100644 --- a/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx +++ b/app/javascript/mastodon/features/home_timeline/components/inline_follow_suggestions.jsx @@ -21,6 +21,7 @@ import { DisplayName } from 'mastodon/components/display_name'; import { Icon } from 'mastodon/components/icon'; import { IconButton } from 'mastodon/components/icon_button'; import { VerifiedBadge } from 'mastodon/components/verified_badge'; +import { domain } from 'mastodon/initial_state'; const messages = defineMessages({ follow: { id: 'account.follow', defaultMessage: 'Follow' }, @@ -28,27 +29,43 @@ const messages = defineMessages({ previous: { id: 'lightbox.previous', defaultMessage: 'Previous' }, next: { id: 'lightbox.next', defaultMessage: 'Next' }, dismiss: { id: 'follow_suggestions.dismiss', defaultMessage: "Don't show again" }, + friendsOfFriendsHint: { id: 'follow_suggestions.hints.friends_of_friends', defaultMessage: 'This profile is popular among the people you follow.' }, + similarToRecentlyFollowedHint: { id: 'follow_suggestions.hints.similar_to_recently_followed', defaultMessage: 'This profile is similar to the profiles you have most recently followed.' }, + featuredHint: { id: 'follow_suggestions.hints.featured', defaultMessage: 'This profile has been hand-picked by the {domain} team.' }, + mostFollowedHint: { id: 'follow_suggestions.hints.most_followed', defaultMessage: 'This profile is one of the most followed on {domain}.'}, + mostInteractionsHint: { id: 'follow_suggestions.hints.most_interactions', defaultMessage: 'This profile has been recently getting a lot of attention on {domain}.' }, }); const Source = ({ id }) => { - let label; + const intl = useIntl(); + + let label, hint; switch (id) { case 'friends_of_friends': + hint = intl.formatMessage(messages.friendsOfFriendsHint); + label = ; + break; case 'similar_to_recently_followed': + hint = intl.formatMessage(messages.similarToRecentlyFollowedHint); label = ; break; case 'featured': - label = ; + hint = intl.formatMessage(messages.featuredHint, { domain }); + label = ; break; case 'most_followed': + hint = intl.formatMessage(messages.mostFollowedHint, { domain }); + label = ; + break; case 'most_interactions': + hint = intl.formatMessage(messages.mostInteractionsHint, { domain }); label = ; break; } return ( -
+
{label}
@@ -92,7 +109,7 @@ const Card = ({ id, sources }) => { {firstVerifiedField ? : }
-
); }; diff --git a/app/javascript/mastodon/features/home_timeline/index.jsx b/app/javascript/mastodon/features/home_timeline/index.jsx index 6e7dc2b6c8..00b5835a16 100644 --- a/app/javascript/mastodon/features/home_timeline/index.jsx +++ b/app/javascript/mastodon/features/home_timeline/index.jsx @@ -14,6 +14,7 @@ import { fetchAnnouncements, toggleShowAnnouncements } from 'mastodon/actions/an import { IconWithBadge } from 'mastodon/components/icon_with_badge'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; import AnnouncementsContainer from 'mastodon/features/getting_started/containers/announcements_container'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { criticalUpdatesPending } from 'mastodon/initial_state'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; @@ -40,12 +41,8 @@ const mapStateToProps = state => ({ }); class HomeTimeline extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, hasUnread: PropTypes.bool, @@ -126,7 +123,7 @@ class HomeTimeline extends PureComponent { render () { const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props; const pinned = !!columnId; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const banners = []; let announcementsButton; @@ -190,4 +187,4 @@ class HomeTimeline extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(HomeTimeline)); +export default connect(mapStateToProps)(withIdentity(injectIntl(HomeTimeline))); diff --git a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx index 622ca525c1..e342958480 100644 --- a/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx +++ b/app/javascript/mastodon/features/keyboard_shortcuts/index.jsx @@ -107,7 +107,7 @@ class KeyboardShortcuts extends ImmutablePureComponent { - s + s, / diff --git a/app/javascript/mastodon/features/list_timeline/index.jsx b/app/javascript/mastodon/features/list_timeline/index.jsx index 24bf122fac..f640e503c2 100644 --- a/app/javascript/mastodon/features/list_timeline/index.jsx +++ b/app/javascript/mastodon/features/list_timeline/index.jsx @@ -193,35 +193,38 @@ class ListTimeline extends PureComponent { pinned={pinned} multiColumn={multiColumn} > -
- +
+
+ - -
+ + -
- - -
- - { replies_policy !== undefined && ( -
- - - -
- { ['none', 'list', 'followed'].map(policy => ( - - ))} +
+
+ +
-
- )} + + + {replies_policy !== undefined && ( +
+

+ +
+ { ['none', 'list', 'followed'].map(policy => ( + + ))} +
+
+ )} +
{ + const handleChange = useCallback(({ target }) => { + onChange(target.checked); + }, [onChange]); + + return ( + + ); +}; + +CheckboxWithLabel.propTypes = { + checked: PropTypes.bool, + disabled: PropTypes.bool, + children: PropTypes.children, + onChange: PropTypes.func, +}; diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.jsx b/app/javascript/mastodon/features/notifications/components/column_settings.jsx index 09154f257a..39e394e449 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.jsx +++ b/app/javascript/mastodon/features/notifications/components/column_settings.jsx @@ -5,19 +5,17 @@ import { FormattedMessage } from 'react-intl'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_REPORTS } from 'mastodon/permissions'; +import { CheckboxWithLabel } from './checkbox_with_label'; import ClearColumnButton from './clear_column_button'; import GrantPermissionButton from './grant_permission_button'; import SettingToggle from './setting_toggle'; -export default class ColumnSettings extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - +class ColumnSettings extends PureComponent { static propTypes = { + identity: identityContextPropShape, settings: ImmutablePropTypes.map.isRequired, pushSettings: ImmutablePropTypes.map.isRequired, onChange: PropTypes.func.isRequired, @@ -26,18 +24,35 @@ export default class ColumnSettings extends PureComponent { alertsEnabled: PropTypes.bool, browserSupport: PropTypes.bool, browserPermission: PropTypes.string, + notificationPolicy: PropTypes.object.isRequired, + onChangePolicy: PropTypes.func.isRequired, }; onPushChange = (path, checked) => { this.props.onChange(['push', ...path], checked); }; - render () { - const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission } = this.props; + handleFilterNotFollowing = checked => { + this.props.onChangePolicy('filter_not_following', checked); + }; + + handleFilterNotFollowers = checked => { + this.props.onChangePolicy('filter_not_followers', checked); + }; + + handleFilterNewAccounts = checked => { + this.props.onChangePolicy('filter_new_accounts', checked); + }; + + handleFilterPrivateMentions = checked => { + this.props.onChangePolicy('filter_private_mentions', checked); + }; + + render () { + const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission, notificationPolicy } = this.props; - const unreadMarkersShowStr = ; - const filterBarShowStr = ; const filterAdvancedStr = ; + const unreadMarkersShowStr = ; const alertStr = ; const showStr = ; const soundStr = ; @@ -46,48 +61,71 @@ export default class ColumnSettings extends PureComponent { const pushStr = showPushSettings && ; return ( -
+
{alertsEnabled && browserSupport && browserPermission === 'denied' && ( -
- -
+ )} +
+ +
+ {alertsEnabled && browserSupport && browserPermission === 'default' && ( -
+
-
+ )} -
- -
+
+

-
- +
+ + + + + + + + + + + + + + + + + + + +
+
+ +
+

- +

-
+ -
- +
+

- +

- - +
-
+ -
- +
+

@@ -95,10 +133,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -106,10 +144,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -117,10 +155,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -128,10 +166,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -139,10 +177,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -150,10 +188,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -161,10 +199,10 @@ export default class ColumnSettings extends PureComponent {
-
+ -
- +
+

@@ -172,11 +210,11 @@ export default class ColumnSettings extends PureComponent {
-
+ - {((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && ( -
- + {((this.props.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) && ( +
+

@@ -184,12 +222,12 @@ export default class ColumnSettings extends PureComponent {
-
+ )} - {((this.context.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && ( -
- + {((this.props.identity.permissions & PERMISSION_MANAGE_REPORTS) === PERMISSION_MANAGE_REPORTS) && ( +
+

@@ -197,10 +235,12 @@ export default class ColumnSettings extends PureComponent {
-
+ )}
); } } + +export default withIdentity(ColumnSettings); diff --git a/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx new file mode 100644 index 0000000000..2c4b3b9717 --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/filtered_notifications_banner.tsx @@ -0,0 +1,68 @@ +import { useEffect } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; +import { fetchNotificationPolicy } from 'mastodon/actions/notification_policies'; +import { Icon } from 'mastodon/components/icon'; +import { useAppSelector, useAppDispatch } from 'mastodon/store'; +import { toCappedNumber } from 'mastodon/utils/numbers'; + +export const FilteredNotificationsBanner: React.FC = () => { + const dispatch = useAppDispatch(); + const policy = useAppSelector((state) => state.notificationPolicy); + + useEffect(() => { + void dispatch(fetchNotificationPolicy()); + + const interval = setInterval(() => { + void dispatch(fetchNotificationPolicy()); + }, 120000); + + return () => { + clearInterval(interval); + }; + }, [dispatch]); + + if (policy === null || policy.summary.pending_notifications_count === 0) { + return null; + } + + return ( + + + +
+ + + + + + +
+ +
+
+ {toCappedNumber(policy.summary.pending_notifications_count)} +
+ +
+ + ); +}; diff --git a/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx b/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx new file mode 100644 index 0000000000..2c1683e218 --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/moderation_warning.tsx @@ -0,0 +1,78 @@ +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import GavelIcon from '@/material-icons/400-24px/gavel.svg?react'; +import { Icon } from 'mastodon/components/icon'; + +// This needs to be kept in sync with app/models/account_warning.rb +const messages = defineMessages({ + none: { + id: 'notification.moderation_warning.action_none', + defaultMessage: 'Your account has received a moderation warning.', + }, + disable: { + id: 'notification.moderation_warning.action_disable', + defaultMessage: 'Your account has been disabled.', + }, + mark_statuses_as_sensitive: { + id: 'notification.moderation_warning.action_mark_statuses_as_sensitive', + defaultMessage: 'Some of your posts have been marked as sensitive.', + }, + delete_statuses: { + id: 'notification.moderation_warning.action_delete_statuses', + defaultMessage: 'Some of your posts have been removed.', + }, + sensitive: { + id: 'notification.moderation_warning.action_sensitive', + defaultMessage: 'Your posts will be marked as sensitive from now on.', + }, + silence: { + id: 'notification.moderation_warning.action_silence', + defaultMessage: 'Your account has been limited.', + }, + suspend: { + id: 'notification.moderation_warning.action_suspend', + defaultMessage: 'Your account has been suspended.', + }, +}); + +interface Props { + action: + | 'none' + | 'disable' + | 'mark_statuses_as_sensitive' + | 'delete_statuses' + | 'sensitive' + | 'silence' + | 'suspend'; + id: string; + hidden: boolean; +} + +export const ModerationWarning: React.FC = ({ action, id, hidden }) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( + + + +
+

{intl.formatMessage(messages[action])}

+ + + +
+
+ ); +}; diff --git a/app/javascript/mastodon/features/notifications/components/notification.jsx b/app/javascript/mastodon/features/notifications/components/notification.jsx index d7101f8384..69084c2111 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.jsx +++ b/app/javascript/mastodon/features/notifications/components/notification.jsx @@ -26,6 +26,8 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import FollowRequestContainer from '../containers/follow_request_container'; +import { ModerationWarning } from './moderation_warning'; +import { RelationshipsSeveranceEvent } from './relationships_severance_event'; import Report from './report'; const messages = defineMessages({ @@ -38,6 +40,8 @@ const messages = defineMessages({ update: { id: 'notification.update', defaultMessage: '{name} edited a post' }, adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' }, adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' }, + relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' }, + moderationWarning: { id: 'notification.moderation_warning', defaultMessage: 'You have received a moderation warning' }, }); const notificationForScreenReader = (intl, message, timestamp) => { @@ -358,6 +362,50 @@ class Notification extends ImmutablePureComponent { ); } + renderRelationshipsSevered (notification) { + const { intl, unread, hidden } = this.props; + const event = notification.get('event'); + + if (!event) { + return null; + } + + return ( + +
+
+
+ ); + } + + renderModerationWarning (notification) { + const { intl, unread, hidden } = this.props; + const warning = notification.get('moderation_warning'); + + if (!warning) { + return null; + } + + return ( + +
+
+
+ ); + } + renderAdminSignUp (notification, account, link) { const { intl, unread } = this.props; @@ -429,6 +477,10 @@ class Notification extends ImmutablePureComponent { return this.renderUpdate(notification, link); case 'poll': return this.renderPoll(notification, account); + case 'severed_relationships': + return this.renderRelationshipsSevered(notification); + case 'moderation_warning': + return this.renderModerationWarning(notification); case 'admin.sign_up': return this.renderAdminSignUp(notification, account, link); case 'admin.report': diff --git a/app/javascript/mastodon/features/notifications/components/notification_request.jsx b/app/javascript/mastodon/features/notifications/components/notification_request.jsx new file mode 100644 index 0000000000..3a77ef4e2e --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/notification_request.jsx @@ -0,0 +1,65 @@ +import PropTypes from 'prop-types'; +import { useCallback } from 'react'; + +import { defineMessages, useIntl } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import { useSelector, useDispatch } from 'react-redux'; + +import DeleteIcon from '@/material-icons/400-24px/delete.svg?react'; +import DoneIcon from '@/material-icons/400-24px/done.svg?react'; +import { acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications'; +import { Avatar } from 'mastodon/components/avatar'; +import { IconButton } from 'mastodon/components/icon_button'; +import { makeGetAccount } from 'mastodon/selectors'; +import { toCappedNumber } from 'mastodon/utils/numbers'; + +const getAccount = makeGetAccount(); + +const messages = defineMessages({ + accept: { id: 'notification_requests.accept', defaultMessage: 'Accept' }, + dismiss: { id: 'notification_requests.dismiss', defaultMessage: 'Dismiss' }, +}); + +export const NotificationRequest = ({ id, accountId, notificationsCount }) => { + const dispatch = useDispatch(); + const account = useSelector(state => getAccount(state, accountId)); + const intl = useIntl(); + + const handleDismiss = useCallback(() => { + dispatch(dismissNotificationRequest(id)); + }, [dispatch, id]); + + const handleAccept = useCallback(() => { + dispatch(acceptNotificationRequest(id)); + }, [dispatch, id]); + + return ( +
+ + + +
+
+ + {toCappedNumber(notificationsCount)} +
+ + @{account?.get('acct')} +
+ + +
+ + +
+
+ ); +}; + +NotificationRequest.propTypes = { + id: PropTypes.string.isRequired, + accountId: PropTypes.string.isRequired, + notificationsCount: PropTypes.string.isRequired, +}; diff --git a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx index 1cdf5b5dfe..276bcbebad 100644 --- a/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx +++ b/app/javascript/mastodon/features/notifications/components/notifications_permission_banner.jsx @@ -5,8 +5,8 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { connect } from 'react-redux'; +import SettingsIcon from '@/material-icons/400-20px/settings.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import TuneIcon from '@/material-icons/400-24px/tune.svg?react'; import { requestBrowserPermission } from 'mastodon/actions/notifications'; import { changeSetting } from 'mastodon/actions/settings'; import { Button } from 'mastodon/components/button'; @@ -42,7 +42,7 @@ class NotificationsPermissionBanner extends PureComponent {

-

}} />

+

}} />

); diff --git a/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx new file mode 100644 index 0000000000..738159fc5a --- /dev/null +++ b/app/javascript/mastodon/features/notifications/components/relationships_severance_event.jsx @@ -0,0 +1,45 @@ +import PropTypes from 'prop-types'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react'; +import { Icon } from 'mastodon/components/icon'; +import { domain } from 'mastodon/initial_state'; + +// This needs to be kept in sync with app/models/relationships_severance_event.rb +const messages = defineMessages({ + account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' }, + domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, + user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' }, +}); + +export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden }) => { + const intl = useIntl(); + + if (hidden) { + return null; + } + + return ( + + + +
+

{intl.formatMessage(messages[type], { from: {domain}, target: {target}, followingCount, followersCount })}

+ +
+
+ ); +}; + +RelationshipsSeveranceEvent.propTypes = { + type: PropTypes.oneOf([ + 'account_suspension', + 'domain_block', + 'user_domain_block', + ]).isRequired, + target: PropTypes.string.isRequired, + followersCount: PropTypes.number.isRequired, + followingCount: PropTypes.number.isRequired, + hidden: PropTypes.bool, +}; diff --git a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js index 1e62ed9a5a..94383d0bb5 100644 --- a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js @@ -4,6 +4,7 @@ import { connect } from 'react-redux'; import { showAlert } from '../../../actions/alerts'; import { openModal } from '../../../actions/modal'; +import { updateNotificationsPolicy } from '../../../actions/notification_policies'; import { setFilter, clearNotifications, requestBrowserPermission } from '../../../actions/notifications'; import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications'; import { changeSetting } from '../../../actions/settings'; @@ -15,12 +16,16 @@ const messages = defineMessages({ permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' }, }); +/** + * @param {import('mastodon/store').RootState} state + */ const mapStateToProps = state => ({ settings: state.getIn(['settings', 'notifications']), pushSettings: state.get('push_notifications'), alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true), browserSupport: state.getIn(['notifications', 'browserSupport']), browserPermission: state.getIn(['notifications', 'browserPermission']), + notificationPolicy: state.notificationPolicy, }); const mapDispatchToProps = (dispatch, { intl }) => ({ @@ -73,6 +78,12 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch(requestBrowserPermission()); }, + onChangePolicy (param, checked) { + dispatch(updateNotificationsPolicy({ + [param]: checked, + })); + }, + }); export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ColumnSettings)); diff --git a/app/javascript/mastodon/features/notifications/containers/notification_container.js b/app/javascript/mastodon/features/notifications/containers/notification_container.js index 4458fd7bc3..650acf4ccd 100644 --- a/app/javascript/mastodon/features/notifications/containers/notification_container.js +++ b/app/javascript/mastodon/features/notifications/containers/notification_container.js @@ -1,6 +1,5 @@ import { connect } from 'react-redux'; -import { initBoostModal } from '../../../actions/boosts'; import { mentionCompose } from '../../../actions/compose'; import { reblog, @@ -8,6 +7,7 @@ import { unreblog, unfavourite, } from '../../../actions/interactions'; +import { openModal } from '../../../actions/modal'; import { hideStatus, revealStatus, @@ -39,17 +39,17 @@ const mapDispatchToProps = dispatch => ({ }, onModalReblog (status, privacy) { - dispatch(reblog(status, privacy)); + dispatch(reblog({ statusId: status.get('id'), visibility: privacy })); }, onReblog (status, e) { if (status.get('reblogged')) { - dispatch(unreblog(status)); + dispatch(unreblog({ statusId: status.get('id') })); } else { if (e.shiftKey || !boostModal) { this.onModalReblog(status); } else { - dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); + dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); } } }, diff --git a/app/javascript/mastodon/features/notifications/index.jsx b/app/javascript/mastodon/features/notifications/index.jsx index 30c63ed32a..d45f517152 100644 --- a/app/javascript/mastodon/features/notifications/index.jsx +++ b/app/javascript/mastodon/features/notifications/index.jsx @@ -17,6 +17,7 @@ import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg? import { compareId } from 'mastodon/compare_id'; import { Icon } from 'mastodon/components/icon'; import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; import { submitMarkers } from '../../actions/markers'; @@ -33,6 +34,7 @@ import ColumnHeader from '../../components/column_header'; import { LoadGap } from '../../components/load_gap'; import ScrollableList from '../../components/scrollable_list'; +import { FilteredNotificationsBanner } from './components/filtered_notifications_banner'; import NotificationsPermissionBanner from './components/notifications_permission_banner'; import ColumnSettingsContainer from './containers/column_settings_container'; import FilterBarContainer from './containers/filter_bar_container'; @@ -65,7 +67,6 @@ const getNotifications = createSelector([ }); const mapStateToProps = state => ({ - showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']), notifications: getNotifications(state), isLoading: state.getIn(['notifications', 'isLoading'], 0) > 0, isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0, @@ -77,15 +78,10 @@ const mapStateToProps = state => ({ }); class Notifications extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, columnId: PropTypes.string, notifications: ImmutablePropTypes.list.isRequired, - showFilterBar: PropTypes.bool.isRequired, dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, isLoading: PropTypes.bool, @@ -188,14 +184,14 @@ class Notifications extends PureComponent { }; render () { - const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, showFilterBar, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props; + const { intl, notifications, isLoading, isUnread, columnId, multiColumn, hasMore, numPending, lastReadId, canMarkAsRead, needsNotificationPermission } = this.props; const pinned = !!columnId; const emptyMessage = ; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; let scrollableContent = null; - const filterBarContainer = (signedIn && showFilterBar) + const filterBarContainer = signedIn ? () : null; @@ -285,6 +281,9 @@ class Notifications extends PureComponent { {filterBarContainer} + + + {scrollContainer} @@ -297,4 +296,4 @@ class Notifications extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(Notifications)); +export default connect(mapStateToProps)(withIdentity(injectIntl(Notifications))); diff --git a/app/javascript/mastodon/features/notifications/request.jsx b/app/javascript/mastodon/features/notifications/request.jsx new file mode 100644 index 0000000000..09bef3beab --- /dev/null +++ b/app/javascript/mastodon/features/notifications/request.jsx @@ -0,0 +1,147 @@ +import PropTypes from 'prop-types'; +import { useRef, useCallback, useEffect } from 'react'; + +import { defineMessages, useIntl } from 'react-intl'; + +import { Helmet } from 'react-helmet'; + +import { useSelector, useDispatch } from 'react-redux'; + +import DoneIcon from '@/material-icons/400-24px/done.svg?react'; +import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; +import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react'; +import { fetchNotificationRequest, fetchNotificationsForRequest, expandNotificationsForRequest, acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications'; +import Column from 'mastodon/components/column'; +import ColumnHeader from 'mastodon/components/column_header'; +import { IconButton } from 'mastodon/components/icon_button'; +import ScrollableList from 'mastodon/components/scrollable_list'; +import { SensitiveMediaContextProvider } from 'mastodon/features/ui/util/sensitive_media_context'; + +import NotificationContainer from './containers/notification_container'; + +const messages = defineMessages({ + title: { id: 'notification_requests.notifications_from', defaultMessage: 'Notifications from {name}' }, + accept: { id: 'notification_requests.accept', defaultMessage: 'Accept' }, + dismiss: { id: 'notification_requests.dismiss', defaultMessage: 'Dismiss' }, +}); + +const selectChild = (ref, index, alignTop) => { + const container = ref.current.node; + const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`); + + if (element) { + if (alignTop && container.scrollTop > element.offsetTop) { + element.scrollIntoView(true); + } else if (!alignTop && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) { + element.scrollIntoView(false); + } + + element.focus(); + } +}; + +export const NotificationRequest = ({ multiColumn, params: { id } }) => { + const columnRef = useRef(); + const intl = useIntl(); + const dispatch = useDispatch(); + const notificationRequest = useSelector(state => state.getIn(['notificationRequests', 'current', 'item', 'id']) === id ? state.getIn(['notificationRequests', 'current', 'item']) : null); + const accountId = notificationRequest?.get('account'); + const account = useSelector(state => state.getIn(['accounts', accountId])); + const notifications = useSelector(state => state.getIn(['notificationRequests', 'current', 'notifications', 'items'])); + const isLoading = useSelector(state => state.getIn(['notificationRequests', 'current', 'notifications', 'isLoading'])); + const hasMore = useSelector(state => !!state.getIn(['notificationRequests', 'current', 'notifications', 'next'])); + const removed = useSelector(state => state.getIn(['notificationRequests', 'current', 'removed'])); + + const handleHeaderClick = useCallback(() => { + columnRef.current?.scrollTop(); + }, [columnRef]); + + const handleLoadMore = useCallback(() => { + dispatch(expandNotificationsForRequest()); + }, [dispatch]); + + const handleDismiss = useCallback(() => { + dispatch(dismissNotificationRequest(id)); + }, [dispatch, id]); + + const handleAccept = useCallback(() => { + dispatch(acceptNotificationRequest(id)); + }, [dispatch, id]); + + const handleMoveUp = useCallback(id => { + const elementIndex = notifications.findIndex(item => item !== null && item.get('id') === id) - 1; + selectChild(columnRef, elementIndex, true); + }, [columnRef, notifications]); + + const handleMoveDown = useCallback(id => { + const elementIndex = notifications.findIndex(item => item !== null && item.get('id') === id) + 1; + selectChild(columnRef, elementIndex, false); + }, [columnRef, notifications]); + + useEffect(() => { + dispatch(fetchNotificationRequest(id)); + }, [dispatch, id]); + + useEffect(() => { + if (accountId) { + dispatch(fetchNotificationsForRequest(accountId)); + } + }, [dispatch, accountId]); + + const columnTitle = intl.formatMessage(messages.title, { name: account?.get('display_name') || account?.get('username') }); + + return ( + + + + + + )} + /> + + + + {notifications.map(item => ( + item && + ))} + + + + + {columnTitle} + + + + ); +}; + +NotificationRequest.propTypes = { + multiColumn: PropTypes.bool, + params: PropTypes.shape({ + id: PropTypes.string.isRequired, + }), +}; + +export default NotificationRequest; diff --git a/app/javascript/mastodon/features/notifications/requests.jsx b/app/javascript/mastodon/features/notifications/requests.jsx new file mode 100644 index 0000000000..2d10c6a06c --- /dev/null +++ b/app/javascript/mastodon/features/notifications/requests.jsx @@ -0,0 +1,85 @@ +import PropTypes from 'prop-types'; +import { useRef, useCallback, useEffect } from 'react'; + +import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; + +import { Helmet } from 'react-helmet'; + +import { useSelector, useDispatch } from 'react-redux'; + +import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react'; +import { fetchNotificationRequests, expandNotificationRequests } from 'mastodon/actions/notifications'; +import Column from 'mastodon/components/column'; +import ColumnHeader from 'mastodon/components/column_header'; +import ScrollableList from 'mastodon/components/scrollable_list'; + +import { NotificationRequest } from './components/notification_request'; + +const messages = defineMessages({ + title: { id: 'notification_requests.title', defaultMessage: 'Filtered notifications' }, +}); + +export const NotificationRequests = ({ multiColumn }) => { + const columnRef = useRef(); + const intl = useIntl(); + const dispatch = useDispatch(); + const isLoading = useSelector(state => state.getIn(['notificationRequests', 'isLoading'])); + const notificationRequests = useSelector(state => state.getIn(['notificationRequests', 'items'])); + const hasMore = useSelector(state => !!state.getIn(['notificationRequests', 'next'])); + + const handleHeaderClick = useCallback(() => { + columnRef.current?.scrollTop(); + }, [columnRef]); + + const handleLoadMore = useCallback(() => { + dispatch(expandNotificationRequests()); + }, [dispatch]); + + useEffect(() => { + dispatch(fetchNotificationRequests()); + }, [dispatch]); + + return ( + + + + } + > + {notificationRequests.map(request => ( + + ))} + + + + {intl.formatMessage(messages.title)} + + + + ); +}; + +NotificationRequests.propTypes = { + multiColumn: PropTypes.bool, +}; + +export default NotificationRequests; diff --git a/app/javascript/mastodon/features/onboarding/index.jsx b/app/javascript/mastodon/features/onboarding/index.jsx index 5900b9ec76..529d53f257 100644 --- a/app/javascript/mastodon/features/onboarding/index.jsx +++ b/app/javascript/mastodon/features/onboarding/index.jsx @@ -16,6 +16,7 @@ import EditNoteIcon from '@/material-icons/400-24px/edit_note.svg?react'; import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; import { focusCompose } from 'mastodon/actions/compose'; import { Icon } from 'mastodon/components/icon'; +import { NotSignedInIndicator } from 'mastodon/components/not_signed_in_indicator'; import Column from 'mastodon/features/ui/components/column'; import { me } from 'mastodon/initial_state'; import { useAppSelector } from 'mastodon/store'; @@ -42,42 +43,44 @@ const Onboarding = () => { return ( - - -
-
- -

-

+ {account ? ( + + +
+
+ +

+

+
+ +
+ 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={} description={} /> + = 1} icon='user-plus' iconComponent={PersonAddIcon} label={} description={} /> + = 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={} description={ }} />} /> + } description={} /> +
+ +

+ +
+ + + + + + + + + +
+
-
- 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={} description={} /> - = 1} icon='user-plus' iconComponent={PersonAddIcon} label={} description={} /> - = 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={} description={ }} />} /> - } description={} /> -
- -

- -
- - - - - - - - - -
-
- - - - - - + + + + + ) : } diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx index 8dfbf54cb6..ba0642da28 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.jsx @@ -14,11 +14,11 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; import StarIcon from '@/material-icons/400-24px/star.svg?react'; -import { initBoostModal } from 'mastodon/actions/boosts'; import { replyCompose } from 'mastodon/actions/compose'; import { reblog, favourite, unreblog, unfavourite } from 'mastodon/actions/interactions'; import { openModal } from 'mastodon/actions/modal'; import { IconButton } from 'mastodon/components/icon_button'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { me, boostModal } from 'mastodon/initial_state'; import { makeGetStatus } from 'mastodon/selectors'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -48,12 +48,8 @@ const makeMapStateToProps = () => { }; class Footer extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, statusId: PropTypes.string.isRequired, status: ImmutablePropTypes.map.isRequired, intl: PropTypes.object.isRequired, @@ -76,7 +72,7 @@ class Footer extends ImmutablePureComponent { handleReplyClick = () => { const { dispatch, askReplyConfirmation, status, intl } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (askReplyConfirmation) { @@ -105,7 +101,7 @@ class Footer extends ImmutablePureComponent { handleFavouriteClick = () => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (status.get('favourited')) { @@ -127,20 +123,20 @@ class Footer extends ImmutablePureComponent { _performReblog = (status, privacy) => { const { dispatch } = this.props; - dispatch(reblog(status, privacy)); + dispatch(reblog({ statusId: status.get('id'), visibility: privacy })); }; handleReblogClick = e => { const { dispatch, status } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (status.get('reblogged')) { - dispatch(unreblog(status)); + dispatch(unreblog({ statusId: status.get('id') })); } else if ((e && e.shiftKey) || !boostModal) { this._performReblog(status); } else { - dispatch(initBoostModal({ status, onReblog: this._performReblog })); + dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this._performReblog } })); } } else { dispatch(openModal({ @@ -210,4 +206,4 @@ class Footer extends ImmutablePureComponent { } -export default withRouter(connect(makeMapStateToProps)(injectIntl(Footer))); +export default connect(makeMapStateToProps)(withIdentity(withRouter(injectIntl(Footer)))); diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.jsx b/app/javascript/mastodon/features/picture_in_picture/components/header.jsx deleted file mode 100644 index 31073d7387..0000000000 --- a/app/javascript/mastodon/features/picture_in_picture/components/header.jsx +++ /dev/null @@ -1,51 +0,0 @@ -import PropTypes from 'prop-types'; - -import { defineMessages, injectIntl } from 'react-intl'; - -import { Link } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import CloseIcon from '@/material-icons/400-24px/close.svg?react'; -import { Avatar } from 'mastodon/components/avatar'; -import { DisplayName } from 'mastodon/components/display_name'; -import { IconButton } from 'mastodon/components/icon_button'; - -const messages = defineMessages({ - close: { id: 'lightbox.close', defaultMessage: 'Close' }, -}); - -const mapStateToProps = (state, { accountId }) => ({ - account: state.getIn(['accounts', accountId]), -}); - -class Header extends ImmutablePureComponent { - - static propTypes = { - accountId: PropTypes.string.isRequired, - statusId: PropTypes.string.isRequired, - account: ImmutablePropTypes.record.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - render () { - const { account, statusId, onClose, intl } = this.props; - - return ( -
- - - - - - -
- ); - } - -} - -export default connect(mapStateToProps)(injectIntl(Header)); diff --git a/app/javascript/mastodon/features/picture_in_picture/components/header.tsx b/app/javascript/mastodon/features/picture_in_picture/components/header.tsx new file mode 100644 index 0000000000..0f897dc441 --- /dev/null +++ b/app/javascript/mastodon/features/picture_in_picture/components/header.tsx @@ -0,0 +1,46 @@ +import { defineMessages, useIntl } from 'react-intl'; + +import { Link } from 'react-router-dom'; + +import CloseIcon from '@/material-icons/400-24px/close.svg?react'; +import { Avatar } from 'mastodon/components/avatar'; +import { DisplayName } from 'mastodon/components/display_name'; +import { IconButton } from 'mastodon/components/icon_button'; +import { useAppSelector } from 'mastodon/store'; + +const messages = defineMessages({ + close: { id: 'lightbox.close', defaultMessage: 'Close' }, +}); + +interface Props { + accountId: string; + statusId: string; + onClose: () => void; +} + +export const Header: React.FC = ({ accountId, statusId, onClose }) => { + const account = useAppSelector((state) => state.accounts.get(accountId)); + + const intl = useIntl(); + + if (!account) return null; + + return ( +
+ + + + + + +
+ ); +}; diff --git a/app/javascript/mastodon/features/picture_in_picture/index.jsx b/app/javascript/mastodon/features/picture_in_picture/index.jsx deleted file mode 100644 index f087cd1b1d..0000000000 --- a/app/javascript/mastodon/features/picture_in_picture/index.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; - -import { connect } from 'react-redux'; - -import { removePictureInPicture } from 'mastodon/actions/picture_in_picture'; -import Audio from 'mastodon/features/audio'; -import Video from 'mastodon/features/video'; - -import Footer from './components/footer'; -import Header from './components/header'; - -const mapStateToProps = state => ({ - ...state.get('picture_in_picture'), -}); - -class PictureInPicture extends Component { - - static propTypes = { - statusId: PropTypes.string, - accountId: PropTypes.string, - type: PropTypes.string, - src: PropTypes.string, - muted: PropTypes.bool, - volume: PropTypes.number, - currentTime: PropTypes.number, - poster: PropTypes.string, - backgroundColor: PropTypes.string, - foregroundColor: PropTypes.string, - accentColor: PropTypes.string, - dispatch: PropTypes.func.isRequired, - }; - - handleClose = () => { - const { dispatch } = this.props; - dispatch(removePictureInPicture()); - }; - - render () { - const { type, src, currentTime, accountId, statusId } = this.props; - - if (!currentTime) { - return null; - } - - let player; - - if (type === 'video') { - player = ( -
-
- } /> - } /> -
+
+
+
+ } /> + } /> +
+
); } diff --git a/app/javascript/mastodon/features/public_timeline/index.jsx b/app/javascript/mastodon/features/public_timeline/index.jsx index 3601dfeae8..91351901f5 100644 --- a/app/javascript/mastodon/features/public_timeline/index.jsx +++ b/app/javascript/mastodon/features/public_timeline/index.jsx @@ -9,6 +9,7 @@ import { connect } from 'react-redux'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import { DismissableBanner } from 'mastodon/components/dismissable_banner'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { domain } from 'mastodon/initial_state'; import { addColumn, removeColumn, moveColumn } from '../../actions/columns'; @@ -40,16 +41,12 @@ const mapStateToProps = (state, { columnId }) => { }; class PublicTimeline extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static defaultProps = { onlyMedia: false, }; static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, columnId: PropTypes.string, @@ -80,7 +77,7 @@ class PublicTimeline extends PureComponent { componentDidMount () { const { dispatch, onlyMedia, onlyRemote } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; dispatch(expandPublicTimeline({ onlyMedia, onlyRemote })); @@ -90,7 +87,7 @@ class PublicTimeline extends PureComponent { } componentDidUpdate (prevProps) { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (prevProps.onlyMedia !== this.props.onlyMedia || prevProps.onlyRemote !== this.props.onlyRemote) { const { dispatch, onlyMedia, onlyRemote } = this.props; @@ -164,4 +161,4 @@ class PublicTimeline extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(PublicTimeline)); +export default connect(mapStateToProps)(withIdentity(injectIntl(PublicTimeline))); diff --git a/app/javascript/mastodon/features/status/components/action_bar.jsx b/app/javascript/mastodon/features/status/components/action_bar.jsx index c243a49129..d610539987 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.jsx +++ b/app/javascript/mastodon/features/status/components/action_bar.jsx @@ -21,6 +21,7 @@ import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react'; import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react'; import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react'; import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -67,14 +68,10 @@ const mapStateToProps = (state, { status }) => ({ }); class ActionBar extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, status: ImmutablePropTypes.map.isRequired, - relationship: ImmutablePropTypes.map, + relationship: ImmutablePropTypes.record, onReply: PropTypes.func.isRequired, onReblog: PropTypes.func.isRequired, onFavourite: PropTypes.func.isRequired, @@ -159,7 +156,7 @@ class ActionBar extends PureComponent { const { status, onBlockDomain } = this.props; const account = status.get('account'); - onBlockDomain(account.get('acct').split('@')[1]); + onBlockDomain(account); }; handleUnblockDomain = () => { @@ -198,7 +195,7 @@ class ActionBar extends PureComponent { render () { const { status, relationship, intl } = this.props; - const { signedIn, permissions } = this.context.identity; + const { signedIn, permissions } = this.props.identity; const publicStatus = ['public', 'unlisted'].includes(status.get('visibility')); const pinnableStatus = ['public', 'unlisted', 'private'].includes(status.get('visibility')); @@ -326,4 +323,4 @@ class ActionBar extends PureComponent { } -export default withRouter(connect(mapStateToProps)(injectIntl(ActionBar))); +export default withRouter(connect(mapStateToProps)(withIdentity(injectIntl(ActionBar)))); diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index f37b558c4c..f562e53f0b 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -7,6 +7,7 @@ import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; + import Immutable from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; @@ -15,6 +16,7 @@ import OpenInNewIcon from '@/material-icons/400-24px/open_in_new.svg?react'; import PlayArrowIcon from '@/material-icons/400-24px/play_arrow-fill.svg?react'; import { Blurhash } from 'mastodon/components/blurhash'; import { Icon } from 'mastodon/components/icon'; +import { MoreFromAuthor } from 'mastodon/components/more_from_author'; import { RelativeTimestamp } from 'mastodon/components/relative_timestamp'; import { useBlurhash } from 'mastodon/initial_state'; @@ -92,6 +94,10 @@ export default class Card extends PureComponent { this.setState({ embedded: true }); }; + handleExternalLinkClick = (e) => { + e.stopPropagation(); + }; + setRef = c => { this.node = c; }; @@ -132,6 +138,7 @@ export default class Card extends PureComponent { const interactive = card.get('type') === 'video'; const language = card.get('language') || ''; const largeImage = (card.get('image')?.length > 0 && card.get('width') > card.get('height')) || interactive; + const showAuthor = !!card.get('author_account'); const description = (
@@ -142,7 +149,7 @@ export default class Card extends PureComponent { {card.get('title')} - {card.get('author_name').length > 0 ? {card.get('author_name')} }} /> : {card.get('description')}} + {!showAuthor && (card.get('author_name').length > 0 ? {card.get('author_name')} }} /> : {card.get('description')})}
); @@ -201,7 +208,7 @@ export default class Card extends PureComponent {
- +
) : spoilerButton} @@ -231,10 +238,14 @@ export default class Card extends PureComponent { } return ( - - {embed} - {description} - + <> + + {embed} + {description} + + + {showAuthor && } + ); } diff --git a/app/javascript/mastodon/features/status/components/detailed_status.jsx b/app/javascript/mastodon/features/status/components/detailed_status.jsx index 437e9e86bf..8843619bc9 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.jsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.jsx @@ -9,8 +9,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; -import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; -import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import { AnimatedNumber } from 'mastodon/components/animated_number'; import EditedTimestamp from 'mastodon/components/edited_timestamp'; import { getHashtagBarForStatus } from 'mastodon/components/hashtag_bar'; @@ -143,10 +141,7 @@ class DetailedStatus extends ImmutablePureComponent { let media = ''; let applicationLink = ''; let reblogLink = ''; - const reblogIcon = 'retweet'; - const reblogIconComponent = RepeatIcon; let favouriteLink = ''; - let edited = ''; if (this.props.measureHeight) { outerStyle.height = `${this.state.height}px`; @@ -218,68 +213,53 @@ class DetailedStatus extends ImmutablePureComponent { } if (status.get('application')) { - applicationLink = <> ยท {status.getIn(['application', 'name'])}; + applicationLink = <>ยท{status.getIn(['application', 'name'])}; } - const visibilityLink = <> ยท ; + const visibilityLink = <>ยท; if (['private', 'direct'].includes(status.get('visibility'))) { reblogLink = ''; } else if (this.props.history) { reblogLink = ( - <> - {' ยท '} - - - - - - - + + + + + + ); } else { reblogLink = ( - <> - {' ยท '} - - - - - - - + + + + + + ); } if (this.props.history) { favouriteLink = ( - + ); } else { favouriteLink = ( - + ); } - if (status.get('edited_at')) { - edited = ( - <> - {' ยท '} - - - ); - } - const {statusContentProps, hashtagBar} = getHashtagBarForStatus(status); const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0; @@ -310,9 +290,23 @@ class DetailedStatus extends ImmutablePureComponent { {expanded && hashtagBar}
- - - {edited}{visibilityLink}{applicationLink}{reblogLink} ยท {favouriteLink} +
+ + + + + {visibilityLink} + + {applicationLink} +
+ + {status.get('edited_at') &&
} + +
+ {reblogLink} + {reblogLink && <>ยท} + {favouriteLink} +
diff --git a/app/javascript/mastodon/features/status/containers/detailed_status_container.js b/app/javascript/mastodon/features/status/containers/detailed_status_container.js index 3e1f8d4d29..c3d4fec4db 100644 --- a/app/javascript/mastodon/features/status/containers/detailed_status_container.js +++ b/app/javascript/mastodon/features/status/containers/detailed_status_container.js @@ -4,7 +4,6 @@ import { connect } from 'react-redux'; import { showAlertForError } from '../../../actions/alerts'; import { initBlockModal } from '../../../actions/blocks'; -import { initBoostModal } from '../../../actions/boosts'; import { replyCompose, mentionCompose, @@ -75,17 +74,17 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }, onModalReblog (status, privacy) { - dispatch(reblog(status, privacy)); + dispatch(reblog({ statusId: status.get('id'), visibility: privacy })); }, onReblog (status, e) { if (status.get('reblogged')) { - dispatch(unreblog(status)); + dispatch(unreblog({ statusId: status.get('id') })); } else { if (e.shiftKey || !boostModal) { this.onModalReblog(status); } else { - dispatch(initBoostModal({ status, onReblog: this.onModalReblog })); + dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.onModalReblog } })); } } }, diff --git a/app/javascript/mastodon/features/status/index.jsx b/app/javascript/mastodon/features/status/index.jsx index a3034bb570..7f37cb50d2 100644 --- a/app/javascript/mastodon/features/status/index.jsx +++ b/app/javascript/mastodon/features/status/index.jsx @@ -1,6 +1,6 @@ import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import classNames from 'classnames'; import { Helmet } from 'react-helmet'; @@ -20,6 +20,7 @@ import { Icon } from 'mastodon/components/icon'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import ScrollContainer from 'mastodon/containers/scroll_container'; import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { @@ -27,14 +28,13 @@ import { unmuteAccount, } from '../../actions/accounts'; import { initBlockModal } from '../../actions/blocks'; -import { initBoostModal } from '../../actions/boosts'; import { replyCompose, mentionCompose, directCompose, } from '../../actions/compose'; import { - blockDomain, + initDomainBlockModal, unblockDomain, } from '../../actions/domain_blocks'; import { @@ -190,12 +190,8 @@ const titleFromStatus = (intl, status) => { }; class Status extends ImmutablePureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, status: ImmutablePropTypes.map, @@ -245,7 +241,7 @@ class Status extends ImmutablePureComponent { handleFavouriteClick = (status) => { const { dispatch } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (status.get('favourited')) { @@ -275,7 +271,7 @@ class Status extends ImmutablePureComponent { handleReplyClick = (status) => { const { askReplyConfirmation, dispatch, intl } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (askReplyConfirmation) { @@ -303,21 +299,21 @@ class Status extends ImmutablePureComponent { }; handleModalReblog = (status, privacy) => { - this.props.dispatch(reblog(status, privacy)); + this.props.dispatch(reblog({ statusId: status.get('id'), visibility: privacy })); }; handleReblogClick = (status, e) => { const { dispatch } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; if (signedIn) { if (status.get('reblogged')) { - dispatch(unreblog(status)); + dispatch(unreblog({ statusId: status.get('id') })); } else { if ((e && e.shiftKey) || !boostModal) { this.handleModalReblog(status); } else { - dispatch(initBoostModal({ status, onReblog: this.handleModalReblog })); + dispatch(openModal({ modalType: 'BOOST', modalProps: { status, onReblog: this.handleModalReblog } })); } } } else { @@ -463,15 +459,8 @@ class Status extends ImmutablePureComponent { this.props.dispatch(unblockAccount(account.get('id'))); }; - handleBlockDomainClick = domain => { - this.props.dispatch(openModal({ - modalType: 'CONFIRM', - modalProps: { - message: {domain} }} />, - confirm: this.props.intl.formatMessage(messages.blockDomainConfirm), - onConfirm: () => this.props.dispatch(blockDomain(domain)), - }, - })); + handleBlockDomainClick = account => { + this.props.dispatch(initDomainBlockModal(account)); }; handleUnblockDomainClick = domain => { @@ -753,4 +742,4 @@ class Status extends ImmutablePureComponent { } -export default withRouter(injectIntl(connect(makeMapStateToProps)(Status))); +export default withRouter(injectIntl(connect(makeMapStateToProps)(withIdentity(Status)))); diff --git a/app/javascript/mastodon/features/ui/components/block_modal.jsx b/app/javascript/mastodon/features/ui/components/block_modal.jsx index cfac692324..fc9233a9cc 100644 --- a/app/javascript/mastodon/features/ui/components/block_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/block_modal.jsx @@ -1,100 +1,116 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; +import { useCallback, useState } from 'react'; -import { injectIntl, FormattedMessage } from 'react-intl'; +import { FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; +import classNames from 'classnames'; -import { blockAccount } from '../../../actions/accounts'; -import { closeModal } from '../../../actions/modal'; -import { initReport } from '../../../actions/reports'; -import { Button } from '../../../components/button'; -import { makeGetAccount } from '../../../selectors'; +import { useDispatch } from 'react-redux'; -const makeMapStateToProps = () => { - const getAccount = makeGetAccount(); +import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; +import BlockIcon from '@/material-icons/400-24px/block.svg?react'; +import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react'; +import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; +import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react'; +import { blockAccount } from 'mastodon/actions/accounts'; +import { closeModal } from 'mastodon/actions/modal'; +import { Button } from 'mastodon/components/button'; +import { Icon } from 'mastodon/components/icon'; - const mapStateToProps = state => ({ - account: getAccount(state, state.getIn(['blocks', 'new', 'account_id'])), - }); +export const BlockModal = ({ accountId, acct }) => { + const dispatch = useDispatch(); + const [expanded, setExpanded] = useState(false); - return mapStateToProps; -}; + const domain = acct.split('@')[1]; -const mapDispatchToProps = dispatch => { - return { - onConfirm(account) { - dispatch(blockAccount(account.get('id'))); - }, + const handleClick = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + dispatch(blockAccount(accountId)); + }, [dispatch, accountId]); - onBlockAndReport(account) { - dispatch(blockAccount(account.get('id'))); - dispatch(initReport(account)); - }, + const handleCancel = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + }, [dispatch]); - onClose() { - dispatch(closeModal({ - modalType: undefined, - ignoreFocus: false, - })); - }, - }; -}; + const handleToggleLearnMore = useCallback(() => { + setExpanded(!expanded); + }, [expanded, setExpanded]); -class BlockModal extends PureComponent { + return ( +
+
+
+
+ +
- static propTypes = { - account: PropTypes.object.isRequired, - onClose: PropTypes.func.isRequired, - onBlockAndReport: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - handleClick = () => { - this.props.onClose(); - this.props.onConfirm(this.props.account); - }; - - handleSecondary = () => { - this.props.onClose(); - this.props.onBlockAndReport(this.props.account); - }; - - handleCancel = () => { - this.props.onClose(); - }; - - render () { - const { account } = this.props; - - return ( -
-
-

- @{account.get('acct')} }} - /> -

+
+

+
@{acct}
+
-
-
+ +
+ {domain && ( +
+
+ {domain} }} + /> +
+
+ )} + +
+ {domain && ( + + )} + +
+ + - - + +
- ); - } +
+ ); +}; -} +BlockModal.propTypes = { + accountId: PropTypes.string.isRequired, + acct: PropTypes.string.isRequired, +}; -export default connect(makeMapStateToProps, mapDispatchToProps)(injectIntl(BlockModal)); +export default BlockModal; diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.jsx b/app/javascript/mastodon/features/ui/components/boost_modal.jsx deleted file mode 100644 index 3b3e1e3f97..0000000000 --- a/app/javascript/mastodon/features/ui/components/boost_modal.jsx +++ /dev/null @@ -1,125 +0,0 @@ -import PropTypes from 'prop-types'; - -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; - -import classNames from 'classnames'; -import { withRouter } from 'react-router-dom'; - -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; - -import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; -import { changeBoostPrivacy } from 'mastodon/actions/boosts'; -import AttachmentList from 'mastodon/components/attachment_list'; -import { Icon } from 'mastodon/components/icon'; -import { VisibilityIcon } from 'mastodon/components/visibility_icon'; -import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown'; -import { WithRouterPropTypes } from 'mastodon/utils/react_router'; - -import { Avatar } from '../../../components/avatar'; -import { Button } from '../../../components/button'; -import { DisplayName } from '../../../components/display_name'; -import { RelativeTimestamp } from '../../../components/relative_timestamp'; -import StatusContent from '../../../components/status_content'; - -const messages = defineMessages({ - cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Unboost' }, - reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, -}); - -const mapStateToProps = state => { - return { - privacy: state.getIn(['boosts', 'new', 'privacy']), - }; -}; - -const mapDispatchToProps = dispatch => { - return { - onChangeBoostPrivacy(value) { - dispatch(changeBoostPrivacy(value)); - }, - }; -}; - -class BoostModal extends ImmutablePureComponent { - static propTypes = { - status: ImmutablePropTypes.map.isRequired, - onReblog: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - onChangeBoostPrivacy: PropTypes.func.isRequired, - privacy: PropTypes.string.isRequired, - intl: PropTypes.object.isRequired, - ...WithRouterPropTypes, - }; - - handleReblog = () => { - this.props.onReblog(this.props.status, this.props.privacy); - this.props.onClose(); - }; - - handleAccountClick = (e) => { - if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.props.onClose(); - this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); - } - }; - - _findContainer = () => { - return document.getElementsByClassName('modal-root__container')[0]; - }; - - render () { - const { status, privacy, intl } = this.props; - const buttonText = status.get('reblogged') ? messages.cancel_reblog : messages.reblog; - - return ( -
-
-
- - - - - {status.get('media_attachments').size > 0 && ( - - )} -
-
- -
-
Shift + }} />
- {status.get('visibility') !== 'private' && !status.get('reblogged') && ( - - )} -
-
- ); - } - -} - -export default withRouter(connect(mapStateToProps, mapDispatchToProps)(injectIntl(BoostModal))); diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.tsx b/app/javascript/mastodon/features/ui/components/boost_modal.tsx new file mode 100644 index 0000000000..40b0c81833 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/boost_modal.tsx @@ -0,0 +1,162 @@ +import type { MouseEventHandler } from 'react'; +import { useCallback, useState } from 'react'; + +import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; + +import classNames from 'classnames'; +import { useHistory } from 'react-router'; + +import type Immutable from 'immutable'; + +import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react'; +import AttachmentList from 'mastodon/components/attachment_list'; +import { Icon } from 'mastodon/components/icon'; +import { VisibilityIcon } from 'mastodon/components/visibility_icon'; +import PrivacyDropdown from 'mastodon/features/compose/components/privacy_dropdown'; +import type { Account } from 'mastodon/models/account'; +import type { Status, StatusVisibility } from 'mastodon/models/status'; +import { useAppSelector } from 'mastodon/store'; + +import { Avatar } from '../../../components/avatar'; +import { Button } from '../../../components/button'; +import { DisplayName } from '../../../components/display_name'; +import { RelativeTimestamp } from '../../../components/relative_timestamp'; +import StatusContent from '../../../components/status_content'; + +const messages = defineMessages({ + cancel_reblog: { + id: 'status.cancel_reblog_private', + defaultMessage: 'Unboost', + }, + reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, +}); + +export const BoostModal: React.FC<{ + status: Status; + onClose: () => void; + onReblog: (status: Status, privacy: StatusVisibility) => void; +}> = ({ status, onReblog, onClose }) => { + const intl = useIntl(); + const history = useHistory(); + + const default_privacy = useAppSelector( + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + (state) => state.compose.get('default_privacy') as StatusVisibility, + ); + + const account = status.get('account') as Account; + const statusVisibility = status.get('visibility') as StatusVisibility; + + const [privacy, setPrivacy] = useState( + statusVisibility === 'private' ? 'private' : default_privacy, + ); + + const onPrivacyChange = useCallback((value: StatusVisibility) => { + setPrivacy(value); + }, []); + + const handleReblog = useCallback(() => { + onReblog(status, privacy); + onClose(); + }, [onClose, onReblog, status, privacy]); + + const handleAccountClick = useCallback( + (e) => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + onClose(); + history.push(`/@${account.acct}`); + } + }, + [history, onClose, account], + ); + + const buttonText = status.get('reblogged') + ? messages.cancel_reblog + : messages.reblog; + + const findContainer = useCallback( + () => document.getElementsByClassName('modal-root__container')[0], + [], + ); + + return ( +
+
+
+ + + {/* @ts-expect-error Expected until StatusContent is typed */} + + + {(status.get('media_attachments') as Immutable.List).size > + 0 && ( + + )} +
+
+ +
+
+ + Shift + + + ), + }} + /> +
+ {statusVisibility !== 'private' && !status.get('reblogged') && ( + + )} +
+
+ ); +}; diff --git a/app/javascript/mastodon/features/ui/components/column_link.jsx b/app/javascript/mastodon/features/ui/components/column_link.jsx index e58fde48b5..6ef122c07b 100644 --- a/app/javascript/mastodon/features/ui/components/column_link.jsx +++ b/app/javascript/mastodon/features/ui/components/column_link.jsx @@ -1,27 +1,30 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; -import { NavLink } from 'react-router-dom'; +import { useRouteMatch, NavLink } from 'react-router-dom'; import { Icon } from 'mastodon/components/icon'; -const ColumnLink = ({ icon, iconComponent, text, to, href, method, badge, transparent, ...other }) => { +const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text, to, href, method, badge, transparent, ...other }) => { + const match = useRouteMatch(to); const className = classNames('column-link', { 'column-link--transparent': transparent }); const badgeElement = typeof badge !== 'undefined' ? {badge} : null; const iconElement = (typeof icon === 'string' || iconComponent) ? : icon; + const activeIconElement = activeIcon ?? (activeIconComponent ? : iconElement); + const active = match?.isExact; if (href) { return ( - {iconElement} + {active ? activeIconElement : iconElement} {text} {badgeElement} ); } else { return ( - - {iconElement} + + {active ? activeIconElement : iconElement} {text} {badgeElement} @@ -32,6 +35,8 @@ const ColumnLink = ({ icon, iconComponent, text, to, href, method, badge, transp ColumnLink.propTypes = { icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, iconComponent: PropTypes.func, + activeIcon: PropTypes.node, + activeIconComponent: PropTypes.func, text: PropTypes.string.isRequired, to: PropTypes.string, href: PropTypes.string, diff --git a/app/javascript/mastodon/features/ui/components/compose_panel.jsx b/app/javascript/mastodon/features/ui/components/compose_panel.jsx index e6ac79bdd9..18321cbe63 100644 --- a/app/javascript/mastodon/features/ui/components/compose_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/compose_panel.jsx @@ -7,16 +7,13 @@ import { changeComposing, mountCompose, unmountCompose } from 'mastodon/actions/ import ServerBanner from 'mastodon/components/server_banner'; import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container'; import SearchContainer from 'mastodon/features/compose/containers/search_container'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import LinkFooter from './link_footer'; class ComposePanel extends PureComponent { - - static contextTypes = { - identity: PropTypes.object.isRequired, - }; - static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, }; @@ -41,7 +38,7 @@ class ComposePanel extends PureComponent { } render() { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; return (
@@ -65,4 +62,4 @@ class ComposePanel extends PureComponent { } -export default connect()(ComposePanel); +export default connect()(withIdentity(ComposePanel)); diff --git a/app/javascript/mastodon/features/ui/components/domain_block_modal.jsx b/app/javascript/mastodon/features/ui/components/domain_block_modal.jsx new file mode 100644 index 0000000000..e69db63489 --- /dev/null +++ b/app/javascript/mastodon/features/ui/components/domain_block_modal.jsx @@ -0,0 +1,106 @@ +import PropTypes from 'prop-types'; +import { useCallback } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { useDispatch } from 'react-redux'; + +import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react'; +import DomainDisabledIcon from '@/material-icons/400-24px/domain_disabled.svg?react'; +import HistoryIcon from '@/material-icons/400-24px/history.svg?react'; +import PersonRemoveIcon from '@/material-icons/400-24px/person_remove.svg?react'; +import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; +import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react'; +import { blockAccount } from 'mastodon/actions/accounts'; +import { blockDomain } from 'mastodon/actions/domain_blocks'; +import { closeModal } from 'mastodon/actions/modal'; +import { Button } from 'mastodon/components/button'; +import { Icon } from 'mastodon/components/icon'; + +export const DomainBlockModal = ({ domain, accountId, acct }) => { + const dispatch = useDispatch(); + + const handleClick = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + dispatch(blockDomain(domain)); + }, [dispatch, domain]); + + const handleSecondaryClick = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + dispatch(blockAccount(accountId)); + }, [dispatch, accountId]); + + const handleCancel = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + }, [dispatch]); + + return ( +
+
+
+
+ +
+ +
+

+
{domain}
+
+
+ +
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+
+
+
+ +
+
+ + +
+ + + + +
+
+
+ ); +}; + +DomainBlockModal.propTypes = { + domain: PropTypes.string.isRequired, + accountId: PropTypes.string.isRequired, + acct: PropTypes.string.isRequired, +}; + +export default DomainBlockModal; diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx index 5f430d5392..7adfc208e7 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.jsx @@ -22,7 +22,7 @@ import { GIFV } from 'mastodon/components/gifv'; import { IconButton } from 'mastodon/components/icon_button'; import Audio from 'mastodon/features/audio'; import { CharacterCounter } from 'mastodon/features/compose/components/character_counter'; -import UploadProgress from 'mastodon/features/compose/components/upload_progress'; +import { UploadProgress } from 'mastodon/features/compose/components/upload_progress'; import { Tesseract as fetchTesseract } from 'mastodon/features/ui/util/async-components'; import { me } from 'mastodon/initial_state'; import { assetHost } from 'mastodon/utils/config'; diff --git a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx b/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx deleted file mode 100644 index 4aa0092631..0000000000 --- a/app/javascript/mastodon/features/ui/components/follow_requests_column_link.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import PropTypes from 'prop-types'; -import { Component } from 'react'; - -import { injectIntl, defineMessages } from 'react-intl'; - -import { List as ImmutableList } from 'immutable'; -import { connect } from 'react-redux'; - -import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; -import { fetchFollowRequests } from 'mastodon/actions/accounts'; -import { IconWithBadge } from 'mastodon/components/icon_with_badge'; -import ColumnLink from 'mastodon/features/ui/components/column_link'; - -const messages = defineMessages({ - text: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, -}); - -const mapStateToProps = state => ({ - count: state.getIn(['user_lists', 'follow_requests', 'items'], ImmutableList()).size, -}); - -class FollowRequestsColumnLink extends Component { - - static propTypes = { - dispatch: PropTypes.func.isRequired, - count: PropTypes.number.isRequired, - intl: PropTypes.object.isRequired, - }; - - componentDidMount () { - const { dispatch } = this.props; - - dispatch(fetchFollowRequests()); - } - - render () { - const { count, intl } = this.props; - - if (count === 0) { - return null; - } - - return ( - } - text={intl.formatMessage(messages.text)} - /> - ); - } - -} - -export default injectIntl(connect(mapStateToProps)(FollowRequestsColumnLink)); diff --git a/app/javascript/mastodon/features/ui/components/header.jsx b/app/javascript/mastodon/features/ui/components/header.jsx index 2f8636b12a..19c76c722b 100644 --- a/app/javascript/mastodon/features/ui/components/header.jsx +++ b/app/javascript/mastodon/features/ui/components/header.jsx @@ -13,6 +13,7 @@ import { fetchServer } from 'mastodon/actions/server'; import { Avatar } from 'mastodon/components/avatar'; import { Icon } from 'mastodon/components/icon'; import { WordmarkLogo, SymbolLogo } from 'mastodon/components/logo'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { registrationsOpen, me, sso_redirect } from 'mastodon/initial_state'; const Account = connect(state => ({ @@ -41,12 +42,8 @@ const mapDispatchToProps = (dispatch) => ({ }); class Header extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, openClosedRegistrationsModal: PropTypes.func, location: PropTypes.object, signupUrl: PropTypes.string.isRequired, @@ -60,7 +57,7 @@ class Header extends PureComponent { } render () { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const { location, openClosedRegistrationsModal, signupUrl, intl } = this.props; let content; @@ -121,4 +118,4 @@ class Header extends PureComponent { } -export default injectIntl(withRouter(connect(mapStateToProps, mapDispatchToProps)(Header))); +export default injectIntl(withRouter(withIdentity(connect(mapStateToProps, mapDispatchToProps)(Header)))); diff --git a/app/javascript/mastodon/features/ui/components/link_footer.jsx b/app/javascript/mastodon/features/ui/components/link_footer.jsx index 6b1555243b..08af6fa444 100644 --- a/app/javascript/mastodon/features/ui/components/link_footer.jsx +++ b/app/javascript/mastodon/features/ui/components/link_footer.jsx @@ -8,6 +8,7 @@ import { Link } from 'react-router-dom'; import { connect } from 'react-redux'; import { openModal } from 'mastodon/actions/modal'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { domain, version, source_url, statusPageUrl, profile_directory as profileDirectory } from 'mastodon/initial_state'; import { PERMISSION_INVITE_USERS } from 'mastodon/permissions'; import { logOut } from 'mastodon/utils/log_out'; @@ -32,12 +33,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ }); class LinkFooter extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, multiColumn: PropTypes.bool, onLogout: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, @@ -53,7 +50,7 @@ class LinkFooter extends PureComponent { }; render () { - const { signedIn, permissions } = this.context.identity; + const { signedIn, permissions } = this.props.identity; const { multiColumn } = this.props; const canInvite = signedIn && ((permissions & PERMISSION_INVITE_USERS) === PERMISSION_INVITE_USERS); @@ -108,4 +105,4 @@ class LinkFooter extends PureComponent { } -export default injectIntl(connect(null, mapDispatchToProps)(LinkFooter)); +export default injectIntl(withIdentity(connect(null, mapDispatchToProps)(LinkFooter))); diff --git a/app/javascript/mastodon/features/ui/components/list_panel.jsx b/app/javascript/mastodon/features/ui/components/list_panel.jsx index fec21f14ca..03c8fce9e8 100644 --- a/app/javascript/mastodon/features/ui/components/list_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/list_panel.jsx @@ -1,10 +1,9 @@ -import PropTypes from 'prop-types'; +import { useEffect } from 'react'; import { createSelector } from '@reduxjs/toolkit'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { connect } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; +import ListAltActiveIcon from '@/material-icons/400-24px/list_alt-fill.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import { fetchLists } from 'mastodon/actions/lists'; @@ -18,40 +17,25 @@ const getOrderedLists = createSelector([state => state.get('lists')], lists => { return lists.toList().filter(item => !!item).sort((a, b) => a.get('title').localeCompare(b.get('title'))).take(4); }); -const mapStateToProps = state => ({ - lists: getOrderedLists(state), -}); +export const ListPanel = () => { + const dispatch = useDispatch(); + const lists = useSelector(state => getOrderedLists(state)); -class ListPanel extends ImmutablePureComponent { - - static propTypes = { - dispatch: PropTypes.func.isRequired, - lists: ImmutablePropTypes.list, - }; - - componentDidMount () { - const { dispatch } = this.props; + useEffect(() => { dispatch(fetchLists()); + }, [dispatch]); + + if (!lists || lists.isEmpty()) { + return null; } - render () { - const { lists } = this.props; + return ( +
+
- if (!lists || lists.isEmpty()) { - return null; - } - - return ( -
-
- - {lists.map(list => ( - - ))} -
- ); - } - -} - -export default connect(mapStateToProps)(ListPanel); + {lists.map(list => ( + + ))} +
+ ); +}; diff --git a/app/javascript/mastodon/features/ui/components/modal_root.jsx b/app/javascript/mastodon/features/ui/components/modal_root.jsx index 46f0dc706f..404b53c742 100644 --- a/app/javascript/mastodon/features/ui/components/modal_root.jsx +++ b/app/javascript/mastodon/features/ui/components/modal_root.jsx @@ -7,6 +7,7 @@ import Base from 'mastodon/components/modal_root'; import { MuteModal, BlockModal, + DomainBlockModal, ReportModal, EmbedModal, ListEditor, @@ -23,7 +24,7 @@ import BundleContainer from '../containers/bundle_container'; import ActionsModal from './actions_modal'; import AudioModal from './audio_modal'; -import BoostModal from './boost_modal'; +import { BoostModal } from './boost_modal'; import BundleModalError from './bundle_modal_error'; import ConfirmationModal from './confirmation_modal'; import FocalPointModal from './focal_point_modal'; @@ -41,6 +42,7 @@ export const MODAL_COMPONENTS = { 'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }), 'MUTE': MuteModal, 'BLOCK': BlockModal, + 'DOMAIN_BLOCK': DomainBlockModal, 'REPORT': ReportModal, 'ACTIONS': () => Promise.resolve({ default: ActionsModal }), 'EMBED': EmbedModal, diff --git a/app/javascript/mastodon/features/ui/components/mute_modal.jsx b/app/javascript/mastodon/features/ui/components/mute_modal.jsx index fa81ea81a3..df466cfac6 100644 --- a/app/javascript/mastodon/features/ui/components/mute_modal.jsx +++ b/app/javascript/mastodon/features/ui/components/mute_modal.jsx @@ -1,138 +1,154 @@ import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; +import { useCallback, useState } from 'react'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; +import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; -import { connect } from 'react-redux'; +import classNames from 'classnames'; -import Toggle from 'react-toggle'; +import { useDispatch } from 'react-redux'; -import { muteAccount } from '../../../actions/accounts'; -import { closeModal } from '../../../actions/modal'; -import { toggleHideNotifications, changeMuteDuration } from '../../../actions/mutes'; -import { Button } from '../../../components/button'; + +import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; +import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react'; +import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; +import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react'; +import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react'; +import { muteAccount } from 'mastodon/actions/accounts'; +import { closeModal } from 'mastodon/actions/modal'; +import { Button } from 'mastodon/components/button'; +import { CheckBox } from 'mastodon/components/check_box'; +import { Icon } from 'mastodon/components/icon'; +import { RadioButton } from 'mastodon/components/radio_button'; const messages = defineMessages({ minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' }, hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' }, days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' }, - indefinite: { id: 'mute_modal.indefinite', defaultMessage: 'Indefinite' }, + indefinite: { id: 'mute_modal.indefinite', defaultMessage: 'Until I unmute them' }, + hideFromNotifications: { id: 'mute_modal.hide_from_notifications', defaultMessage: 'Hide from notifications' }, }); -const mapStateToProps = state => { - return { - account: state.getIn(['mutes', 'new', 'account']), - notifications: state.getIn(['mutes', 'new', 'notifications']), - muteDuration: state.getIn(['mutes', 'new', 'duration']), - }; +const RadioButtonLabel = ({ name, value, currentValue, onChange, label }) => ( + +); + +RadioButtonLabel.propTypes = { + name: PropTypes.string, + value: PropTypes.oneOf([PropTypes.string, PropTypes.number, PropTypes.bool]), + currentValue: PropTypes.oneOf([PropTypes.string, PropTypes.number, PropTypes.bool]), + checked: PropTypes.bool, + onChange: PropTypes.func, + label: PropTypes.node, }; -const mapDispatchToProps = dispatch => { - return { - onConfirm(account, notifications, muteDuration) { - dispatch(muteAccount(account.get('id'), notifications, muteDuration)); - }, +export const MuteModal = ({ accountId, acct }) => { + const intl = useIntl(); + const dispatch = useDispatch(); + const [notifications, setNotifications] = useState(true); + const [muteDuration, setMuteDuration] = useState('0'); + const [expanded, setExpanded] = useState(false); - onClose() { - dispatch(closeModal({ - modalType: undefined, - ignoreFocus: false, - })); - }, + const handleClick = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + dispatch(muteAccount(accountId, notifications, muteDuration)); + }, [dispatch, accountId, notifications, muteDuration]); - onToggleNotifications() { - dispatch(toggleHideNotifications()); - }, + const handleCancel = useCallback(() => { + dispatch(closeModal({ modalType: undefined, ignoreFocus: false })); + }, [dispatch]); - onChangeMuteDuration(e) { - dispatch(changeMuteDuration(e.target.value)); - }, - }; -}; + const handleToggleNotifications = useCallback(({ target }) => { + setNotifications(target.checked); + }, [setNotifications]); -class MuteModal extends PureComponent { + const handleChangeMuteDuration = useCallback(({ target }) => { + setMuteDuration(target.value); + }, [setMuteDuration]); - static propTypes = { - account: PropTypes.object.isRequired, - notifications: PropTypes.bool.isRequired, - onClose: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired, - onToggleNotifications: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - muteDuration: PropTypes.number.isRequired, - onChangeMuteDuration: PropTypes.func.isRequired, - }; + const handleToggleSettings = useCallback(() => { + setExpanded(!expanded); + }, [expanded, setExpanded]); - handleClick = () => { - this.props.onClose(); - this.props.onConfirm(this.props.account, this.props.notifications, this.props.muteDuration); - }; - - handleCancel = () => { - this.props.onClose(); - }; - - toggleNotifications = () => { - this.props.onToggleNotifications(); - }; - - changeMuteDuration = (e) => { - this.props.onChangeMuteDuration(e); - }; - - render () { - const { account, notifications, muteDuration, intl } = this.props; - - return ( -
-
-

- @{account.get('acct')} }} - /> -

-

- -

-
- - + return ( +
+
+
+
+
-
- : - +
+

+
@{acct}
-
-
+ +
+
+
+ + + + +
+ +
+ +
+
+ +
+ + +
+ + - + +
- ); - } +
+ ); +}; -} +MuteModal.propTypes = { + accountId: PropTypes.string.isRequired, + acct: PropTypes.string.isRequired, +}; -export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(MuteModal)); +export default MuteModal; diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx index bf5e2826bb..ff90eef359 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.jsx +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.jsx @@ -1,30 +1,43 @@ import PropTypes from 'prop-types'; -import { Component } from 'react'; +import { Component, useEffect } from 'react'; -import { defineMessages, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl, useIntl } from 'react-intl'; import { Link } from 'react-router-dom'; +import { useSelector, useDispatch } from 'react-redux'; + + import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; -import BookmarksIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; -import HomeIcon from '@/material-icons/400-24px/home-fill.svg?react'; +import BookmarksActiveIcon from '@/material-icons/400-24px/bookmarks-fill.svg?react'; +import BookmarksIcon from '@/material-icons/400-24px/bookmarks.svg?react'; +import ExploreActiveIcon from '@/material-icons/400-24px/explore-fill.svg?react'; +import ExploreIcon from '@/material-icons/400-24px/explore.svg?react'; +import HomeActiveIcon from '@/material-icons/400-24px/home-fill.svg?react'; +import HomeIcon from '@/material-icons/400-24px/home.svg?react'; +import ListAltActiveIcon from '@/material-icons/400-24px/list_alt-fill.svg?react'; import ListAltIcon from '@/material-icons/400-24px/list_alt.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; +import NotificationsActiveIcon from '@/material-icons/400-24px/notifications-fill.svg?react'; +import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react'; +import PersonAddActiveIcon from '@/material-icons/400-24px/person_add-fill.svg?react'; +import PersonAddIcon from '@/material-icons/400-24px/person_add.svg?react'; import PublicIcon from '@/material-icons/400-24px/public.svg?react'; import SearchIcon from '@/material-icons/400-24px/search.svg?react'; -import SettingsIcon from '@/material-icons/400-24px/settings-fill.svg?react'; -import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; -import TagIcon from '@/material-icons/400-24px/tag.svg?react'; +import SettingsIcon from '@/material-icons/400-24px/settings.svg?react'; +import StarActiveIcon from '@/material-icons/400-24px/star-fill.svg?react'; +import StarIcon from '@/material-icons/400-24px/star.svg?react'; +import { fetchFollowRequests } from 'mastodon/actions/accounts'; +import { IconWithBadge } from 'mastodon/components/icon_with_badge'; import { WordmarkLogo } from 'mastodon/components/logo'; import { NavigationPortal } from 'mastodon/components/navigation_portal'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { timelinePreview, trendsEnabled } from 'mastodon/initial_state'; import { transientSingleColumn } from 'mastodon/is_mobile'; import ColumnLink from './column_link'; import DisabledAccountBanner from './disabled_account_banner'; -import FollowRequestsColumnLink from './follow_requests_column_link'; -import ListPanel from './list_panel'; -import NotificationsCounterIcon from './notifications_counter_icon'; +import { ListPanel } from './list_panel'; import SignInBanner from './sign_in_banner'; const messages = defineMessages({ @@ -42,15 +55,51 @@ const messages = defineMessages({ search: { id: 'navigation_bar.search', defaultMessage: 'Search' }, advancedInterface: { id: 'navigation_bar.advanced_interface', defaultMessage: 'Open in advanced web interface' }, openedInClassicInterface: { id: 'navigation_bar.opened_in_classic_interface', defaultMessage: 'Posts, accounts, and other specific pages are opened by default in the classic web interface.' }, + followRequests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' }, }); +const NotificationsLink = () => { + const count = useSelector(state => state.getIn(['notifications', 'unread'])); + const intl = useIntl(); + + return ( + } + activeIcon={} + text={intl.formatMessage(messages.notifications)} + /> + ); +}; + +const FollowRequestsLink = () => { + const count = useSelector(state => state.getIn(['user_lists', 'follow_requests', 'items'])?.size ?? 0); + const intl = useIntl(); + const dispatch = useDispatch(); + + useEffect(() => { + dispatch(fetchFollowRequests()); + }, [dispatch]); + + if (count === 0) { + return null; + } + + return ( + } + activeIcon={} + text={intl.formatMessage(messages.followRequests)} + /> + ); +}; + class NavigationPanel extends Component { - - static contextTypes = { - identity: PropTypes.object.isRequired, - }; - static propTypes = { + identity: identityContextPropShape, intl: PropTypes.object.isRequired, }; @@ -60,7 +109,7 @@ class NavigationPanel extends Component { render () { const { intl } = this.props; - const { signedIn, disabledAccountId } = this.context.identity; + const { signedIn, disabledAccountId } = this.props.identity; let banner = undefined; @@ -87,14 +136,14 @@ class NavigationPanel extends Component { {signedIn && ( <> - - } text={intl.formatMessage(messages.notifications)} /> - + + + )} {trendsEnabled ? ( - + ) : ( )} @@ -113,9 +162,9 @@ class NavigationPanel extends Component { {signedIn && ( <> - - - + + + @@ -137,4 +186,4 @@ class NavigationPanel extends Component { } -export default injectIntl(NavigationPanel); +export default injectIntl(withIdentity(NavigationPanel)); diff --git a/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js b/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js deleted file mode 100644 index 7d59d616d8..0000000000 --- a/app/javascript/mastodon/features/ui/components/notifications_counter_icon.js +++ /dev/null @@ -1,13 +0,0 @@ -import { connect } from 'react-redux'; - -import NotificationsIcon from '@/material-icons/400-24px/notifications-fill.svg?react'; -import { IconWithBadge } from 'mastodon/components/icon_with_badge'; - - -const mapStateToProps = state => ({ - count: state.getIn(['notifications', 'unread']), - id: 'bell', - icon: NotificationsIcon, -}); - -export default connect(mapStateToProps)(IconWithBadge); diff --git a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx index 4216f3da38..74a8fdb841 100644 --- a/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx +++ b/app/javascript/mastodon/features/ui/components/sign_in_banner.jsx @@ -22,7 +22,8 @@ const SignInBanner = () => { if (sso_redirect) { return (
-

+

+

); @@ -44,7 +45,8 @@ const SignInBanner = () => { return (
-

+

+

{signupButton}
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index b17b59a0e6..7742f64860 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -14,7 +14,8 @@ import { HotKeys } from 'react-hotkeys'; import { focusApp, unfocusApp, changeLayout } from 'mastodon/actions/app'; import { synchronouslySubmitMarkers, submitMarkers, fetchMarkers } from 'mastodon/actions/markers'; import { INTRODUCTION_VERSION } from 'mastodon/actions/onboarding'; -import PictureInPicture from 'mastodon/features/picture_in_picture'; +import { PictureInPicture } from 'mastodon/features/picture_in_picture'; +import { identityContextPropShape, withIdentity } from 'mastodon/identity_context'; import { layoutFromWindow } from 'mastodon/is_mobile'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; @@ -48,6 +49,8 @@ import { DirectTimeline, HashtagTimeline, Notifications, + NotificationRequests, + NotificationRequest, FollowRequests, FavouritedStatuses, BookmarkedStatuses, @@ -80,7 +83,6 @@ const mapStateToProps = state => ({ hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, - dropdownMenuIsOpen: state.dropdownMenu.openId !== null, firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION, username: state.getIn(['accounts', me, 'username']), }); @@ -88,7 +90,7 @@ const mapStateToProps = state => ({ const keyMap = { help: '?', new: 'n', - search: 's', + search: ['s', '/'], forceNew: 'option+n', toggleComposeSpoilers: 'option+x', focusColumn: ['1', '2', '3', '4', '5', '6', '7', '8', '9'], @@ -119,12 +121,8 @@ const keyMap = { }; class SwitchingColumnsArea extends PureComponent { - - static contextTypes = { - identity: PropTypes.object, - }; - static propTypes = { + identity: identityContextPropShape, children: PropTypes.node, location: PropTypes.object, singleColumn: PropTypes.bool, @@ -159,7 +157,7 @@ class SwitchingColumnsArea extends PureComponent { render () { const { children, singleColumn } = this.props; - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; const pathName = this.props.location.pathname; let redirect; @@ -204,7 +202,9 @@ class SwitchingColumnsArea extends PureComponent { - + + + @@ -249,12 +249,8 @@ class SwitchingColumnsArea extends PureComponent { } class UI extends PureComponent { - - static contextTypes = { - identity: PropTypes.object.isRequired, - }; - static propTypes = { + identity: identityContextPropShape, dispatch: PropTypes.func.isRequired, children: PropTypes.node, isComposing: PropTypes.bool, @@ -262,7 +258,6 @@ class UI extends PureComponent { hasMediaAttachments: PropTypes.bool, canUploadMore: PropTypes.bool, intl: PropTypes.object.isRequired, - dropdownMenuIsOpen: PropTypes.bool, layout: PropTypes.string.isRequired, firstLaunch: PropTypes.bool, username: PropTypes.string, @@ -307,7 +302,7 @@ class UI extends PureComponent { this.dragTargets.push(e.target); } - if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files') && this.props.canUploadMore && this.context.identity.signedIn) { + if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files') && this.props.canUploadMore && this.props.identity.signedIn) { this.setState({ draggingOver: true }); } }; @@ -335,7 +330,7 @@ class UI extends PureComponent { this.setState({ draggingOver: false }); this.dragTargets = []; - if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore && this.context.identity.signedIn) { + if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore && this.props.identity.signedIn) { this.props.dispatch(uploadCompose(e.dataTransfer.files)); } }; @@ -387,7 +382,7 @@ class UI extends PureComponent { }; componentDidMount () { - const { signedIn } = this.context.identity; + const { signedIn } = this.props.identity; window.addEventListener('focus', this.handleWindowFocus, false); window.addEventListener('blur', this.handleWindowBlur, false); @@ -555,7 +550,7 @@ class UI extends PureComponent { render () { const { draggingOver } = this.state; - const { children, isComposing, location, dropdownMenuIsOpen, layout } = this.props; + const { children, isComposing, location, layout } = this.props; const handlers = { help: this.handleHotkeyToggleHelp, @@ -581,10 +576,10 @@ class UI extends PureComponent { return ( -
+
- + {children} @@ -600,4 +595,4 @@ class UI extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(withRouter(UI))); +export default connect(mapStateToProps)(injectIntl(withRouter(withIdentity(UI)))); diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js index 7b968204be..e1f5bfdaf6 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -118,6 +118,10 @@ export function BlockModal () { return import(/* webpackChunkName: "modals/block_modal" */'../components/block_modal'); } +export function DomainBlockModal () { + return import(/* webpackChunkName: "modals/domain_block_modal" */'../components/domain_block_modal'); +} + export function ReportModal () { return import(/* webpackChunkName: "modals/report_modal" */'../components/report_modal'); } @@ -189,3 +193,11 @@ export function About () { export function PrivacyPolicy () { return import(/*webpackChunkName: "features/privacy_policy" */'../../privacy_policy'); } + +export function NotificationRequests () { + return import(/*webpackChunkName: "features/notifications/requests" */'../../notifications/requests'); +} + +export function NotificationRequest () { + return import(/*webpackChunkName: "features/notifications/request" */'../../notifications/request'); +} diff --git a/app/javascript/mastodon/features/ui/util/sensitive_media_context.tsx b/app/javascript/mastodon/features/ui/util/sensitive_media_context.tsx new file mode 100644 index 0000000000..408154c31b --- /dev/null +++ b/app/javascript/mastodon/features/ui/util/sensitive_media_context.tsx @@ -0,0 +1,28 @@ +import { createContext, useContext, useMemo } from 'react'; + +export const SensitiveMediaContext = createContext<{ + hideMediaByDefault: boolean; +}>({ + hideMediaByDefault: false, +}); + +export function useSensitiveMediaContext() { + return useContext(SensitiveMediaContext); +} + +type ContextValue = React.ContextType; + +export const SensitiveMediaContextProvider: React.FC< + React.PropsWithChildren<{ hideMediaByDefault: boolean }> +> = ({ hideMediaByDefault, children }) => { + const contextValue = useMemo( + () => ({ hideMediaByDefault }), + [hideMediaByDefault], + ); + + return ( + + {children} + + ); +}; diff --git a/app/javascript/mastodon/identity_context.tsx b/app/javascript/mastodon/identity_context.tsx new file mode 100644 index 0000000000..7f28ab77a3 --- /dev/null +++ b/app/javascript/mastodon/identity_context.tsx @@ -0,0 +1,70 @@ +import PropTypes from 'prop-types'; +import { createContext, useContext } from 'react'; + +import hoistStatics from 'hoist-non-react-statics'; + +import type { InitialState } from 'mastodon/initial_state'; + +export interface IdentityContextType { + signedIn: boolean; + accountId: string | undefined; + disabledAccountId: string | undefined; + permissions: number; +} + +export const identityContextPropShape = PropTypes.shape({ + signedIn: PropTypes.bool.isRequired, + accountId: PropTypes.string, + disabledAccountId: PropTypes.string, +}).isRequired; + +export const createIdentityContext = (state: InitialState) => ({ + signedIn: !!state.meta.me, + accountId: state.meta.me, + disabledAccountId: state.meta.disabled_account_id, + permissions: state.role?.permissions ?? 0, +}); + +export const IdentityContext = createContext({ + signedIn: false, + permissions: 0, + accountId: undefined, + disabledAccountId: undefined, +}); + +export const useIdentity = () => useContext(IdentityContext); + +export interface IdentityProps { + ref?: unknown; + wrappedComponentRef?: unknown; +} + +/* Injects an `identity` props into the wrapped component to be able to use the new context in class components */ +export function withIdentity< + ComponentType extends React.ComponentType, +>(Component: ComponentType) { + const displayName = `withIdentity(${Component.displayName ?? Component.name})`; + const C = (props: React.ComponentProps) => { + const { wrappedComponentRef, ...remainingProps } = props; + + return ( + + {(context) => { + return ( + // @ts-expect-error - Dynamic covariant generic components are tough to type. + + ); + }} + + ); + }; + + C.displayName = displayName; + C.WrappedComponent = Component; + + return hoistStatics(C, Component); +} diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 596c9ca49f..9ec3df0df8 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -38,19 +38,28 @@ * @property {string} title * @property {boolean} show_trends * @property {boolean} trends_as_landing_page - * @property {boolean} unfollow_modal * @property {boolean} use_blurhash * @property {boolean=} use_pending_items * @property {string} version * @property {string} sso_redirect */ +/** + * @typedef Role + * @property {string} id + * @property {string} name + * @property {string} permissions + * @property {string} color + * @property {boolean} highlighted + */ + /** * @typedef InitialState * @property {Record} accounts * @property {InitialStateLanguage[]} languages * @property {boolean=} critical_updates_pending * @property {InitialStateMeta} meta + * @property {Role?} role */ const element = document.getElementById('initial-state'); @@ -99,7 +108,6 @@ export const source_url = getMeta('source_url'); export const timelinePreview = getMeta('timeline_preview'); export const title = getMeta('title'); export const trendsAsLanding = getMeta('trends_as_landing_page'); -export const unfollowModal = getMeta('unfollow_modal'); export const useBlurhash = getMeta('use_blurhash'); export const usePendingItems = getMeta('use_pending_items'); export const version = getMeta('version'); @@ -109,4 +117,11 @@ export const criticalUpdatesPending = initialState?.critical_updates_pending; export const statusPageUrl = getMeta('status_page_url'); export const sso_redirect = getMeta('sso_redirect'); +/** + * @returns {string | undefined} + */ +export function getAccessToken() { + return getMeta('access_token'); +} + export default initialState; diff --git a/app/javascript/mastodon/locales/af.json b/app/javascript/mastodon/locales/af.json index baa7e7bf70..e4f7f12b0e 100644 --- a/app/javascript/mastodon/locales/af.json +++ b/app/javascript/mastodon/locales/af.json @@ -119,9 +119,7 @@ "compose_form.spoiler.marked": "Verwyder inhoudswaarskuwing", "compose_form.spoiler.unmarked": "Voeg inhoudswaarskuwing by", "confirmation_modal.cancel": "Kanselleer", - "confirmations.block.block_and_report": "Blokkeer en rapporteer", "confirmations.block.confirm": "Blokkeer", - "confirmations.block.message": "Is jy seker jy wil {name} blokkeer?", "confirmations.cancel_follow_request.confirm": "Herroep versoek", "confirmations.cancel_follow_request.message": "Is jy seker jy wil jou versoek om {name} te volg, terugtrek?", "confirmations.delete.confirm": "Wis uit", @@ -129,7 +127,6 @@ "confirmations.delete_list.confirm": "Wis uit", "confirmations.delete_list.message": "Is jy seker jy wil hierdie lys permanent verwyder?", "confirmations.discard_edit_media.confirm": "Gooi weg", - "confirmations.domain_block.confirm": "Blokkeer die hele domein", "confirmations.logout.confirm": "Teken Uit", "confirmations.logout.message": "Is jy seker jy wil uitteken?", "confirmations.reply.confirm": "Antwoord", diff --git a/app/javascript/mastodon/locales/an.json b/app/javascript/mastodon/locales/an.json index e9d609a1ce..af5f8426d0 100644 --- a/app/javascript/mastodon/locales/an.json +++ b/app/javascript/mastodon/locales/an.json @@ -132,9 +132,7 @@ "compose_form.spoiler.marked": "Texto amagau dimpuรฉs de l'alvertencia", "compose_form.spoiler.unmarked": "Texto no amagau", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Blocar y Denunciar", "confirmations.block.confirm": "Blocar", - "confirmations.block.message": "Yes seguro que quiers blocar a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar solicitut", "confirmations.cancel_follow_request.message": "Yes seguro que deseyas retirar la tuya solicitut pa seguir a {name}?", "confirmations.delete.confirm": "Eliminar", @@ -143,13 +141,10 @@ "confirmations.delete_list.message": "Seguro que quiers borrar esta lista permanentment?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tiens cambios sin alzar en a descripciรณn u vista previa d'o fichero audiovisual, descartar-los de totz modos?", - "confirmations.domain_block.confirm": "Amagar dominio entero", "confirmations.domain_block.message": "Yes seguro que quiers blocar lo dominio {domain} entero? En cheneral ye prou, y preferible, fer uns quantos bloqueyos y silenciaus concretos. Los tuyos seguidros d'ixe dominio serรกn eliminaus.", "confirmations.logout.confirm": "Zarrar sesiรณn", "confirmations.logout.message": "Yes seguro de querer zarrar la sesiรณn?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Esto amagarรก las publicacions d'ells y en as qualas los has mencionau, pero les permitirรก veyer los tuyos mensaches y seguir-te.", - "confirmations.mute.message": "Yes seguro que quiers silenciar a {name}?", "confirmations.redraft.confirm": "Borrar y tornar ta borrador", "confirmations.reply.confirm": "Responder", "confirmations.reply.message": "Responder sobrescribirรก lo mensache que yes escribindo. Yes seguro que deseyas continar?", @@ -253,7 +248,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "Seguir etiqueta", "hashtag.unfollow": "Deixar de seguir etiqueta", - "home.column_settings.basic": "Basico", "home.column_settings.show_reblogs": "Amostrar retutz", "home.column_settings.show_replies": "Amostrar respuestas", "home.hide_announcements": "Amagar anuncios", @@ -324,9 +318,6 @@ "load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}", "media_gallery.toggle_visible": "{number, plural, one {Amaga la imachen} other {Amaga las imรกchens}}", "moved_to_account_banner.text": "La tuya cuenta {disabledAccount} ye actualment deshabilitada perque t'has mudau a {movedToAccount}.", - "mute_modal.duration": "Duraciรณn", - "mute_modal.hide_notifications": "Amagar notificacions d'este usuario?", - "mute_modal.indefinite": "Indefinida", "navigation_bar.about": "Sobre", "navigation_bar.blocks": "Usuarios blocaus", "navigation_bar.bookmarks": "Marcadors", @@ -363,9 +354,6 @@ "notifications.column_settings.admin.report": "Nuevos informes:", "notifications.column_settings.admin.sign_up": "Nuevos rechistros:", "notifications.column_settings.alert": "Notificacions d'escritorio", - "notifications.column_settings.filter_bar.advanced": "Amostrar totas las categorรญas", - "notifications.column_settings.filter_bar.category": "Barra de filtrau rapido", - "notifications.column_settings.filter_bar.show_bar": "Amostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitutz de seguimiento:", "notifications.column_settings.mention": "Mencions:", @@ -488,8 +476,6 @@ "server_banner.about_active_users": "Usuarios activos en o servidor entre los zaguers 30 dรญas (Usuarios Activos Mensuals)", "server_banner.active_users": "usuarios activos", "server_banner.administered_by": "Administrau per:", - "server_banner.introduction": "{domain} ye parte d'o ret social descentralizau liderada per {mastodon}.", - "server_banner.learn_more": "Saber mas", "server_banner.server_stats": "Estatisticas d'o servidor:", "sign_in_banner.create_account": "Creyar cuenta", "sign_in_banner.sign_in": "Iniciar sesiรณn", @@ -504,7 +490,6 @@ "status.delete": "Borrar", "status.detailed_status": "Vista de conversaciรณn detallada", "status.edit": "Editar", - "status.edited": "Editau {date}", "status.edited_x_times": "Editau {count, plural, one {{count} vez} other {{count} veces}}", "status.embed": "Incrustado", "status.filter": "Filtrar esta publicaciรณn", diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 790a971cdf..b5ce0ae861 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -5,7 +5,7 @@ "about.domain_blocks.no_reason_available": "ุงู„ุณุจุจ ุบูŠุฑ ู…ุชูˆูุฑ", "about.domain_blocks.preamble": "ูŠุณู…ุญ ู„ูƒ ู…ุงุณุชุฏูˆู† ุนู…ูˆู…ุงู‹ ุจุนุฑุถ ุงู„ู…ุญุชูˆู‰ ู…ู† ุงู„ู…ุณุชุฎุฏู…ูŠู† ู…ู† ุฃูŠ ุฎุงุฏู… ุขุฎุฑ ููŠ ุงู„ูุฏุฑุงู„ูŠุฉ ูˆุงู„ุชูุงุนู„ ู…ุนู‡ู…. ูˆู‡ุฐู‡ ู‡ูŠ ุงู„ุงุณุชุซู†ุงุกุงุช ุงู„ุชูŠ ูˆุถุนุช ุนู„ู‰ ู‡ุฐุง ุงู„ุฎุงุฏู… ุจุงู„ุฐุงุช.", "about.domain_blocks.silenced.explanation": "ุนู…ูˆู…ุงู‹ุŒ ู„ู† ุชุฑู‰ ู…ู„ูุงุช ุงู„ุชุนุฑูŠู ูˆุงู„ู…ุญุชูˆู‰ ู…ู† ู‡ุฐุง ุงู„ุฎุงุฏู…ุŒ ุฅู„ุง ุฅุฐุง ูƒู†ุช ุชุจุญุซ ุนู†ู‡ ุจุดูƒู„ ุตุฑูŠุญ ุฃูˆ ุชุฎุชุงุฑ ุฃู† ุชุชุงุจุนู‡.", - "about.domain_blocks.silenced.title": "ุชู… ูƒุชู…ู‡", + "about.domain_blocks.silenced.title": "ู…ุญุฏูˆุฏ", "about.domain_blocks.suspended.explanation": "ู„ู† ูŠุชู… ู…ุนุงู„ุฌุฉ ุฃูŠ ุจูŠุงู†ุงุช ู…ู† ู‡ุฐุง ุงู„ุฎุงุฏู… ุฃูˆ ุชุฎุฒูŠู†ู‡ุง ุฃูˆ ุชุจุงุฏู„ู‡ุงุŒ ู…ู…ุง ูŠุฌุนู„ ุฃูŠ ุชูุงุนู„ ุฃูˆ ุงุชุตุงู„ ู…ุน ุงู„ู…ุณุชุฎุฏู…ูŠู† ู…ู† ู‡ุฐุง ุงู„ุฎุงุฏู… ู…ุณุชุญูŠู„ุง.", "about.domain_blocks.suspended.title": "ู…ูุนู„ู‘ู‚", "about.not_available": "ู„ู… ูŠุชู… ุชูˆููŠุฑ ู‡ุฐู‡ ุงู„ู…ุนู„ูˆู…ุงุช ุนู„ู‰ ู‡ุฐุง ุงู„ุฎุงุฏู….", @@ -21,7 +21,7 @@ "account.blocked": "ู…ุญุธูˆุฑ", "account.browse_more_on_origin_server": "ุชุตูุญ ุงู„ู…ุฒูŠุฏ ููŠ ุงู„ู…ู„ู ุงู„ุดุฎุตูŠ ุงู„ุฃุตู„ูŠ", "account.cancel_follow_request": "ุฅู„ุบุงุก ุทู„ุจ ุงู„ู…ุชุงุจุนุฉ", - "account.copy": "ู†ุณุฎ ุงู„ุฑุงุจุท ุฅู„ู‰ ุงู„ู…ู„ู ุงู„ุดุฎุตูŠ", + "account.copy": "ู†ุณุฎ ุงู„ุฑุงุจุท ุฅู„ู‰ ุงู„ุญุณุงุจ", "account.direct": "ุฅุดุงุฑุฉ ุฎุงุตุฉ ู„ู€ @{name}", "account.disable_notifications": "ุชูˆู‚ู ุนู† ุฅุดุนุงุฑูŠ ุนู†ุฏู…ุง ูŠู†ุดุฑ @{name}", "account.domain_blocked": "ุงุณู… ุงู„ู†ู‘ูุทุงู‚ ู…ุญุธูˆุฑ", @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "ู„ุง ุชูˆุฌุฏ ุฑุณุงุฆู„", "account.featured_tags.title": "ูˆุณูˆู… {name} ุงู„ู…ู…ูŠู‘ูŽุฒุฉ", "account.follow": "ู…ุชุงุจุนุฉ", - "account.follow_back": "ุชุงุจุนู‡ ุจุฏูˆุฑูƒ", + "account.follow_back": "ุฑุฏ ุงู„ู…ุชุงุจุนุฉ", "account.followers": "ู…ูุชุงุจูุนูˆู†", "account.followers.empty": "ู„ุง ุฃุญุฏูŽ ูŠูุชุงุจุน ู‡ุฐุง ุงู„ู…ูุณุชุฎุฏู… ุฅู„ู‰ ุญุฏ ุงู„ุขู†.", "account.followers_counter": "{count, plural, zero{ู„ุง ู…ูุชุงุจุน} one {ู…ูุชุงุจุนูŒ ูˆุงุญูุฏ} two {ู…ูุชุงุจุนุงู†ู ุงูุซู†ุงู†} few {{counter} ู…ูุชุงุจูุนูŠู†} many {{counter} ู…ูุชุงุจูุนู‹ุง} other {{counter} ู…ูุชุงุจุน}}", @@ -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": "ู„ุง ูŠู…ูƒู† ุชู‚ุฏูŠู… ุงู„ุตูุญุฉ ุงู„ู…ุทู„ูˆุจุฉ. ู‚ุฏ ูŠูƒูˆู† ุจุณุจุจ ุฎุทุฃ ููŠ ุงู„ุชุนู„ูŠู…ุงุช ุงู„ุจุฑู…ุฌูŠุฉุŒ ุฃูˆ ู…ุดูƒู„ุฉ ุชูˆุงูู‚ ุงู„ู…ุชุตูุญ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ุฅุถุงูุฉ ุชุญุฐูŠุฑ ู„ู„ู…ุญุชูˆู‰", "compose_form.spoiler_placeholder": "ุชุญุฐูŠุฑ ุงู„ู…ุญุชูˆู‰ (ุงุฎุชูŠุงุฑูŠ)", "confirmation_modal.cancel": "ุฅู„ุบุงุก", - "confirmations.block.block_and_report": "ุญุธุฑู‡ ูˆุงู„ุฅุจู„ุงุบ ุนู†ู‡", "confirmations.block.confirm": "ุญุธุฑ", - "confirmations.block.message": "ู‡ู„ ุฃู†ุชูŽ ู…ูุชุฃูƒุฏูŒ ุฃู†ูƒูŽ ุชูุฑูŠุฏู ุญูŽุธุฑูŽ {name}ุŸ", "confirmations.cancel_follow_request.confirm": "ุฅู„ุบุงุก ุงู„ุทู„ุจ", "confirmations.cancel_follow_request.message": "ู…ุชุฃูƒุฏ ู…ู† ุฃู†ูƒ ุชุฑูŠุฏ ุฅู„ุบุงุก ุทู„ุจ ู…ุชุงุจุนุชูƒ ู„ู€ {name}ุŸ", "confirmations.delete.confirm": "ุญุฐู", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ู‡ู„ ุฃู†ุชูŽ ู…ูุชุฃูƒุฏูŒ ุฃู†ูƒูŽ ุชูุฑูŠุฏู ุญูŽุฐููŽ ู‡ุฐูู‡ู ุงู„ู‚ุงุฆู…ุฉ ุจุดูƒู„ู ุฏุงุฆู…ุŸ", "confirmations.discard_edit_media.confirm": "ุชุฌุงู‡ู„", "confirmations.discard_edit_media.message": "ู„ุฏูŠูƒ ุชุบูŠูŠุฑุงุช ุบูŠุฑ ู…ุญููˆุธุฉ ู„ูˆุตู ุงู„ูˆุณุงุฆุท ุฃูˆ ู…ุนุงูŠู†ุชู‡ุงุŒ ุฃุชุฑูŠุฏ ุชุฌุงู‡ู„ู‡ุง ุนู„ู‰ ุฃูŠ ุญุงู„ุŸ", - "confirmations.domain_block.confirm": "ุญุธุฑ ุงูุณู… ุงู„ู†ู‘ูุทุงู‚ ุจุดูƒู„ู ูƒุงู…ู„", + "confirmations.domain_block.confirm": "ุญุธุฑ ุงู„ุฎุงุฏู…", "confirmations.domain_block.message": "ู…ุชุฃูƒุฏ ู…ู† ุฃู†ูƒ ุชูˆุฏ ุญุธุฑ ุงุณู… ุงู„ู†ุทุงู‚ {domain} ุจุงู„ูƒุงู…ู„ ุŸ ููŠ ุบุงู„ุจ ุงู„ุฃุญูŠุงู† ูŠูุณุชูŽุญุณูŽู† ูƒุชู… ุฃูˆ ุญุธุฑ ุจุนุถ ุงู„ุญุณุงุจุงุช ุจุฏู„ุง ู…ู† ุญุธุฑ ู†ุทุงู‚ ุจุงู„ูƒุงู…ู„.\nู„ู† ุชุชู…ูƒู† ู…ูู† ุฑุคูŠุฉ ู…ุญุชูˆู‰ ู‡ุฐุง ุงู„ู†ุทุงู‚ ู„ุง ุนู„ู‰ ุฎูŠูˆุทูƒ ุงู„ุนู…ูˆู…ูŠุฉ ูˆ ู„ุง ููŠ ุฅุดุนุงุฑุงุชูƒ. ุณูˆู ูŠุชู… ูƒุฐู„ูƒ ุฅุฒุงู„ุฉ ูƒุงูุฉ ู…ุชุงุจุนูŠูƒ ุงู„ู…ู†ุชู…ูŠู† ุฅู„ู‰ ู‡ุฐุง ุงู„ู†ุทุงู‚.", "confirmations.edit.confirm": "ุชุนุฏูŠู„", "confirmations.edit.message": "ุงู„ุชุนุฏูŠู„ ููŠ ุงู„ุญูŠู† ุณูˆู ูŠูุนูŠุฏ ูƒุชุงุจุฉ ุงู„ุฑุณุงู„ุฉ ุงู„ุชูŠ ุฃู†ุช ุจุตุฏุฏ ุชุญุฑูŠุฑู‡ุง. ู…ุชุฃูƒุฏ ู…ู† ุฃู†ูƒ ุชุฑูŠุฏ ุงู„ู…ูˆุงุตู„ุฉุŸ", "confirmations.logout.confirm": "ุฎุฑูˆุฌ", "confirmations.logout.message": "ู…ุชุฃูƒุฏ ู…ู† ุฃู†ูƒ ุชุฑูŠุฏ ุงู„ุฎุฑูˆุฌุŸ", "confirmations.mute.confirm": "ุฃูƒุชู…", - "confirmations.mute.explanation": "ู‡ุฐุง ุณูŠุฎููŠ ุงู„ู…ู†ุดูˆุฑุงุช ุนู†ู‡ู… ูˆุชู„ูƒ ุงู„ู…ุดุงุฑ ููŠู‡ุง ุฅู„ูŠู‡ู…ุŒ ู„ูƒู†ู‡ ุณูŠุณู…ุญ ู„ู‡ู… ุจุฑุคูŠุฉ ู…ู†ุดูˆุฑุงุชูƒ ูˆู…ุชุงุจุนุชูƒ.", - "confirmations.mute.message": "ู‡ู„ ุฃู†ุช ู…ุชุฃูƒุฏ ุฃู†ูƒ ุชุฑูŠุฏ ูƒุชู… {name} ุŸ", "confirmations.redraft.confirm": "ุฅุฒุงู„ุฉ ูˆุฅุนุงุฏุฉ ุงู„ุตูŠุงุบุฉ", "confirmations.redraft.message": "ู‡ู„ ุฃู†ุช ู…ุชุฃูƒุฏ ู…ู† ุฃู†ูƒ ุชุฑูŠุฏ ุญุฐู ู‡ุฐุง ุงู„ู…ู†ุดูˆุฑ ูˆ ุฅุนุงุฏุฉ ุตูŠุงุบุชู‡ุŸ ุณูˆู ุชูู‚ุฏ ุฌู…ูŠุน ุงู„ุฅุนุฌุงุจุงุช ูˆ ุงู„ุชุฑู‚ูŠุงุช ุฃู…ุง ุงู„ุฑุฏูˆุฏ ุงู„ู…ุชุตู„ุฉ ุจู‡ ูุณุชูุตุจูุญ ูŠุชูŠู…ุฉ.", "confirmations.reply.confirm": "ุฑุฏ", @@ -205,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": "ูŠุชูŠุญ ู„ูƒ ุงู„ุชูˆุงุตู„ ูˆุงู„ุชูุงุนู„ ู…ุน ุงู„ู†ุงุณ ู„ูŠุณ ูู‚ุท ุนู„ู‰ ู…ุงุณุชุฏูˆู†ุŒ ูˆู„ูƒู† ุนุจุฑ ุชุทุจูŠู‚ุงุช ุงุฌุชู…ุงุนูŠุฉ ู…ุฎุชู„ูุฉ ุฃูŠุถุง.", + "domain_pill.activitypub_like_language": "ุฅู†ู‘ ActivityPub ู…ุซู„ ู„ุบุฉ ู…ุงุณุชุฏูˆู† ุงู„ุชูŠ ูŠุชุญุฏุซ ุจู‡ุง ู…ุน ุดุจูƒุงุช ุงุฌุชู…ุงุนูŠุฉ ุฃุฎุฑู‰.", + "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": "ุงู„ุฃู†ุดุทุฉ", @@ -241,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": "ู†ุธุฑุง ู„ูˆุฌูˆุฏ ุฎุทุฃ ููŠ ุงู„ุชุนู„ูŠู…ุงุช ุงู„ุจุฑู…ุฌูŠุฉ ุฃูˆ ู…ุดูƒู„ุฉ ุชูˆุงูู‚ ู…ุน ุงู„ู…ุชุตูู‘ุญุŒ ุชุนุฐุฑ ุนุฑุถ ู‡ุฐู‡ ุงู„ุตูุญุฉ ุจุดูƒู„ ุตุญูŠุญ.", @@ -271,16 +297,28 @@ "filter_modal.select_filter.subtitle": "ุงุณุชุฎุฏู… ูุฆุฉ ู…ูˆุฌูˆุฏุฉ ุฃูˆ ู‚ู… ุจุฅู†ุดุงุก ูุฆุฉ ุฌุฏูŠุฏุฉ", "filter_modal.select_filter.title": "ุชุตููŠุฉ ู‡ุฐุง ุงู„ู…ู†ุดูˆุฑ", "filter_modal.title.status": "ุชุตููŠุฉ ู…ู†ุดูˆุฑ", + "filtered_notifications_banner.mentions": "{count, plural, one {ุฅุดุงุฑุฉ} two {ุฅุดุงุฑุชูŠู†} few {# ุฅุดุงุฑุงุช} other {# ุฅุดุงุฑุฉ}}", + "filtered_notifications_banner.pending_requests": "ุฅุดุนุงุฑุงุช ู…ู† {count, plural, zero {}=0 {ู„ุง ุฃุญุฏ} one {ุดุฎุต ูˆุงุญุฏ ู‚ุฏ ุชุนุฑูู‡} two {ุดุฎุตูŠู† ู‚ุฏ ุชุนุฑูู‡ู…ุง} few {# ุฃุดุฎุงุต ู‚ุฏ ุชุนุฑูู‡ู…} many {# ุดุฎุต ู‚ุฏ ุชุนุฑูู‡ู…} 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.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}.", + "follow_suggestions.hints.most_interactions": "ู‡ุฐุง ุงู„ู…ู„ู ุงู„ุดุฎุตูŠ ู‚ุฏ ุญุตู„ ู…ุคุฎุฑุง ุนู„ู‰ ุงู„ูƒุซูŠุฑ ู…ู† ุงู„ุงู‡ุชู…ุงู… ุนู„ู‰ {domain}.", + "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": "ุงู„ูˆุณูˆู… ุงู„ู…ุชุงุจูŽุนุฉ", @@ -309,7 +347,6 @@ "hashtag.follow": "ุงุชุจุน ุงู„ูˆุณู…", "hashtag.unfollow": "ุฃู„ุบู ู…ุชุงุจุนุฉ ุงู„ูˆุณู…", "hashtags.and_other": "โ€ฆูˆ {count, plural, zero {} one {# ูˆุงุญุฏ ุขุฎุฑ} two {# ุงุซู†ุงู† ุขุฎุฑุงู†} few {# ุขุฎุฑูˆู†} many {# ุขุฎูŽุฑู‹ุง}other {# ุขุฎุฑูˆู†}}", - "home.column_settings.basic": "ุงู„ุฃุณุงุณูŠุฉ", "home.column_settings.show_reblogs": "ุงุนุฑุถ ุงู„ู…ุนุงุฏ ู†ุดุฑู‡ุง", "home.column_settings.show_replies": "ุงุนุฑุถ ุงู„ุฑุฏูˆุฏ", "home.hide_announcements": "ุฅุฎูุงุก ุงู„ุฅุนู„ุงู†ุงุช", @@ -334,8 +371,8 @@ "interaction_modal.title.reply": "ุงู„ุฑุฏ ุนู„ู‰ ู…ู†ุดูˆุฑ {name}", "intervals.full.days": "{number, plural, one {# ูŠูˆู…} other {# ุฃูŠุงู…}}", "intervals.full.hours": "{number, plural, one {# ุณุงุนุฉ} other {# ุณุงุนุงุช}}", - "intervals.full.minutes": "{number, plural, one {# ุฏู‚ูŠู‚ุฉ} other {# ุฏู‚ุงุฆู‚}}", - "keyboard_shortcuts.back": "ู„ู„ุนูˆุฏุฉ", + "intervals.full.minutes": "{number, plural, one {ุฏู‚ูŠู‚ุฉ ูˆุงุญุฏุฉ}two {ุฏู‚ูŠู‚ุชุงู†} other {# ุฏู‚ุงุฆู‚}}", + "keyboard_shortcuts.back": "ู„ู„ุฑุฌูˆุน", "keyboard_shortcuts.blocked": "ู„ูุชุญ ู‚ุงุฆู…ุฉ ุงู„ู…ุณุชุฎุฏู…ูŠู† ุงู„ู…ุญุธูˆุฑูŠู†", "keyboard_shortcuts.boost": "ู„ุฅุนุงุฏุฉ ุงู„ู†ุดุฑ", "keyboard_shortcuts.column": "ู„ู„ุชุฑูƒูŠุฒ ุนู„ู‰ ู…ู†ุดูˆุฑ ุนู„ู‰ ุฃุญุฏ ุงู„ุฃุนู…ุฏุฉ", @@ -377,6 +414,7 @@ "limited_account_hint.action": "ุฅุธู‡ุงุฑ ุงู„ู…ู„ู ุงู„ุชุนุฑูŠููŠ ุนู„ู‰ ุฃูŠ ุญุงู„", "limited_account_hint.title": "ุชู… ุฅุฎูุงุก ู‡ุฐุง ุงู„ู…ู„ู ุงู„ุดุฎุตูŠ ู…ู† ู‚ุจู„ ู…ุดุฑููŠ {domain}.", "link_preview.author": "ู…ูู† {name}", + "link_preview.more_from_author": "ุงู„ู…ุฒูŠุฏ ู…ู† {name}", "lists.account.add": "ุฃุถู ุฅู„ู‰ ุงู„ู‚ุงุฆู…ุฉ", "lists.account.remove": "ุงุญุฐู ู…ู† ุงู„ู‚ุงุฆู…ุฉ", "lists.delete": "ุงุญุฐู ุงู„ู‚ุงุฆู…ุฉ", @@ -395,9 +433,15 @@ "loading_indicator.label": "ุฌุงุฑูŠ ุงู„ุชุญู…ูŠู„โ€ฆ", "media_gallery.toggle_visible": "{number, plural, zero {} one {ุงุฎู ุงู„ุตูˆุฑุฉ} two {ุงุฎู ุงู„ุตูˆุฑุชูŠู†} few {ุงุฎู ุงู„ุตูˆุฑ} many {ุงุฎู ุงู„ุตูˆุฑ} other {ุงุฎู ุงู„ุตูˆุฑ}}", "moved_to_account_banner.text": "ุญุณุงุจูƒ {disabledAccount} ู…ุนุทู„ ุญุงู„ูŠู‹ุง ู„ุฃู†ูƒ ุงู†ุชู‚ู„ุช ุฅู„ู‰ {movedToAccount}.", - "mute_modal.duration": "ุงู„ู…ุฏุฉ", - "mute_modal.hide_notifications": "ู‡ู„ ุชูˆุฏ ุฅุฎูุงุก ุงู„ุฅุฎุทุงุฑุงุช ุงู„ู‚ุงุฏู…ุฉ ู…ู† ู‡ุฐุง ุงู„ู…ุณุชุฎุฏู… ุŸ", - "mute_modal.indefinite": "ุฅู„ู‰ ุฃุฌู„ ุบูŠุฑ ู…ุณู…ู‰", + "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": "ุงู„ุญุณุงุจุงุช ุงู„ู…ุญุฌูˆุจุฉ", @@ -430,20 +474,37 @@ "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.relationships_severance_event": "ูู‚ุฏุช ุงู„ุงุชุตุงู„ุงุช ู…ุน {name}", + "notification.relationships_severance_event.account_suspension": "ู‚ุงู… ู…ุดุฑู ู…ู† {from} ุจุชุนู„ูŠู‚ {target}ุŒ ู…ู…ุง ูŠุนู†ูŠ ุฃู†ูƒ ู„ู… ูŠุนุฏ ุจุฅู…ูƒุงู†ูƒ ุชู„ู‚ูŠ ุงู„ุชุญุฏูŠุซุงุช ู…ู†ู‡ู… ุฃูˆ ุงู„ุชูุงุนู„ ู…ุนู‡ู….", + "notification.relationships_severance_event.domain_block": "ู‚ุงู… ู…ุดุฑู ู…ู† {from} ุจุญุธุฑ {target}ุŒ ุจู…ุง ููŠ ุฐู„ูƒ {followersCount} ู…ู† ู…ุชุงุจุนูŠู†ูƒ ูˆ {followingCount, plural, one {# ุญุณุงุจ} other {# ุญุณุงุจุงุช}} ุชุชุงุจุนู‡ุง.", + "notification.relationships_severance_event.learn_more": "ุงุนุฑู ุงู„ู…ุฒูŠุฏ", + "notification.relationships_severance_event.user_domain_block": "ู„ู‚ุฏ ู‚ู…ุช ุจุญุธุฑ {target}ุŒ ู…ู…ุง ุฃุฏู‰ ุฅู„ู‰ ุฅุฒุงู„ุฉ {followersCount} ู…ู† ู…ุชุงุจุนูŠู†ูƒ ูˆ {followingCount, plural, one {# ุญุณุงุจ} 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": "ุงู„ุชุจู„ูŠุบุงุช ุงู„ุฌุฏูŠุฏุฉ:", "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.filter_bar.show_bar": "ุฅุธู‡ุงุฑ ุดุฑูŠุท ุงู„ุชุตููŠุฉ", + "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": "ุงู„ุฅุดุงุฑุงุช:", @@ -469,6 +530,15 @@ "notifications.permission_denied": "ุชู†ุจูŠู‡ุงุช ุณุทุญ ุงู„ู…ูƒุชุจ ุบูŠุฑ ู…ุชูˆูุฑุฉ ุจุณุจุจ ุฑูุถ ุฃุฐูˆู†ุงุช ุงู„ู…ุชุตูุญ ู…ุณุจู‚ุงู‹", "notifications.permission_denied_alert": "ู„ุง ูŠู…ูƒู† ุชูุนูŠู„ ุฅุดุนุงุฑุงุช ุณุทุญ ุงู„ู…ูƒุชุจุŒ ู„ุฃู† ุฅุฐู† ุงู„ู…ุชุตูุญ ู‚ุฏ ุชู… ุฑูุถู‡ ุณุงุจู‚ุงู‹", "notifications.permission_required": "ุฅุดุนุงุฑุงุช ุณุทุญ ุงู„ู…ูƒุชุจ ุบูŠุฑ ู…ุชูˆูุฑุฉ ู„ุฃู†ู‡ ู„ู… ูŠุชู… ู…ู†ุญ ุงู„ุฅุฐู† ุงู„ู…ุทู„ูˆุจ.", + "notifications.policy.filter_new_accounts.hint": "ุชู… ุฅู†ุดุงุคู‡ุง ู…ู†ุฐ {days, plural, zero {}one {ูŠูˆู… ูˆุงุญุฏ} two {ูŠูˆู…ุงู†} few {# ุฃูŠุงู…} many {# ุฃูŠุงู…} other {# ุฃูŠุงู…}}", + "notifications.policy.filter_new_accounts_title": "ุญุณุงุจุงุช ุฌุฏูŠุฏุฉ", + "notifications.policy.filter_not_followers_hint": "ุจู…ุง ููŠ ุฐู„ูƒ ุงู„ุฃุดุฎุงุต ุงู„ุฐูŠู† ูŠุชุงุจุนูˆู†ูƒ ุฃู‚ู„ ู…ู† {days, plural, zero {}one {ูŠูˆู… ูˆุงุญุฏ} two {ูŠูˆู…ุงู†} few {# ุฃูŠุงู…} many {# ุฃูŠุงู…} other {# ุฃูŠุงู…}}", + "notifications.policy.filter_not_followers_title": "ุฃุดุฎุงุต ู„ุง ูŠุชุงุจุนูˆู†ูƒ", + "notifications.policy.filter_not_following_hint": "ุญุชู‰ ุชูˆุงูู‚ ุนู„ูŠู‡ู… ูŠุฏูˆูŠุง", + "notifications.policy.filter_not_following_title": "ุฃุดุฎุงุต ู„ุง ุชุชุงุจุนู‡ู…", + "notifications.policy.filter_private_mentions_hint": "ุชู…ุช ุชุตููŠุชู‡ ุฅู„ุง ุฅุฐุง ุฃู† ูŠูƒูˆู† ุฑุฏู‹ุง ุนู„ู‰ ุฐูƒุฑูƒ ุฃูˆ ุฅุฐุง ูƒู†ุช ุชุชุงุจุน ุงู„ุญุณุงุจ", + "notifications.policy.filter_private_mentions_title": "ุฅุดุงุฑุงุช ุฎุงุตุฉ ุบูŠุฑ ู…ุฑุบูˆุจ ููŠู‡ุง", + "notifications.policy.title": "ุชุตููŠุฉ ุงู„ุฅุดุนุงุฑุงุช ู…ู†โ€ฆ", "notifications_permission_banner.enable": "ุชูุนูŠู„ ุฅุดุนุงุฑุงุช ุณุทุญ ุงู„ู…ูƒุชุจ", "notifications_permission_banner.how_to_control": "ู„ุชู„ู‚ูŠ ุงู„ุฅุดุนุงุฑุงุช ุนู†ุฏู…ุง ู„ุง ูŠูƒูˆู† ู…ุงุณุชุฏูˆู† ู…ูุชูˆุญุŒ ู‚ู… ุจุชูุนูŠู„ ุฅุดุนุงุฑุงุช ุณุทุญ ุงู„ู…ูƒุชุจุŒ ูŠู…ูƒู†ูƒ ุงู„ุชุญูƒู… ุจุฏู‚ุฉ ููŠ ุฃู†ูˆุงุน ุงู„ุชูุงุนู„ุงุช ุงู„ุชูŠ ุชูˆู„ุฏ ุฅุดุนุงุฑุงุช ุณุทุญ ุงู„ู…ูƒุชุจ ู…ู† ุฎู„ุงู„ ุฒุฑ ุงู„ู€{icon} ุฃุนู„ุงู‡ ุจู…ุฌุฑุฏ ุชูุนูŠู„ู‡ุง.", "notifications_permission_banner.title": "ู„ุง ุชููˆุช ุดูŠุฆุงู‹ ุฃุจุฏุงู‹", @@ -625,13 +695,10 @@ "server_banner.about_active_users": "ุงู„ุฃุดุฎุงุต ุงู„ุฐูŠู† ูŠุณุชุฎุฏู…ูˆู† ู‡ุฐุง ุงู„ุฎุงุฏู… ุฎู„ุงู„ ุงู„ุฃูŠุงู… ุงู„ุซู„ุงุซูŠู† ุงู„ุฃุฎูŠุฑุฉ (ุงู„ู…ุณุชุฎุฏู…ูˆู† ุงู„ู†ุดุทูˆู† ุดู‡ุฑูŠู‹ุง)", "server_banner.active_users": "ู…ุณุชุฎุฏู… ู†ุดุท", "server_banner.administered_by": "ูŠูุฏูŠุฑู‡:", - "server_banner.introduction": "{domain} ู‡ูˆ ุฌุฒุก ู…ู† ุงู„ุดุจูƒุฉ ุงู„ุงุฌุชู…ุงุนูŠุฉ ุงู„ู„ุงู…ุฑูƒุฒูŠุฉ ุงู„ุชูŠ ุชุนู…ู„ ุจูˆุงุณุทุฉ {mastodon}.", - "server_banner.learn_more": "ุชุนู„ู… ุงู„ู…ุฒูŠุฏ", "server_banner.server_stats": "ุฅุญุตุงุฆูŠุงุช ุงู„ุฎุงุฏู…:", "sign_in_banner.create_account": "ุฃู†ุดุฆ ุญุณุงุจู‹ุง", "sign_in_banner.sign_in": "ุชุณุฌูŠู„ ุงู„ุฏุฎูˆู„", "sign_in_banner.sso_redirect": "ุชุณุฌูŠู„ ุงู„ุฏุฎูˆู„ ุฃูˆ ุฅู†ุดุงุก ุญุณุงุจ", - "sign_in_banner.text": "ู‚ู… ุจุงู„ูˆู„ูˆุฌ ุจุญุณุงุจูƒ ู„ู…ุชุงุจุนุฉ ุงู„ุตูุญุงุช ุงู„ุดุฎุตูŠุฉ ุฃูˆ ุงู„ูˆุณูˆู…ุŒ ุฃูˆ ู„ุฅุถุงูุฉ ุงู„ู…ู†ุดูˆุฑุงุช ุฅู„ู‰ ุงู„ู…ูุถู„ุฉ ูˆู…ุดุงุฑูƒุชู‡ุง ูˆุงู„ุฑุฏ ุนู„ูŠู‡ุง ุฃูˆ ุงู„ุชูุงุนู„ ุจูˆุงุณุทุฉ ุญุณุงุจูƒ ุงู„ู…ุชูˆุงุฌุฏ ุนู„ู‰ ุฎุงุฏู… ู…ุฎุชู„ู.", "status.admin_account": "ุงูุชุญ ุงู„ูˆุงุฌู‡ุฉ ุงู„ุฅุฏุงุฑูŠุฉ ู„ู€ @{name}", "status.admin_domain": "ูุชุญ ูˆุงุฌู‡ุฉ ุงู„ุฅุดุฑุงู ู„ู€ {domain}", "status.admin_status": "ุงูุชุญ ู‡ุฐุง ุงู„ู…ู†ุดูˆุฑ ุนู„ู‰ ูˆุงุฌู‡ุฉ ุงู„ุฅุดุฑุงู", @@ -645,10 +712,11 @@ "status.direct": "ุฅุดุงุฑุฉ ุฎุงุตุฉ ู„ู€ @{name}", "status.direct_indicator": "ุฅุดุงุฑุฉ ุฎุงุตุฉ", "status.edit": "ุชุนุฏูŠู„", - "status.edited": "ุนูุฏู‘ู„ ููŠ {date}", + "status.edited": "ุขุฎุฑ ุชุนุฏูŠู„ ูŠูˆู… {date}", "status.edited_x_times": "ุนูุฏู‘ู„ {count, plural, zero {} one {ู…ุฑุฉู‹ ูˆุงุญุฏุฉ} two {ู…ุฑู‘ุชุงู†} few {{count} ู…ุฑุงุช} many {{count} ู…ุฑุฉ} other {{count} ู…ุฑุฉ}}", "status.embed": "ุฅุฏู…ุงุฌ", "status.favourite": "ูุถู‘ู„", + "status.favourites": "{count, plural, zero {}one {ู…ูุถู„ุฉ ูˆุงุญุฏุฉ} two {ู…ูุถู„ุชุงู†} few {# ู…ูุถู„ุงุช} many {# ู…ูุถู„ุงุช} other {# ู…ูุถู„ุงุช}}", "status.filter": "ุชุตููŠุฉ ู‡ุฐู‡ ุงู„ุฑุณุงู„ุฉ", "status.filtered": "ู…ูุตูู‘ู‰", "status.hide": "ุฅุฎูุงุก ุงู„ู…ู†ุดูˆุฑ", @@ -669,6 +737,7 @@ "status.reblog": "ุฅุนุงุฏุฉ ุงู„ู†ุดุฑ", "status.reblog_private": "ุฅุนุงุฏุฉ ุงู„ู†ุดุฑ ุฅู„ู‰ ุงู„ุฌู…ู‡ูˆุฑ ุงู„ุฃุตู„ูŠ", "status.reblogged_by": "ุดุงุฑูŽูƒูŽู‡ {name}", + "status.reblogs": "{count, plural, one {ุชุนุฒูŠุฒ ูˆุงุญุฏ} two {ุชุนุฒูŠุฒุชุงู†} few {# ุชุนุฒูŠุฒุงุช} many {# ุชุนุฒูŠุฒุงุช} other {# ุชุนุฒูŠุฒุงุช}}", "status.reblogs.empty": "ู„ู… ูŠู‚ู… ุฃูŠ ุฃุญุฏ ุจู…ุดุงุฑูƒุฉ ู‡ุฐุง ุงู„ู…ู†ุดูˆุฑ ุจุนุฏ. ุนู†ุฏู…ุง ูŠู‚ูˆู… ุฃุญุฏู‡ู… ุจุฐู„ูƒ ุณูˆู ูŠุธู‡ุฑ ู‡ู†ุง.", "status.redraft": "ุฅุฒุงู„ุฉ ูˆุฅุนุงุฏุฉ ุงู„ุตูŠุงุบุฉ", "status.remove_bookmark": "ุงุญุฐูู‡ ู…ูู† ุงู„ููˆุงุตู„ ุงู„ู…ุฑุฌุนูŠุฉ", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index 18bba99117..80e0aa6cbf 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -112,16 +112,13 @@ "compose_form.poll.type": "Estilu", "compose_form.publish_form": "Artรญculu nuevu", "confirmation_modal.cancel": "Encaboxar", - "confirmations.block.block_and_report": "Bloquiar ya informar", "confirmations.block.confirm": "Bloquiar", - "confirmations.block.message": "ยฟDe xuru que quies bloquiar a {name}?", "confirmations.cancel_follow_request.confirm": "Retirala", "confirmations.cancel_follow_request.message": "ยฟDe xuru que quies retirar la solicitรบ pa siguir a {name}?", "confirmations.delete.confirm": "Desaniciar", "confirmations.delete.message": "ยฟDe xuru que quies desaniciar esti artรญculu?", "confirmations.delete_list.confirm": "Desaniciar", "confirmations.discard_edit_media.confirm": "Escartar", - "confirmations.domain_block.confirm": "Bloquiar tol dominiu", "confirmations.edit.message": "La ediciรณn va sobrescribir el mensaxe que tas escribiendo. ยฟDe xuru que quies siguir?", "confirmations.logout.confirm": "Zarrar la sesiรณn", "confirmations.logout.message": "ยฟDe xuru que quies zarrar la sesiรณn?", @@ -199,7 +196,6 @@ "follow_request.authorize": "Autorizar", "follow_request.reject": "Refugar", "follow_requests.unlocked_explanation": "Magar que la to cuenta nun seya privada, el personal del dominiu ยซ{domain}ยป pensรณ qu'a lo meyor quies revisar manualmente les solicitรบes de siguimientu d'estes cuentes.", - "follow_suggestions.curated_suggestion": "Escoyeta del sirvidor", "follow_suggestions.dismiss": "Nun volver amosar", "follow_suggestions.personalized_suggestion": "Suxerencia personalizada", "follow_suggestions.popular_suggestion": "Suxerencia popular", @@ -222,7 +218,6 @@ "hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}", "hashtag.follow": "Siguir a la etiqueta", "hashtag.unfollow": "Dexar de siguir a la etiqueta", - "home.column_settings.basic": "Configuraciรณn bรกsica", "home.column_settings.show_reblogs": "Amosar los artรญculos compartรญos", "home.column_settings.show_replies": "Amosar les rempuestes", "home.pending_critical_update.body": "ยกAnueva'l sirvidor de Mastodon namรกs que puedas!", @@ -279,8 +274,6 @@ "lists.subheading": "Les tos llistes", "load_pending": "{count, plural, one {# elementu nuevu} other {# elementos nuevos}}", "media_gallery.toggle_visible": "{number, plural, one {Anubrir la imaxe} other {Anubrir les imรกxenes}}", - "mute_modal.duration": "Duraciรณn", - "mute_modal.hide_notifications": "ยฟQuies anubrir los avisos d'esti perfil?", "navigation_bar.about": "Tocante a", "navigation_bar.blocks": "Perfiles bloquiaos", "navigation_bar.bookmarks": "Marcadores", @@ -312,9 +305,6 @@ "notifications.clear": "Borrar los avisos", "notifications.column_settings.admin.report": "Informes nuevos:", "notifications.column_settings.admin.sign_up": "Rexistros nuevos:", - "notifications.column_settings.filter_bar.advanced": "Amosar toles categorรญes", - "notifications.column_settings.filter_bar.category": "Barra de peรฑera rรกpida", - "notifications.column_settings.filter_bar.show_bar": "Amosar la barra de peรฑera", "notifications.column_settings.follow": "Siguidores nuevos:", "notifications.column_settings.follow_request": "Solicitรบes de siguimientu nueves:", "notifications.column_settings.mention": "Menciones:", @@ -419,8 +409,6 @@ "search_results.see_all": "Ver too", "search_results.statuses": "Artรญculos", "search_results.title": "Busca de: {q}", - "server_banner.introduction": "{domain} ye parte de la rede social descentralizada que tien la teunoloxรญa de {mastodon}.", - "server_banner.learn_more": "Saber mรกs", "server_banner.server_stats": "Estadรญstiques del sirvidor:", "sign_in_banner.create_account": "Crear una cuenta", "sign_in_banner.sso_redirect": "Aniciar la sesiรณn o rexistrase", @@ -434,7 +422,6 @@ "status.delete": "Desaniciar", "status.direct": "Mentar a @{name} per privao", "status.direct_indicator": "Menciรณn privada", - "status.edited": "Editรณse'l {date}", "status.edited_x_times": "Editรณse {count, plural, one {{count} vegada} other {{count} vegaes}}", "status.embed": "Empotrar", "status.filter": "Peรฑerar esti artรญculu", diff --git a/app/javascript/mastodon/locales/be.json b/app/javascript/mastodon/locales/be.json index 7e21703b4a..03164c4290 100644 --- a/app/javascript/mastodon/locales/be.json +++ b/app/javascript/mastodon/locales/be.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": "ะ—ะฐะฟั‹ั‚ะฐะฝะฐั ัั‚ะฐั€ะพะฝะบะฐ ะฝะต ะผะพะถะฐ ะฑั‹ั†ัŒ ะฐะดะปัŽัั‚ั€ะฐะฒะฐะฝะฐั. ะ“ัั‚ะฐ ะผะฐะณะปะพ ัั‚ะฐั†ั†ะฐ ะฟั€ะฐะท ั…ั–ะฑัƒ ัž ะฝะฐัˆั‹ะผ ะบะพะดะทะต, ะฐะฑะพ ะฟั€ะฐะท ะฟะฐะผั‹ะปะบัƒ ััƒะผััˆั‡ะฐะปัŒะฝะฐัั†ั– ะท ะฑั€ะฐัžะทะตั€ะฐะผ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ะ”ะฐะดะฐั†ัŒ ะฟะฐะฟัั€ัะดะถะฐะฝะฝะต ะฐะฑ ะทะผะตัั†ั–ะฒะต", "compose_form.spoiler_placeholder": "ะŸะฐะฟัั€ัะดะถะฐะฝะฝะต ะฐะฑ ะทะผะตัั†ั–ะฒะต (ะฝะตะฐะฑะฐะฒัะทะบะพะฒะฐ)", "confirmation_modal.cancel": "ะกะบะฐัะฐะฒะฐั†ัŒ", - "confirmations.block.block_and_report": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ ั– ะฟะฐัะบะฐั€ะดะทั–ั†ั†ะฐ", "confirmations.block.confirm": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ", - "confirmations.block.message": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹ั ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะทะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ {name}?", "confirmations.cancel_follow_request.confirm": "ะกะบะฐัะฐะฒะฐั†ัŒ ะทะฐะฟั‹ั‚", "confirmations.cancel_follow_request.message": "ะกะฐะฟั€ะฐัžะดั‹ ั…ะพั‡ะฐั†ะต ัะบะฐัะฐะฒะฐั†ัŒ ัะฒะพะน ะทะฐะฟั‹ั‚ ะฝะฐ ะฟะฐะดะฟั–ัะบัƒ ะฝะฐ {name}?", "confirmations.delete.confirm": "ะ’ั‹ะดะฐะปั–ั†ัŒ", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹ั, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะฑะตะทะทะฒะฐั€ะพั‚ะฝะฐ ะฒั‹ะดะฐะปั–ั†ัŒ ะณัั‚ั‹ ั‡ะฐั€ะฝะฐะฒั–ะบ?", "confirmations.discard_edit_media.confirm": "ะะดะผัะฝั–ั†ัŒ", "confirmations.discard_edit_media.message": "ะฃ ะฒะฐั ั‘ัั†ัŒ ะฝะตะทะฐั…ะฐะฒะฐะฝั‹ั ะทะผะตะฝั‹ ัž ะฐะฟั–ัะฐะฝะฝั– ะฐะฑะพ ะฟั€ัะฒ'ัŽ, ัƒัะต ั€ะพัžะฝะฐ ัะบะฐัะฐะฒะฐั†ัŒ ั–ั…?", - "confirmations.domain_block.confirm": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ ะดะฐะผะตะฝ ั†ะฐะปะบะฐะผ", + "confirmations.domain_block.confirm": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ ัะตั€ะฒะตั€", "confirmations.domain_block.message": "ะ’ั‹ ะฐะฑัะฐะปัŽั‚ะฝะฐ ะดะฐะบะปะฐะดะฝะฐ ัžะฟััžะฝะตะฝั‹, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะทะฐะฑะปะฐะบั–ั€ะฐะฒะฐั†ัŒ {domain} ะทัƒัั–ะผ? ะฃ ะฑะพะปัŒัˆะฐัั†ั– ะฒั‹ะฟะฐะดะบะฐัž, ะดะฐัั‚ะฐั‚ะบะพะฒะฐ ะฝะตะบะฐะปัŒะบั–ั… ะผัั‚ะฐะฒั‹ั… ะฑะปะฐะบั–ั€ะพะฒะฐะบ ั†ั– ั–ะณะฝะฐั€ะฐะฒะฐะฝะฝััž. ะ’ั‹ ะฟะตั€ะฐัั‚ะฐะฝะตั†ะต ะฑะฐั‡ั‹ั†ัŒ ะทะผะตัั†ั–ะฒะฐ ะท ะณัั‚ะฐะณะฐ ะดะฐะผะตะฝัƒ ะฒะฐ ัžัั–ั… ัั‚ัƒะถะบะฐั… ั– ะฐะฟะฐะฒััˆั‡ัะฝะฝัั…. ะ’ะฐัˆั‹ ะฟะฐะดะฟั–ัะบั– ะท ะณัั‚ะฐะณะฐ ะดะฐะผะตะฝัƒ ะฑัƒะดัƒั†ัŒ ะฒั‹ะดะฐะปะตะฝั‹ั.", "confirmations.edit.confirm": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ", "confirmations.edit.message": "ะšะฐะปั– ะฒั‹ ะทะผะตะฝั–ั†ะต ะทะฐั€ะฐะท, ะณัั‚ะฐ ะฟะตั€ะฐั‚ั€ั ะฟะฐะฒะตะดะฐะผะปะตะฝะฝะต, ัะบะพะต ะฒั‹ ะฟั–ัˆะฐั†ะต. ะ’ั‹ ัžะฟััžะฝะตะฝั‹, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะฟั€ะฐั†ัะณะฝัƒั†ัŒ?", "confirmations.logout.confirm": "ะ’ั‹ะนัั†ั–", "confirmations.logout.message": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹ั, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะฒั‹ะนัั†ั–?", "confirmations.mute.confirm": "ะ†ะณะฝะฐั€ะฐะฒะฐั†ัŒ", - "confirmations.mute.explanation": "ะ“ัั‚ะฐ ัั…ะฐะฒะฐะต ะดะพะฟั–ัั‹ ะฐะด ะณัั‚ะฐะณะฐ ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบะฐ ั– ะฟั€ะฐ ัะณะพ, ะฐะปะต ัžัั‘ ััˆั‡ั ะดะฐะทะฒะพะปั–ั†ัŒ ัะผัƒ ั‡ั‹ั‚ะฐั†ัŒ ะฒะฐัˆั‹ั ะดะพะฟั–ัั‹ ั– ะฑั‹ั†ัŒ ะฟะฐะดะฟั–ัะฐะฝั‹ะผ ะฝะฐ ะฒะฐั.", - "confirmations.mute.message": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹ั, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ั–ะณะฝะฐั€ะฐะฒะฐั†ัŒ {name}?", "confirmations.redraft.confirm": "ะ’ั‹ะดะฐะปั–ั†ัŒ ั– ะฟะตั€ะฐะฟั–ัะฐั†ัŒ", "confirmations.redraft.message": "ะ’ั‹ ัžะฟััžะฝะตะฝั‹, ัˆั‚ะพ ั…ะพั‡ะฐั†ะต ะฒั‹ะดะฐะปั–ั†ัŒ ะดะพะฟั–ั ั– ะฟะตั€ะฐะฟั–ัะฐั†ัŒ ัะณะพ? ะฃะฟะฐะดะฐะฑะฐะฝะฝั– ั– ะฟะฐัˆั‹ั€ัะฝะฝั– ะทะณัƒะฑัั†ั†ะฐ, ะฐ ะฐะดะบะฐะทั‹ ะดะฐ ะฐั€ั‹ะณั–ะฝะฐะปัŒะฝะฐะณะฐ ะดะพะฟั–ััƒ ะฐัั–ั€ะฐั†ะตัŽั†ัŒ.", "confirmations.reply.confirm": "ะะดะบะฐะทะฐั†ัŒ", @@ -205,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": "ะะบั‚ั‹ัžะฝะฐัั†ัŒ", @@ -241,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": "ะ“ัั‚ะฐ ัั‚ะฐั€ะพะฝะบะฐ ะฝะต ะผะพะถะฐ ะฑั‹ั†ัŒ ะฐะดะปัŽัั‚ั€ะฐะฒะฐะฝะฐ ะบะฐั€ัะบั‚ะฝะฐ ะท-ะทะฐ ะฟะฐะผั‹ะปะบั– ัž ะฝะฐัˆั‹ะผ ะบะพะดะทะต, ะฐะฑะพ ะฟั€ะฐะฑะปะตะผั‹ ะท ััƒะผััˆั‡ะฐะปัŒะฝะฐัั†ัŽ ะฑั€ะฐัžะทะตั€ะฐ.", @@ -271,16 +297,28 @@ "filter_modal.select_filter.subtitle": "ะกะบะฐั€ั‹ัั‚ะฐะนั†ะตัั ั–ัะฝัƒัŽั‡ะฐะน ะบะฐั‚ัะณะพั€ั‹ัะน ะฐะฑะพ ัั‚ะฒะฐั€ั‹ั†ะต ะฝะพะฒัƒัŽ", "filter_modal.select_filter.title": "ะคั–ะปัŒั‚ั€ะฐะฒะฐั†ัŒ ะณัั‚ั‹ ะดะพะฟั–ั", "filter_modal.title.status": "ะคั–ะปัŒั‚ั€ะฐะฒะฐั†ัŒ ะดะพะฟั–ั", + "filtered_notifications_banner.mentions": "{count, plural, one {ะทะณะฐะดะฒะฐะฝะฝะต} few {ะทะณะฐะดะฒะฐะฝะฝั–} many {ะทะณะฐะดะฒะฐะฝะฝััž} other {ะทะณะฐะดะฒะฐะฝะฝั}}", + "filtered_notifications_banner.pending_requests": "ะะฟะฐะฒััˆั‡ัะฝะฝั– ะฐะด {count, plural, =0 {# ะปัŽะดะทะตะน ัะบั–ั…} one {# ั‡ะฐะปะฐะฒะตะบะฐ ัะบั–ั…} few {# ั‡ะฐะปะฐะฒะตะบ ัะบั–ั…} many {# ะปัŽะดะทะตะน ัะบั–ั…} 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.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}.", + "follow_suggestions.hints.most_interactions": "ะฃ ะฐะฟะพัˆะฝั– ั‡ะฐั ะณัั‚ั‹ ะฟั€ะพั„ั–ะปัŒ ะฟั€ั‹ั†ัะณะฒะฐะต ัˆะผะฐั‚ ัƒะฒะฐะณั– ะฝะฐ {domain}.", + "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": "ะŸะฐะดะฟั–ัะบั–", @@ -309,7 +347,6 @@ "hashtag.follow": "ะŸะฐะดะฟั–ัะฐั†ั†ะฐ ะฝะฐ ั…ััˆั‚ัะณ", "hashtag.unfollow": "ะะดะฟั–ัะฐั†ั†ะฐ ะฐะด ั…ััˆั‚ัะณะฐ", "hashtags.and_other": "โ€ฆั– ััˆั‡ั {count, plural, other {#}}", - "home.column_settings.basic": "ะัะฝะพัžะฝั‹ั", "home.column_settings.show_reblogs": "ะŸะฐะบะฐะทะฐั†ัŒ ะฟะฐัˆั‹ั€ัะฝะฝั–", "home.column_settings.show_replies": "ะŸะฐะบะฐะทะฒะฐั†ัŒ ะฐะดะบะฐะทั‹", "home.hide_announcements": "ะกั…ะฐะฒะฐั†ัŒ ะฐะฑ'ัะฒั‹", @@ -377,6 +414,7 @@ "limited_account_hint.action": "ะฃัะต ั€ะพัžะฝะฐ ะฟะฐะบะฐะทะฒะฐั†ัŒ ะฟั€ะพั„ั–ะปัŒ", "limited_account_hint.title": "ะ“ัั‚ั‹ ะฟั€ะพั„ั–ะปัŒ ะฑั‹ัž ัั…ะฐะฒะฐะฝั‹ ะผะฐะดัั€ะฐั‚ะฐั€ะฐะผั–", "link_preview.author": "ะะด {name}", + "link_preview.more_from_author": "ะ‘ะพะปัŒัˆ ะฐะด {name}", "lists.account.add": "ะ”ะฐะดะฐั†ัŒ ะดะฐ ัะฟั–ััƒ", "lists.account.remove": "ะ’ั‹ะดะฐะปั–ั†ัŒ ัะฐ ัะฟั–ััƒ", "lists.delete": "ะ’ั‹ะดะฐะปั–ั†ัŒ ัะฟั–ั", @@ -395,12 +433,18 @@ "loading_indicator.label": "ะ—ะฐะณั€ัƒะทะบะฐโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ะกั…ะฐะฒะฐั†ัŒ ะฒั–ะดะฐั€ั‹ั} other {ะกั…ะฐะฒะฐั†ัŒ ะฒั–ะดะฐั€ั‹ัั‹}}", "moved_to_account_banner.text": "ะ’ะฐัˆ ัƒะปั–ะบะพะฒั‹ ะทะฐะฟั–ั {disabledAccount} ะทะฐั€ะฐะท ะฐะดะบะปัŽั‡ะฐะฝั‹ ั‚ะฐะผัƒ ัˆั‚ะพ ะฒั‹ ะฟะตั€ะฐะฝะตัะตะฝั‹ ะฝะฐ {movedToAccount}.", - "mute_modal.duration": "ะŸั€ะฐั†ัะณะปะฐัั†ัŒ", - "mute_modal.hide_notifications": "ะกั…ะฐะฒะฐั†ัŒ ะฐะฟะฐะฒััˆั‡ัะฝะฝั– ะฐะด ะณัั‚ะฐะณะฐ ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบะฐ?", - "mute_modal.indefinite": "ะ‘ะตัั‚ัั€ะผั–ะฝะพะฒะฐ", + "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": "ะ—ะฐะฑะปะฐะบะฐะฒะฐะฝั‹ั ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบั–", + "navigation_bar.blocks": "ะ—ะฐะฑะปะฐะบั–ั€ะฐะฒะฐะฝั‹ั ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบั–", "navigation_bar.bookmarks": "ะ—ะฐะบะปะฐะดะบั–", "navigation_bar.community_timeline": "ะ›ะฐะบะฐะปัŒะฝะฐั ัั‚ัƒะถะบะฐ", "navigation_bar.compose": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ะฝะพะฒั‹ ะดะพะฟั–ั", @@ -419,7 +463,7 @@ "navigation_bar.opened_in_classic_interface": "ะ”ะพะฟั–ัั‹, ัƒะปั–ะบะพะฒั‹ั ะทะฐะฟั–ัั‹ ั– ั–ะฝัˆั‹ั ัะฟะตั†ั‹ั„ั–ั‡ะฝั‹ั ัั‚ะฐั€ะพะฝะบั– ะฟะฐ ะทะผะพัžั‡ะฐะฝะฝั– ะฐะดั‡ั‹ะฝััŽั†ั†ะฐ ัž ะบะปะฐัั–ั‡ะฝั‹ะผ ะฒัะฑ-ั–ะฝั‚ัั€ั„ะตะนัะต.", "navigation_bar.personal": "ะัะฐะฑั–ัั‚ะฐะต", "navigation_bar.pins": "ะ—ะฐะผะฐั†ะฐะฒะฐะฝั‹ั ะดะพะฟั–ัั‹", - "navigation_bar.preferences": "ะŸะฐั€ะฐะผะตั‚ั€ั‹", + "navigation_bar.preferences": "ะะฐะปะฐะดั‹", "navigation_bar.public_timeline": "ะ“ะปะฐะฑะฐะปัŒะฝะฐั ัั‚ัƒะถะบะฐ", "navigation_bar.search": "ะŸะพัˆัƒะบ", "navigation_bar.security": "ะ‘ััะฟะตะบะฐ", @@ -430,20 +474,37 @@ "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.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 {# ัƒะปั–ะบะพะฒั‹ั ะทะฐะฟั–ัั‹} many {# ัƒะปั–ะบะพะฒั‹ั… ะทะฐะฟั–ัะฐัž} other {# ัƒะปั–ะบะพะฒั‹ั… ะทะฐะฟั–ัะฐัž}}.", + "notification.relationships_severance_event.learn_more": "ะ”ะฐะฒะตะดะฐั†ั†ะฐ ะฑะพะปัŒัˆ", + "notification.relationships_severance_event.user_domain_block": "ะ’ั‹ ะทะฐะฑะปะฐะบั–ั€ะฐะฒะฐะปั– {target} ะฒั‹ะดะฐะปั–ัžัˆั‹ {followersCount} ัะฒะฐั–ั… ะฟะฐะดะฟั–ัั‡ั‹ะบะฐัž ั– {followingCount, plural, one {# ัƒะปั–ะบะพะฒั‹ ะทะฐะฟั–ั} few {# ัƒะปั–ะบะพะฒั‹ั ะทะฐะฟั–ัั‹} many {# ัƒะปั–ะบะพะฒั‹ั… ะทะฐะฟั–ัะฐัž} 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": "ะะพะฒั‹ั ัะบะฐั€ะณั–:", "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.advanced": "ะŸะฐะบะฐะทะฐั†ัŒ ัƒัะต ะบะฐั‚ัะณะพั€ั‹ั–", "notifications.column_settings.filter_bar.category": "ะŸะฐะฝัะปัŒ ั…ัƒั‚ะบะฐะน ั„ั–ะปัŒั‚ั€ะฐั†ั‹ั–", - "notifications.column_settings.filter_bar.show_bar": "ะŸะฐะบะฐะทะฒะฐั†ัŒ ะฟะฐะฝัะปัŒ ั„ั–ะปัŒั‚ั€ะฐั†ั‹ั–", "notifications.column_settings.follow": "ะะพะฒั‹ั ะฟะฐะดะฟั–ัั‡ั‹ะบั–:", "notifications.column_settings.follow_request": "ะะพะฒั‹ั ะทะฐะฟั‹ั‚ั‹ ะฝะฐ ะฟะฐะดะฟั–ัะบัƒ:", "notifications.column_settings.mention": "ะ—ะณะฐะดะฒะฐะฝะฝั–:", @@ -469,6 +530,15 @@ "notifications.permission_denied": "ะะฟะฐะฒััˆั‡ัะฝะฝั– ะฝะฐ ะฟั€ะฐั†ะพัžะฝั‹ะผ ัั‚ะฐะปะต ะฝะตะดะฐัั‚ัƒะฟะฝั‹ั ะท-ะทะฐ ะฟะฐะฟัั€ัะดะฝะต ะฐะดั…ั–ะปะตะฝะฐะณะฐ ะทะฐะฟั‹ั‚ะฐ ะฟั€ะฐัž ะฑั€ะฐัžะทะตั€ะฐ", "notifications.permission_denied_alert": "ะะฟะฐะฒััˆั‡ัะฝะฝั– ะฝะฐ ะฟั€ะฐั†ะพัžะฝั‹ะผ ัั‚ะฐะปะต ะฝะต ะผะพะณัƒั†ัŒ ะฑั‹ั†ัŒ ัƒะบะปัŽั‡ะฐะฝั‹ั, ะท-ะทะฐ ั‚ะฐะณะพ ัˆั‚ะพ ะทะฐะฟั‹ั‚ ะฑั€ะฐัžะทะตั€ะฐ ะฑั‹ัž ะฐะดั…ั–ะปะตะฝั‹", "notifications.permission_required": "ะะฟะฐะฒััˆั‡ัะฝะฝั– ะฝะฐ ะฟั€ะฐั†ะพัžะฝั‹ะผ ัั‚ะฐะปะต ะฝะตะดะฐัั‚ัƒะฟะฝั‹ั, ะท-ะทะฐ ั‚ะฐะณะพ ัˆั‚ะพ ะฝะตะฐะฑั…ะพะดะฝั‹ ะดะฐะทะฒะพะป ะฝะต ะฑั‹ัž ะดะฐะดะทะตะฝั‹.", + "notifications.policy.filter_new_accounts.hint": "ะกั‚ะฒะพั€ะฐะฝั‹ั ะฝะฐ ะฟั€ะฐั†ัะณัƒ {days, plural, one {ะฐะฟะพัˆะฝัะณะฐ # ะดะฝั} few {ะฐะฟะพัˆะฝั–ั… # ะดะทั‘ะฝ} many {ะฐะฟะพัˆะฝั–ั… # ะดะทั‘ะฝ} other {ะฐะฟะพัˆะฝัะน # ะดะฝั}}", + "notifications.policy.filter_new_accounts_title": "ะะพะฒั‹ั ัžะปั–ะบะพะฒั‹ั ะทะฐะฟั–ัั‹", + "notifications.policy.filter_not_followers_hint": "ะฃะบะปัŽั‡ะฐัŽั‡ั‹ ะปัŽะดะทะตะน, ัะบั–ั ะฟะฐะดะฟั–ัะฐะฝั‹ ะฝะฐ ะฒะฐั ะผะตะฝัˆ, ั‡ั‹ะผ {days, plural, one {# ะดะทะตะฝัŒ} few {# ะดะฝั–} many {# ะดะทั‘ะฝ} other {# ะดะฝั}}", + "notifications.policy.filter_not_followers_title": "ะ›ัŽะดะทั–, ัะบั–ั ะฝะต ะฟะฐะดะฟั–ัะฐะฝั‹ ะฝะฐ ะฒะฐั", + "notifications.policy.filter_not_following_hint": "ะŸะฐะบัƒะปัŒ ะฒั‹ ะฝะต ะฟะฐั†ะฒะตั€ะดะทั–ั†ะต ั–ั… ัƒั€ัƒั‡ะฝัƒัŽ", + "notifications.policy.filter_not_following_title": "ะ›ัŽะดะทั–, ะฝะฐ ัะบั–ั… ะฒั‹ ะฝะต ะฟะฐะดะฟั–ัะฐะฝั‹", + "notifications.policy.filter_private_mentions_hint": "ะคั–ะปัŒั‚ั€ัƒะตั†ั†ะฐ ะทะฐ ะฒั‹ะบะปัŽั‡ัะฝะฝะตะผ ะฐะดะบะฐะทัƒ ะฝะฐ ะฒะฐัˆะฐะต ะทะณะฐะดะฒะฐะฝะฝะต ั†ั– ะบะฐะปั– ะฒั‹ ะฟะฐะดะฟั–ัะฐะฝั‹ ะฝะฐ ะฐะดะฟั€ะฐัžะฝั–ะบะฐ", + "notifications.policy.filter_private_mentions_title": "ะะตะฟะฐะถะฐะดะฐะฝั‹ั ะฐัะฐะฑะปั–ะฒั‹ั ะทะณะฐะดะฒะฐะฝะฝั–", + "notifications.policy.title": "ะะดั„ั–ะปัŒั‚ั€ะพัžะฒะฐั†ัŒ ะฐะฟะฐะฒััˆั‡ัะฝะฝั– ะฐะดโ€ฆ", "notifications_permission_banner.enable": "ะฃะบะปัŽั‡ั‹ั†ัŒ ะฐะฟะฐะฒััˆั‡ัะฝะฝั– ะฝะฐ ะฟั€ะฐั†ะพัžะฝั‹ะผ ัั‚ะฐะปะต", "notifications_permission_banner.how_to_control": "ะšะฐะฑ ะฐั‚ั€ั‹ะผะปั–ะฒะฐั†ัŒ ะฐะฟะฐะฒััˆั‡ัะฝะฝั–, ะบะฐะปั– Mastodon ะฝะต ะฐะดะบั€ั‹ั‚ั‹, ัƒะบะปัŽั‡ั‹ั†ะต ะฐะฟะฐะฒััˆั‡ัะฝะฝั– ะฟั€ะฐั†ะพัžะฝะฐะณะฐ ัั‚ะฐะปะฐ. ะ’ั‹ ะทะผะพะถะฐั†ะต ะดะฐะบะปะฐะดะฝะฐ ะบะฐะฝั‚ั€ะฐะปัะฒะฐั†ัŒ, ัะบั–ั ะฟะฐะดะทะตั– ะฑัƒะดัƒั†ัŒ ัั‚ะฒะฐั€ะฐั†ัŒ ะฐะฟะฐะฒััˆั‡ัะฝะฝั– ะท ะดะฐะฟะฐะผะพะณะฐะน {icon} ะบะฝะพะฟะบั–, ัะบ ั‚ะพะปัŒะบั– ัะฝั‹ ะฑัƒะดัƒั†ัŒ ัƒะบะปัŽั‡ะฐะฝั‹.", "notifications_permission_banner.title": "ะะต ะฟั€ะฐะฟัƒัั†ั–ั†ะต ะฝั–ั‡ะพะณะฐ", @@ -625,13 +695,10 @@ "server_banner.about_active_users": "ะ›ัŽะดะทั–, ัะบั–ั ะบะฐั€ั‹ัั‚ะฐัŽั†ั†ะฐ ะณัั‚ั‹ะผ ัะตั€ะฒะตั€ะฐ ะฝะฐ ะฟั€ะฐั†ัะณัƒ ะฐะฟะพัˆะฝั–ั… 30 ะดะทั‘ะฝ (ะจั‚ะพะผะตััั‡ะฝะฐ ะะบั‚ั‹ัžะฝั‹ั ะšะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบั–)", "server_banner.active_users": "ะฐะบั‚ั‹ัžะฝั‹ั ะบะฐั€ั‹ัั‚ะฐะปัŒะฝั–ะบั–", "server_banner.administered_by": "ะะดะผั–ะฝั–ัั‚ั€ะฐั‚ะฐั€:", - "server_banner.introduction": "{domain} ั‘ัั†ัŒ ั‡ะฐัั‚ะบะฐะน ะดัั†ัะฝั‚ั€ะฐะปั–ะทะฐะฒะฐะฝะฐะน ัะฐั†ั‹ัะปัŒะฝะฐะน ัะตั‚ะบั– ะฐะด {mastodon}.", - "server_banner.learn_more": "ะ”ะฐะฒะตะดะฐั†ั†ะฐ ะฑะพะปัŒัˆ", "server_banner.server_stats": "ะกั‚ะฐั‚ั‹ัั‚ั‹ะบะฐ ัะตั€ะฒะตั€ะฐ:", "sign_in_banner.create_account": "ะกั‚ะฒะฐั€ั‹ั†ัŒ ัƒะปั–ะบะพะฒั‹ ะทะฐะฟั–ั", "sign_in_banner.sign_in": "ะฃะฒะฐะนัั†ั–", "sign_in_banner.sso_redirect": "ะฃะฒะฐั…ะพะด ั†ั– ั€ัะณั–ัั‚ั€ะฐั†ั‹ั", - "sign_in_banner.text": "ะฃะฒะฐะนะดะทั–ั†ะต, ะบะฐะฑ ะฟะฐะดะฟั–ัะฐั†ั†ะฐ ะฝะฐ ะปัŽะดะทะตะน ั– ั‚ัะณั–, ะบะฐะฑ ะฐะดะบะฐะทะฒะฐั†ัŒ ะฝะฐ ะดะพะฟั–ัั‹, ะดะทัะปั–ั†ั†ะฐ ั–ะผั– ั– ะฟะฐะดะฐะฑะฐั†ัŒ ั–ั…, ะฐะปัŒะฑะพ ะบะฐะฝั‚ะฐะบั‚ะฐะฒะฐั†ัŒ ะท ะฒะฐัˆะฐะณะฐ ัžะปั–ะบะพะฒะฐะณะฐ ะทะฐะฟั–ััƒ ะฝะฐ ั–ะฝัˆั‹ะผ ัะตั€ะฒะตั€ั‹.", "status.admin_account": "ะะดะบั€ั‹ั†ัŒ ั–ะฝั‚ัั€ั„ะตะนั ะผะฐะดัั€ะฐั‚ะฐั€ะฐ ะดะปั @{name}", "status.admin_domain": "ะะดะบั€ั‹ั†ัŒ ั–ะฝั‚ัั€ั„ะตะนั ะผะฐะดัั€ะฐั‚ะฐั€ะฐ ะดะปั {domain}", "status.admin_status": "ะะดะบั€ั‹ั†ัŒ ะณัั‚ั‹ ะดะพะฟั–ั ัƒ ั–ะฝั‚ัั€ั„ะตะนัะต ะผะฐะดัั€ะฐั†ั‹ั–", @@ -645,10 +712,11 @@ "status.direct": "ะ—ะณะฐะดะฐั†ัŒ ะฐัะฐะฑั–ัั‚ะฐ @{name}", "status.direct_indicator": "ะัะฐะฑั–ัั‚ะฐะต ะทะณะฐะดะฒะฐะฝะฝะต", "status.edit": "ะ ัะดะฐะณะฐะฒะฐั†ัŒ", - "status.edited": "ะะดั€ัะดะฐะณะฐะฒะฐะฝะฐ {date}", + "status.edited": "ะะฟะพัˆะฝัะต ั€ัะดะฐะณะฐะฒะฐะฝะฝะต {date}", "status.edited_x_times": "ะ ัะดะฐะณะฐะฒะฐะฝะฐ {count, plural, one {{count} ั€ะฐะท} few {{count} ั€ะฐะทั‹} many {{count} ั€ะฐะทะพัž} other {{count} ั€ะฐะทัƒ}}", "status.embed": "ะฃะฑัƒะดะฐะฒะฐั†ัŒ", "status.favourite": "ะฃะฟะฐะดะฐะฑะฐะฝะฐะต", + "status.favourites": "{count, plural, one {# ัƒะฟะฐะดะฐะฑะฐะฝะฐะต} few {# ัƒะฟะฐะดะฐะฑะฐะฝั‹ั} many {# ัƒะฟะฐะดะฐะฑะฐะฝั‹ั…} other {# ัƒะฟะฐะดะฐะฑะฐะฝะฐะณะฐ}}", "status.filter": "ะคั–ะปัŒั‚ั€ะฐะฒะฐั†ัŒ ะณัั‚ั‹ ะดะพะฟั–ั", "status.filtered": "ะะดั„ั–ะปัŒั‚ั€ะฐะฒะฐะฝะฐ", "status.hide": "ะกั…ะฐะฒะฐั†ัŒ ะดะพะฟั–ั", @@ -669,6 +737,7 @@ "status.reblog": "ะŸะฐัˆั‹ั€ั‹ั†ัŒ", "status.reblog_private": "ะŸะฐัˆั‹ั€ั‹ั†ัŒ ะท ะฟะตั€ัˆะฐะฟะฐั‡ะฐั‚ะบะพะฒะฐะน ะฑะฐั‡ะฝะฐัั†ัŽ", "status.reblogged_by": "{name} ะฟะฐัˆั‹ั€ั‹ัž(-ะปะฐ)", + "status.reblogs": "{count, plural, one {# ะฟะฐัˆั‹ั€ัะฝะฝะต} few {# ะฟะฐัˆั‹ั€ัะฝะฝั–} many {# ะฟะฐัˆั‹ั€ัะฝะฝััž} other {# ะฟะฐัˆั‹ั€ัะฝะฝั}}", "status.reblogs.empty": "ะ“ัั‚ั‹ ะดะพะฟั–ั ััˆั‡ั ะฝั–ั…ั‚ะพ ะฝะต ะฟะฐัˆั‹ั€ั‹ัž. ะšะฐะปั– ะณัั‚ะฐ ะฐะดะฑัƒะดะทะตั†ั†ะฐ, ะณัั‚ั‹ั… ะปัŽะดะทะตะน ะฑัƒะดะทะต ะฑะฐั‡ะฝะฐ ั‚ัƒั‚.", "status.redraft": "ะ’ั‹ะดะฐะปั–ั†ัŒ ั– ะฟะฐะฟั€ะฐะฒั–ั†ัŒ", "status.remove_bookmark": "ะ’ั‹ะดะฐะปั–ั†ัŒ ะทะฐะบะปะฐะดะบัƒ", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 3e7f6e51b2..98e84c45d7 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.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": "ะ—ะฐัะฒะตะฝะฐั‚ะฐ ัั‚ั€ะฐะฝะธั†ะฐ ะฝะต ะผะพะถะต ะดะฐ ัะต ะธะทะพะฑั€ะฐะทะธ. ะขะพะฒะฐ ะผะพะถะต ะดะฐ ะต ะทะฐั€ะฐะดะธ ะณั€ะตัˆะบะฐ ะฒ ะบะพะดะฐ ะฝะธ ะธะปะธ ะฟั€ะพะฑะปะตะผ ััŠั ััŠะฒะผะตัั‚ะธะผะพัั‚ั‚ะฐ ะฝะฐ ะฑั€ะฐัƒะทัŠั€ะฐ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ะ”ะพะฑะฐะฒัะฝะต ะฝะฐ ะฟั€ะตะดัƒะฟั€ะตะถะดะตะฝะธะต ะทะฐ ััŠะดัŠั€ะถะฐะฝะธะต", "compose_form.spoiler_placeholder": "ะŸั€ะตะดัƒะฟั€ะตะถะดะตะฝะธะต ะทะฐ ััŠะดัŠั€ะถะฐะฝะธะต (ะฟะพ ะธะทะฑะพั€)", "confirmation_modal.cancel": "ะžั‚ะบะฐะท", - "confirmations.block.block_and_report": "ะ‘ะปะพะบะธั€ะฐะฝะต ะธ ะดะพะบะปะฐะดะฒะฐะฝะต", "confirmations.block.confirm": "ะ‘ะปะพะบะธั€ะฐะฝะต", - "confirmations.block.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะฑะปะพะบะธั€ะฐั‚ะต {name}?", "confirmations.cancel_follow_request.confirm": "ะžั‚ั‚ะตะณะปัะฝะต ะฝะฐ ะทะฐัะฒะบะฐั‚ะฐ", "confirmations.cancel_follow_request.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะพั‚ั‚ะตะณะปะธั‚ะต ะทะฐัะฒะบะฐั‚ะฐ ัะธ ะทะฐ ะฟะพัะปะตะดะฒะฐะฝะต ะฝะฐ {name}?", "confirmations.delete.confirm": "ะ˜ะทั‚ั€ะธะฒะฐะฝะต", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะธะทั‚ั€ะธะตั‚ะต ะทะฐะฒะธะฝะฐะณะธ ัะฟะธััŠะบะฐ?", "confirmations.discard_edit_media.confirm": "ะžั‚ั…ะฒัŠั€ะปัะฝะต", "confirmations.discard_edit_media.message": "ะะต ัั‚ะต ะทะฐะฟะฐะทะธะปะธ ะฟั€ะพะผะตะฝะธ ะฝะฐ ะพะฟะธัะฐะฝะธะตั‚ะพ ะธะปะธ ะพะณะปะตะดะฐ ะฝะฐ ะผัƒะปั‚ะธะผะตะดะธัั‚ะฐ, ะพั‚ั…ะฒัŠั€ะปัั‚ะต ะปะธ ะณะธ?", - "confirmations.domain_block.confirm": "ะ‘ะปะพะบะธั€ะฐะฝะต ะฝะฐ ั†ะตะปะธั ะดะพะผะตะนะฝ", + "confirmations.domain_block.confirm": "ะ‘ะปะพะบะธั€ะฐะฝะต ะฝะฐ ััŠั€ะฒัŠั€", "confirmations.domain_block.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะฑะปะพะบะธั€ะฐั‚ะต ั†ะตะปะธั {domain}? ะ’ ะฟะพะฒะตั‡ะตั‚ะพ ัะปัƒั‡ะฐะธ ะฝัะบะพะปะบะพ ะฑะปะพะบะธั€ะฐะฝะธั ะธะปะธ ะทะฐะณะปัƒัˆะฐะฒะฐะฝะธั ัะฐ ะดะพัั‚ะฐั‚ัŠั‡ะฝะพ ะธ ะทะฐ ะฟั€ะตะดะฟะพั‡ะธั‚ะฐะฝะต. ะัะผะฐ ะดะฐ ะฒะธะถะดะฐั‚ะต ััŠะดัŠั€ะถะฐะฝะธะต ะพั‚ ะดะพะผะตะนะฝะฐ ะธะท ะฟัƒะฑะปะธั‡ะฝะธ ั‡ะฐัะพะฒะธ ะพัะธ ะธะปะธ ะธะทะฒะตัั‚ะธัั‚ะฐ ัะธ. ะ’ะฐัˆะธั‚ะต ะฟะพัะปะตะดะพะฒะฐั‚ะตะปะธ ะพั‚ ั‚ะพะทะธ ะดะพะผะตะนะฝ ั‰ะต ัะต ะฟั€ะตะผะฐั…ะฝะฐั‚.", "confirmations.edit.confirm": "ะ ะตะดะฐะบั‚ะธั€ะฐะฝะต", "confirmations.edit.message": "ะ ะตะดะฐะบั‚ะธั€ะฐะฝะตั‚ะพ ัะตะณะฐ ั‰ะต ะทะฐะผะตะฝะธ ััŠะพะฑั‰ะตะฝะธะตั‚ะพ, ะบะพะตั‚ะพ ะฒ ะผะพะผะตะฝั‚ะฐ ััŠัั‚ะฐะฒัั‚ะต. ะกะธะณัƒั€ะฝะธ ะปะธ ัั‚ะต, ั‡ะต ะธัะบะฐั‚ะต ะดะฐ ะฟั€ะพะดัŠะปะถะธั‚ะต?", "confirmations.logout.confirm": "ะ˜ะทะปะธะทะฐะฝะต", "confirmations.logout.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะธะทะปะตะทะตั‚ะต?", "confirmations.mute.confirm": "ะ—ะฐะณะปัƒัˆะฐะฒะฐะฝะต", - "confirmations.mute.explanation": "ะขะพะฒะฐ ั‰ะต ัะบั€ะธะต ะฟัƒะฑะปะธะบะฐั†ะธะธั‚ะต ะพั‚ ั‚ัั… ะธ ะฟัƒะฑะปะธะบะฐั†ะธะธ, ะบะพะธั‚ะพ ะณะธ ัะฟะพะผะตะฝะฐะฒะฐั‚, ะฝะพ ะฒัะต ะพั‰ะต ั‰ะต ะธะผ ะฟะพะทะฒะพะปัะฒะฐ ะดะฐ ะฒะธะถะดะฐั‚ ะฟัƒะฑะปะธะบะฐั†ะธะธั‚ะต ะฒะธ ะธ ะดะฐ ะฒะธ ัะปะตะดะฒะฐั‚.", - "confirmations.mute.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะทะฐะณะปัƒัˆะธั‚ะต {name}?", "confirmations.redraft.confirm": "ะ˜ะทั‚ั€ะธะฒะฐะฝะต ะธ ะฟั€ะตั€ะฐะฑะพั‚ะฒะฐะฝะต", "confirmations.redraft.message": "ะะฐะธัั‚ะธะฝะฐ ะปะธ ะธัะบะฐั‚ะต ะดะฐ ะธะทั‚ั€ะธะตั‚ะต ั‚ะฐะทะธ ะฟัƒะฑะปะธะบะฐั†ะธั ะธ ะดะฐ ั ะฝะฐะฟั€ะฐะฒะธั‚ะต ั‡ะตั€ะฝะพะฒะฐ? ะžะทะฝะฐั‡ะฐะฒะฐะฝะธัั‚ะฐ ะบะฐั‚ะพ ะปัŽะฑะธะผะธ ะธ ะฟะพะดัะธะปะฒะฐะฝะธัั‚ะฐ ั‰ะต ัะต ะธะทะณัƒะฑัั‚, ะฐ ะธ ะพั‚ะณะพะฒะพั€ะธั‚ะต ะบัŠะผ ะฟัŠั€ะฒะพะฝะฐั‡ะฐะปะฝะฐั‚ะฐ ะฟัƒะฑะปะธะบะฐั†ะธั ั‰ะต ะพัะธั€ะพั‚ะตัั‚.", "confirmations.reply.confirm": "ะžั‚ะณะพะฒะพั€", @@ -205,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": "ะ”ะตะนะฝะพัั‚", @@ -241,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": "ะŸะพั€ะฐะดะธ ะณั€ะตัˆะบะฐ ะฒ ะฝะฐัˆะธั ะบะพะด ะธะปะธ ะฟั€ะพะฑะปะตะผ ััŠั ััŠะฒะผะตัั‚ะธะผะพัั‚ั‚ะฐ ะฝะฐ ะฑั€ะฐัƒะทัŠั€ะฐ, ั‚ะฐะทะธ ัั‚ั€ะฐะฝะธั†ะฐ ะฝะต ะผะพะถะต ะดะฐ ัะต ะฟะพะบะฐะถะต ะฟั€ะฐะฒะธะปะฝะพ.", @@ -271,16 +297,28 @@ "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 {ะฝะธะบะพะณะพ, ะบะพะณะพั‚ะพ ะผะพะถะต ะดะฐ ะฟะพะทะฝะฐะฒะฐั‚ะต} 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.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}.", + "follow_suggestions.hints.most_interactions": "ะขะพะทะธ ะฟั€ะพั„ะธะป ะฝะฐัะบะพั€ะพ ะฟะพะปัƒั‡ะธ ะผะฝะพะณะพ ะฒะฝะธะผะฐะฝะธะต ะฟั€ะธ {domain}.", + "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": "ะŸะพัะปะตะดะฒะฐะฝะธ ั…ะฐัˆั‚ะฐะณะพะฒะต", @@ -309,7 +347,6 @@ "hashtag.follow": "ะกะปะตะดะฒะฐะฝะต ะฝะฐ ั…ะฐัˆั‚ะฐะณ", "hashtag.unfollow": "ะกะฟะธั€ะฐะฝะต ะฝะฐ ัะปะตะดะฒะฐะฝะต ะฝะฐ ั…ะฐัˆั‚ะฐะณ", "hashtags.and_other": "โ€ฆะธ {count, plural, other {# ะพั‰ะต}}", - "home.column_settings.basic": "ะžัะฝะพะฒะฝะพ", "home.column_settings.show_reblogs": "ะŸะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะฟะพะดัะธะปะฒะฐะฝะธัั‚ะฐ", "home.column_settings.show_replies": "ะŸะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะพั‚ะณะพะฒะพั€ะธั‚ะต", "home.hide_announcements": "ะกะบั€ะธะฒะฐะฝะต ะฝะฐ ะพะฟะพะฒะตัั‚ัะฒะฐะฝะธัั‚ะฐ", @@ -377,6 +414,8 @@ "limited_account_hint.action": "ะŸะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะฟั€ะพั„ะธะปะฐ ะฒัŠะฟั€ะตะบะธ ั‚ะพะฒะฐ", "limited_account_hint.title": "ะขะพะทะธ ะฟั€ะพั„ะธะป ะต ะฑะธะป ัะบั€ะธั‚ ะพั‚ ะผะพะดะตั€ะฐั‚ะพั€ะธั‚ะต ะฝะฐ {domain}.", "link_preview.author": "ะžั‚ {name}", + "link_preview.more_from_author": "ะžั‰ะต ะพั‚ {name}", + "link_preview.shares": "{count, plural, one {{counter} ะฟัƒะฑะปะธะบะฐั†ะธั} other {{counter} ะฟัƒะฑะปะธะบะฐั†ะธะธ}}", "lists.account.add": "ะ”ะพะฑะฐะฒัะฝะต ะบัŠะผ ัะฟะธััŠะบ", "lists.account.remove": "ะŸั€ะตะผะฐั…ะฒะฐะฝะต ะพั‚ ัะฟะธััŠะบะฐ", "lists.delete": "ะ˜ะทั‚ั€ะธะฒะฐะฝะต ะฝะฐ ัะฟะธััŠะบะฐ", @@ -395,9 +434,15 @@ "loading_indicator.label": "ะ—ะฐั€ะตะถะดะฐะฝะตโ€ฆ", "media_gallery.toggle_visible": "ะกะบั€ะธะฒะฐะฝะต ะฝะฐ {number, plural, one {ะธะทะพะฑั€ะฐะถะตะฝะธะต} other {ะธะทะพะฑั€ะฐะถะตะฝะธั}}", "moved_to_account_banner.text": "ะ’ะฐัˆะธัั‚ ะฐะบะฐัƒะฝั‚ {disabledAccount} ัะตะณะฐ ะต ะธะทะบะปัŽั‡ะตะฝ, ะทะฐั‰ะพั‚ะพ ัะต ะฟั€ะตะผะตัั‚ะธั…ั‚ะต ะฒ {movedToAccount}.", - "mute_modal.duration": "ะ’ั€ะตะผะตั‚ั€ะฐะตะฝะต", - "mute_modal.hide_notifications": "ะกะบั€ะธะฒะฐะฝะต ะฝะฐ ะธะทะฒะตัั‚ะธั ะพั‚ ั‚ะพะทะธ ะฟะพั‚ั€ะตะฑะธั‚ะตะป?", - "mute_modal.indefinite": "ะะตะพะฟั€ะตะดะตะปะตะฝะพ", + "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": "ะ‘ะปะพะบะธั€ะฐะฝะธ ะฟะพั‚ั€ะตะฑะธั‚ะตะปะธ", @@ -430,11 +475,29 @@ "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.relationships_severance_event": "ะ˜ะทะณัƒะฑะธ ัะต ะฒั€ัŠะทะบะฐั‚ะฐ ั {name}", + "notification.relationships_severance_event.account_suspension": "ะะดะผะธะฝะธัั‚ั€ะฐั‚ะพั€ ะพั‚ {from} ัะฟั€ั {target}, ะบะพะตั‚ะพ ะทะฝะฐั‡ะธ ั‡ะต ะฟะพะฒะตั‡ะต ะฝะต ะผะพะถะต ะดะฐ ะฟะพะปัƒั‡ะฐะฒะฐั‚ะต ะฝะพะฒะพัั‚ะธ ะพั‚ ั‚ัั… ะธะปะธ ะดะฐ ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะฐั‚ะต ั ั‚ัั….", + "notification.relationships_severance_event.domain_block": "ะะดะผะธะฝะธัั‚ั€ะฐั‚ะพั€ ะพั‚ {from} ะฑะปะพะบะธั€ะฐ {target}, ะฒะบัŽั‡ะฒะฐั‰ะพ {followersCount} ะพั‚ ะฟะพัะปะตะดะพะฒะฐั‚ะตะปะธั‚ะต ะฒะธ ะธ {followingCount, plural, one {# ะฐะบะฐัƒะฝั‚, ะบะพะนั‚ะพ} other {# ะฐะบะฐัƒะฝั‚ะฐ, ะบะพะธั‚ะพ}} ัะปะตะดะฒะฐั‚ะต.", + "notification.relationships_severance_event.learn_more": "ะะฐัƒั‡ะตั‚ะต ะฟะพะฒะตั‡ะต", + "notification.relationships_severance_event.user_domain_block": "ะ‘ะปะพะบะธั€ะฐั…ั‚ะต {target}, ะฟั€ะตะผะฐั…ะฒะฐะนะบะธ {followersCount} ะพั‚ ะฟะพัะปะตะดะพะฒะฐั‚ะตะปะธั‚ะต ัะธ ะธ {followingCount, plural, one {# ะฐะบะฐัƒะฝั‚, ะบะพะนั‚ะพ} 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": "ะะพะฒะธ ะดะพะบะปะฐะดะธ:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "ะ›ัŽะฑะธะผะธ:", "notifications.column_settings.filter_bar.advanced": "ะŸะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะฒัะธั‡ะบะธ ะบะฐั‚ะตะณะพั€ะธะธ", "notifications.column_settings.filter_bar.category": "ะ›ะตะฝั‚ะฐ ะทะฐ ะฑัŠั€ะท ั„ะธะปั‚ัŠั€", - "notifications.column_settings.filter_bar.show_bar": "ะŸะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะปะตะฝั‚ะฐั‚ะฐ ั ั„ะธะปั‚ั€ะธ", "notifications.column_settings.follow": "ะะพะฒะธ ะฟะพัะปะตะดะพะฒะฐั‚ะตะปะธ:", "notifications.column_settings.follow_request": "ะะพะฒะธ ะทะฐัะฒะบะธ ะทะฐ ะฟะพัะปะตะดะฒะฐะฝะต:", "notifications.column_settings.mention": "ะกะฟะพะผะตะฝะฐะฒะฐะฝะธั:", @@ -469,13 +531,22 @@ "notifications.permission_denied": "ะ˜ะทะฒะตัั‚ะธัั‚ะฐ ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚ ะฝะต ัะฐ ะฝะฐะปะธั‡ะฝะธ ะฟะพั€ะฐะดะธ ะฟั€ะตะดะฒะฐั€ะธั‚ะตะปะฝะพ ะพั‚ะบะฐะทะฐะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ั€ะฐะทั€ะตัˆะตะฝะธะต ะฒ ะฑั€ะฐัƒะทัŠั€ะฐ", "notifications.permission_denied_alert": "ะ˜ะทะฒะตัั‚ะธัั‚ะฐ ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚ ะฝะต ะผะพะณะฐั‚ ะดะฐ ัะต ะฒะบะปัŽั‡ะฐั‚, ั‚ัŠะน ะบะฐั‚ะพ ั€ะฐะทั€ะตัˆะตะฝะธะตั‚ะพ ะฝะฐ ะฑั€ะฐัƒะทัŠั€ะฐ ะต ะพั‚ะบะฐะทะฒะฐะฝะพ ะฟั€ะตะดะธ", "notifications.permission_required": "ะ˜ะทะฒะตัั‚ะธัั‚ะฐ ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚ ะณะธ ะฝัะผะฐ, ั‰ะพั‚ะพ ะฝัะผะฐ ะดะฐะดะตะฝะพ ะฝัƒะถะฝะพั‚ะพ ะฟะพะทะฒะพะปะตะฝะธะต.", + "notifications.policy.filter_new_accounts.hint": "ะกัŠั‚ะฒะพั€ะตะฝะพ ะฟั€ะตะท {days, plural, one {ะฟะพัะปะตะดะฝะธั ะดะตะฝ} other {ะฟะพัะปะตะดะฝะธั‚ะต # ะดะตะฝะฐ}}", + "notifications.policy.filter_new_accounts_title": "ะะพะฒะธ ะฐะบะฐัƒะฝั‚ะธ", + "notifications.policy.filter_not_followers_hint": "ะ’ะบะปัŽั‡ะธั‚ะตะปะฝะพ ั…ะพั€ะฐ, ะบะพะธั‚ะพ ัะฐ ะฒะธ ะฟะพัะปะตะดะฒะฐะปะธ ะฟะพ-ะผะฐะปะบะพ ะพั‚ {days, plural, one {ะดะตะฝ} other {# ะดะฝะธ}}", + "notifications.policy.filter_not_followers_title": "ะฅะพั€ะฐ, ะบะพะธั‚ะพ ะฝะต ะฒะธ ัะปะตะดะฒะฐั‚", + "notifications.policy.filter_not_following_hint": "ะ”ะพะบะฐั‚ะพ ะฝะต ะณะธ ะพะดะพะฑั€ะธั‚ะต ั€ัŠั‡ะฝะพ", + "notifications.policy.filter_not_following_title": "ะฅะพั€ะฐ, ะบะพะธั‚ะพ ะฝะต ัะปะตะดะฒะฐั‚ะต", + "notifications.policy.filter_private_mentions_hint": "ะคะธะปั‚ั€ะธั€ะฐะฝะพ, ะพัะฒะตะฝ ะฐะบะพ ะต ะพั‚ะณะพะฒะพั€ ะบัŠะผ ะฒะฐัˆะต ัะพะฑัั‚ะฒะตะฝะพ ัะฟะพะผะตะฝะฐะฒะฐะฝะต ะธะปะธ ะฐะบะพ ัะปะตะดะฒะฐั‚ะต ะฟะพะดะฐั‚ะตะปั", + "notifications.policy.filter_private_mentions_title": "ะะตะฟะพะธัะบะฐะฝะธ ั‡ะฐัั‚ะฝะธ ัะฟะพะผะตะฝะฐะฒะฐะฝะธั", + "notifications.policy.title": "ะ”ะฐ ัะต ั„ะธะปั‚ั€ะธั€ะฐั‚ ะธะทะฒะตัั‚ะธั ะพั‚โ€ฆ", "notifications_permission_banner.enable": "ะ’ะบะปัŽั‡ะฒะฐะฝะต ะฝะฐ ะธะทะฒะตัั‚ะธัั‚ะฐ ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚", "notifications_permission_banner.how_to_control": "ะ—ะฐ ะดะฐ ะฟะพะปัƒั‡ะฐะฒะฐั‚ะต ะธะทะฒะตัั‚ะธั, ะบะพะณะฐั‚ะพ Mastodon ะฝะต ะต ะพั‚ะฒะพั€ะตะฝ, ะฒะบะปัŽั‡ะตั‚ะต ะธะทะฒะตัั‚ะธัั‚ะฐ ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚. ะœะพะถะต ะดะฐ ัƒะฟั€ะฐะฒะปัะฒะฐั‚ะต ั‚ะพั‡ะฝะพ ะบะพะธ ะฒะธะดะพะฒะต ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะธั ะฟะพั€ะฐะถะดะฐั‚ ะธะทะฒะตัั‚ะธั ะฝะฐ ั€ะฐะฑะพั‚ะฝะธั ะฟะปะพั‚ ั‡ั€ะตะท ะฑัƒั‚ะพะฝะฐ {icon} ะฟะพ-ะณะพั€ะต, ัะปะตะด ะบะฐั‚ะพ ะฑัŠะดะฐั‚ ะฒะบะปัŽั‡ะตะฝะธ.", - "notifications_permission_banner.title": "ะะธะบะพะณะฐ ะฝะต ะฟั€ะพะฟัƒัะบะฐั‚ะต ะฝะตั‰ะพ", + "notifications_permission_banner.title": "ะะธะบะพะณะฐ ะฝะต ะฟั€ะพะฟัƒัะบะฐะนั‚ะต ะฝะธั‰ะพ", "onboarding.action.back": "ะ’ัŠั€ะฝะตั‚ะต ะผะต ะพะฑั€ะฐั‚ะฝะพ", "onboarding.actions.back": "ะ’ัŠั€ะฝะตั‚ะต ะผะต ะพะฑั€ะฐั‚ะฝะพ", "onboarding.actions.go_to_explore": "ะ’ะธะถ ั‚ะตะฝะดะตะฝั†ะธะธ", - "onboarding.actions.go_to_home": "ะšัŠะผ ะฝะฐั‡ะฐะปะฝะธั ะฒะธ ะธะฝั„ะพะบะฐะฝะฐะป", + "onboarding.actions.go_to_home": "ะšัŠะผ ะฝะฐั‡ะฐะปะฝะธั ะผะธ ะธะฝั„ะพะบะฐะฝะฐะป", "onboarding.compose.template": "ะ—ะดั€ะฐะฒะตะนั‚ะต, #Mastodon!", "onboarding.follows.empty": "ะ—ะฐ ััŠะถะฐะปะตะฝะธะต, ะฒ ะผะพะผะตะฝั‚ะฐ ะฝะต ะผะพะณะฐั‚ ะดะฐ ะฑัŠะดะฐั‚ ะฟะพะบะฐะทะฐะฝะธ ั€ะตะทัƒะปั‚ะฐั‚ะธ. ะœะพะถะต ะดะฐ ะพะฟะธั‚ะฐั‚ะต ะดะฐ ั‚ัŠั€ัะธั‚ะต ะธะปะธ ะดะฐ ั€ะฐะทะณะปะตะดะฐั‚ะต, ะทะฐ ะดะฐ ะฝะฐะผะตั€ะธั‚ะต ะบะพะณะพ ะดะฐ ะฟะพัะปะตะดะฒะฐั‚ะต, ะธะปะธ ะพะฟะธั‚ะฐะนั‚ะต ะพั‚ะฝะพะฒะพ ะฟะพ-ะบัŠัะฝะพ.", "onboarding.follows.lead": "ะœะพะถะต ะดะฐ ะฑัŠะดะตั‚ะต ะบัƒั€ะฐั‚ะพั€ ะฝะฐ ะฝะฐั‡ะฐะปะฝะธั ัะธ ะธะฝั„ะพะบะฐะฝะฐะป. ะŸะพัะปะตะดะฒะฐะนะบะธ ะฟะพะฒะตั‡ะต ั…ะพั€ะฐ, ะฟะพ-ะดะตะตะฝ ะธ ะฟะพ-ะธะฝั‚ะตั€ะตัะตะฝ ั‰ะต ัั‚ะฐะฒะฐ. ะขะตะทะธ ะฟั€ะพั„ะธะปะธ ะผะพะถะต ะดะฐ ัะฐ ะดะพะฑั€ะฐ ะฝะฐั‡ะฐะปะฝะฐ ั‚ะพั‡ะบะฐ, ะพั‚ ะบะพัั‚ะพ ะฒะธะฝะฐะณะธ ะฟะพ-ะบัŠัะฝะพ ะดะฐ ัะฟั€ะตั‚ะต ะดะฐ ัะปะตะดะฒะฐั‚ะต!", @@ -499,7 +570,7 @@ "onboarding.start.skip": "ะ–ะตะปะฐะตั‚ะต ะปะธ ะดะฐ ะฟั€ะตัะบะพั‡ะธั‚ะต?", "onboarding.start.title": "ะฃัะฟัั…ั‚ะต!", "onboarding.steps.follow_people.body": "ะœะพะถะต ะดะฐ ะฑัŠะดะตั‚ะต ะบัƒั€ะฐั‚ะพั€ ะฝะฐ ะธะฝั„ะพะบะฐะฝะฐะปะฐ ัะธ. ะฅะฐะนะดะต ะดะฐ ะณะพ ะทะฐะฟัŠะปะฝะธะผ ั ะธะฝั‚ะตั€ะตัะฝะธ ั…ะพั€ะฐ.", - "onboarding.steps.follow_people.title": "ะŸะพัะปะตะดะฒะฐะนั‚ะต {count, plural, one {ะตะดะธะฝ ั‡ะพะฒะตะบ} other {# ะดัƒัˆะธ}}", + "onboarding.steps.follow_people.title": "ะŸะตั€ัะพะฝะฐะปะธะทะธั€ะฐะฝะต ะฝะฐ ะฝะฐั‡ะฐะปะฝะธั ะฒะธ ะธะฝั„ะพะบะฐะฝะฐะป", "onboarding.steps.publish_status.body": "ะŸะพะทะดั€ะฐะฒะตั‚ะต ั†ะตะปะธั ัะฒัั‚.", "onboarding.steps.publish_status.title": "ะะฐะฟั€ะฐะฒะตั‚ะต ะฟัŠั€ะฒะฐั‚ะฐ ัะธ ะฟัƒะฑะปะธะบะฐั†ะธั", "onboarding.steps.setup_profile.body": "ะ”ั€ัƒะณะธ ัะฐ ะฟะพ-ะฒะตั€ะพัั‚ะฝะพ ะดะฐ ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะฐั‚ ั ะฒะฐั ั ะฟะพะฟัŠะปะฝะตะฝะธั ะฟั€ะพั„ะธะป.", @@ -606,7 +677,7 @@ "search.quick_action.go_to_hashtag": "ะšัŠะผ ั…ะฐัˆั‚ะฐะณ {x}", "search.quick_action.open_url": "ะžั‚ะฒะฐั€ัะฝะต ะฝะฐ URL ะฐะดั€ะตัะฐ ะฒ Mastodon", "search.quick_action.status_search": "ะกัŠะฒะฟะฐะดะตะฝะธะต ะฝะฐ ะฟัƒะฑะปะธะบะฐั†ะธะธ {x}", - "search.search_or_paste": "ะขัŠั€ัะตะฝะต ะธะปะธ ะฟะพัั‚ะฐะฒัะฝะต ะฝะฐ URL ะฐะดั€ะตั", + "search.search_or_paste": "ะขัŠั€ัะตะฝะต/ะฟะพัั‚ะฐะฒัะฝะต ะฝะฐ URL", "search_popout.full_text_search_disabled_message": "ะะต ะต ะดะพัั‚ัŠะฟะฝะพ ะฝะฐ {domain}.", "search_popout.full_text_search_logged_out_message": "ะ”ะพัั‚ัŠะฟะฝะพ ัะฐะผะพ ะฟั€ะธ ะฒะปะธะทะฐะฝะต ะฒ ัะธัั‚ะตะผะฐั‚ะฐ.", "search_popout.language_code": "ะšะพะด ะฝะฐ ะตะทะธะบะฐ ะฟะพ ISO", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "ะŸะพะปะทะฒะฐั‰ะธั‚ะต ััŠั€ะฒัŠั€ะฐ ะฟั€ะตะท ะฟะพัะปะตะดะฝะธั‚ะต 30 ะดะฝะธ (ะดะตะนะฝะธั‚ะต ะผะตัะตั‡ะฝะพ ะฟะพั‚ั€ะตะฑะธั‚ะตะปะธ)", "server_banner.active_users": "ะดะตะนะฝะธ ะฟะพั‚ั€ะตะฑะธั‚ะตะปะธ", "server_banner.administered_by": "ะะดะผะธะฝะธัั‚ั€ะธั€ะฐ ัะต ะพั‚:", - "server_banner.introduction": "{domain} ะต ั‡ะฐัั‚ ะพั‚ ะดะตั†ะตะฝั‚ั€ะฐะปะธะทะธั€ะฐะฝะฐั‚ะฐ ัะพั†ะธะฐะปะฝะฐ ะผั€ะตะถะฐ, ะฟะพะดะดัŠั€ะถะฐะฝะฐ ะพั‚ {mastodon}.", - "server_banner.learn_more": "ะะฐัƒั‡ะตั‚ะต ะฟะพะฒะตั‡ะต", + "server_banner.is_one_of_many": "{domain} ะต ะตะดะธะฝ ะพั‚ ะผะฝะพะณะพั‚ะพ ะฝะตะทะฐะฒะธัะธะผะธ ััŠั€ะฒัŠั€ะธ ะฝะฐ Mastodon, ะบะพะธั‚ะพ ะผะพะถะต ะดะฐ ัƒะฟะพั‚ั€ะตะฑัะฒะฐั‚ะต, ะทะฐ ะดะฐ ัƒั‡ะฐัั‚ะฒะฐั‚ะต ะฒัŠะฒ ั„ะตะดะธะฒัะตะปะตะฝะฐั‚ะฐ.", "server_banner.server_stats": "ะกั‚ะฐั‚ะธัั‚ะธะบะฐ ะฝะฐ ััŠั€ะฒัŠั€ะฐ:", "sign_in_banner.create_account": "ะกัŠะทะดะฐะฒะฐะฝะต ะฝะฐ ะฐะบะฐัƒะฝั‚", + "sign_in_banner.follow_anyone": "ะŸะพัะปะตะดะฒะฐะนั‚ะต ะฝัะบะพะณะพ ะฟั€ะตะท ั„ะตะดะธะฒัะตะปะตะฝะฐั‚ะฐ ะธ ะฒะธะถั‚ะต ะฒัะธั‡ะบะพ ะฒ ั…ั€ะพะฝะพะปะพะณะธั‡ะตะฝ ั€ะตะด. ะ‘ะตะท ะฐะปะณะพั€ะธั‚ะผะธ, ั€ะตะบะปะฐะผะธ, ะธะปะธ ะฟั€ะธะผะฐะผะฒะฐั‰ะธ ะฒั€ัŠะทะบะธ ะฒ ะฟะพะปะตะทั€ะตะฝะธะตั‚ะพ.", + "sign_in_banner.mastodon_is": "Mastodon ะต ะฝะฐะน-ะดะพะฑั€ะธั ะฝะฐั‡ะธะฝ ะดะฐ ะฑัŠะดะตั‚ะต ะฒ ะบั€ะฐะบ ััŠั ัะปัƒั‡ะฒะฐั‰ะพั‚ะพ ัะต.", "sign_in_banner.sign_in": "ะ’ั…ะพะด", "sign_in_banner.sso_redirect": "ะ’ะปะธะทะฐะฝะต ะธะปะธ ั€ะตะณะธัั‚ั€ะธั€ะฐะฝะต", - "sign_in_banner.text": "ะ’ะปะตะทั‚ะต, ะทะฐ ะดะฐ ะฟะพัะปะตะดะฒะฐั‚ะต ะฟั€ะพั„ะธะปะธ ะธะปะธ ั…ะฐัˆั‚ะฐะณะพะฒะต, ะพั‚ะฑะตะปัะทะฒะฐั‚ะต ะบะฐั‚ะพ ะปัŽะฑะธะผะธ, ัะฟะพะดะตะปัั‚ะต ะธ ะพั‚ะณะพะฒะฐั€ัั‚ะต ะฝะฐ ะฟัƒะฑะปะธะบะฐั†ะธะธ. ะœะพะถะต ััŠั‰ะพ ั‚ะฐะบะฐ ะดะฐ ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะฐั‚ะต ะพั‚ ะฐะบะฐัƒะฝั‚ะฐ ัะธ ะฝะฐ ะดั€ัƒะณ ััŠั€ะฒัŠั€.", "status.admin_account": "ะžั‚ะฒะฐั€ัะฝะต ะฝะฐ ะธะฝั‚ะตั€ั„ะตะนั ะทะฐ ะผะพะดะตั€ะธั€ะฐะฝะต ะทะฐ @{name}", "status.admin_domain": "ะžั‚ะฒะฐั€ัะฝะต ะฝะฐ ะผะพะดะตั€ะธั€ะฐั‰ะธั ะธะฝั‚ะตั€ั„ะตะนั ะทะฐ {domain}", "status.admin_status": "ะžั‚ะฒะฐั€ัะฝะต ะฝะฐ ะฟัƒะฑะปะธะบะฐั†ะธัั‚ะฐ ะฒ ะผะพะดะตั€ะธั€ะฐั‰ะธั ะธะฝั‚ะตั€ั„ะตะนั", @@ -645,10 +716,11 @@ "status.direct": "ะงะฐัั‚ะฝะพ ัะฟะพะผะตะฝะฐะฒะฐะฝะต ะฝะฐ @{name}", "status.direct_indicator": "ะงะฐัั‚ะฝะพ ัะฟะพะผะตะฝะฐะฒะฐะฝะต", "status.edit": "ะ ะตะดะฐะบั‚ะธั€ะฐะฝะต", - "status.edited": "ะ ะตะดะฐะบั‚ะธั€ะฐะฝะพ ะฝะฐ {date}", + "status.edited": "ะŸะพัะปะตะดะฝะพ ั€ะตะดะฐะบั‚ะธั€ะฐะฝะพ ะฝะฐ {date}", "status.edited_x_times": "ะ ะตะดะฐะบั‚ะธั€ะฐะฝะพ {count, plural,one {{count} ะฟัŠั‚} other {{count} ะฟัŠั‚ะธ}}", "status.embed": "ะ’ะณั€ะฐะถะดะฐะฝะต", "status.favourite": "ะ›ัŽะฑะธะผะพ", + "status.favourites": "{count, plural, one {ะปัŽะฑะธะผะพ} other {ะปัŽะฑะธะผะธ}}", "status.filter": "ะคะธะปั‚ั€ะธั€ะฐะฝะต ะฝะฐ ะฟัƒะฑะป.", "status.filtered": "ะคะธะปั‚ั€ะธั€ะฐะฝะพ", "status.hide": "ะกะบั€ะธะฒะฐะฝะต ะฝะฐ ะฟัƒะฑะป.", @@ -669,8 +741,9 @@ "status.reblog": "ะŸะพะดัะธะปะฒะฐะฝะต", "status.reblog_private": "ะŸะพะดัะธะปะฒะฐะฝะต ั ะพั€ะธะณะธะฝะฐะปะฝะฐั‚ะฐ ะฒะธะดะธะผะพัั‚", "status.reblogged_by": "{name} ะฟะพะดัะธะปะธ", + "status.reblogs": "{count, plural, one {ะฟะพะดัะธะปะฒะฐะฝะต} other {ะฟะพะดัะธะปะฒะฐะฝะธั}}", "status.reblogs.empty": "ะžั‰ะต ะฝะธะบะพะณะพ ะฝะต ะต ะฟะพะดัะธะปะฒะฐะป ะฟัƒะฑะปะธะบะฐั†ะธัั‚ะฐ. ะŸะพะดัะธะปะฒะฐั‰ะธัั‚ ั‰ะต ัะต ะฟะพะบะฐะถะต ั‚ัƒะบ.", - "status.redraft": "ะ˜ะทั‚ั€ะธะฒะฐะฝะต ะธ ะฟั€ะตะฝะฐั‡ะตั€ั‚ะฐะฒะฐะฝะต", + "status.redraft": "ะ˜ะทั‚ั€ะธะฒะฐะฝะต ะธ ะฟั€ะตั€ะฐะฑะพั‚ะฒะฐะฝะต", "status.remove_bookmark": "ะŸั€ะตะผะฐั…ะฒะฐะฝะต ะฝะฐ ะพั‚ะผะตั‚ะบะฐั‚ะฐ", "status.replied_to": "ะ’ ะพั‚ะณะพะฒะพั€ ะดะพ {name}", "status.reply": "ะžั‚ะณะพะฒะพั€", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index 508caa2f42..4c4138bcf1 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -148,9 +148,7 @@ "compose_form.spoiler.marked": "เฆธเฆคเฆฐเงเฆ•เฆคเฆพเฆฐ เฆชเฆฟเฆ›เฆจเง‡ เฆฒเง‡เฆ–เฆพเฆจเฆŸเฆฟ เฆฒเงเฆ•เฆพเฆจเง‹ เฆ†เฆ›เง‡", "compose_form.spoiler.unmarked": "เฆฒเง‡เฆ–เฆพเฆŸเฆฟ เฆฒเงเฆ•เฆพเฆจเง‹ เฆจเง‡เฆ‡", "confirmation_modal.cancel": "เฆฌเฆพเฆคเฆฟเฆฒ เฆ•เฆฐเงเฆจ", - "confirmations.block.block_and_report": "เฆฌเงเฆฒเฆ• เฆ•เฆฐเงเฆจ เฆเฆฌเฆ‚ เฆฐเฆฟเฆชเง‹เฆฐเงเฆŸ เฆ•เฆฐเงเฆจ", "confirmations.block.confirm": "เฆฌเงเฆฒเฆ• เฆ•เฆฐเงเฆจ", - "confirmations.block.message": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆจเฆฟเฆถเงเฆšเฆฟเฆค {name} เฆ•เง‡ เฆฌเงเฆฒเฆ• เฆ•เฆฐเฆคเง‡ เฆšเฆพเฆจ?", "confirmations.cancel_follow_request.confirm": "เฆ…เฆจเงเฆฐเง‹เฆง เฆฌเฆพเฆคเฆฟเฆฒ เฆ•เฆฐเงเฆจ", "confirmations.cancel_follow_request.message": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆจเฆฟเฆถเงเฆšเฆฟเฆค เฆฏเง‡ เฆ†เฆชเฆจเฆฟ {name} เฆ•เง‡ เฆ…เฆจเงเฆธเฆฐเฆฃ เฆ•เฆฐเฆพเฆฐ เฆ…เฆจเงเฆฐเง‹เฆง เฆชเงเฆฐเฆคเงเฆฏเฆพเฆนเฆพเฆฐ เฆ•เฆฐเฆคเง‡ เฆšเฆพเฆจ?", "confirmations.delete.confirm": "เฆฎเงเฆ›เง‡ เฆซเง‡เฆฒเงเฆจ", @@ -159,15 +157,12 @@ "confirmations.delete_list.message": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆจเฆฟเฆถเงเฆšเฆฟเฆค เฆฏเง‡ เฆ†เฆชเฆจเฆฟ เฆเฆ‡ เฆคเฆพเฆฒเฆฟเฆ•เฆพเฆŸเฆฟ เฆธเงเฆฅเฆพเฆฏเฆผเฆฟเฆญเฆพเฆฌเง‡ เฆฎเงเฆ›เง‡ เฆซเง‡เฆฒเฆคเง‡ เฆšเฆพเฆจ ?", "confirmations.discard_edit_media.confirm": "เฆฌเฆพเฆคเฆฟเฆฒ เฆ•เฆฐเง‹", "confirmations.discard_edit_media.message": "เฆฎเฆฟเฆกเฆฟเงŸเฆพ Description เฆฌเฆพ Preview เฆคเง‡ เฆ†เฆชเฆจเฆพเฆฐ เฆ†เฆชเฆจเฆพเฆฐ เฆ…เฆธเฆ‚เฆฐเฆ•เงเฆทเฆฟเฆค เฆชเฆฐเฆฟเฆฌเฆฐเงเฆคเฆจ เฆ†เฆ›เง‡, เฆธเง‡เฆ—เงเฆฒเง‹ เฆฌเฆพเฆคเฆฟเฆฒ เฆ•เฆฐเฆฌเง‡เฆจ?", - "confirmations.domain_block.confirm": "เฆเฆ‡ เฆกเง‹เฆฎเง‡เฆจ เฆฅเง‡เฆ•เง‡ เฆธเฆฌ เฆฒเงเฆ•เฆพเฆจ", "confirmations.domain_block.message": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆธเฆคเงเฆฏเฆฟเฆ‡ เฆธเฆคเงเฆฏเฆ‡ เฆจเฆฟเฆถเงเฆšเฆฟเฆค เฆฏเง‡ เฆ†เฆชเฆจเฆฟ เฆชเงเฆฐเง‹ {domain}'เฆŸเฆฟ เฆฌเงเฆฒเฆ• เฆ•เฆฐเฆคเง‡ เฆšเฆพเฆจ? เฆฌเง‡เฆถเฆฟเฆฐเฆญเฆพเฆ— เฆ•เงเฆทเง‡เฆคเงเฆฐเง‡ เฆ•เฆฏเฆผเง‡เฆ•เฆŸเฆฟ เฆฒเฆ•เงเฆทเงเฆฏเฆฏเงเฆ•เงเฆค เฆฌเงเฆฒเฆ• เฆฌเฆพ เฆจเง€เฆฐเฆฌเฆคเฆพ เฆฏเฆฅเง‡เฆทเงเฆŸ เฆเฆฌเฆ‚ เฆชเฆ›เฆจเงเฆฆเฆธเฆ‡เฅค เฆ†เฆชเฆจเฆฟ เฆ•เง‹เฆจเฆ“ เฆชเฆพเฆฌเฆฒเฆฟเฆ• เฆŸเฆพเฆ‡เฆฎเฆฒเฆพเฆ‡เฆจ เฆฌเฆพ เฆ†เฆชเฆจเฆพเฆฐ เฆฌเฆฟเฆœเงเฆžเฆชเงเฆคเฆฟเฆ—เงเฆฒเฆฟเฆคเง‡ เฆธเง‡เฆ‡ เฆกเง‹เฆฎเง‡เฆจ เฆฅเง‡เฆ•เง‡ เฆธเฆพเฆฎเฆ—เงเฆฐเง€ เฆฆเง‡เฆ–เฆคเง‡ เฆชเฆพเฆฌเง‡เฆจ เฆจเฆพเฅค เฆธเง‡เฆ‡ เฆกเง‹เฆฎเง‡เฆจ เฆฅเง‡เฆ•เง‡ เฆ†เฆชเฆจเฆพเฆฐ เฆ…เฆจเงเฆธเฆฐเฆฃเฆ•เฆพเฆฐเง€เฆฆเง‡เฆฐ เฆธเฆฐเฆพเฆจเง‹ เฆนเฆฌเง‡เฅค", "confirmations.edit.confirm": "เฆธเฆฎเงเฆชเฆพเฆฆเฆจ", "confirmations.edit.message": "เฆเฆ–เฆจ เฆธเฆฎเงเฆชเฆพเฆฆเฆจเฆพ เฆ•เฆฐเฆฒเง‡ เฆ†เฆชเฆจเฆฟ เฆฏเง‡ เฆฎเง‡เฆธเง‡เฆœ เฆฒเฆฟเฆ–เฆ›เง‡เฆจ เฆคเฆพ overwrite เฆ•เฆฐเฆฌเง‡, เฆšเฆพเฆฒเฆฟเงŸเง‡ เฆฏเง‡เฆคเง‡ เฆšเฆพเฆจ?", "confirmations.logout.confirm": "เฆชเงเฆฐเฆธเงเฆฅเฆพเฆจ", "confirmations.logout.message": "เฆ†เฆชเฆจเฆฟ เฆฒเฆ— เฆ†เฆ‰เฆŸ เฆ•เฆฐเฆคเง‡ เฆšเฆพเฆจ?", "confirmations.mute.confirm": "เฆธเฆฐเฆฟเงŸเง‡ เฆซเง‡เฆฒเงเฆจ", - "confirmations.mute.explanation": "เฆเฆŸเฆฟ เฆคเฆพเฆฆเง‡เฆฐ เฆ•เฆพเฆ› เฆฅเง‡เฆ•เง‡ เฆชเง‹เฆธเงเฆŸ เฆเฆฌเฆ‚ เฆคเฆพเฆฆเง‡เฆฐเฆ•เง‡ เฆฎเง‡เฆจเฆถเฆจ เฆ•เฆฐเฆพ เฆชเง‹เฆธเงเฆŸเฆ—เงเฆฒเฆฟ เฆนเฆพเฆ‡เฆก เฆ•เฆฐเฆฌเง‡, เฆคเฆฌเงเฆ“ เฆคเฆพเฆฆเง‡เฆฐเฆ•เง‡ เฆเฆŸเฆฟ เฆ†เฆชเฆจเฆพเฆฐ เฆชเง‹เฆธเงเฆŸ เฆ—เงเฆฒเง‹ เฆฆเง‡เฆ–เฆคเง‡ เฆฆเฆฟเฆฌเง‡ เฆ“ เฆคเฆพเฆฐเฆพ เฆ†เฆชเฆจเฆพเฆ•เง‡ เฆ…เฆจเงเฆธเฆฐเฆจ เฆ•เฆฐเฆคเง‡ เฆชเฆพเฆฐเฆฌเง‡เฅค.", - "confirmations.mute.message": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆจเฆฟเฆถเงเฆšเฆฟเฆค {name} เฆธเฆฐเฆฟเงŸเง‡ เฆซเง‡เฆฒเฆคเง‡ เฆšเฆพเฆจ ?", "confirmations.redraft.confirm": "เฆฎเงเฆ›เง‡ เฆซเง‡เฆฒเงเฆจ เฆเฆฌเฆ‚ เฆ†เฆฌเฆพเฆฐ เฆธเฆฎเงเฆชเฆพเฆฆเฆจ เฆ•เฆฐเงเฆจ", "confirmations.reply.confirm": "เฆฎเฆคเฆพเฆฎเฆค", "confirmations.reply.message": "เฆเฆ–เฆจ เฆฎเฆคเฆพเฆฎเฆค เฆฒเฆฟเฆ–เฆคเง‡ เฆ—เง‡เฆฒเง‡ เฆ†เฆชเฆจเฆพเฆฐ เฆเฆ–เฆจ เฆฏเง‡เฆŸเฆพ เฆฒเฆฟเฆ–เฆ›เง‡เฆจ เฆธเง‡เฆŸเฆพ เฆฎเงเฆ›เง‡ เฆฏเฆพเฆฌเง‡เฅค เฆ†เฆชเฆจเฆฟ เฆจเฆฟ เฆจเฆฟเฆถเงเฆšเฆฟเฆค เฆเฆŸเฆพ เฆ•เฆฐเฆคเง‡ เฆšเฆพเฆจ ?", @@ -248,7 +243,6 @@ "hashtag.column_settings.tag_mode.any": "เฆเฆฐ เฆญเง‡เฆคเฆฐเง‡ เฆฏเง‡เฆ•เง‹เฆจเง‹เฆŸเฆพ", "hashtag.column_settings.tag_mode.none": "เฆเฆ—เงเฆฒเง‹เฆฐ เฆเฆ•เฆŸเฆพเฆ“ เฆจเฆพ", "hashtag.column_settings.tag_toggle": "เฆ†เฆฐเง‹ เฆŸเงเฆฏเฆพเฆ— เฆเฆ‡ เฆ•เฆฒเฆพเฆฎเง‡ เฆฏเงเฆ•เงเฆค เฆ•เฆฐเฆคเง‡", - "home.column_settings.basic": "เฆธเฆพเฆงเฆพเฆฐเฆฃ", "home.column_settings.show_reblogs": "เฆธเฆฎเฆฐเงเฆฅเฆจเฆ—เงเฆฒเง‹ เฆฆเง‡เฆ–เฆพเฆจ", "home.column_settings.show_replies": "เฆฎเฆคเฆพเฆฎเฆค เฆฆเง‡เฆ–เฆพเฆจ", "home.hide_announcements": "เฆ˜เง‹เฆทเฆฃเฆพ เฆฒเงเฆ•เฆพเฆจ", @@ -303,9 +297,6 @@ "lists.subheading": "เฆ†เฆชเฆจเฆพเฆฐ เฆคเฆพเฆฒเฆฟเฆ•เฆพ", "load_pending": "{count, plural, one {# เฆจเฆคเงเฆจ เฆœเฆฟเฆจเฆฟเฆธ} other {# เฆจเฆคเงเฆจ เฆœเฆฟเฆจเฆฟเฆธ}}", "media_gallery.toggle_visible": "เฆฆเงƒเฆถเงเฆฏเฆคเฆพเฆฐ เฆ…เฆฌเฆธเงเฆฅเฆพ เฆฌเฆฆเฆฒเฆพเฆจ", - "mute_modal.duration": "เฆธเฆฎเงŸเฆ•เฆพเฆฒ", - "mute_modal.hide_notifications": "เฆเฆ‡ เฆฌเงเฆฏเฆฌเฆนเฆพเฆฐเฆ•เฆพเฆฐเง€เฆฐ เฆชเงเฆฐเฆœเงเฆžเฆพเฆชเฆจ เฆฌเฆจเงเฆง เฆ•เฆฐเฆฌเง‡เฆจ ?", - "mute_modal.indefinite": "เฆ…เฆจเฆฟเฆฐเงเฆฆเฆฟเฆทเงเฆŸ", "navigation_bar.about": "เฆชเฆฐเฆฟเฆšเฆฟเฆคเฆฟ", "navigation_bar.blocks": "เฆฌเฆจเงเฆง เฆ•เฆฐเฆพ เฆฌเงเฆฏเฆฌเฆนเฆพเฆฐเฆ•เฆพเฆฐเง€", "navigation_bar.bookmarks": "เฆฌเงเฆ•เฆฎเฆพเฆฐเงเฆ•", @@ -338,8 +329,6 @@ "notifications.clear_confirmation": "เฆ†เฆชเฆจเฆฟ เฆ•เฆฟ เฆจเฆฟเฆฐเงเฆšเฆฟเฆค เฆชเงเฆฐเฆœเงเฆžเฆพเฆชเฆจเฆ—เงเฆฒเง‹ เฆฎเงเฆ›เง‡ เฆซเง‡เฆฒเฆคเง‡ เฆšเฆพเฆจ ?", "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": "เฆชเงเฆฐเฆœเงเฆžเฆพเฆชเฆจเฆ—เงเฆฒเง‹:", @@ -418,7 +407,6 @@ "search_results.all": "เฆธเฆฌ", "search_results.hashtags": "เฆนเงเฆฏเฆพเฆถเฆŸเงเฆฏเฆพเฆ—เฆ—เงเฆฒเฆฟ", "search_results.statuses": "เฆŸเงเฆŸ", - "server_banner.learn_more": "เฆ†เฆฐเง‹ เฆœเฆพเฆจเง‹", "sign_in_banner.sign_in": "Sign in", "status.admin_account": "@{name} เฆฐ เฆœเฆจเงเฆฏ เฆชเฆฐเฆฟเฆšเฆพเฆฒเฆจเฆพเฆฐ เฆ‡เฆจเงเฆŸเฆพเฆฐเฆซเง‡เฆธเง‡ เฆขเงเฆ•เงเฆจ", "status.admin_status": "เฆฏเฆพเงŸ เฆฒเง‡เฆ–เฆพเฆŸเฆฟ เฆชเฆฐเฆฟเฆšเฆพเฆฒเฆจเฆพเฆฐ เฆ‡เฆจเงเฆŸเฆพเฆฐเฆซเง‡เฆธเง‡ เฆ–เงเฆฒเงเฆจ", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json index 8cbe4591d5..7cd49ba59d 100644 --- a/app/javascript/mastodon/locales/br.json +++ b/app/javascript/mastodon/locales/br.json @@ -29,7 +29,7 @@ "account.enable_notifications": "Ma c'hemenn pa vez embannet traoรน gant @{name}", "account.endorse": "Lakaat war-wel war ar profil", "account.featured_tags.last_status_at": "Toud diwezhaรฑ : {date}", - "account.featured_tags.last_status_never": "Toud ebet", + "account.featured_tags.last_status_never": "Embannadur ebet", "account.featured_tags.title": "Hashtagoรน pennaรฑ {name}", "account.follow": "Heuliaรฑ", "account.follow_back": "Heuliaรฑ d'ho tro", @@ -62,7 +62,7 @@ "account.requested_follow": "Gant {name} eo bet goulennet ho heuliaรฑ", "account.share": "Skignaรฑ profil @{name}", "account.show_reblogs": "Diskouez skignadennoรน @{name}", - "account.statuses_counter": "{count, plural, one {{counter} Toud} two {{counter} Doud} other {{counter} a Doudoรน}}", + "account.statuses_counter": "{count, plural, one {{counter} C'hannad} two {{counter} Gannad} other {{counter} a Gannadoรน}}", "account.unblock": "Diverzaรฑ @{name}", "account.unblock_domain": "Diverzaรฑ an domani {domain}", "account.unblock_short": "Distankaรฑ", @@ -87,6 +87,8 @@ "announcement.announcement": "Kemennad", "attachments_list.unprocessed": "(ket meret)", "audio.hide": "Kuzhat ar c'hleved", + "block_modal.show_less": "Diskouez nebeutoc'h", + "block_modal.show_more": "Diskouez muioc'h", "boost_modal.combo": "Ar wezh kentaรฑ e c'halliot gwaskaรฑ war {combo} evit tremen hebiou", "bundle_column_error.copy_stacktrace": "Eilaรฑ an danevell fazi", "bundle_column_error.error.body": "N'haller ket skrammaรฑ ar bajenn goulennet. Gallout a ra bezaรฑ abalamour d'ur beug er c'hod pe d'ur gudenn keverlec'hded gant ar merdeer.", @@ -113,14 +115,15 @@ "column.directory": "Mont a-dreuz ar profiloรน", "column.domain_blocks": "Domani berzet", "column.favourites": "Muiaรฑ-karet", + "column.firehose": "Redoรน war-eeun", "column.follow_requests": "Rekedoรน heuliaรฑ", "column.home": "Degemer", "column.lists": "Listennoรน", "column.mutes": "Implijerยทionยทezed kuzhet", "column.notifications": "Kemennoรน", - "column.pins": "Toudoรน spilhennet", + "column.pins": "Embannadurioรน spilhennet", "column.public": "Red-amzer kevredet", - "column_back_button.label": "Distro", + "column_back_button.label": "Distreiรฑ", "column_header.hide_settings": "Kuzhat an arventennoรน", "column_header.moveLeft_settings": "Dilec'hiaรฑ ar bannad a-gleiz", "column_header.moveRight_settings": "Dilec'hiaรฑ ar bannad a-zehou", @@ -143,6 +146,8 @@ "compose_form.lock_disclaimer.lock": "prennet", "compose_form.placeholder": "Petra emaoc'h o soรฑjal e-barzh ?", "compose_form.poll.duration": "Pad ar sontadeg", + "compose_form.poll.multiple": "Meur a choaz", + "compose_form.poll.option_placeholder": "Choaz {number}", "compose_form.poll.single": "Dibabit unan", "compose_form.poll.switch_to_multiple": "Kemmaรฑ ar sontadeg evit aotren meur a zibab", "compose_form.poll.switch_to_single": "Kemmaรฑ ar sontadeg evit aotren un dibab hepken", @@ -154,9 +159,7 @@ "compose_form.spoiler.marked": "Kuzhet eo an destenn a-dreรฑv ur c'hemenn", "compose_form.spoiler.unmarked": "N'eo ket kuzhet an destenn", "confirmation_modal.cancel": "Nullaรฑ", - "confirmations.block.block_and_report": "Berzaรฑ ha Disklรชriaรฑ", "confirmations.block.confirm": "Stankaรฑ", - "confirmations.block.message": "Ha sur oc'h e fell deoc'h stankaรฑ {name} ?", "confirmations.cancel_follow_request.confirm": "Nullaรฑ ar reked", "confirmations.cancel_follow_request.message": "Ha sur oc'h e fell deoc'h nullaรฑ ho reked evit heuliaรฑ {name} ?", "confirmations.delete.confirm": "Dilemel", @@ -165,14 +168,11 @@ "confirmations.delete_list.message": "Ha sur eo hoc'h eus c'hoant da zilemel ar roll-maรฑ da vat ?", "confirmations.discard_edit_media.confirm": "Nac'haรฑ", "confirmations.discard_edit_media.message": "Bez ez eus kemmoรน n'int ket enrollet e deskrivadur ar media pe ar rakwel, nullaรฑ anezho evelato?", - "confirmations.domain_block.confirm": "Berzaรฑ an domani a-bezh", "confirmations.domain_block.message": "Ha sur oc'h e fell deoc'h berzaรฑ an {domain} a-bezh? Peurvuiaรฑ eo trawalc'h berzaรฑ pe mudaรฑ un nebeud implijerยทezedยทien. Ne welot danvez ebet o tont eus an domani-maรฑ. Dilamet e vo ar c'houmanantoรน war an domani-maรฑ.", "confirmations.edit.confirm": "Kemmaรฑ", "confirmations.logout.confirm": "Digevreaรฑ", "confirmations.logout.message": "Ha sur oc'h e fell deoc'h digevreaรฑ ?", "confirmations.mute.confirm": "Kuzhat", - "confirmations.mute.explanation": "Kement-se a guzho an toudoรน skrivet gantaรฑยทi hag ar re a veneg anezhaรฑยทi, met ne viro ket outaรฑยทi a welet ho toudoรน nag a heuliaรฑ ac'hanoc'h.", - "confirmations.mute.message": "Ha sur oc'h e fell deoc'h kuzhaat {name} ?", "confirmations.redraft.confirm": "Diverkaรฑ ha skrivaรฑ en-dro", "confirmations.reply.confirm": "Respont", "confirmations.reply.message": "Respont bremaรฑ a zilamo ar gemennadenn emaoc'h o skrivaรฑ. Sur e oc'h e fell deoc'h kenderc'hel ganti?", @@ -195,13 +195,15 @@ "dismissable_banner.dismiss": "Diverkaรฑ", "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.server": "Dafariad", + "domain_pill.username": "Anv-implijer", "embed.instructions": "Enframmit an toud-maรฑ en ho lec'hienn en ur eilaรฑ ar c'hod amaรฑ-dindan.", "embed.preview": "Setu penaos e teuio war wel :", "emoji_button.activity": "Obererezh", "emoji_button.clear": "Diverkaรฑ", - "emoji_button.custom": "Kempennet", + "emoji_button.custom": "Personelaet", "emoji_button.flags": "Bannieloรน", - "emoji_button.food": "Boued hag Evaj", + "emoji_button.food": "Boued & Evajoรน", "emoji_button.label": "Enlakaat un emoji", "emoji_button.nature": "Natur", "emoji_button.not_found": "Emoji ebet !! (โ•ฏยฐโ–กยฐ๏ผ‰โ•ฏ๏ธต โ”ปโ”โ”ป", @@ -211,12 +213,12 @@ "emoji_button.search": "O klask...", "emoji_button.search_results": "Disoc'hoรน an enklask", "emoji_button.symbols": "Arouezioรน", - "emoji_button.travel": "Lec'hioรน ha Beajoรน", + "emoji_button.travel": "Beajiรฑ & Lec'hioรน", "empty_column.account_suspended": "Kont ehanet", "empty_column.account_timeline": "Toud ebet amaรฑ !", "empty_column.account_unavailable": "Profil dihegerz", "empty_column.blocks": "N'eus ket bet berzet implijerยทez ganeoc'h c'hoazh.", - "empty_column.bookmarked_statuses": "N'ho peus toud ebet enrollet en ho sinedoรน c'hoazh. Pa vo ouzhpennet unan e teuio war wel amaรฑ.", + "empty_column.bookmarked_statuses": "N'ho peus embannadur ebet enrollet en ho sinedoรน c'hoazh. Pa vo ouzhpennet unan e teuio war wel amaรฑ.", "empty_column.community": "Goulo eo ar red-amzer lec'hel. Skrivit'ta un dra evit lakaat tan dezhi !", "empty_column.domain_blocks": "N'eus domani kuzh ebet c'hoazh.", "empty_column.explore_statuses": "N'eus tuadur ebet evit c'hoazh. Distroit diwezhatoc'h !", @@ -254,12 +256,16 @@ "filter_modal.select_filter.subtitle": "Implijout ur rummad a zo anezhaรฑ pe krouiรฑ unan nevez", "filter_modal.select_filter.title": "Silaรฑ an toud-maรฑ", "filter_modal.title.status": "Silaรฑ un toud", + "filtered_notifications_banner.mentions": "{count, plural, one {meneg} two {veneg} few {meneg} other {a venegoรน}}", "firehose.all": "Pep tra", "firehose.local": "Ar servijer-maรฑ", "firehose.remote": "Servijerioรน all", "follow_request.authorize": "Aotren", "follow_request.reject": "Nac'haรฑ", "follow_requests.unlocked_explanation": "Daoust ma n'eo ket ho kont prennet, skipailh {domain} a soรฑj e fellfe deoc'h gwiriekaat pedadennoรน heuliaรฑ deus ar c'hontoรน-se diwar-zorn.", + "follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h", + "follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}", + "follow_suggestions.view_all": "Gwelet pep tra", "followed_tags": "Hashtagoรน o heuliaรฑ", "footer.about": "Diwar-benn", "footer.directory": "Kavlec'h ar profiloรน", @@ -267,7 +273,7 @@ "footer.invite": "Pediรฑ tud", "footer.keyboard_shortcuts": "Berradennoรน klavier", "footer.privacy_policy": "Reolennoรน prevezded", - "footer.source_code": "Gwelet kod mammenn", + "footer.source_code": "Gwelet ar c'hod mammenn", "footer.status": "Statud", "generic.saved": "Enrollet", "getting_started.heading": "Loc'haรฑ", @@ -285,7 +291,6 @@ "hashtag.follow": "Heuliaรฑ ar ger-klik", "hashtag.unfollow": "Paouez heuliaรฑ an hashtag", "hashtags.and_other": "โ€ฆ{count, plural, one {hag # all} other {ha # all}}", - "home.column_settings.basic": "Diazez", "home.column_settings.show_reblogs": "Diskouez ar skignadennoรน", "home.column_settings.show_replies": "Diskouez ar respontoรน", "home.hide_announcements": "Kuzhat ar c'hemennoรน", @@ -295,7 +300,7 @@ "interaction_modal.description.follow": "Gant ur gont Mastodon e c'hellit heuliaรฑ {name} evit resev an toudoรน a embann war ho red degemer.", "interaction_modal.description.reblog": "Gant ur gont Mastodon e c'hellit skignaรฑ an toud-maรฑ evit rannaรฑ anezhaรฑ gant ho heulierienยทezed.", "interaction_modal.description.reply": "Gant ur gont Mastodon e c'hellit respont d'an toud-maรฑ.", - "interaction_modal.no_account_yet": "N'eo ket war vMastodon?", + "interaction_modal.no_account_yet": "N'emaรฑ ket war vMastodon?", "interaction_modal.on_another_server": "War ur servijer all", "interaction_modal.on_this_server": "War ar servijer-maรฑ", "interaction_modal.title.favourite": "Ouzhpennaรฑ embannadur {name} d'ar re vuiaรฑ-karet", @@ -363,9 +368,6 @@ "load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}", "loading_indicator.label": "O kargaรฑโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}", - "mute_modal.duration": "Padelezh", - "mute_modal.hide_notifications": "Kuzhat kemenadennoรน eus an implijer-se ?", - "mute_modal.indefinite": "Amstrizh", "navigation_bar.about": "Diwar-benn", "navigation_bar.blocks": "Implijerยทezedยทien berzet", "navigation_bar.bookmarks": "Sinedoรน", @@ -395,6 +397,7 @@ "notification.follow": "heuliaรฑ a ra {name} ac'hanoc'h", "notification.follow_request": "Gant {name} eo bet goulennet ho heuliaรฑ", "notification.mention": "Gant {name} oc'h bet meneget", + "notification.moderation-warning.learn_more": "Gouzout hiroc'h", "notification.own_poll": "Echu eo ho sontadeg", "notification.poll": "Ur sontadeg ho deus mouezhet warnaรฑ a zo echuet", "notification.reblog": "Gant {name} eo bet skignet ho toud", @@ -406,9 +409,6 @@ "notifications.column_settings.admin.sign_up": "Enskrivadurioรน nevez :", "notifications.column_settings.alert": "Kemennoรน war ar burev", "notifications.column_settings.favourite": "Muiaรฑ-karet:", - "notifications.column_settings.filter_bar.advanced": "Skrammaรฑ an-holl rummadoรน", - "notifications.column_settings.filter_bar.category": "Barrenn siloรน prim", - "notifications.column_settings.filter_bar.show_bar": "Diskouezh barrenn siloรน", "notifications.column_settings.follow": "Heulierien nevez:", "notifications.column_settings.follow_request": "Pedadoรน heuliaรฑ nevez :", "notifications.column_settings.mention": "Menegoรน:", @@ -434,13 +434,14 @@ "notifications.permission_denied": "Kemennoรน war ar burev n'int ket hegerz rak pedadenn aotren ar merdeer a zo bet nullet araok", "notifications.permission_denied_alert": "Kemennoรน wa ar burev na c'hellont ket bezaรฑ lezelet, rak aotre ar merdeer a zo bet nac'het a-raok", "notifications.permission_required": "Kemennoรน war ar burev n'int ket hegerz abalamour d'an aotre rekis n'eo ket bet roet.", + "notifications.policy.filter_new_accounts_title": "Kontoรน nevez", "notifications_permission_banner.enable": "Lezel kemennoรน war ar burev", "notifications_permission_banner.how_to_control": "Evit reseviรฑ kemennoรน pa ne vez ket digoret Mastodon, lezelit kemennoรน war ar burev. Gallout a rit kontrollaรฑ peseurt eskemmoรน a c'henel kemennoรน war ar burev gant ar {icon} nozelenn a-us kentre ma'z int lezelet.", "notifications_permission_banner.title": "Na vankit netra morse", "onboarding.action.back": "Distreiรฑ", "onboarding.actions.back": "Distreiรฑ", "onboarding.actions.go_to_explore": "See what's trending", - "onboarding.actions.go_to_home": "Go to your home feed", + "onboarding.actions.go_to_home": "Mont d'ho red degemer", "onboarding.compose.template": "Salud #Mastodon!", "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.title": "Popular on Mastodon", @@ -463,7 +464,7 @@ "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", - "onboarding.steps.share_profile.title": "Share your profile", + "onboarding.steps.share_profile.title": "Rannit ho kont Mastodon", "password_confirmation.mismatching": "Disheรฑvel eo an daou c'her-termen-se", "picture_in_picture.restore": "Adlakaat", "poll.closed": "Serret", @@ -476,7 +477,8 @@ "poll.votes": "{votes, plural,one {#votadenn} other {# votadenn}}", "poll_button.add_poll": "Ouzhpennaรฑ ur sontadeg", "poll_button.remove_poll": "Dilemel ar sontadeg", - "privacy.change": "Cheรฑch prevezded an toud", + "privacy.change": "Cheรฑch prevezded an embannadur", + "privacy.direct.short": "Tud resis", "privacy.private.short": "Heulierien", "privacy.public.short": "Publik", "privacy_policy.last_updated": "Hizivadenn ziwezhaรฑ {date}", @@ -564,7 +566,6 @@ "search_results.title": "Klask {q}", "server_banner.active_users": "implijerienยทezed oberiant", "server_banner.administered_by": "Meret gant :", - "server_banner.learn_more": "Gouzout hiroc'h", "server_banner.server_stats": "Stadegoรน ar servijer :", "sign_in_banner.create_account": "Krouiรฑ ur gont", "sign_in_banner.sign_in": "Kevreaรฑ", @@ -582,7 +583,7 @@ "status.direct": "Menegiรฑ @{name} ent-prevez", "status.direct_indicator": "Meneg prevez", "status.edit": "Kemmaรฑ", - "status.edited": "Aozet {date}", + "status.edited": "Kemmet da ziwezhaรฑ d'an {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "Enframmaรฑ", "status.favourite": "Muiaรฑ-karet", diff --git a/app/javascript/mastodon/locales/bs.json b/app/javascript/mastodon/locales/bs.json index c978a8b01f..d06054ee58 100644 --- a/app/javascript/mastodon/locales/bs.json +++ b/app/javascript/mastodon/locales/bs.json @@ -11,7 +11,6 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmations.delete.message": "Are you sure you want to delete this status?", - "confirmations.domain_block.confirm": "Hide entire domain", "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.", "embed.instructions": "Embed this status on your website by copying the code below.", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 42de594cdc..88dd34aff0 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -89,6 +89,14 @@ "announcement.announcement": "Anunci", "attachments_list.unprocessed": "(sense processar)", "audio.hide": "Amaga l'ร udio", + "block_modal.remote_users_caveat": "Li demanarem al servidor {domain} que respecti la vostra decisiรณ, tot i que no podem garantir-ho, ja que alguns servidors gestionen de forma diferent els blocatges. ร‰s possible que els usuaris no autenticats puguin veure les publicacions pรบbliques.", + "block_modal.show_less": "Mostra'n menys", + "block_modal.show_more": "Mostra'n mรฉs", + "block_modal.they_cant_mention": "No us poden esmentar, ni seguir.", + "block_modal.they_cant_see_posts": "No poden veure les vostres publicacions, ni vosaltres les seves.", + "block_modal.they_will_know": "Poden veure que els heu blocat.", + "block_modal.title": "Bloquem l'usuari?", + "block_modal.you_wont_see_mentions": "No veureu publicacions que l'esmentin.", "boost_modal.combo": "Pots prรฉmer {combo} per a evitar-ho el prรฒxim cop", "bundle_column_error.copy_stacktrace": "Copia l'informe d'error", "bundle_column_error.error.body": "No s'ha pogut renderitzar la pร gina solยทlicitada. Podria ser per un error en el nostre codi o per un problema de compatibilitat del navegador.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Afegeix avรญs de contingut", "compose_form.spoiler_placeholder": "Avรญs de contingut (opcional)", "confirmation_modal.cancel": "Cancelยทla", - "confirmations.block.block_and_report": "Bloca i denuncia", "confirmations.block.confirm": "Bloca", - "confirmations.block.message": "Segur que vols blocar a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar la solยทlicitud", "confirmations.cancel_follow_request.message": "Segur que vols retirar la solยทlicitud de seguiment de {name}?", "confirmations.delete.confirm": "Elimina", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Segur que vols suprimir permanentment aquesta llista?", "confirmations.discard_edit_media.confirm": "Descarta", "confirmations.discard_edit_media.message": "Tens canvis no desats en la descripciรณ del contingut o en la previsualitzaciรณ, els vols descartar?", - "confirmations.domain_block.confirm": "Bloca el domini sencer", + "confirmations.domain_block.confirm": "Bloca el servidor", "confirmations.domain_block.message": "Segur que vols blocar {domain} del tot? En la majoria dels casos, nomรฉs amb blocar o silenciar uns pocs comptes n'hi ha prou i รฉs millor. No veurร s el contingut dโ€™aquest domini en cap de les lรญnies de temps ni en les notificacions. S'eliminaran els teus seguidors dโ€™aquest domini.", "confirmations.edit.confirm": "Edita", "confirmations.edit.message": "Editant ara sobreescriurร s el missatge que estร s editant. Segur que vols continuar?", "confirmations.logout.confirm": "Tanca la sessiรณ", "confirmations.logout.message": "Segur que vols tancar la sessiรณ?", "confirmations.mute.confirm": "Silencia", - "confirmations.mute.explanation": "Aixรฒ amagarร  els tuts d'ells i els d'els que els mencionin, perรฒ encara els permetrร  veure els teus tuts i seguir-te.", - "confirmations.mute.message": "Segur que vols silenciar {name}?", "confirmations.redraft.confirm": "Esborra i reescriu", "confirmations.redraft.message": "Segur que vols eliminar aquest tut i tornar a escriure'l? Es perdran tots els impulsos i els favorits, i les respostes al tut original quedaran aรฏllades.", "confirmations.reply.confirm": "Respon", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Aquests son els tuts de la xarxa descentralitzada que guanyen atenciรณ ara mateix. Els tuts mรฉs nous amb mรฉs impulsos i favorits tenen millor rร nquing.", "dismissable_banner.explore_tags": "Aquestes etiquetes estan guanyant ara mateix l'atenciรณ dels usuaris d'aquest i altres servidors de la xarxa descentralitzada.", "dismissable_banner.public_timeline": "Aquests son els tuts pรบblics mรฉs recents de les persones a la web social que les persones de {domain} segueixen.", + "domain_block_modal.block": "Bloca el servidor", + "domain_block_modal.block_account_instead": "En lloc d'aixรฒ, bloca @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Els usuaris d'aquest servidor poden interactuar amb les vostres publicacions antigues.", + "domain_block_modal.they_cant_follow": "Ningรบ d'aquest servidor us pot seguir.", + "domain_block_modal.they_wont_know": "No sabran que sรณn blocats.", + "domain_block_modal.title": "Bloquem el domini?", + "domain_block_modal.you_will_lose_followers": "S'eliminaran tots els vostres seguidors d'aquest servidor.", + "domain_block_modal.you_wont_see_posts": "No veureu ni les publicacions ni les notificacions dels usuaris d'aquest servidor.", + "domain_pill.activitypub_lets_connect": "Us permet connectar i interactuar amb persones a Mastodon i tambรฉ a d'altres apps socials.", + "domain_pill.activitypub_like_language": "ActivityPub รฉs el llenguatge que Mastodon parla amb altres xarxes socials.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "El seu identificador:", + "domain_pill.their_server": "La seva llar digital, on sรณn totes les seves publicacions.", + "domain_pill.their_username": "El seu identificador รบnic al servidor. ร‰s possible que hi hagi usuaris amb el mateix nom d'usuari a diferents servidors.", + "domain_pill.username": "Nom d'usuari", + "domain_pill.whats_in_a_handle": "Quรจ constitueix un identificador?", + "domain_pill.who_they_are": "Com que un identificador expressa qui i on s'รฉs, podeu interactuar amb persones d'arreu de les .", + "domain_pill.who_you_are": "Com que un identificador expressa qui i on sou, les persones d'arreu de les poden interactuar amb vosaltres.", + "domain_pill.your_handle": "El vostre identificador:", + "domain_pill.your_server": "La vostra llar digital, on sรณn totes les vostres publicacions. No us agrada aquesta? Canvieu de servidor quan vulgueu i emporteu-vos els vostres seguidors.", + "domain_pill.your_username": "El vostre identificador รบnic en aquest servidor. Hi pot haver usuaris amb el mateix nom a diferents servidors.", "embed.instructions": "Incrusta aquest tut a la teva pร gina web copiant el codi segรผent.", "embed.preview": "Aquest aspecte tindrร :", "emoji_button.activity": "Activitat", @@ -241,6 +266,7 @@ "empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres facin nous tuts, apareixeran aquรญ.", "empty_column.lists": "Encara no tens cap llista. Quan en facis una, apareixerร  aquรญ.", "empty_column.mutes": "Encara no has silenciat cap usuari.", + "empty_column.notification_requests": "Tot net, ja no hi ha res aquรญ! Quan rebeu notificacions noves, segons la vostra configuraciรณ, apareixeran aquรญ.", "empty_column.notifications": "Encara no tens notificacions. Quan altre gent interactuรฏ amb tu, les veurร s aquรญ.", "empty_column.public": "Aquรญ no hi ha res! Escriu pรบblicament alguna cosa o segueix manualment usuaris d'altres servidors per omplir-ho", "error.unexpected_crash.explanation": "A causa d'un error en el nostre codi o d'un problema de compatibilitat amb el navegador, aquesta pร gina no s'ha pogut mostrar correctament.", @@ -271,16 +297,28 @@ "filter_modal.select_filter.subtitle": "Usa una categoria existent o crea'n una de nova", "filter_modal.select_filter.title": "Filtra aquest tut", "filter_modal.title.status": "Filtra un tut", + "filtered_notifications_banner.mentions": "{count, plural, one {menciรณ} other {mencions}}", + "filtered_notifications_banner.pending_requests": "Notificacions {count, plural, =0 {de ningรบ} one {d'una persona} other {de # persones}} que potser coneixes", + "filtered_notifications_banner.title": "Notificacions filtrades", "firehose.all": "Tots", "firehose.local": "Aquest servidor", "firehose.remote": "Altres servidors", "follow_request.authorize": "Autoritza", "follow_request.reject": "Rebutja", "follow_requests.unlocked_explanation": "Tot i que el teu compte no estร  blocat, el personal de {domain} ha pensat que รฉs possible que vulguis revisar manualment les solยทlicituds de seguiment dโ€™aquests comptes.", - "follow_suggestions.curated_suggestion": "Tria de l'editor", + "follow_suggestions.curated_suggestion": "Tria de l'equip", "follow_suggestions.dismiss": "No ho tornis a mostrar", + "follow_suggestions.featured_longer": "Triat personalment per l'equip de {domain}", + "follow_suggestions.friends_of_friends_longer": "Popular entre la gent que segueixes", + "follow_suggestions.hints.featured": "L'equip de {domain} ha seleccionat aquest perfil.", + "follow_suggestions.hints.friends_of_friends": "Aquest perfil รฉs popular entre la gent que seguiu.", + "follow_suggestions.hints.most_followed": "Aquest perfil รฉs un dels mรฉs seguits a {domain}.", + "follow_suggestions.hints.most_interactions": "Aquest perfil ha estat rebent un munt d'atenciรณ recentment a {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Aquest perfil รฉs similar a d'altres que heu seguit recentment.", "follow_suggestions.personalized_suggestion": "Suggeriment personalitzat", "follow_suggestions.popular_suggestion": "Suggeriment popular", + "follow_suggestions.popular_suggestion_longer": "Popular a {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Semblant a perfils que seguiu de fa poc", "follow_suggestions.view_all": "Mostra-ho tot", "follow_suggestions.who_to_follow": "A qui seguir", "followed_tags": "Etiquetes seguides", @@ -309,7 +347,6 @@ "hashtag.follow": "Segueix l'etiqueta", "hashtag.unfollow": "Deixa de seguir l'etiqueta", "hashtags.and_other": "โ€ฆi {count, plural, other {# mรฉs}}", - "home.column_settings.basic": "Bร sic", "home.column_settings.show_reblogs": "Mostra els impulsos", "home.column_settings.show_replies": "Mostra les respostes", "home.hide_announcements": "Amaga els anuncis", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Mostra el perfil de totes maneres", "limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.", "link_preview.author": "Per {name}", + "link_preview.more_from_author": "Mรฉs de {name}", + "link_preview.shares": "{count, plural, one {{counter} publicaciรณ} other {{counter} publicacions}}", "lists.account.add": "Afegeix a la llista", "lists.account.remove": "Elimina de la llista", "lists.delete": "Elimina la llista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Es carregaโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Amaga la imatge} other {Amaga les imatges}}", "moved_to_account_banner.text": "El teu compte {disabledAccount} estร  desactivat perquรจ l'has mogut a {movedToAccount}.", - "mute_modal.duration": "Durada", - "mute_modal.hide_notifications": "Amagar les notificacions d'aquest usuari?", - "mute_modal.indefinite": "Indefinit", + "mute_modal.hide_from_notifications": "Amaga de les notificacions", + "mute_modal.hide_options": "Amaga les opcions", + "mute_modal.indefinite": "Fins que els deixi de silenciar", + "mute_modal.show_options": "Mostra les opcions", + "mute_modal.they_can_mention_and_follow": "Us poden esmentar i seguir, perรฒ no els veureu.", + "mute_modal.they_wont_know": "No sabran que sรณn silenciats.", + "mute_modal.title": "Silenciem l'usuari?", + "mute_modal.you_wont_see_mentions": "No veureu publicacions que els esmentin.", + "mute_modal.you_wont_see_posts": "Encara poden veure les vostres publicacions, perรฒ no veureu les seves.", "navigation_bar.about": "Quant a", "navigation_bar.advanced_interface": "Obre en la interfรญcie web avanรงada", "navigation_bar.blocks": "Usuaris blocats", @@ -430,11 +475,29 @@ "notification.follow": "{name} et segueix", "notification.follow_request": "{name} ha solยทlicitat de seguir-te", "notification.mention": "{name} t'ha esmentat", + "notification.moderation-warning.learn_more": "Per a saber-ne mรฉs", + "notification.moderation_warning": "Heu rebut un avรญs de moderaciรณ", + "notification.moderation_warning.action_delete_statuses": "S'han eliminat algunes de les vostres publicacions.", + "notification.moderation_warning.action_disable": "S'ha desactivat el vostre compte.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "S'ha marcat com a sensibles algunes de les vostres publicacions.", + "notification.moderation_warning.action_none": "El vostre compte ha rebut un avรญs de moderaciรณ.", + "notification.moderation_warning.action_sensitive": "A partir d'ara les vostres publicacions es marcaran com sensibles.", + "notification.moderation_warning.action_silence": "S'ha limitat el vostre compte.", + "notification.moderation_warning.action_suspend": "S'ha suspรจs el vostre compte.", "notification.own_poll": "La teva enquesta ha finalitzat", "notification.poll": "Ha finalitzat una enquesta en quรจ has votat", "notification.reblog": "{name} t'ha impulsat", + "notification.relationships_severance_event": "S'han perdut les connexions amb {name}", + "notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspรจs {target}; aixรฒ vol dir que ja no en podreu rebre actualitzacions o interactuar-hi.", + "notification.relationships_severance_event.domain_block": "Un administrador de {from} ha blocat {target}, incloent-hi {followersCount} dels vostres seguidors i {followingCount, plural, one {# compte} other {# comptes}} que seguiu.", + "notification.relationships_severance_event.learn_more": "Per a saber-ne mรฉs", + "notification.relationships_severance_event.user_domain_block": "Heu blocat {target}, eliminant {followersCount} dels vostres seguidors i {followingCount, plural, one {# compte} other {# comptes}} que seguiu.", "notification.status": "{name} acaba de publicar", "notification.update": "{name} ha editat un tut", + "notification_requests.accept": "Accepta", + "notification_requests.dismiss": "Ignora", + "notification_requests.notifications_from": "Notificacions de {name}", + "notification_requests.title": "Notificacions filtrades", "notifications.clear": "Esborra les notificacions", "notifications.clear_confirmation": "Segur que vols esborrar permanentment totes les teves notificacions?", "notifications.column_settings.admin.report": "Nous informes:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "Favorits:", "notifications.column_settings.filter_bar.advanced": "Mostra totes les categories", "notifications.column_settings.filter_bar.category": "Barra rร pida de filtres", - "notifications.column_settings.filter_bar.show_bar": "Mostra la barra de filtres", "notifications.column_settings.follow": "Nous seguidors:", "notifications.column_settings.follow_request": "Noves solยทlicituds de seguiment:", "notifications.column_settings.mention": "Mencions:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Les notificacions dโ€™escriptori no estan disponibles perquรจ prรจviament sโ€™ha denegat el permรญs al navegador", "notifications.permission_denied_alert": "No es poden activar les notificacions de l'escriptori perquรจ abans s'ha denegat el permรญs del navegador", "notifications.permission_required": "Les notificacions d'escriptori no estan disponibles perquรจ el permรญs requerit no ha estat concedit.", + "notifications.policy.filter_new_accounts.hint": "Creat {days, plural, one {ahir} other {durant els # dies passats}}", + "notifications.policy.filter_new_accounts_title": "Comptes nous", + "notifications.policy.filter_not_followers_hint": "Incloent les persones que us segueixen fa menys {days, plural, one {d'un dia} other {de # dies}}", + "notifications.policy.filter_not_followers_title": "Persones que no us segueixen", + "notifications.policy.filter_not_following_hint": "Fins que no ho aproveu de forma manual", + "notifications.policy.filter_not_following_title": "Persones que no seguiu", + "notifications.policy.filter_private_mentions_hint": "Filtrat si no รฉs que รฉs en resposta a una menciรณ vostra o si seguiu el remitent", + "notifications.policy.filter_private_mentions_title": "Mencions privades no solยทlicitades", + "notifications.policy.title": "Filtra les notificacions deโ€ฆ", "notifications_permission_banner.enable": "Activa les notificacions dโ€™escriptori", "notifications_permission_banner.how_to_control": "Per a rebre notificacions quan Mastodon no รฉs obert cal activar les notificacions dโ€™escriptori. Pots controlar amb precisiรณ quins tipus dโ€™interaccions generen notificacions dโ€™escriptori desprรฉs dโ€™activar el botรณ {icon} de dalt.", "notifications_permission_banner.title": "No et perdis mai res", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Gent que ha fet servir aquest servidor en els darrers 30 dies (Usuaris Actius Mensuals)", "server_banner.active_users": "usuaris actius", "server_banner.administered_by": "Administrat per:", - "server_banner.introduction": "{domain} รฉs part de la xarxa social descentralitzada impulsada per {mastodon}.", - "server_banner.learn_more": "Mรฉs informaciรณ", + "server_banner.is_one_of_many": "{domain} รฉs un dels molts servidors de Mastodon que pots fer servir per a participar en el fedivers.", "server_banner.server_stats": "Estadรญstiques del servidor:", "sign_in_banner.create_account": "Crea un compte", + "sign_in_banner.follow_anyone": "Segueix qui sigui al fedivers i ho veurร s tot en ordre cronolรฒgic. Sense algorismes, anuncis o pescaclics.", + "sign_in_banner.mastodon_is": "Mastodon รฉs la millor manera de seguir al moment quรจ passa.", "sign_in_banner.sign_in": "Inici de sessiรณ", "sign_in_banner.sso_redirect": "Inici de sessiรณ o Registre", - "sign_in_banner.text": "Inicia la sessiรณ per a seguir perfils o etiquetes, afavorir, compartir i respondre tuts. Tambรฉ pots interactuar des del teu compte a un servidor diferent.", "status.admin_account": "Obre la interfรญcie de moderaciรณ per a @{name}", "status.admin_domain": "Obre la interfรญcie de moderaciรณ per a @{domain}", "status.admin_status": "Obre aquest tut a la interfรญcie de moderaciรณ", @@ -645,10 +716,11 @@ "status.direct": "Menciona privadament @{name}", "status.direct_indicator": "Menciรณ privada", "status.edit": "Edita", - "status.edited": "Editat {date}", + "status.edited": "Darrera ediciรณ {date}", "status.edited_x_times": "Editat {count, plural, one {{count} vegada} other {{count} vegades}}", "status.embed": "Incrusta", "status.favourite": "Favorit", + "status.favourites": "{count, plural, one {favorit} other {favorits}}", "status.filter": "Filtra aquest tut", "status.filtered": "Filtrada", "status.hide": "Amaga el tut", @@ -669,6 +741,7 @@ "status.reblog": "Impulsa", "status.reblog_private": "Impulsa amb la visibilitat original", "status.reblogged_by": "impulsat per {name}", + "status.reblogs": "{count, plural, one {impuls} other {impulsos}}", "status.reblogs.empty": "Encara no ha impulsat ningรบ aquest tut. Quan algรบ ho faci, apareixerร  aquรญ.", "status.redraft": "Esborra i reescriu", "status.remove_bookmark": "Elimina el marcador", diff --git a/app/javascript/mastodon/locales/ckb.json b/app/javascript/mastodon/locales/ckb.json index 73910f9b7c..c212b53a8b 100644 --- a/app/javascript/mastodon/locales/ckb.json +++ b/app/javascript/mastodon/locales/ckb.json @@ -17,9 +17,11 @@ "account.badges.group": "ฺฏุฑูˆูˆูพ", "account.block": "ุจู„†ฺฉŒ @{name}", "account.block_domain": "ุจู„†ฺฉŒ ู‡•ู…ูˆูˆ ุดุชŽฺฉ ู„• {domain}", + "account.block_short": "ุจู„†ฺฉ", "account.blocked": "ุจู„†ฺฉฺฉุฑุง", "account.browse_more_on_origin_server": "ฺฏ•ฺ•ุงู†Œ ูุฑ•ุชุฑ ู„• ุณ•ุฑ ูพุฑ†ูุงŒู„Œ ุณ•ุฑ•ฺฉŒ", "account.cancel_follow_request": "ุฏุงูˆุงฺฉุงุฑŒ ู†ฺต†ูˆ ุจฺฉุดŽู†•ูˆ•", + "account.copy": "ฺ•ูˆูˆู†ูˆูˆุณŒ ุจ•ุณุช•ุฑ ุจ† ุชูˆุช", "account.direct": "ุจ• ุดŽูˆ•Œ•ฺฉŒ ุชุงŒุจ•ุช ุจุงุณŒ @{name} ุจฺฉ•", "account.disable_notifications": "ุฆุงฺฏุงู†ุงู…• ู…•ู†Žุฑ• ุจ†ู… ฺฉุงุชŽฺฉ @{name} ูพ†ุณุช ุฏ•ฺฉุฑŽุช", "account.domain_blocked": "ุฏ†ู…•Œู† ู‚•ูพุงุชฺฉุฑุง", @@ -30,6 +32,7 @@ "account.featured_tags.last_status_never": "ู‡Œฺ† ูพ†ุณุชŽฺฉ ู†ŒŒ•", "account.featured_tags.title": "ู‡ุงุดุชุงฺฏ• ุชุงŒุจ•ุช•ฺฉุงู†Œ {name}", "account.follow": "ุจ•ุฏูˆุงุฏุงฺ†ูˆูˆู†", + "account.follow_back": "ู†ฺต†ูˆ ุจฺฉ•ู†•ูˆ•", "account.followers": "ุดูˆŽู†ฺฉ•ูˆุชูˆูˆุงู†", "account.followers.empty": "ฺฉ•ุณŽฺฉ ุดูˆŽู† ุฆ•ู… ุจ•ฺฉุงุฑู‡Žู†•ุฑ• ู†•ฺฉ•ูˆุชูˆูˆ•", "account.followers_counter": "{count, plural, one {{counter} ุดูˆŽู†ฺฉ•ูˆุชูˆูˆ} other {{counter} ุดูˆŽู†ฺฉ•ูˆุชูˆูˆ}}", @@ -38,6 +41,7 @@ "account.follows.empty": "ุฆ•ู… ุจ•ฺฉุงุฑู‡Žู†•ุฑ• ุชุง ุฆŽุณุชุง ุดูˆŽู† ฺฉ•ุณ ู†•ฺฉ•ูˆุชูˆูˆ•.", "account.go_to_profile": "ุจฺ•† ุจ† ูพฺ•†ูุงŒู„Œ", "account.hide_reblogs": "ุฏุงุดุงุฑุฏู†Œ ุจูˆูˆุณุช•ฺฉุงู† ู„• @{name}", + "account.in_memoriam": "ู„• Œุงุฏ•ูˆ•ุฑŒุฏุง.", "account.joined_short": "ุจ•ุดุฏุงุฑŒ ฺฉุฑุฏูˆูˆ•", "account.languages": "ฺฏ†ฺ•Œู†Œ ุฒู…ุงู†• ุจ•ุดุฏุงุฑุจูˆูˆ•ฺฉุงู†", "account.link_verified_on": "ุฎุงูˆ•ู†ุฏุงุฑŒ•ุชŒ ุฆ•ู… ู„Œู†ฺฉ• ู„• {date} ฺ†Žฺฉ ฺฉุฑุงูˆ•", @@ -46,7 +50,11 @@ "account.mention": "ุฆุงู…ุงฺ˜• @{name}", "account.moved_to": "{name} ุฆุงู…ุงฺ˜•Œ ุจ•ูˆ• ฺฉุฑุฏูˆูˆ• ฺฉ• ุฆ•ฺฉุงูˆู†ุช• ู†ูˆŽŒ•ฺฉ•Œุงู† ุฆŽุณุชุง:", "account.mute": "ุจŽุฏ•ู†ฺฏฺฉุฑุฏู† @{name}", + "account.mute_notifications_short": "ูพุงฺต ุจ• ุฆุงฺฏุงุฏุงุฑฺฉุฑุฏู†•ูˆ•ฺฉุงู†•ูˆ• ุจู†Ž", + "account.mute_short": "ุจŽุฏ•ู†ฺฏ", "account.muted": "ุจŽ ุฏ•ู†ฺฏ", + "account.mutual": "ุฏูˆูˆู„ุงŒ•ู†•", + "account.no_bio": "ู‡Œฺ† ูˆ•ุณูŽฺฉ ู†•ุฎุฑุงูˆ•ุช•ฺ•ูˆูˆ.", "account.open_original_page": "ู„ุงูพ•ฺ••Œ ุฆ•ุณฺตŒ ุจฺฉ•ุฑ•ูˆ•", "account.posts": "ู†ูˆูˆุณุฑุงูˆ•ฺฉุงู†", "account.posts_with_replies": "ุชูˆุชุณ ูˆ ูˆ•ฺตุงู…•ฺฉุงู†", @@ -62,6 +70,7 @@ "account.unendorse": "ุชุงŒุจ•ุชู…•ู†ุฏŒ ู„•ุณ•ุฑ ูพุฑ†ูุงŒู„•ฺฉ• ู†Œ•", "account.unfollow": "ุจ•ุฏูˆุงุฏุงู†•ฺ†ูˆ", "account.unmute": "ุจŽุฏ•ู†ฺฏฺฉุฑุฏู†Œ @{name}", + "account.unmute_notifications_short": "ุฆุงฺฏุงุฏุงุฑฺฉุฑุฏู†•ูˆ•ฺฉุงู† ุจŽุฏ•ู†ฺฏ ุจฺฉ•ุฑ•ูˆ•", "account.unmute_short": "ุจŽุฏ•ู†ฺฏŒ ู…•ฺฉ•", "account_note.placeholder": "ฺฉุฑุช•ุจฺฉ• ุจ† ุฒŒุงุฏฺฉุฑุฏู†Œ ุชŽุจŒู†Œ", "admin.dashboard.daily_retention": "ฺ•Žฺ˜•Œ ู…ุงู†•ูˆ•Œ ุจ•ฺฉุงุฑู‡Žู†•ุฑ ุจ•ูพŽŒ ฺ•†ฺ˜ ุฏูˆุงŒ ู†ุงูˆ ุช†ู…ุงุฑฺฉุฑุฏู†", @@ -69,6 +78,10 @@ "admin.dashboard.retention.average": "ฺ•Žฺ˜•", "admin.dashboard.retention.cohort": "ฺ†ูˆูˆู†•ฺ˜ูˆูˆุฑ•ูˆ•Œ ู…ุงู†ฺฏุงู†•", "admin.dashboard.retention.cohort_size": "ุฆ•ู†ุฏุงู…Œ ู†ูˆŽ", + "admin.impact_report.instance_accounts": "ูพฺ•†ูุงŒู„Œ ู‡•ฺ˜ู…ุงุฑ•ฺฉุงู† ุฆ•ู…• ุฏ•ุณฺ•Žุช•ูˆ•", + "admin.impact_report.instance_followers": "ู†ฺต†ูˆ•ุฑ•ฺฉุงู† ุจ•ฺฉุงุฑู‡Žู†•ุฑุงู† ู„•ุฏ•ุณุช ุฏ•ุฏ•ู†", + "admin.impact_report.instance_follows": "ู†ฺต†ูˆ•ุฑ•ฺฉุงู† ุฆ•ู…ุจ•ฺฉุงุฑู‡Žู†•ุฑ• ู„•ุฏ•ุณุช ุฏ•ุฏ•ู†", + "admin.impact_report.title": "ูพูˆุฎุช•Œ ฺฉุงุฑŒฺฏ•ุฑŒŒ•ฺฉุงู†", "alert.rate_limited.message": "ุชฺฉุงŒ• ู‡•ูˆฺตุจุฏ•ุฑ•ูˆ• ุฏูˆุงŒ {retry_time, time, medium}.", "alert.rate_limited.title": "ฺ•Žฺ˜•Œ ุณู†ูˆูˆุฑุฏุงุฑ", "alert.unexpected.message": "ู‡•ฺต•Œ•ฺฉŒ ฺ†ุงูˆ•ฺ•ูˆุงู† ู†•ฺฉุฑุงูˆ ฺ•ูˆูˆŒุฏุง.", @@ -101,6 +114,8 @@ "column.direct": "ุฆุงู…ุงฺ˜•Œ ุชุงŒุจ•ุช", "column.directory": "ฺฏ•ฺ•ุงู† ู„• ูพุฑ†ูุงŒู„•ฺฉุงู†", "column.domain_blocks": "ุฏ†ู…•Œู†• ุฏุงุฎุฑุงูˆ•ฺฉุงู†", + "column.favourites": "ุฏฺตุฎูˆุงุฒ•ฺฉุงู†", + "column.firehose": "ูŒุฏŒ ฺ•ุงุณุช•ูˆุฎ†", "column.follow_requests": "ุจ•ุฏูˆุงุฏุงฺ†ูˆŒ ุฏุงูˆุงฺฉุงุฑŒ•ฺฉุงู† ุจฺฉ•", "column.home": "ุณ•ุฑ•ุชุง", "column.lists": "ูพŽุฑุณุช", @@ -121,6 +136,9 @@ "community.column_settings.remote_only": "ุช•ู†ู‡ุง ุจ† ุฏูˆูˆุฑ", "compose.language.change": "ฺฏ†ฺ•Œู†Œ ุฒู…ุงู†", "compose.language.search": "ฺฏ•ฺ•ุงู† ุจ• ุฒู…ุงู†•ฺฉุงู†...", + "compose.published.body": "ูพ†ุณุช ุจฺตุงูˆฺฉุฑุงูˆ•ุช•ูˆ•.", + "compose.published.open": "ุจŒฺฉ•ูˆ•", + "compose.saved.body": "ูพ†ุณุช•ฺฉ• ุณ•Œฺค ฺฉุฑุงูˆ•.", "compose_form.direct_message_warning_learn_more": "ุฒŒุงุชุฑ ูŽุฑุจู‡", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.hashtag_warning": "ุฆ•ู… ุจฺตุงูˆฺฉุฑุงูˆ•Œ• ู„• ฺ˜Žุฑ ู‡Œฺ† ู‡ุงุดุชุงฺฏŽฺฉุฏุง ุฏุง ู†ุงู†ุฑŽุช ูˆ•ฺฉ ุฆ•ูˆ•Œ•ุŒ ฺฉ• ฺฏุดุชŒ ู†•ุจŽุช. ุช•ู†ู‡ุง ุจฺตุงูˆฺฉุฑุงูˆ• ฺฏุดุชŒ•ฺฉุงู† ุฏ•ุชูˆุงู†ุฑŽ ุจ• ู‡ุงุดุชุงฺฏ ฺฏ•ฺ•ุงู†Œ ุจ† ุจฺฉุฑŽุช.", @@ -128,15 +146,21 @@ "compose_form.lock_disclaimer.lock": "ู‚ูฺต ุฏุฑุงูˆ•", "compose_form.placeholder": "ฺ†Œ ู„• ู…ŽุดฺฉุชุฏุงŒ•?", "compose_form.poll.duration": "ู…ุงูˆ•Œ ฺ•ุงูพุฑุณŒ", + "compose_form.poll.multiple": "ูุฑ• ู‡•ฺตุจฺ˜ุงุฑุฏ•", + "compose_form.poll.option_placeholder": "ุจฺ˜ุงุฑุฏ•Œ {number}", + "compose_form.poll.single": "Œ•ฺฉŽูƒ ู‡•ู„ุจฺ˜Žุฑ•", "compose_form.poll.switch_to_multiple": "ฺ•ุงูพุฑุณŒ ุจฺฏ†ฺ•• ุจ† ฺ•Žฺฏ•ุฏุงู† ุจ• ฺ†•ู†ุฏ ู‡•ฺตุจฺ˜ุงุฑุฏู†Žฺฉ", "compose_form.poll.switch_to_single": "ฺฏ†ฺ•Œู†Œ ฺ•ุงูพุฑุณŒ ุจ† ฺ•Žฺฏ•ุฏุงู† ุจ• ุชุงฺฉ• ู‡•ฺตุจฺ˜ุงุฑุฏู†Žฺฉ", + "compose_form.poll.type": "ุณุชุงŒฺต", + "compose_form.publish": "ูพ†ุณุช", "compose_form.publish_form": "ุจฺตุงูˆŒ ุจฺฉ•ูˆ•", + "compose_form.reply": "ูˆ•ฺตุงู…", + "compose_form.save_changes": "ู†ูˆŽฺฉุฑุฏู†•ูˆ•", "compose_form.spoiler.marked": "ุฏ•ู‚ ู„• ูพุดุช ุฆุงฺฏุงุฏุงุฑŒุฏุง ุดุงุฑุงูˆ•ุช•ูˆ•", "compose_form.spoiler.unmarked": "ุฏ•ู‚ ุดุงุฑุงูˆ• ู†ŒŒ•", + "compose_form.spoiler_placeholder": "ุฆุงฺฏุงุฏุงุฑฺฉุฑุฏู†•ูˆ•Œ ู†ุงูˆ•ฺ•†ฺฉ (ุฆŒุฎุชŒุงุฑŒ)", "confirmation_modal.cancel": "ู‡•ฺตูˆ•ุดุงู†ุฏู†•ูˆู‡", - "confirmations.block.block_and_report": "ุจู„†ฺฉ & ฺฏูˆุฒุงุฑุดุช", "confirmations.block.confirm": "ุจู„†ฺฉ", - "confirmations.block.message": "ุฆุงŒุง ุฏฺตู†ŒุงŒุช ู„•ูˆ•Œ ุฏ•ุช•ูˆŽุช {name} ุจู„†ฺฉ ุจฺฉ•Œุช?", "confirmations.cancel_follow_request.confirm": "ุฏุงูˆุงฺฉุงุฑŒ ฺฉุดุงู†•ูˆ•", "confirmations.cancel_follow_request.message": "ุฆุงŒุง ุฏฺตู†ŒุงŒ ฺฉ• ุฏ•ุช•ูˆŽุช ุฏุงูˆุงฺฉุงุฑŒŒ•ฺฉ•ุช ุจ† ุดูˆŽู†ฺฉ•ูˆุชู†Œ {ู†ุงูˆ} ุจฺฉุดŽู†Œุช•ูˆ•ุŸ", "confirmations.delete.confirm": "ุณฺ•Œู†•ูˆ•", @@ -145,16 +169,14 @@ "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": "ุฏ•ุณุชฺฉุงุฑŒ ฺฉุฑุฏู†Œ ุฆŽุณุชุง: ุฏ•ุจŽุช• ู‡†Œ ู†ูˆูˆุณŒู†•ูˆ•Œ ุฆ•ูˆ ูพ•Œุงู…•ŒุŒ ฺฉ• ุฆŽุณุชุง ุฏุงุชุฏ•ฺ•ุดุช. ุฆุงŒุง ุฏฺตู†ŒุงŒุŒ ฺฉ• ุฏ•ุช•ูˆŽุช ุจ•ุฑุฏ•ูˆุงู… ุจŒุชุŸ", "confirmations.logout.confirm": "ฺ†ูˆูˆู†• ุฏ•ุฑ•ูˆ•", "confirmations.logout.message": "ุฆุงŒุง ุฏฺตู†ŒุงŒุช ู„•ูˆ•Œ ุฏ•ุช•ูˆŽุช ุจฺ†Œุช• ุฏ•ุฑ•ูˆ•?", "confirmations.mute.confirm": "ุจŽุฏ•ู†ฺฏ", - "confirmations.mute.explanation": "ุฆ•ู…•ุด ุฏ•ุจŽุช• ู‡†Œ ุดุงุฑุฏู†•ูˆ•Œ ูพ†ุณุช•ฺฉุงู† Œุงู† ุฆ•ูˆ ุจุงุจ•ุชุงู†•Œ ฺฉ• ุฆุงู…ุงฺ˜•Œุงู† ูพŽ ุฏ•ฺฉุงุช ุŒ ุจ•ฺตุงู… ู‡Žุดุชุง ฺ•Žฺฏ•Œุงู† ูพŽ ุฏ•ุฏุงุช ฺฉ• ูพ†ุณุช•ฺฉุงู†ุชุงู† ุจุจŒู†ู† ูˆ ุดูˆŽู†ุชุงู† ุจฺฉ•ูˆู†.", - "confirmations.mute.message": "ุฆุงŒุง ุฏฺตู†ŒุงŒุช ู„•ูˆ•Œ ุฏ•ุช•ูˆŽุช ุจŒู„ŽŒุช {name}?", "confirmations.redraft.confirm": "ุณฺ•Œู†•ูˆ• & ุฏูˆูˆุจุงุฑ• ฺ••ุดฺฉุฑุฏู†•ูˆ•", + "confirmations.redraft.message": "ุฏฺตู†ŒุงŒ ุฏ•ุช•ูˆŽุช ุฆ•ู… ูพ†ุณุช• ุจุณฺ•Œุช•ูˆ• ูˆ ุฏูˆูˆุจุงุฑ• ุฏุงŒุจฺ•Žฺ˜Œุช•ูˆ•ุŸ ู•ฺค†ุฑŒุช ูˆ ุจูˆูˆุณุช•ฺฉุงู† ู„•ุฏ•ุณุช ุฏ•ฺ†ู†ุŒ ูˆ•ฺตุงู…•ฺฉุงู†Œ ูพ†ุณุช• ุฆ•ุณฺตŒ•ฺฉ•ุด ู‡•ุชŒูˆ ุฏ•ุจู†.", "confirmations.reply.confirm": "ูˆ•ฺตุงู…", "confirmations.reply.message": "ูˆ•ฺตุงู…ุฏุงู†•ูˆ• ุฆŽุณุชุง ุฆ•ูˆ ู†ุงู…•Œ• Œ ฺฉ• ุช† ุฆŽุณุชุง ุฏุงŒฺ•ุดุชูˆูˆ•ุŒ ุฏ•ู†ูˆูˆุณŽุช•ูˆ•. ุฆุงŒุง ุฏฺตู†ŒุงŒุช ฺฉ• ุฏ•ุช•ูˆŽุช ุจ•ุฑุฏ•ูˆุงู… ุจŒุช?", "confirmations.unfollow.confirm": "ุจ•ุฏูˆุงุฏุงู†•ฺ†ูˆ", @@ -163,7 +185,9 @@ "conversation.mark_as_read": "ู†Œุดุงู†•ฺฉุฑุฏู† ูˆ•ฺฉ ุฎูˆŽู†ุฏุฑุงูˆ•", "conversation.open": "ู†Œุดุงู†ุฏุงู† ฺฏูุชูˆฺฏ†", "conversation.with": "ู„•ฺฏ•ฺต{names}", + "copy_icon_button.copied": "ฺฉ†ูพŒ ฺฉุฑุงูˆ• ุจ† ฺฉู„Œูพุจ†ุฑุฏ", "copypaste.copied": "ฺฉ†ูพŒ ฺฉุฑุงูˆ•", + "copypaste.copy_to_clipboard": "ฺฉ†ูพŒ ฺฉุฑุงูˆ• ุจ† ฺฉู„Œูพุจ†ุฑุฏ", "directory.federated": "ู„• ฺ•ุงฺ˜•ฺฉุงู†Œ ู†ุงุณุฑุงูˆ", "directory.local": "ุช•ู†ู‡ุง ู„• {domain}", "directory.new_arrivals": "ุชุงุฒ• ฺฏ•Œุดุชู†•ฺฉุงู†", @@ -173,6 +197,7 @@ "dismissable_banner.community_timeline": "ุฆ•ู…ุงู†• ุฏูˆุงŒŒู† ูพ†ุณุชŒ ฺฏุดุชŒ ุฆ•ูˆ ฺฉ•ุณุงู†•ู† ฺฉ• ุฆ•ฺฉุงูˆู†ุช•ฺฉุงู†Œุงู† ู„•ู„ุงŒ•ู† {domain}•ูˆ• ู‡†ุณุช ฺฉุฑุงูˆ•.", "dismissable_banner.dismiss": "ุจ•ู„ุงูˆ• ู†ุงู†", "dismissable_banner.explore_links": "ุฆ•ู… ู‡•ูˆุงฺตุงู†• ู„• ุฆŽุณุชุงุฏุง ู„•ู„ุงŒ•ู† ฺฉ•ุณุงู†Žฺฉ•ูˆ• ู„•ุณ•ุฑ ุฆ•ู… ุณŽุฑฺค•ุฑ• ูˆ ุณŽุฑฺค•ุฑ•ฺฉุงู†Œ ุชุฑŒ ุช†ฺ•Œ ู„ุงู…•ุฑฺฉ•ุฒŒ ุจุงุณ ุฏ•ฺฉุฑŽู†.", + "dismissable_banner.explore_statuses": "ุฆ•ู…ุงู†• ูพ†ุณุช•ฺฉุงู†ู† ู„• ุณ•ุฑุงู†ุณ•ุฑŒ ูˆŽุจŒ ฺฉ†ู…•ฺตุงŒ•ุชŒ ฺฉ• ุฆ•ู…ฺ•† ฺฉŽุดฺฉุฑุฏู†Œุงู† ุจ•ุฏ•ุณุชู‡Žู†ุงูˆ•. ูพ†ุณุช• ู†ูˆŽŒ•ฺฉุงู† ฺฉ• ุจูˆูˆุณุช ูˆ ู•ฺคุฑŒุชŒ ุฒŒุงุชุฑŒุงู† ู‡•Œ• ฺ•Œุฒุจ•ู†ุฏŒ ุจ•ุฑุฒุชุฑŒุงู† ู‡•Œ•.", "dismissable_banner.explore_tags": "ุฆ•ู… ู‡ุงุดุชุงฺฏุงู†• ู„• ุฆŽุณุชุงุฏุง ู„• ู†Žูˆ ุฎ•ฺตฺฉŒ ุณ•ุฑ ุฆ•ู… ุณŽุฑฺค•ุฑ• ูˆ ุณŽุฑฺค•ุฑ•ฺฉุงู†Œ ุชุฑŒ ุช†ฺ•Œ ู„ุงู…•ุฑฺฉ•ุฒŒุฏุง ุฌŽฺฏ•Œ ุฎ†Œุงู† ุฏ•ฺฏุฑู†.", "embed.instructions": "ุฆ•ู… ุชูˆุช• ุจู†ฺ†Œู† ุจฺฉ• ู„•ุณ•ุฑ ูˆŽุจ ุณุงŒุช•ฺฉ•ุช ุจ• ฺฉ†ูพŒฺฉุฑุฏู†Œ ฺฉ†ุฏ•ฺฉ•Œ ุฎูˆุงุฑ•ูˆ•.", "embed.preview": "ุฆ•ู…• ุฆ•ูˆ ุดุช•Œ• ฺฉ• ู„• ุดŽูˆ•Œ ุฎ†Œ ุฏ•ฺ†Žุช:", @@ -216,6 +241,7 @@ "errors.unexpected_crash.copy_stacktrace": "ฺฉ†ูพŒฺฉุฑุฏู†Œ ุณุชŽฺฉุชุฑุงุณŒ ุจ† ฺฉู„Œูพ ุจ†ุฑุฏ", "errors.unexpected_crash.report_issue": "ฺฉŽุด•Œ ฺฏูˆุฒุงุฑุดุช", "explore.search_results": "ุฆ•ู†ุฌุงู…•ฺฉุงู†Œ ฺฏ•ฺ•ุงู†", + "explore.suggested_follows": "ุฎ•ฺตฺฉ", "explore.title": "ฺฏ•ฺ•ุงู†", "explore.trending_links": "ู‡•ูˆุงฺต•ฺฉุงู†", "explore.trending_statuses": "ุจฺตุงูˆฺฉุฑุงูˆ•ฺฉุงู†", @@ -236,9 +262,16 @@ "filter_modal.select_filter.subtitle": "ุจ•ฺฉุงุฑู‡Žู†ุงู†Œ ูพ†ู„Žู†Œ ุจ•ุฑุฏ•ุณุช Œุงู† ุฏุฑูˆุณุชฺฉุฑุฏู†Œ ูพ†ู„Žู†ŽฺฉŒ ู†ูˆŽ", "filter_modal.select_filter.title": "ุฆ•ู… ุจฺตุงูˆฺฉุฑุงูˆ•Œ• ุจูพุงฺตŽูˆ•", "filter_modal.title.status": "ุจฺตุงูˆฺฉุฑุงูˆ•Œ•ฺฉ ุจูพุงฺตŽูˆ•", + "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.view_all": "ุจŒู†Œู†Œ ู‡•ู…ูˆูˆ", + "follow_suggestions.who_to_follow": "ุฏูˆุงฺฉ•ูˆุชู†Œ ฺฉŽ", "followed_tags": "ู‡ุงุดุชุงฺฏ• ุดูˆŽู†ฺฉ•ูˆุชูˆูˆ•ฺฉุงู†", "footer.about": "ุฏ•ุฑุจุงุฑ•", "footer.directory": "ฺ•ุงุจ•ุฑŒ ูพ•ฺ••Œ ู†ุงุณุงู†ุฏู†", @@ -259,9 +292,9 @@ "hashtag.column_settings.tag_mode.any": "ู‡•ุฑ ฺฉุงู… ู„•ู…ุงู†•", "hashtag.column_settings.tag_mode.none": "ู‡Œฺ† ฺฉุงู… ู„•ู…ุงู†•", "hashtag.column_settings.tag_toggle": "ุชุงฺฏŒ ุฒŒุงุฏ• Œ ุฆ•ู… ุณุชูˆูˆู†• ู„•ุฎ† ุจู†ูˆูˆุณ•", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} participant} other {{counter} participants}}", "hashtag.follow": "ุดูˆŽู†ฺฉ•ูˆุชู†Œ ู‡ุงุดุชุงฺฏ", "hashtag.unfollow": "ุดูˆŽู† ู†•ฺฉ•ูˆุชู†Œ ู‡ุงุดุชุงฺฏ", - "home.column_settings.basic": "ุจู†•ฺ••ุชŒ", "home.column_settings.show_reblogs": "ูพŒุดุงู†ุฏุงู†Œ ุจ•ู‡Žุฒฺฉุฑุฏู†", "home.column_settings.show_replies": "ูˆ•ฺตุงู…ุฏุงู†•ูˆ•ฺฉุงู† ูพŒุดุงู† ุจุฏ•", "home.hide_announcements": "ุดุงุฑุฏู†•ูˆ•Œ ุฑุงฺฏ•Œ•ู†ุฑุงูˆ•ฺฉุงู†", @@ -332,9 +365,6 @@ "load_pending": "{count, plural, one {# ุจ•ฺ•ฺฏ•Œ ู†ูˆŽ} other {# ุจ•ฺ•ฺฏ•Œ ู†ูˆŽ}}", "media_gallery.toggle_visible": "ุดุงุฑุฏู†•ูˆ•Œ {number, plural, one {image} other {images}}", "moved_to_account_banner.text": "ุฆ•ฺฉุงูˆู†ุช•ฺฉ•ุช {disabledAccount} ู„• ุฆŽุณุชุงุฏุง ู„•ฺฉุงุฑุฎุฑุงูˆ• ฺ†ูˆู†ฺฉ• ุช† ฺ†ูˆูˆŒุช• {movedToAccount}.", - "mute_modal.duration": "ู…ุงูˆ•", - "mute_modal.hide_notifications": "ุดุงุฑุฏู†•ูˆ•Œ ุฆุงฺฏุงู†ุงู…•ฺฉุงู† ู„•ู… ุจ•ฺฉุงุฑู‡Žู†•ุฑ•ุŸ ", - "mute_modal.indefinite": "ู†ุงุฏŒุงุฑ", "navigation_bar.about": "ุฏ•ุฑุจุงุฑ•", "navigation_bar.blocks": "ุจ•ฺฉุงุฑู‡Žู†•ุฑ• ุจู„†ฺฉฺฉุฑุงูˆ•ฺฉุงู†", "navigation_bar.bookmarks": "ู†Œุดุงู†ฺฉุฑุงูˆ•ฺฉุงู†", @@ -373,9 +403,6 @@ "notifications.column_settings.admin.report": "ฺ•ุงูพ†ุฑุช• ู†ูˆŽŒ•ฺฉุงู†:", "notifications.column_settings.admin.sign_up": "ฺ†ูˆูˆู†•ฺ˜ูˆูˆุฑ•ูˆ•Œ ู†ูˆŽ:", "notifications.column_settings.alert": "ุฆุงฺฏุงู†ุงู…•ฺฉุงู†Œ ูพŒุดุงู†ฺฏ•ุฑุฑ ฺ•ูˆู…ŽุฒŒ", - "notifications.column_settings.filter_bar.advanced": "ู‡•ู…ูˆูˆ ูพ†ู„•ฺฉุงู† ูพŒุดุงู† ุจุฏ•", - "notifications.column_settings.filter_bar.category": "ุดุฑŒุชŒ ูพุงฺตŽูˆ•ุฑŒ ุฎŽุฑุง", - "notifications.column_settings.filter_bar.show_bar": "ู†Œุดุงู†ุฏุงู†Œ ุดุฑŒุชŒ ูพุงฺตุงูุชู†", "notifications.column_settings.follow": "ุดูˆŽู†ฺฉ•ูˆุชูˆุงู†Œ ู†ูˆŽ:", "notifications.column_settings.follow_request": "ุดูˆŒู†ฺฉ•ูˆุชู†Œ ุฏุงูˆุงฺฉุงุฑŒ ู†ูˆŽ:", "notifications.column_settings.mention": "ุฆุงู…ุงฺ˜•ฺฉุงู†:", @@ -506,8 +533,6 @@ "server_banner.about_active_users": "ุฆ•ูˆ ฺฉ•ุณุงู†•Œ ู„• ู…ุงูˆ•Œ ูฃู  ฺ•†ฺ˜Œ ฺ•ุงุจุฑุฏูˆูˆุฏุง ุฆ•ู… ุณŽุฑฺค•ุฑ• ุจ•ฺฉุงุฑุฏ•ู‡Žู†ู† (ุจ•ฺฉุงุฑู‡Žู†•ุฑุงู†Œ ฺ†ุงู„ุงฺฉ ู…ุงู†ฺฏุงู†•)", "server_banner.active_users": "ุจ•ฺฉุงุฑู‡Žู†•ุฑุงู†Œ ฺ†ุงู„ุงฺฉ", "server_banner.administered_by": "ุจ•ฺ•Žูˆ•ุจุฑุฏู† ู„•ู„ุงŒ•ู†:", - "server_banner.introduction": "{domain} ุจ•ุดŽฺฉ• ู„•ูˆ ุช†ฺ•• ฺฉ†ู…•ฺตุงŒ•ุชŒŒ• ู„ุงู…•ุฑฺฉ•ุฒŒŒ•Œ ฺฉ• ู„•ู„ุงŒ•ู† {mastodon}•ูˆ• ุจ•ู‡Žุฒ ุฏ•ฺฉุฑŽุช.", - "server_banner.learn_more": "ุฒŒุงุชุฑ ูŽุฑุจู‡", "server_banner.server_stats": "ุฏ†ุฎŒ ฺ•ุงฺ˜•ฺฉุงุฑ:", "sign_in_banner.create_account": "ู‡•ฺ˜ู…ุงุฑ ุฏุฑูˆุณุชุจฺฉ•", "sign_in_banner.sign_in": "ุจฺ†† ฺ˜ูˆูˆุฑ•ูˆ•", @@ -524,7 +549,6 @@ "status.direct": "ุจ• ุดŽูˆ•Œ•ฺฉŒ ุชุงŒุจ•ุช ุจุงุณŒ @{name} ุจฺฉ•", "status.direct_indicator": "ุฆุงู…ุงฺ˜•Œ ุชุงŒุจ•ุช", "status.edit": "ุฏ•ุณุชฺฉุงุฑŒ", - "status.edited": "ุจ•ุดุฏุงุฑŒ {date}", "status.edited_x_times": "ุฏ•ุณุชฺฉุงุฑŒฺฉุฑุงูˆ• {count, plural, one {{count} ฺฉุงุช} other {{count} ฺฉุงุช}}", "status.embed": "ู†Œุดุช•ุฌŽ ุจฺฉ•", "status.filter": "ุฆ•ู… ูพ†ุณุช• ูู„ุช•ุฑ ุจฺฉ•", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 9d0b0306c8..be4cce2692 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -86,21 +86,16 @@ "compose_form.spoiler.marked": "Testu piattatu daret'ร  un'avertimentu", "compose_form.spoiler.unmarked": "Testu micca piattatu", "confirmation_modal.cancel": "Annullร ", - "confirmations.block.block_and_report": "Bluccร  รจ signalร ", "confirmations.block.confirm": "Bluccร ", - "confirmations.block.message": "Site sicuruยทa che vulete bluccร  @{name}?", "confirmations.delete.confirm": "Toglie", "confirmations.delete.message": "Site sicuruยทa che vulete sguassร  stu statutu?", "confirmations.delete_list.confirm": "Toglie", "confirmations.delete_list.message": "Site sicuruยทa che vulete toglie sta lista?", "confirmations.discard_edit_media.confirm": "Scartร ", - "confirmations.domain_block.confirm": "Piattร  tuttu u duminiu", "confirmations.domain_block.message": "Site veramente sicuruยทa che vulete piattร  tuttu ร  {domain}? Saria forse abbastanza di bluccร  รฒ piattร  alcuni conti da quallร . ร™n viderete piรน nunda da quallร  indรจ e linee pubbliche o e nutificazione. I vostri abbunati da stu duminiu saranu tolti.", "confirmations.logout.confirm": "Scunnettassi", "confirmations.logout.message": "Site sicuruยทa che vulete scunnettร  vi?", "confirmations.mute.confirm": "Piattร ", - "confirmations.mute.explanation": "Quessu hร  da piattร  i statuti da sta persona รจ i posti chรฌ a mintuvanu, ma elluยทa puderร  sempre vede i vostri statuti รจ siguitร  vi.", - "confirmations.mute.message": "Site sicuruยทa che vulete piattร  @{name}?", "confirmations.redraft.confirm": "Sguassร  รจ riscrive", "confirmations.reply.confirm": "Risponde", "confirmations.reply.message": "Risponde avร  sguasserร  u missaghju chรฌ scrivite. Site sicuruยทa chรฌ vulete cuntinuร ?", @@ -167,7 +162,6 @@ "hashtag.column_settings.tag_mode.any": "Unu di quessi", "hashtag.column_settings.tag_mode.none": "Nisunu di quessi", "hashtag.column_settings.tag_toggle": "Inchjude tag addiziunali per sta colonna", - "home.column_settings.basic": "Bร sichi", "home.column_settings.show_reblogs": "Vede e spartere", "home.column_settings.show_replies": "Vede e risposte", "home.hide_announcements": "Piattร  annunzii", @@ -227,9 +221,6 @@ "lists.subheading": "E vo liste", "load_pending": "{count, plural, one {# entrata nova} other {# entrate nove}}", "media_gallery.toggle_visible": "Piattร  {number, plural, one {ritrattu} other {ritratti}}", - "mute_modal.duration": "Durata", - "mute_modal.hide_notifications": "Piattร  nutificazione da st'utilizatore?", - "mute_modal.indefinite": "Indifinita", "navigation_bar.blocks": "Utilizatori bluccati", "navigation_bar.bookmarks": "Segnalibri", "navigation_bar.community_timeline": "Linea pubblica lucale", @@ -258,8 +249,6 @@ "notifications.clear": "Purgร  e nutificazione", "notifications.clear_confirmation": "Site sicuruยทa che vulete toglie tutte ste nutificazione?", "notifications.column_settings.alert": "Nutificazione nant'ร  l'urdinatore", - "notifications.column_settings.filter_bar.advanced": "Affissร  tutte e categurie", - "notifications.column_settings.filter_bar.category": "Barra di ricerca pronta", "notifications.column_settings.follow": "Abbunati novi:", "notifications.column_settings.follow_request": "Nove dumande d'abbunamentu:", "notifications.column_settings.mention": "Minzione:", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 24248db15c..d8d83ae5fa 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -89,6 +89,14 @@ "announcement.announcement": "Oznรกmenรญ", "attachments_list.unprocessed": "(nezpracovรกno)", "audio.hide": "Skrรฝt zvuk", + "block_modal.remote_users_caveat": "Poลพรกdรกme server {domain}, aby respektoval vaลกe rozhodnutรญ. รšplnรฉ dodrลพovรกnรญ nastavenรญ vลกak nenรญ zaruฤeno, protoลพe nฤ›kterรฉ servery mohou ล™eลกit blokovรกnรญ rลฏznฤ›. Veล™ejnรฉ pล™รญspฤ›vky mohou bรฝt stรกle viditelnรฉ pro nepล™ihlรกลกenรฉ uลพivatele.", + "block_modal.show_less": "Zobrazit mรฉnฤ›", + "block_modal.show_more": "Zobrazit vรญce", + "block_modal.they_cant_mention": "Nemลฏลพe vรกs zmiลˆovat ani sledovat.", + "block_modal.they_cant_see_posts": "Nemลฏลพe vidฤ›t vaลกe pล™รญspฤ›vky a vy neuvidรญte jeho.", + "block_modal.they_will_know": "Mลฏลพe vidฤ›t, ลพe je zablokovanรฝ.", + "block_modal.title": "Zablokovat uลพivatele?", + "block_modal.you_wont_see_mentions": "Neuvidรญte pล™รญspฤ›vky, kterรฉ ho zmiลˆujรญ.", "boost_modal.combo": "Pล™รญลกtฤ› mลฏลพete pro pล™eskoฤenรญ stisknout {combo}", "bundle_column_error.copy_stacktrace": "Zkopรญrovat zprรกvu o chybฤ›", "bundle_column_error.error.body": "Poลพadovanou strรกnku nelze vykreslit. Mลฏลพe to bรฝt zpลฏsobeno chybou v naลกem kรณdu nebo problรฉmem s kompatibilitou prohlรญลพeฤe.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Pล™idat varovรกnรญ o obsahu", "compose_form.spoiler_placeholder": "Upozornฤ›nรญ na obsah (nepovinnรฉ)", "confirmation_modal.cancel": "Zruลกit", - "confirmations.block.block_and_report": "Blokovat a nahlรกsit", "confirmations.block.confirm": "Blokovat", - "confirmations.block.message": "Opravdu chcete blokovat {name}?", "confirmations.cancel_follow_request.confirm": "Zruลกit ลพรกdost", "confirmations.cancel_follow_request.message": "Opravdu chcete zruลกit svou ลพรกdost o sledovรกnรญ {name}?", "confirmations.delete.confirm": "Smazat", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Opravdu chcete tento seznam navลพdy smazat?", "confirmations.discard_edit_media.confirm": "Zahodit", "confirmations.discard_edit_media.message": "Mรกte neuloลพenรฉ zmฤ›ny popisku mรฉdiรญ nebo nรกhledu, chcete je pล™esto zahodit?", - "confirmations.domain_block.confirm": "Blokovat celou domรฉnu", + "confirmations.domain_block.confirm": "Blokovat server", "confirmations.domain_block.message": "Opravdu chcete blokovat celou domรฉnu {domain}? Ve vฤ›tลกinฤ› pล™รญpadลฏ staฤรญ blokovat nebo skrรฝt pรกr konkrรฉtnรญch uลพivatelลฏ, coลพ takรฉ doporuฤujeme. Z tรฉto domรฉny neuvidรญte obsah v ลพรกdnรฉ veล™ejnรฉ ฤasovรฉ ose ani v oznรกmenรญch. Vaลกi sledujรญcรญ z tรฉto domรฉny budou odstranฤ›ni.", "confirmations.edit.confirm": "Upravit", "confirmations.edit.message": "Editovat teฤ znamenรก pล™epsรกnรญ zprรกvy, kterou prรกvฤ› tvoล™รญte. Opravdu chcete pokraฤovat?", "confirmations.logout.confirm": "Odhlรกsit se", "confirmations.logout.message": "Opravdu se chcete odhlรกsit?", "confirmations.mute.confirm": "Skrรฝt", - "confirmations.mute.explanation": "Tohle skryje uลพivatelovy pล™รญspฤ›vky a pล™รญspฤ›vky, kterรฉ ho zmiลˆujรญ, ale uลพivatel stรกle uvidรญ vaลกe pล™รญspฤ›vky a mลฏลพe vรกs sledovat.", - "confirmations.mute.message": "Opravdu chcete skrรฝt uลพivatele {name}?", "confirmations.redraft.confirm": "Smazat a pล™epsat", "confirmations.redraft.message": "Jste si jistรญ, ลพe chcete odstranit tento pล™รญspฤ›vek a vytvoล™it z nฤ›j koncept? Oblรญbenรฉ a boosty budou ztraceny a odpovฤ›di na pลฏvodnรญ pล™รญspฤ›vek ztratรญ kontext.", "confirmations.reply.confirm": "Odpovฤ›dฤ›t", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Toto jsou pล™รญspฤ›vky ze sociรกlnรญch sรญtรญ, kterรฉ dnes zรญskรกvajรญ na popularitฤ›. Novฤ›jลกรญ pล™รญspฤ›vky s vฤ›tลกรญm poฤtem boostลฏ a oblรญbenรญ jsou hodnoceny vรฝลกe.", "dismissable_banner.explore_tags": "Tyto hashtagy prรกvฤ› teฤ zรญskรกvajรญ na popularitฤ› mezi lidmi na tomto a dalลกรญch serverech decentralizovanรฉ sรญtฤ›.", "dismissable_banner.public_timeline": "Toto jsou nejnovฤ›jลกรญ veล™ejnรฉ pล™รญspฤ›vky od lidรญ na sociรกlnรญ sรญti, kterรฉ sledujรญ lidรฉ na {domain}.", + "domain_block_modal.block": "Blokovat server", + "domain_block_modal.block_account_instead": "Radฤ›ji blokovat @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Lidรฉ z tohoto serveru mohou interagovat s vaลกimi starรฝmi pล™รญspฤ›vky.", + "domain_block_modal.they_cant_follow": "Nikdo z tohoto serveru vรกs nemลฏลพe sledovat.", + "domain_block_modal.they_wont_know": "Nebude vฤ›dฤ›t, ลพe je zablokovรกn.", + "domain_block_modal.title": "Blokovat domรฉnu?", + "domain_block_modal.you_will_lose_followers": "Vลกichni vaลกi sledujรญcรญ z tohoto serveru budou odstranฤ›ni.", + "domain_block_modal.you_wont_see_posts": "Neuvidรญte pล™รญspฤ›vky ani upozornฤ›nรญ od uลพivatelลฏ z tohoto serveru.", + "domain_pill.activitypub_lets_connect": "Umoลพลˆuje vรกm spojit se a komunikovat s lidmi nejen na Mastodonu, ale i s dalลกรญmi sociรกlnรญmi aplikacemi.", + "domain_pill.activitypub_like_language": "ActivityPub je jako jazyk, kterรฝm Mastodon mluvรญ s jinรฝmi sociรกlnรญmi sรญtฤ›mi.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Handle:", + "domain_pill.their_server": "Digitรกlnรญ domov, kde ลพijรญ vลกechny pล™รญspฤ›vky.", + "domain_pill.their_username": "Jedineฤnรฝ identikรกtor na serveru. Je moลพnรฉ najรญt uลพivatele se stejnรฝm uลพivatelskรฝm jmรฉnem na rลฏznรฝch serverech.", + "domain_pill.username": "Uลพivatelskรฉ jmรฉno", + "domain_pill.whats_in_a_handle": "Co obsahuje handle?", + "domain_pill.who_they_are": "Protoลพe handle ล™รญkajรญ kdo je kdo a takรฉ kde, je moลพnรฉ interagovat s lidmi napล™รญฤ sociรกlnรญmi weby .", + "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", @@ -237,10 +262,11 @@ "empty_column.follow_requests": "Zatรญm nemรกte ลพรกdnรฉ ลพรกdosti o sledovรกnรญ. Aลพ nฤ›jakou obdrลพรญte, zobrazรญ se zde.", "empty_column.followed_tags": "Zatรญm jste nesledovali ลพรกdnรฉ hashtagy. Aลพ to udฤ›lรกte, objevรญ se zde.", "empty_column.hashtag": "Pod tรญmto hashtagem zde zatรญm nic nenรญ.", - "empty_column.home": "Vaลกe domovskรก ฤasovรก osa je prรกzdnรก! Naplลˆte ji sledovรกnรญm dalลกรญch lidรญ. {suggestions}", + "empty_column.home": "Vaลกe domovskรก ฤasovรก osa je prรกzdnรก! Naplลˆte ji sledovรกnรญm dalลกรญch lidรญ.", "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.", @@ -271,14 +297,29 @@ "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", "follow_request.authorize": "Autorizovat", "follow_request.reject": "Zamรญtnout", - "follow_requests.unlocked_explanation": "Pล™estoลพe vรกลก รบฤet nenรญ zamฤenรฝ, administrรกtor {domain} usoudil, ลพe byste mohli chtรญt tyto ลพรกdosti o sledovรกnรญ zkontrolovat ruฤnฤ›.", + "follow_requests.unlocked_explanation": "Pล™estoลพe vรกลก รบฤet nenรญ uzamฤen, personรกl {domain} usoudil, ลพe byste mohli chtรญt tyto poลพadavky na sledovรกnรญ zkontrolovat ruฤnฤ›.", + "follow_suggestions.curated_suggestion": "Vรฝbฤ›r personรกlลฏ", "follow_suggestions.dismiss": "Znovu nezobrazovat", + "follow_suggestions.featured_longer": "Ruฤnฤ› vybrรกno tรฝmem {domain}", + "follow_suggestions.friends_of_friends_longer": "Populรกrnรญ mezi lidmi, kterรฉ sledujete", + "follow_suggestions.hints.featured": "Tento profil byl ruฤnฤ› vybrรกn tรฝmem {domain}.", + "follow_suggestions.hints.friends_of_friends": "Tento profil je populรกrnรญ mezi lidmi, kterรฉ sledujete.", + "follow_suggestions.hints.most_followed": "Tento profil je jednรญm z nejvรญce sledovanรฝch na {domain}.", + "follow_suggestions.hints.most_interactions": "Tento profil nedรกvno dostalo velkou pozornost na {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobnรฝ profilลฏm, kterรฉ jste nedรกvno sledovali.", + "follow_suggestions.personalized_suggestion": "Pล™izpลฏsobenรฝ nรกvrh", "follow_suggestions.popular_suggestion": "Populรกrnรญ nรกvrh", + "follow_suggestions.popular_suggestion_longer": "Populรกrnรญ na {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Podobnรฉ profilลฏm, kterรฉ jste nedรกvno sledovali", + "follow_suggestions.view_all": "Zobrazit vลกe", "follow_suggestions.who_to_follow": "Koho sledovat", "followed_tags": "Sledovanรฉ hashtagy", "footer.about": "O aplikaci", @@ -300,9 +341,12 @@ "hashtag.column_settings.tag_mode.any": "Jakรฝkoliv z tฤ›chto", "hashtag.column_settings.tag_mode.none": "ลฝรกdnรฝ z tฤ›chto", "hashtag.column_settings.tag_toggle": "Zahrnout v tomto sloupci dalลกรญ ลกtรญtky", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} รบฤastnรญk} few {{counter} รบฤastnรญci} other {{counter} รบฤastnรญkลฏ}}", + "hashtag.counter_by_uses": "{count, plural, one {{counter} pล™รญspฤ›vek} few {{counter} pล™รญspฤ›vky} other {{counter} pล™รญspฤ›vkลฏ}}", + "hashtag.counter_by_uses_today": "Dnes {count, plural, one {{counter} pล™รญspฤ›vek} few {{counter} pล™รญspฤ›vky} other {{counter} pล™รญspฤ›vkลฏ}}", "hashtag.follow": "Sledovat hashtag", "hashtag.unfollow": "Pล™estat sledovat hashtag", - "home.column_settings.basic": "Zรกkladnรญ", + "hashtags.and_other": "โ€ฆa {count, plural, one {# dalลกรญ} few {# dalลกรญ} other {# dalลกรญch}}", "home.column_settings.show_reblogs": "Zobrazit boosty", "home.column_settings.show_replies": "Zobrazit odpovฤ›di", "home.hide_announcements": "Skrรฝt oznรกmenรญ", @@ -388,9 +432,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.duration": "Trvรกnรญ", - "mute_modal.hide_notifications": "Skrรฝt oznรกmenรญ od tohoto uลพivatele?", - "mute_modal.indefinite": "Neomezenฤ›", + "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รฉ", @@ -423,11 +473,29 @@ "notification.follow": "Uลพivatel {name} vรกs zaฤal sledovat", "notification.follow_request": "Uลพivatel {name} poลพรกdal o povolenรญ vรกs sledovat", "notification.mention": "Uลพivatel {name} vรกs zmรญnil", + "notification.moderation-warning.learn_more": "Zjistit vรญce", + "notification.moderation_warning": "Obdrลพeli jste moderaฤnรญ varovรกnรญ", + "notification.moderation_warning.action_delete_statuses": "Nฤ›kterรฉ z vaลกich pล™รญspฤ›vkลฏ byly odstranฤ›ny.", + "notification.moderation_warning.action_disable": "Vรกลก รบฤet je zablokovรกn.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Nฤ›kterรฉ z vaลกich pล™รญspฤ›vkลฏ byly oznaฤeny jako citlivรฉ.", + "notification.moderation_warning.action_none": "Vรกลก รบฤet obdrลพel moderaฤnรญ varovรกnรญ.", + "notification.moderation_warning.action_sensitive": "Vaลกe pล™รญspฤ›vky budou od nynฤ›jลกka oznaฤeny jako citlivรฉ.", + "notification.moderation_warning.action_silence": "Vรกลก รบฤet byl omezen.", + "notification.moderation_warning.action_suspend": "Vรกลก รบฤet byl pozastaven.", "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รญ:", @@ -436,7 +504,6 @@ "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.filter_bar.show_bar": "Zobrazit panel filtrลฏ", "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 +529,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", @@ -471,8 +547,8 @@ "onboarding.actions.go_to_home": "Pล™ejรญt na svลฏj domovskรฝ feed", "onboarding.compose.template": "Ahoj #Mastodon!", "onboarding.follows.empty": "Bohuลพel, ลพรกdnรฉ vรฝsledky nelze momentรกlnฤ› zobrazit. Mลฏลพete zkusit vyhledat nebo prochรกzet strรกnku s prลฏzkumem a najรญt lidi, kteล™รญ budou sledovat, nebo to zkuste znovu pozdฤ›ji.", - "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.title": "Populรกrnรญ na Mastodonu", + "onboarding.follows.lead": "Domovskรฝ kanรกl je hlavnรญ metodou zaลพรญvรกnรญ Mastodonu. ฤŒรญm vรญce lidรญ sledujete, tรญm aktivnฤ›jลกรญ a zajรญmavฤ›jลกรญ bude. Pro zaฤnutรญ, zde mรกte nฤ›kolik nรกvrhลฏ:", + "onboarding.follows.title": "Pล™ispลฏsobit vlastnรญ domovskรฝ kanรกl", "onboarding.profile.discoverable": "Udฤ›lat svลฏj profil vyhledatelnรฝm", "onboarding.profile.discoverable_hint": "Kdyลพ se rozhodnete bรฝt vyhledatelnรฝ na Mastodonu, vaลกe pล™รญspฤ›vky se mohou objevit ve vรฝsledcรญch vyhledรกvรกnรญ a v populรกrnรญch, a vรกลก profil mลฏลพe bรฝt navrhovรกn lidem s podobnรฝmi zรกjmy.", "onboarding.profile.display_name": "Zobrazovanรฉ jmรฉno", @@ -491,13 +567,13 @@ "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.skip": "Want to skip right ahead?", "onboarding.start.title": "Dokรกzali jste to!", - "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", - "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", - "onboarding.steps.publish_status.body": "ล˜eknฤ›te svฤ›tu Ahoj.", + "onboarding.steps.follow_people.body": "Mastodon je o sledovรกnรญ zajimavรฝch lidรญ.", + "onboarding.steps.follow_people.title": "Pล™ispลฏsobit vlastnรญ domovskรฝ kanรกl", + "onboarding.steps.publish_status.body": "ล˜eknฤ›te svฤ›tu ahoj s pomocรญ textem, fotografiemi, videami nebo anketami {emoji}", "onboarding.steps.publish_status.title": "Vytvoล™te svลฏj prvnรญ pล™รญspฤ›vek", "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.title": "Pล™izpลฏsobit svลฏj profil", - "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", + "onboarding.steps.share_profile.body": "Dejte blรญzkรฝm lidem vฤ›dฤ›t, jak vรกs mohou najรญt na Mastodonu", "onboarding.steps.share_profile.title": "Sdรญlejte svลฏj profil", "onboarding.tips.2fa": "Vรญte, ลพe? Svลฏj รบฤet mลฏลพete zabezpeฤit nastavenรญm dvoufaktorovรฉho ovฤ›ล™ovรกnรญ v nastavenรญ รบฤtu. Funguje s jakoukoli TOTP aplikacรญ podle vaลกeho vรฝbฤ›ru, telefonnรญ ฤรญslo nenรญ nutnรฉ!", "onboarding.tips.accounts_from_other_servers": "Vรญte, ลพe? Protoลพe je Mastodon decentralizovanรฝ, nฤ›kterรฉ profily, na kterรฉ narazรญte, budou hostovรกny na jinรฝch serverech, neลพ je ten vรกลก. A pล™esto s nimi mลฏลพete bezproblรฉmovฤ› komunikovat! Jejich server se nachรกzรญ v druhรฉ polovinฤ› uลพivatelskรฉho jmรฉna!", @@ -525,6 +601,7 @@ "privacy.public.short": "Veล™ejnรฉ", "privacy.unlisted.additional": "Chovรก se stejnฤ› jako veล™ejnรฝ, aลพ na to, ลพe se pล™รญspฤ›vek neobjevรญ v ลพivรฝch kanรกlech nebo hashtazรญch, v objevovรกnรญ nebo vyhledรกvรกnรญ na Mastodonu, a to i kdyลพ je รบฤet nastaven tak, aby se zde vลกude tyto pล™รญspฤ›vky zobrazovaly.", "privacy.unlisted.long": "Mรฉnฤ› algoritmickรฝch fanfรกr", + "privacy.unlisted.short": "Ztiลกenรฉ veล™ejnรฉ", "privacy_policy.last_updated": "Naposledy aktualizovรกno {date}", "privacy_policy.title": "Zรกsady ochrany osobnรญch รบdajลฏ", "recommended": "Doporuฤeno", @@ -542,6 +619,7 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "dnes", + "reply_indicator.attachments": "{count, plural, one {{counter} pล™รญloha} few {{counter} pล™รญlohy} other {{counter} pล™ilohลฏ}}", "reply_indicator.cancel": "Zruลกit", "reply_indicator.poll": "Anketa", "report.block": "Blokovat", @@ -616,13 +694,10 @@ "server_banner.about_active_users": "Lidรฉ pouลพรญvajรญcรญ tento server bฤ›hem poslednรญch 30 dnรญ (mฤ›sรญฤnรญ aktivnรญ uลพivatelรฉ)", "server_banner.active_users": "aktivnรญ uลพivatelรฉ", "server_banner.administered_by": "Spravovรกno:", - "server_banner.introduction": "{domain} je souฤรกstรญ decentralizovanรฉ sociรกlnรญ sรญtฤ› bฤ›ลพรญcรญ na {mastodon}.", - "server_banner.learn_more": "Zjistit vรญce", "server_banner.server_stats": "Statistiky serveru:", "sign_in_banner.create_account": "Vytvoล™it รบฤet", "sign_in_banner.sign_in": "Pล™ihlรกsit se", "sign_in_banner.sso_redirect": "Pล™ihlรกลกenรญ nebo Registrace", - "sign_in_banner.text": "Pล™ihlaste se pro sledovรกnรญ profilลฏ nebo hashtagลฏ, oblรญbenรญ, sdรญlenรญ a odpovรญdรกnรญ na pล™รญspฤ›vky. Svลฏj รบฤet mลฏลพete takรฉ pouลพรญvat k interagovรกnรญ i na jinรฉm serveru.", "status.admin_account": "Otevล™รญt moderรกtorskรฉ rozhranรญ pro @{name}", "status.admin_domain": "Otevล™รญt moderรกtorskรฉ rozhranรญ pro {domain}", "status.admin_status": "Otevล™รญt tento pล™รญspฤ›vek v moderรกtorskรฉm rozhranรญ", @@ -636,10 +711,11 @@ "status.direct": "Soukromฤ› zmรญnit @{name}", "status.direct_indicator": "Soukromรก zmรญnka", "status.edit": "Upravit", - "status.edited": "Upraveno {date}", + "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", @@ -660,6 +736,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/cy.json b/app/javascript/mastodon/locales/cy.json index f023c5a2a7..96476b1433 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -89,6 +89,14 @@ "announcement.announcement": "Cyhoeddiad", "attachments_list.unprocessed": "(heb eu prosesu)", "audio.hide": "Cuddio sain", + "block_modal.remote_users_caveat": "Byddwn yn gofyn i'r gweinydd {domain} barchu eich penderfyniad. Fodd bynnag, nid yw cydymffurfiad wedi'i warantu gan y gall rhai gweinyddwyr drin rhwystro mewn ffyrdd gwahanol. Mae'n bosibl y bydd postiadau cyhoeddus yn dal i fod yn weladwy i ddefnyddwyr nad ydynt wedi mewngofnodi.", + "block_modal.show_less": "Dangos llai", + "block_modal.show_more": "Dangos mwy", + "block_modal.they_cant_mention": "Nid ydynt yn gallu eich crybwyll na'ch dilyn.", + "block_modal.they_cant_see_posts": "Nid ydynt yn gallu gweld eich postiadau ac ni fyddwch yn gweld eu rhai hwy.", + "block_modal.they_will_know": "Gallant weld eu bod wedi'u rhwystro.", + "block_modal.title": "Rhwystro defnyddiwr?", + "block_modal.you_wont_see_mentions": "Ni welwch bostiadau sy'n sรดn amdanynt.", "boost_modal.combo": "Mae modd pwyso {combo} er mwyn hepgor hyn tro nesa", "bundle_column_error.copy_stacktrace": "Copรฏo'r adroddiad gwall", "bundle_column_error.error.body": "Nid oedd modd cynhyrchu'r dudalen honno. Gall fod oherwydd gwall yn ein cod neu fater cydnawsedd porwr.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Ychwanegu rhybudd cynnwys", "compose_form.spoiler_placeholder": "Rhybudd cynnwys (dewisol)", "confirmation_modal.cancel": "Diddymu", - "confirmations.block.block_and_report": "Rhwystro ac Adrodd", "confirmations.block.confirm": "Blocio", - "confirmations.block.message": "Ydych chi'n siลตr eich bod eisiau blocio {name}?", "confirmations.cancel_follow_request.confirm": "Tynnu'r cais yn รดl", "confirmations.cancel_follow_request.message": "Ydych chi'n siลตr eich bod am dynnu'ch cais i ddilyn {name} yn รดl?", "confirmations.delete.confirm": "Dileu", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Ydych chi'n siลตr eich bod eisiau dileu'r rhestr hwn am byth?", "confirmations.discard_edit_media.confirm": "Dileu", "confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?", - "confirmations.domain_block.confirm": "Blocio parth cyfan", + "confirmations.domain_block.confirm": "Rhwystro gweinydd", "confirmations.domain_block.message": "Ydych chi wir, wir eisiau blocio'r holl {domain}? Fel arfer, mae blocio neu dewi pobl penodol yn broses mwy effeithiol. Fyddwch chi ddim yn gweld cynnwys o'r parth hwnnw mewn ffrydiau cyhoeddus neu yn eich hysbysiadau. Bydd eich dilynwyr o'r parth hwnnw yn cael eu ddileu.", "confirmations.edit.confirm": "Golygu", "confirmations.edit.message": "Bydd golygu nawr yn trosysgrifennu'r neges rydych yn ei ysgrifennu ar hyn o bryd. Ydych chi'n siลตr eich bod eisiau gwneud hyn?", "confirmations.logout.confirm": "Allgofnodi", "confirmations.logout.message": "Ydych chi'n siลตr eich bod am allgofnodi?", "confirmations.mute.confirm": "Tewi", - "confirmations.mute.explanation": "Bydd hyn yn cuddio postiadau oddi wrthyn nhw a phostiadau sydd yn sรดn amdanyn nhw, ond bydd hyn dal yn gadael iddyn nhw gweld eich postiadau a'ch dilyn.", - "confirmations.mute.message": "Ydych chi wir eisiau tewi {name}?", "confirmations.redraft.confirm": "Dileu ac ailddrafftio", "confirmations.redraft.message": "Ydych chi'n siลตr eich bod am ddileu'r postiad hwn a'i ailddrafftio? Bydd ffefrynnau a hybiau'n cael eu colli, a bydd atebion i'r post gwreiddiol yn mynd yn amddifad.", "confirmations.reply.confirm": "Ateb", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Mae'r rhain yn bostiadau o bob rhan o'r we gymdeithasol sydd ar gynnydd heddiw. Mae postiadau mwy diweddar sydd รข mwy o hybiau a ffefrynu'n cael eu graddio'n uwch.", "dismissable_banner.explore_tags": "Mae'r rhain yn hashnodau sydd ar gynnydd ar y we gymdeithasol heddiw. Mae hashnodau sy'n cael eu defnyddio gan fwy o unigolion gwahanol yn cael eu graddio'n uwch.", "dismissable_banner.public_timeline": "Dyma'r postiadau cyhoeddus diweddaraf gan bobl ar y we gymdeithasol y mae pobl ar {domain} yn eu dilyn.", + "domain_block_modal.block": "Rhwystro gweinydd", + "domain_block_modal.block_account_instead": "Rhwystro @{name} yn lle hynny", + "domain_block_modal.they_can_interact_with_old_posts": "Gall pobl o'r gweinydd hwn ryngweithio รข'ch hen bostiadau.", + "domain_block_modal.they_cant_follow": "Ni all neb o'r gweinydd hwn eich dilyn.", + "domain_block_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu rhwystro.", + "domain_block_modal.title": "Rhwystro parth?", + "domain_block_modal.you_will_lose_followers": "Bydd eich holl ddilynwyr o'r gweinydd hwn yn cael eu tynnu.", + "domain_block_modal.you_wont_see_posts": "Fyddwch chi ddim yn gweld postiadau na hysbysiadau gan ddefnyddwyr ar y gweinydd hwn.", + "domain_pill.activitypub_lets_connect": "Mae'n caniatรกu ichi gysylltu a rhyngweithio รข phobl nid yn unig ar Mastodon, ond ar draws gwahanol apiau cymdeithasol hefyd.", + "domain_pill.activitypub_like_language": "Mae ActivityPub fel yr iaith y mae Mastodon yn ei siarad รข rhwydweithiau cymdeithasol eraill.", + "domain_pill.server": "Gweinydd", + "domain_pill.their_handle": "Eu handlen:", + "domain_pill.their_server": "Eu cartref digidol, lle mae eu holl negeseuon yn byw.", + "domain_pill.their_username": "Eu dynodwr unigryw ar eu gweinydd. Mae'n bosibl dod o hyd i ddefnyddwyr gyda'r un enw defnyddiwr ar wahanol weinyddion.", + "domain_pill.username": "Enw Defnyddiwr", + "domain_pill.whats_in_a_handle": "Beth sydd mewn handlen?", + "domain_pill.who_they_are": "Gan fod handlen yn dweud pwy yw rhywun a ble maen nhw, gallwch chi ryngweithio รข phobl ar draws gwe gymdeithasol .", + "domain_pill.who_you_are": "Oherwydd bod eich handlen yn dweud pwy ydych chi a ble rydych chi, gall pobl ryngweithio รข chi ar draws gwe gymdeithasol .", + "domain_pill.your_handle": "Eich handlen:", + "domain_pill.your_server": "Eich cartref digidol, lle mae'ch holl bostiadau'n byw. Ddim yn hoffi'r un hon? Trosglwyddwch weinyddion ar unrhyw adeg a dewch รข'ch dilynwyr hefyd.", + "domain_pill.your_username": "Eich dynodwr unigryw ar y gweinydd hwn. Mae'n bosibl dod o hyd i ddefnyddwyr gyda'r un enw defnyddiwr ar wahanol weinyddion.", "embed.instructions": "Gosodwch y post hwn ar eich gwefan drwy gopรฏo'r cรดd isod.", "embed.preview": "Dyma sut olwg fydd arno:", "emoji_button.activity": "Gweithgarwch", @@ -241,6 +266,7 @@ "empty_column.list": "Does dim yn y rhestr yma eto. Pan fydd aelodau'r rhestr yn cyhoeddi postiad newydd, mi fydd yn ymddangos yma.", "empty_column.lists": "Nid oes gennych unrhyw restrau eto. Pan fyddwch yn creu un, mi fydd yn ymddangos yma.", "empty_column.mutes": "Nid ydych wedi tewi unrhyw ddefnyddwyr eto.", + "empty_column.notification_requests": "Dim i boeni amdano! Does dim byd yma. Pan fyddwch yn derbyn hysbysiadau newydd, byddan nhw'n ymddangos yma yn รดl eich gosodiadau.", "empty_column.notifications": "Nid oes gennych unrhyw hysbysiadau eto. Rhyngweithiwch ag eraill i ddechrau'r sgwrs.", "empty_column.public": "Does dim byd yma! Ysgrifennwch rywbeth cyhoeddus, neu dilynwch ddefnyddwyr o weinyddion eraill i'w lanw", "error.unexpected_crash.explanation": "Oherwydd gwall yn ein cod neu oherwydd problem cysondeb porwr, nid oedd y dudalen hon gallu cael ei dangos yn gywir.", @@ -271,16 +297,28 @@ "filter_modal.select_filter.subtitle": "Defnyddiwch gategori sy'n bodoli eisoes neu crรซu un newydd", "filter_modal.select_filter.title": "Hidlo'r postiad hwn", "filter_modal.title.status": "Hidlo postiad", + "filtered_notifications_banner.mentions": "{count, plural, one {crybwylliad} other {crybwylliad}}", + "filtered_notifications_banner.pending_requests": "Hysbysiadau gan {count, plural, =0 {neb} one {un person} other {# person}} efallai y gwyddoch amdanyn nhw", + "filtered_notifications_banner.title": "Hysbysiadau wedi'u hidlo", "firehose.all": "Popeth", "firehose.local": "Gweinydd hwn", "firehose.remote": "Gweinyddion eraill", "follow_request.authorize": "Awdurdodi", "follow_request.reject": "Gwrthod", "follow_requests.unlocked_explanation": "Er nid yw eich cyfrif wedi'i gloi, roedd y staff {domain} yn meddwl efallai hoffech adolygu ceisiadau dilyn o'r cyfrifau rhain wrth law.", - "follow_suggestions.curated_suggestion": "Dewis y Golygydd", + "follow_suggestions.curated_suggestion": "Dewis staff", "follow_suggestions.dismiss": "Peidio รข dangos hwn eto", + "follow_suggestions.featured_longer": "Wedi'i ddewis รข llaw gan dรฎm {domain}", + "follow_suggestions.friends_of_friends_longer": "Yn boblogaidd ymhlith y bobl rydych chi'n eu dilyn", + "follow_suggestions.hints.featured": "Mae'r proffil hwn wedi'i ddewis yn arbennig gan dรฎm {domain}.", + "follow_suggestions.hints.friends_of_friends": "Mae'r proffil hwn yn boblogaidd ymhlith y bobl rydych chi'n eu dilyn.", + "follow_suggestions.hints.most_followed": "Mae'r proffil hwn yn un o'r rhai sy'n cael ei ddilyn fwyaf ar {domain}.", + "follow_suggestions.hints.most_interactions": "Mae'r proffil hwn wedi bod yn cael llawer o sylw yn ddiweddar ar {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Mae'r proffil hwn yn debyg i'r proffiliau rydych chi wedi'u dilyn yn fwyaf diweddar.", "follow_suggestions.personalized_suggestion": "Awgrym personol", "follow_suggestions.popular_suggestion": "Awgrym poblogaidd", + "follow_suggestions.popular_suggestion_longer": "Yn boblogaidd ar {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Yn debyg i broffiliau y gwnaethoch chi eu dilyn yn ddiweddar", "follow_suggestions.view_all": "Gweld y cyfan", "follow_suggestions.who_to_follow": "Pwy i ddilyn", "followed_tags": "Hashnodau rydych yn eu dilyn", @@ -309,7 +347,6 @@ "hashtag.follow": "Dilyn hashnod", "hashtag.unfollow": "Dad-ddilyn hashnod", "hashtags.and_other": "โ€ฆa {count, plural, other {# more}}", - "home.column_settings.basic": "Syml", "home.column_settings.show_reblogs": "Dangos hybiau", "home.column_settings.show_replies": "Dangos atebion", "home.hide_announcements": "Cuddio cyhoeddiadau", @@ -395,9 +432,15 @@ "loading_indicator.label": "Yn llwythoโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}", "moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.", - "mute_modal.duration": "Hyd", - "mute_modal.hide_notifications": "Cuddio hysbysiadau gan y defnyddiwr hwn?", - "mute_modal.indefinite": "Parhaus", + "mute_modal.hide_from_notifications": "Cuddio rhag hysbysiadau", + "mute_modal.hide_options": "Cuddio'r dewis", + "mute_modal.indefinite": "Nes i mi eu dad-dewi", + "mute_modal.show_options": "Dangos y dewis", + "mute_modal.they_can_mention_and_follow": "Gallan nhw eich crybwyll a'ch dilyn, ond fyddwch chi ddim yn eu gweld.", + "mute_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu tawelu.", + "mute_modal.title": "Tewi defnyddiwr?", + "mute_modal.you_wont_see_mentions": "Welwch chi ddim postiadau sy'n sรดn amdanyn nhw.", + "mute_modal.you_wont_see_posts": "Gallan nhw weld eich postiadau o hyd, ond fyddwch chi ddim yn gweld eu rhai hwy.", "navigation_bar.about": "Ynghylch", "navigation_bar.advanced_interface": "Agor mewn rhyngwyneb gwe uwch", "navigation_bar.blocks": "Defnyddwyr wedi eu blocio", @@ -430,11 +473,29 @@ "notification.follow": "Dilynodd {name} chi", "notification.follow_request": "Mae {name} wedi gwneud cais i'ch dilyn", "notification.mention": "Crybwyllodd {name} amdanoch chi", + "notification.moderation-warning.learn_more": "Dysgu mwy", + "notification.moderation_warning": "Rydych wedi derbyn rhybudd gan gymedrolwr", + "notification.moderation_warning.action_delete_statuses": "Mae rhai o'ch postiadau wedi'u dileu.", + "notification.moderation_warning.action_disable": "Mae eich cyfrif wedi'i analluogi.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Mae rhai o'ch postiadau wedi'u marcio'n sensitif.", + "notification.moderation_warning.action_none": "Mae eich cyfrif wedi derbyn rhybudd cymedroli.", + "notification.moderation_warning.action_sensitive": "Bydd eich postiadau'n cael eu marcio'n sensitif o hyn ymlaen.", + "notification.moderation_warning.action_silence": "Mae eich cyfrif wedi'i gyfyngu.", + "notification.moderation_warning.action_suspend": "Mae eich cyfrif wedi'i hatal.", "notification.own_poll": "Mae eich pleidlais wedi dod i ben", "notification.poll": "Mae pleidlais rydych wedi pleidleisio ynddi wedi dod i ben", "notification.reblog": "Hybodd {name} eich post", + "notification.relationships_severance_event": "Wedi colli cysylltiad รข {name}", + "notification.relationships_severance_event.account_suspension": "Mae gweinyddwr o {from} wedi atal {target}, sy'n golygu na allwch dderbyn diweddariadau ganddynt mwyach na rhyngweithio รข nhw.", + "notification.relationships_severance_event.domain_block": "Mae gweinyddwr o {from} wedi rhwystro {target}, gan gynnwys {followersCount} o'ch dilynwyr a {followingCount, plural, one {# cyfrif} other {# cyfrif}} arall rydych chi'n ei ddilyn.", + "notification.relationships_severance_event.learn_more": "Dysgu mwy", + "notification.relationships_severance_event.user_domain_block": "Rydych wedi rhwystro {target}, gan ddileu {followersCount} o'ch dilynwyr a {followingCount, plural, one {# cyfrif} other {#cyfrifon}} arall rydych yn ei ddilyn.", "notification.status": "{name} newydd ei bostio", "notification.update": "Golygodd {name} bostiad", + "notification_requests.accept": "Derbyn", + "notification_requests.dismiss": "Cau", + "notification_requests.notifications_from": "Hysbysiadau gan {name}", + "notification_requests.title": "Hysbysiadau wedi'u hidlo", "notifications.clear": "Clirio hysbysiadau", "notifications.clear_confirmation": "Ydych chi'n siลตr eich bod am glirio'ch holl hysbysiadau am byth?", "notifications.column_settings.admin.report": "Adroddiadau newydd:", @@ -443,7 +504,6 @@ "notifications.column_settings.favourite": "Ffefrynnau:", "notifications.column_settings.filter_bar.advanced": "Dangos pob categori", "notifications.column_settings.filter_bar.category": "Bar hidlo cyflym", - "notifications.column_settings.filter_bar.show_bar": "Dangos y bar hidlo", "notifications.column_settings.follow": "Dilynwyr newydd:", "notifications.column_settings.follow_request": "Ceisiadau dilyn newydd:", "notifications.column_settings.mention": "Crybwylliadau:", @@ -469,6 +529,15 @@ "notifications.permission_denied": "Nid oes hysbysiadau bwrdd gwaith ar gael oherwydd cais am ganiatรขd porwr a wrthodwyd yn flaenorol", "notifications.permission_denied_alert": "Nid oes modd galluogi hysbysiadau bwrdd gwaith, gan fod caniatรขd porwr wedi'i wrthod o'r blaen", "notifications.permission_required": "Nid oes hysbysiadau bwrdd gwaith ar gael oherwydd na roddwyd y caniatรขd gofynnol.", + "notifications.policy.filter_new_accounts.hint": "Crรซwyd o fewn {days, lluosog, un {yr un diwrnod} arall {y # diwrnod}} diwethaf", + "notifications.policy.filter_new_accounts_title": "Cyfrifon newydd", + "notifications.policy.filter_not_followers_hint": "Gan gynnwys pobl sydd wedi bod yn eich dilyn am llai {days, plural, un {nag un diwrnod} arall {na # diwrnod}}", + "notifications.policy.filter_not_followers_title": "Pobl sydd ddim yn eich dilyn", + "notifications.policy.filter_not_following_hint": "Hyd nes i chi eu cymeradwyo รข llaw", + "notifications.policy.filter_not_following_title": "Pobl nad ydych yn eu dilyn", + "notifications.policy.filter_private_mentions_hint": "Wedi'i hidlo oni bai ei fod mewn ymateb i'ch crybwylliad eich hun neu os ydych yn dilyn yr anfonwr", + "notifications.policy.filter_private_mentions_title": "Crybwylliadau preifat digymell", + "notifications.policy.title": "Hidlo hysbysiadau ganโ€ฆ", "notifications_permission_banner.enable": "Galluogi hysbysiadau bwrdd gwaith", "notifications_permission_banner.how_to_control": "I dderbyn hysbysiadau pan nad yw Mastodon ar agor, galluogwch hysbysiadau bwrdd gwaith. Gallwch reoli'n union pa fathau o ryngweithiadau sy'n cynhyrchu hysbysiadau bwrdd gwaith trwy'r botwm {icon} uchod unwaith y byddan nhw wedi'u galluogi.", "notifications_permission_banner.title": "Peidiwch รข cholli dim", @@ -625,13 +694,10 @@ "server_banner.about_active_users": "Pobl sy'n defnyddio'r gweinydd hwn yn ystod y 30 diwrnod diwethaf (Defnyddwyr Gweithredol Misol)", "server_banner.active_users": "defnyddwyr gweithredol", "server_banner.administered_by": "Gweinyddir gan:", - "server_banner.introduction": "Mae {domain} yn rhan o'r rhwydwaith cymdeithasol datganoledig sy'n cael ei bweru gan {mastodon}.", - "server_banner.learn_more": "Dysgu mwy", "server_banner.server_stats": "Ystadegau'r gweinydd:", "sign_in_banner.create_account": "Creu cyfrif", "sign_in_banner.sign_in": "Mewngofnodi", "sign_in_banner.sso_redirect": "Mewngofnodi neu Gofrestru", - "sign_in_banner.text": "Mewngofnodwch i ddilyn proffiliau neu hashnodau, ffefrynnau, rhannu ac ymateb i bostiadau. Gallwch hefyd ryngweithio o'ch cyfrif ar weinyddion gwahanol.", "status.admin_account": "Agor rhyngwyneb cymedroli ar gyfer @{name}", "status.admin_domain": "Agor rhyngwyneb cymedroli {domain}", "status.admin_status": "Agor y postiad hwn yn y rhyngwyneb cymedroli", @@ -645,10 +711,11 @@ "status.direct": "Crybwyll yn breifat @{name}", "status.direct_indicator": "Crybwyll preifat", "status.edit": "Golygu", - "status.edited": "Golygwyd {date}", + "status.edited": "Golygwyd ddiwethaf {date}", "status.edited_x_times": "Golygwyd {count, plural, one {count} two {count} other {{count} gwaith}}", "status.embed": "Mewnblannu", "status.favourite": "Hoffi", + "status.favourites": "{count, plural, one {ffefryn} other {ffefryn}}", "status.filter": "Hidlo'r postiad hwn", "status.filtered": "Wedi'i hidlo", "status.hide": "Cuddio'r postiad", @@ -669,6 +736,7 @@ "status.reblog": "Hybu", "status.reblog_private": "Hybu i'r gynulleidfa wreiddiol", "status.reblogged_by": "Hybodd {name}", + "status.reblogs": "{count, plural, one {hwb} other {hwb}}", "status.reblogs.empty": "Does neb wedi hybio'r post yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.", "status.redraft": "Dileu ac ailddrafftio", "status.remove_bookmark": "Tynnu nod tudalen", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index 548421b3c0..5ac7128a37 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -89,6 +89,14 @@ "announcement.announcement": "Bekendtgรธrelse", "attachments_list.unprocessed": "(ubehandlet)", "audio.hide": "Skjul lyd", + "block_modal.remote_users_caveat": "Serveren {domain} vil blive bedt om at respektere din beslutning. Overholdelse er dog ikke garanteret, da nogle servere kan hรฅndtere blokke forskelligt. Offentlige indlรฆg kan stadig vรฆre synlige for ikke-indloggede brugere.", + "block_modal.show_less": "Vis mindre", + "block_modal.show_more": "Vis flere", + "block_modal.they_cant_mention": "Vedkommende kan ikke nรฆvne eller fรธlge dig.", + "block_modal.they_cant_see_posts": "Vedkommende kan ikke se dine indlรฆg, og du vil ikke se vedkommendes.", + "block_modal.they_will_know": "Vedkommende kan se den aktive blokering.", + "block_modal.title": "Blokรฉr bruger?", + "block_modal.you_wont_see_mentions": "Du vil ikke se indlรฆg, som nรฆvner vedkommende.", "boost_modal.combo": "Du kan trykke {combo} for at springe dette over nรฆste gang", "bundle_column_error.copy_stacktrace": "Kopiรฉr fejlrapport", "bundle_column_error.error.body": "Den anmodede side kunne ikke gengives. Dette kan skyldes flere typer fejl.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Tilfรธj indholdsadvarsel", "compose_form.spoiler_placeholder": "Indholdsadvarsel (valgfri)", "confirmation_modal.cancel": "Afbryd", - "confirmations.block.block_and_report": "Blokรฉr og Anmeld", "confirmations.block.confirm": "Blokรฉr", - "confirmations.block.message": "Er du sikker pรฅ, at du vil blokere {name}?", "confirmations.cancel_follow_request.confirm": "Annullรฉr anmodning", "confirmations.cancel_follow_request.message": "Er du sikker pรฅ, at anmodningen om at fรธlge {name} skal annulleres?", "confirmations.delete.confirm": "Slet", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Er du sikker pรฅ, at du vil slette denne liste permanent?", "confirmations.discard_edit_media.confirm": "Kassรฉr", "confirmations.discard_edit_media.message": "Der er ugemte รฆndringer i mediebeskrivelsen eller forhรฅndsvisningen, kassรฉr dem alligevel?", - "confirmations.domain_block.confirm": "Blokรฉr hele domรฆnet", + "confirmations.domain_block.confirm": "Blokรฉr server", "confirmations.domain_block.message": "Er du fuldstรฆndig sikker pรฅ, at du vil blokere hele {domain}-domรฆnet? Oftest vil nogle fรฅ mรฅlrettede blokeringer eller skjulninger vรฆre tilstrรฆkkelige og at foretrรฆkke. Du vil ikke se indhold fra dette domรฆne i nogle offentlige tidslinjer eller i dine notifikationer, og dine fรธlgere herfra fjernes ligeledes.", "confirmations.edit.confirm": "Redigรฉr", "confirmations.edit.message": "Redigeres nu, overskrive den besked, der forfattes pt. Fortsรฆt alligevel?", "confirmations.logout.confirm": "Log ud", "confirmations.logout.message": "Er du sikker pรฅ, at du vil logge ud?", "confirmations.mute.confirm": "Skjul (mute)", - "confirmations.mute.explanation": "Dette skjuler indlรฆg fra (og om) dem, men lader dem fortsat se dine indlรฆg og fรธlge dig.", - "confirmations.mute.message": "Er du sikker pรฅ, at du vil skjule {name}?", "confirmations.redraft.confirm": "Slet og omformulรฉr", "confirmations.redraft.message": "Sikker pรฅ, at dette indlรฆg skal slettes og omskrives? Favoritter og boosts gรฅr tabt, og svar til det oprindelige indlรฆg mister tilknytningen.", "confirmations.reply.confirm": "Svar", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Disse indlรฆg fra diverse sociale netvรฆrk vinder fodfรฆste i dag. Nyere indlรฆg med flere boosts og favoritter rangeres hรธjere.", "dismissable_banner.explore_tags": "Disse hashtages vinder lige nu fodfรฆste blandt folk pรฅ denne og andre servere i det decentraliserede netvรฆrk.", "dismissable_banner.public_timeline": "Dette er de seneste offentlige indlรฆg fra folk pรฅ det sociale netvรฆrk, som folk pรฅ {domain} fรธlger.", + "domain_block_modal.block": "Blokรฉr server", + "domain_block_modal.block_account_instead": "Blokรฉr i stedet @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Folk fra denne server kan interagere med de gamle indlรฆg.", + "domain_block_modal.they_cant_follow": "Ingen fra denne server kan fรธlge dig.", + "domain_block_modal.they_wont_know": "Vedkommende ser ikke den aktive blokering.", + "domain_block_modal.title": "Blokรฉr domรฆne?", + "domain_block_modal.you_will_lose_followers": "Alle fรธlgerne fra denne server fjernes.", + "domain_block_modal.you_wont_see_posts": "Indlรฆg eller notifikationer fra brugere pรฅ denne server vises ikke.", + "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": "Vedkommendes handle:", + "domain_pill.their_server": "Det digitale hjem, hvor alle indlรฆggene findes.", + "domain_pill.their_username": "Entydig identifikator pรฅ denne server. Det er muligt at finde brugere med samme brugernavn pรฅ forskellige servere.", + "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 .", + "domain_pill.who_you_are": "Da et handle fortรฆller, hvem man er, og hvor man er, kan man interagere med folk pรฅ tvรฆrs af det sociale net af .", + "domain_pill.your_handle": "Dit handle:", + "domain_pill.your_server": "Dit digitale hjem, hvor alle dine indlรฆg lever. Synes ikke om denne? Overfรธr til enhver tid servere samt tilhรฆngere ogsรฅ.", + "domain_pill.your_username": "Din entydige identifikator pรฅ denne server. Det er muligt at finde brugere med samme brugernavn pรฅ forskellige servere.", "embed.instructions": "Indlejr dette indlรฆg pรฅ dit websted ved at kopiere nedenstรฅende kode.", "embed.preview": "Sรฅdan kommer det til at se ud:", "emoji_button.activity": "Aktivitet", @@ -241,6 +266,7 @@ "empty_column.list": "Der er ikke noget pรฅ denne liste endnu. Nรฅr medlemmer af listen udgiver nye indlรฆg vil de fremgรฅ hรฉr.", "empty_column.lists": "Du har endnu ingen lister. Nรฅr du opretter รฉn, vil den fremgรฅ hรฉr.", "empty_column.mutes": "Du har endnu ikke skjult (muted) nogle brugere.", + "empty_column.notification_requests": "Alt er klar! Der er intet her. Nรฅr der modtages nye notifikationer, fremgรฅr de her jf. dine indstillinger.", "empty_column.notifications": "Du har endnu ingen notifikationer. Nรฅr andre interagerer med dig, vil det fremgรฅ hรฉr.", "empty_column.public": "Der er intet hรฉr! Skriv noget offentligt eller fรธlg manuelt brugere fra andre servere for at se indhold", "error.unexpected_crash.explanation": "Grundet en fejl i vores kode, eller en browser-kompatibilitetsfejl, kunne siden ikke vises korrekt.", @@ -271,15 +297,28 @@ "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", "firehose.local": "Denne server", "firehose.remote": "Andre servere", "follow_request.authorize": "Godkend", "follow_request.reject": "Afvis", "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}.", + "follow_suggestions.hints.most_interactions": "Denne profil har for nylig fรฅet stor opmรฆrksomhed pรฅ {domain}.", + "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", @@ -308,7 +347,6 @@ "hashtag.follow": "Fรธlg hashtag", "hashtag.unfollow": "Stop med at fรธlge hashtag", "hashtags.and_other": "โ€ฆog {count, plural, one {}other {# flere}}", - "home.column_settings.basic": "Grundlรฆggende", "home.column_settings.show_reblogs": "Vis boosts", "home.column_settings.show_replies": "Vis svar", "home.hide_announcements": "Skjul bekendtgรธrelser", @@ -376,6 +414,8 @@ "limited_account_hint.action": "Vis profil alligevel", "limited_account_hint.title": "Denne profil er blevet skjult af {domain}-moderatorerne.", "link_preview.author": "Af {name}", + "link_preview.more_from_author": "Mere fra {name}", + "link_preview.shares": "{count, plural, one {{counter} indlรฆg} other {{counter} indlรฆg}}", "lists.account.add": "Fรธj til liste", "lists.account.remove": "Fjern fra liste", "lists.delete": "Slet liste", @@ -394,9 +434,15 @@ "loading_indicator.label": "Indlรฆserโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Skjul billede} other {Skjul billeder}}", "moved_to_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret, da du flyttede til {movedToAccount}.", - "mute_modal.duration": "Varighed", - "mute_modal.hide_notifications": "Skjul notifikationer fra denne bruger?", - "mute_modal.indefinite": "Tidsubegrรฆnset", + "mute_modal.hide_from_notifications": "Skjul fra notifikationer", + "mute_modal.hide_options": "Skjul valgmuligheder", + "mute_modal.indefinite": "Indtil jeg fjerner tavsgรธrelsen", + "mute_modal.show_options": "Vis valgmuligheder", + "mute_modal.they_can_mention_and_follow": "Vedkommende kan nรฆvne og fรธlge dig, men vil ikke blive vist.", + "mute_modal.they_wont_know": "Vedkommende ser ikke den aktive tavsgรธrelse.", + "mute_modal.title": "Tavsgรธr bruger?", + "mute_modal.you_wont_see_mentions": "Indlรฆg, som nรฆvner vedkommende, vises ikke.", + "mute_modal.you_wont_see_posts": "Vedkommende kan stadig se dine indlรฆg, med vedkommendes vise ikke.", "navigation_bar.about": "Om", "navigation_bar.advanced_interface": "ร…bn i avanceret webgrรฆnseflade", "navigation_bar.blocks": "Blokerede brugere", @@ -429,11 +475,29 @@ "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", + "notification_requests.dismiss": "Afvis", + "notification_requests.notifications_from": "Notifikationer fra {name}", + "notification_requests.title": "Filtrerede notifikationer", "notifications.clear": "Ryd notifikationer", "notifications.clear_confirmation": "Er du sikker pรฅ, at du vil rydde alle dine notifikationer permanent?", "notifications.column_settings.admin.report": "Nye anmeldelser:", @@ -441,8 +505,7 @@ "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": "Hurtigfilterbjรฆlke", - "notifications.column_settings.filter_bar.show_bar": "Vis filterbjรฆlke", + "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:", @@ -468,6 +531,15 @@ "notifications.permission_denied": "Computernotifikationer er utilgรฆngelige grundet tidligere afvist browsertilladelsesanmodning", "notifications.permission_denied_alert": "Computernotifikationer kan ikke aktiveres, da browsertilladelse tidligere blev nรฆgtet", "notifications.permission_required": "Computernotifikationer er utilgรฆngelige, da den krรฆvede tilladelse ikke er tildelt.", + "notifications.policy.filter_new_accounts.hint": "Oprettet indenfor {days, plural, one {den seneste dag} other {de seneste # dage}}", + "notifications.policy.filter_new_accounts_title": "Ny konti", + "notifications.policy.filter_not_followers_hint": "Inklusiv personer, som har fulgt dig {days, plural, one {mindre end รฉn dag} other {fรฆrre end # dage}}", + "notifications.policy.filter_not_followers_title": "Folk, som ikke fรธlger dig", + "notifications.policy.filter_not_following_hint": "Indtil de manuelt godkendes", + "notifications.policy.filter_not_following_title": "Folk, du ikke fรธlger", + "notifications.policy.filter_private_mentions_hint": "Filtreret, medmindre det er i svar pรฅ egen omtale, eller hvis afsenderen fรธlges", + "notifications.policy.filter_private_mentions_title": "Uopfordrede private omtaler", + "notifications.policy.title": "Bortfiltrรฉr notifikationer fraโ€ฆ", "notifications_permission_banner.enable": "Aktivรฉr computernotifikationer", "notifications_permission_banner.how_to_control": "Aktivรฉr computernotifikationer for at fรฅ besked, nรฅr Mastodon ikke er รฅben. Nรฅr de er aktiveret, kan man via knappen {icon} ovenfor prรฆcist styre, hvilke typer af interaktioner, som genererer computernotifikationer.", "notifications_permission_banner.title": "Gรฅ aldrig glip af noget", @@ -624,13 +696,10 @@ "server_banner.about_active_users": "Folk, som brugte denne server de seneste 30 dage (mรฅnedlige aktive brugere)", "server_banner.active_users": "aktive brugere", "server_banner.administered_by": "Hรฅndteres af:", - "server_banner.introduction": "{domain} er en del af det decentraliserede, sociale netvรฆrk drevet af {mastodon}.", - "server_banner.learn_more": "Lรฆs mere", "server_banner.server_stats": "Serverstatstik:", "sign_in_banner.create_account": "Opret konto", "sign_in_banner.sign_in": "Log ind", "sign_in_banner.sso_redirect": "Log ind eller Tilmeld", - "sign_in_banner.text": "Log ind for at fรธlge profiler eller hashtags, markere som favorit, dele og besvare indlรฆg eller interagere fra din konto pรฅ en anden server.", "status.admin_account": "ร…bn modereringsbrugerflade for @{name}", "status.admin_domain": "ร…bn modereringsbrugerflade for {domain}", "status.admin_status": "ร…bn dette indlรฆg i modereringsbrugerfladen", @@ -644,10 +713,11 @@ "status.direct": "Privat omtale @{name}", "status.direct_indicator": "Privat omtale", "status.edit": "Redigรฉr", - "status.edited": "Redigeret {date}", + "status.edited": "Senest redigeret {date}", "status.edited_x_times": "Redigeret {count, plural, one {{count} gang} other {{count} gange}}", "status.embed": "Indlejr", "status.favourite": "Favorit", + "status.favourites": "{count, plural, one {# favorit} other {# favoritter}}", "status.filter": "Filtrรฉr dette indlรฆg", "status.filtered": "Filtreret", "status.hide": "Skjul indlรฆg", @@ -668,6 +738,7 @@ "status.reblog": "Fremhรฆv", "status.reblog_private": "Boost med oprindelig synlighed", "status.reblogged_by": "{name} fremhรฆvede", + "status.reblogs": "{count, plural, one {# boost} other {# boosts}}", "status.reblogs.empty": "Ingen har endnu fremhรฆvet dette indlรฆg. Nรฅr nogen gรธr, vil det fremgรฅ hรฉr.", "status.redraft": "Slet og omformulรฉr", "status.remove_bookmark": "Fjern bogmรฆrke", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index f29d016b07..86438757a3 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -85,10 +85,18 @@ "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", + "block_modal.remote_users_caveat": "Wir werden den Server {domain} bitten, deine Entscheidung zu respektieren. Allerdings kann nicht garantiert werden, dass sie eingehalten wird, weil einige Server Blockierungen unterschiedlich handhaben kรถnnen. ร–ffentliche Beitrรคge kรถnnen fรผr nicht angemeldete Nutzer*innen weiterhin sichtbar sein.", + "block_modal.show_less": "Weniger anzeigen", + "block_modal.show_more": "Mehr anzeigen", + "block_modal.they_cant_mention": "Das Profil wird dich nicht erwรคhnen oder dir folgen kรถnnen.", + "block_modal.they_cant_see_posts": "Deine Beitrรคge kรถnnen nicht mehr angesehen werden und du wirst deren Beitrรคge nicht mehr sehen.", + "block_modal.they_will_know": "Es wird erkennbar sein, dass dieses Profil blockiert wurde.", + "block_modal.title": "Profil blockieren?", + "block_modal.you_wont_see_mentions": "Du wirst keine Beitrรคge sehen, die dieses Profil erwรคhnen.", "boost_modal.combo": "Mit {combo} wird dieses Fenster beim nรคchsten Mal nicht mehr angezeigt", "bundle_column_error.copy_stacktrace": "Fehlerbericht kopieren", "bundle_column_error.error.body": "Die angeforderte Seite konnte nicht dargestellt werden. Dies kรถnnte auf einen Fehler in unserem Code oder auf ein Browser-Kompatibilitรคtsproblem zurรผckzufรผhren sein.", @@ -151,7 +159,7 @@ "compose_form.poll.single": "Einfachauswahl", "compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben", "compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben", - "compose_form.poll.type": "Stil", + "compose_form.poll.type": "Art", "compose_form.publish": "Verรถffentlichen", "compose_form.publish_form": "Neuer Beitrag", "compose_form.reply": "Antworten", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Inhaltswarnung hinzufรผgen", "compose_form.spoiler_placeholder": "Inhaltswarnung (optional)", "confirmation_modal.cancel": "Abbrechen", - "confirmations.block.block_and_report": "Blockieren und melden", "confirmations.block.confirm": "Blockieren", - "confirmations.block.message": "Mรถchtest du {name} wirklich blockieren?", "confirmations.cancel_follow_request.confirm": "Anfrage zurรผckziehen", "confirmations.cancel_follow_request.message": "Mรถchtest du deine Anfrage, {name} zu folgen, wirklich zurรผckziehen?", "confirmations.delete.confirm": "Lรถschen", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Mรถchtest du diese Liste fรผr immer lรถschen?", "confirmations.discard_edit_media.confirm": "Verwerfen", "confirmations.discard_edit_media.message": "Du hast ร„nderungen an der Medienbeschreibung oder -vorschau vorgenommen, die noch nicht gespeichert sind. Trotzdem verwerfen?", - "confirmations.domain_block.confirm": "Domain blockieren", + "confirmations.domain_block.confirm": "Server blockieren", "confirmations.domain_block.message": "Mรถchtest du die gesamte Domain {domain} wirklich blockieren? In den meisten Fรคllen reichen ein paar gezielte Blockierungen oder Stummschaltungen aus. Du wirst den Inhalt von dieser Domain nicht in irgendwelchen รถffentlichen Timelines oder den Benachrichtigungen finden. Auch deine Follower von dieser Domain werden entfernt.", "confirmations.edit.confirm": "Bearbeiten", "confirmations.edit.message": "Das Bearbeiten รผberschreibt die Nachricht, die du gerade verfasst. Mรถchtest du wirklich fortfahren?", "confirmations.logout.confirm": "Abmelden", "confirmations.logout.message": "Mรถchtest du dich wirklich abmelden?", "confirmations.mute.confirm": "Stummschalten", - "confirmations.mute.explanation": "Dies wird Beitrรคge von dieser Person und Beitrรคge, die diese Person erwรคhnen, ausblenden, aber es wird der Person trotzdem erlauben, deine Beitrรคge zu sehen und dir zu folgen.", - "confirmations.mute.message": "Mรถchtest du {name} wirklich stummschalten?", "confirmations.redraft.confirm": "Lรถschen und neu erstellen", "confirmations.redraft.message": "Mรถchtest du diesen Beitrag wirklich lรถschen und neu verfassen? Favoriten und geteilte Beitrรคge gehen verloren, und Antworten auf den ursprรผnglichen Beitrag verlieren den Zusammenhang.", "confirmations.reply.confirm": "Antworten", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Diese Beitrรคge stammen aus dem gesamten sozialen Netzwerk und gewinnen derzeit an Reichweite. Neuere Beitrรคge, die hรคufiger geteilt und favorisiert wurden, werden hรถher eingestuft.", "dismissable_banner.explore_tags": "Das sind Hashtags, die derzeit an Reichweite gewinnen. Hashtags, die von vielen verschiedenen Profilen verwendet werden, werden hรถher eingestuft.", "dismissable_banner.public_timeline": "Das sind die neuesten รถffentlichen Beitrรคge von Profilen im sozialen Netzwerk, denen Leute auf {domain} folgen.", + "domain_block_modal.block": "Server blockieren", + "domain_block_modal.block_account_instead": "Stattdessen @{name} blockieren", + "domain_block_modal.they_can_interact_with_old_posts": "Profile von diesem Server werden mit deinen รคlteren Beitrรคgen interagieren kรถnnen.", + "domain_block_modal.they_cant_follow": "Niemand von diesem Server wird dir folgen kรถnnen.", + "domain_block_modal.they_wont_know": "Es wird nicht erkennbar sein, dass diese Domain blockiert wurde.", + "domain_block_modal.title": "Domain blockieren?", + "domain_block_modal.you_will_lose_followers": "Alle Follower von diesem Server werden entfernt.", + "domain_block_modal.you_wont_see_posts": "Du wirst keine Beitrรคge oder Benachrichtigungen von Profilen auf diesem Server sehen.", + "domain_pill.activitypub_lets_connect": "Somit kannst du dich nicht nur auf Mastodon mit Leuten verbinden und mit ihnen interagieren, sondern รผber alle sozialen Apps hinweg.", + "domain_pill.activitypub_like_language": "ActivityPub ist sozusagen die Sprache, die Mastodon mit anderen sozialen Netzwerken spricht.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Deren Adresse:", + "domain_pill.their_server": "Deren digitales Zuhause. Hier โ€žlebenโ€œ alle Beitrรคge von diesem Profil.", + "domain_pill.their_username": "Deren eindeutigen Identitรคt auf dem betreffenden Server. Es ist mรถglich, Profile mit dem gleichen Profilnamen auf verschiedenen Servern zu finden.", + "domain_pill.username": "Profilname", + "domain_pill.whats_in_a_handle": "Was ist Teil der Adresse?", + "domain_pill.who_they_are": "Adressen teilen mit, wer jemand ist und wo sich jemand aufhรคlt. Daher kannst du mit Leuten im gesamten Social Web interagieren, wenn es eine durch ist.", + "domain_pill.who_you_are": "Deine Adresse teilt mit, wer du bist und wo du dich aufhรคltst. Daher kรถnnen andere Leute im gesamten Social Web mit dir interagieren, wenn es eine durch ist.", + "domain_pill.your_handle": "Deine Adresse:", + "domain_pill.your_server": "Dein digitales Zuhause. Hier โ€žlebenโ€œ alle Beitrรคge von dir. Dir gefรคllt es hier nicht? Du kannst jederzeit den Server wechseln und ebenso deine Follower รผbertragen.", + "domain_pill.your_username": "Deine eindeutige Identitรคt auf diesem Server. Es ist mรถglich, Profile mit dem gleichen Profilnamen auf verschiedenen Servern zu finden.", "embed.instructions": "Du kannst diesen Beitrag auรŸerhalb des Fediverse (z. B. auf deiner Website) einbetten, indem du diesen iFrame-Code einfรผgst.", "embed.preview": "Vorschau:", "emoji_button.activity": "Aktivitรคten", @@ -241,6 +266,7 @@ "empty_column.list": "Diese Liste ist derzeit leer. Wenn Konten auf dieser Liste neue Beitrรคge verรถffentlichen, werden sie hier erscheinen.", "empty_column.lists": "Du hast noch keine Listen. Sobald du eine anlegst, wird sie hier erscheinen.", "empty_column.mutes": "Du hast keine Profile stummgeschaltet.", + "empty_column.notification_requests": "Alles klar! Hier gibt es nichts. Wenn Sie neue Mitteilungen erhalten, werden diese entsprechend Ihren Einstellungen hier angezeigt.", "empty_column.notifications": "Du hast noch keine Benachrichtigungen. Sobald andere Personen mit dir interagieren, wirst du hier darรผber informiert.", "empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas รถffentlich oder folge Profilen von anderen Servern, um die Timeline aufzufรผllen", "error.unexpected_crash.explanation": "Wegen eines Fehlers in unserem Code oder aufgrund einer Browser-Inkompatibilitรคt kann diese Seite nicht korrekt angezeigt werden.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Dieser Server", "firehose.remote": "Andere Server", "follow_request.authorize": "Genehmigen", "follow_request.reject": "Ablehnen", "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": "Auswahl des Herausgebers", + "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}.", + "follow_suggestions.hints.most_interactions": "Dieses Profil erhielt auf {domain} in letzter Zeit viel Aufmerksamkeit.", + "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", @@ -293,7 +331,7 @@ "footer.source_code": "Quellcode anzeigen", "footer.status": "Status", "generic.saved": "Gespeichert", - "getting_started.heading": "Auf gehtโ€™s!", + "getting_started.heading": "Auf gehts!", "hashtag.column_header.tag_mode.all": "und {additional}", "hashtag.column_header.tag_mode.any": "oder {additional}", "hashtag.column_header.tag_mode.none": "ohne {additional}", @@ -309,7 +347,6 @@ "hashtag.follow": "Hashtag folgen", "hashtag.unfollow": "Hashtag entfolgen", "hashtags.and_other": "โ€ฆย und {count, plural, one{# weiterer} other {# weitere}}", - "home.column_settings.basic": "Allgemein", "home.column_settings.show_reblogs": "Geteilte Beitrรคge anzeigen", "home.column_settings.show_replies": "Antworten anzeigen", "home.hide_announcements": "Ankรผndigungen ausblenden", @@ -363,7 +400,7 @@ "keyboard_shortcuts.requests": "Liste der Follower-Anfragen aufrufen", "keyboard_shortcuts.search": "Suchleiste fokussieren", "keyboard_shortcuts.spoilers": "Feld fรผr Inhaltswarnung anzeigen/ausblenden", - "keyboard_shortcuts.start": "โ€žAuf gehtโ€™s!โ€œ รถffnen", + "keyboard_shortcuts.start": "โ€žAuf gehts!โ€œ รถffnen", "keyboard_shortcuts.toggle_hidden": "Beitragstext hinter der Inhaltswarnung anzeigen/ausblenden", "keyboard_shortcuts.toggle_sensitivity": "Medien anzeigen/ausblenden", "keyboard_shortcuts.toot": "Neuen Beitrag erstellen", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Profil trotzdem anzeigen", "limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen von {domain} ausgeblendet.", "link_preview.author": "Von {name}", + "link_preview.more_from_author": "Mehr von {name}", + "link_preview.shares": "{count, plural, one {{counter} Beitrag} other {{counter} Beitrรคge}}", "lists.account.add": "Zur Liste hinzufรผgen", "lists.account.remove": "Von der Liste entfernen", "lists.delete": "Liste lรถschen", @@ -395,9 +434,15 @@ "loading_indicator.label": "Wird geladenย โ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Medium ausblenden} other {Medien ausblenden}}", "moved_to_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert, weil du zu {movedToAccount} umgezogen bist.", - "mute_modal.duration": "Dauer", - "mute_modal.hide_notifications": "Benachrichtigungen dieses Profils ausblenden?", - "mute_modal.indefinite": "Unbegrenzt", + "mute_modal.hide_from_notifications": "Benachrichtigungen ausblenden", + "mute_modal.hide_options": "Einstellungen ausblenden", + "mute_modal.indefinite": "Bis ich die Stummschaltung aufhebe", + "mute_modal.show_options": "Einstellungen anzeigen", + "mute_modal.they_can_mention_and_follow": "Das Profil wird dich weiterhin erwรคhnen und dir folgen kรถnnen, aber du wirst davon nichts sehen.", + "mute_modal.they_wont_know": "Es wird nicht erkennbar sein, dass dieses Profil stummgeschaltet wurde.", + "mute_modal.title": "Profil stummschalten?", + "mute_modal.you_wont_see_mentions": "Du wirst keine Beitrรคge sehen, die dieses Profil erwรคhnen.", + "mute_modal.you_wont_see_posts": "Deine Beitrรคge kรถnnen weiterhin angesehen werden, aber du wirst deren Beitrรคge nicht mehr sehen.", "navigation_bar.about": "รœber", "navigation_bar.advanced_interface": "Im erweiterten Webinterface รถffnen", "navigation_bar.blocks": "Blockierte Profile", @@ -430,11 +475,29 @@ "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.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", + "notification_requests.dismiss": "Ablehnen", + "notification_requests.notifications_from": "Benachrichtigungen von {name}", + "notification_requests.title": "Gefilterte Benachrichtigungen", "notifications.clear": "Benachrichtigungen lรถschen", "notifications.clear_confirmation": "Mรถchtest du wirklich alle Benachrichtigungen fรผr immer lรถschen?", "notifications.column_settings.admin.report": "Neue Meldungen:", @@ -442,8 +505,7 @@ "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.filter_bar.show_bar": "Filterleiste 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:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Desktop-Benachrichtigungen kรถnnen aufgrund einer zuvor verweigerten Berechtigung nicht aktiviert werden", "notifications.permission_denied_alert": "Desktop-Benachrichtigungen kรถnnen nicht aktiviert werden, da die Browser-Berechtigung zuvor verweigert wurde", "notifications.permission_required": "Desktop-Benachrichtigungen sind nicht verfรผgbar, da die erforderliche Berechtigung nicht erteilt wurde.", + "notifications.policy.filter_new_accounts.hint": "Innerhalb {days, plural, one {des letzten Tages} other {der letzten # Tagen}} erstellt", + "notifications.policy.filter_new_accounts_title": "Neuen Konten", + "notifications.policy.filter_not_followers_hint": "EinschlieรŸlich Profilen, die dir seit weniger als {days, plural, one {einem Tag} other {# Tagen}} folgen", + "notifications.policy.filter_not_followers_title": "Profilen, die mir nicht folgen", + "notifications.policy.filter_not_following_hint": "Solange du sie nicht manuell akzeptierst", + "notifications.policy.filter_not_following_title": "Profilen, denen ich nicht folge", + "notifications.policy.filter_private_mentions_hint": "Solange sie keine Antwort auf deine Erwรคhnung ist oder du dem Profil nicht folgst", + "notifications.policy.filter_private_mentions_title": "Unerwรผnschten privaten Erwรคhnungen", + "notifications.policy.title": "Benachrichtigungen herausfiltern vonย โ€ฆ", "notifications_permission_banner.enable": "Aktiviere Desktop-Benachrichtigungen", "notifications_permission_banner.how_to_control": "Um Benachrichtigungen zu erhalten, wenn Mastodon nicht geรถffnet ist, aktiviere die Desktop-Benachrichtigungen. Du kannst genau bestimmen, welche Arten von Interaktionen Desktop-Benachrichtigungen รผber die {icon} -Taste erzeugen, sobald diese aktiviert sind.", "notifications_permission_banner.title": "Nichts verpassen", @@ -480,11 +551,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", @@ -500,16 +571,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", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Personen, die diesen Server in den vergangenen 30 Tagen verwendet haben (monatlich aktive Nutzer*innen)", "server_banner.active_users": "aktive Profile", "server_banner.administered_by": "Verwaltet von:", - "server_banner.introduction": "{domain} ist Teil eines dezentralisierten sozialen Netzwerks, angetrieben von {mastodon}.", - "server_banner.learn_more": "Mehr erfahren", + "server_banner.is_one_of_many": "{domain} ist einer von vielen unabhรคngigen Mastodon-Servern, mit dem du dich im Fediverse beteiligen kannst.", "server_banner.server_stats": "Serverstatistik:", "sign_in_banner.create_account": "Konto erstellen", + "sign_in_banner.follow_anyone": "Du kannst jedem im Fediverse folgen und alles in chronologischer Reihenfolge sehen. Keine Algorithmen, Werbung oder Clickbaits vorhanden.", + "sign_in_banner.mastodon_is": "Mastodon ist der beste Zugang, um auf dem Laufenden zu bleiben.", "sign_in_banner.sign_in": "Anmelden", "sign_in_banner.sso_redirect": "Anmelden oder registrieren", - "sign_in_banner.text": "Melde dich an, um Profilen oder Hashtags zu folgen, Beitrรคge zu favorisieren, zu teilen und auf sie zu antworten. Du kannst auch von deinem Konto aus auf einem anderen Server interagieren.", "status.admin_account": "@{name} moderieren", "status.admin_domain": "{domain} moderieren", "status.admin_status": "Beitrag moderieren", @@ -645,10 +716,11 @@ "status.direct": "@{name} privat erwรคhnen", "status.direct_indicator": "Private Erwรคhnung", "status.edit": "Beitrag bearbeiten", - "status.edited": "Bearbeitet {date}", + "status.edited": "Zuletzt am {date} bearbeitet", "status.edited_x_times": "{count, plural, one {{count}-mal} other {{count}-mal}} bearbeitet", "status.embed": "Beitrag per iFrame einbetten", "status.favourite": "Favorisieren", + "status.favourites": "{count, plural, one {Mal favorisiert} other {Mal favorisiert}}", "status.filter": "Beitrag filtern", "status.filtered": "Gefiltert", "status.hide": "Beitrag ausblenden", @@ -669,6 +741,7 @@ "status.reblog": "Teilen", "status.reblog_private": "Mit der ursprรผnglichen Zielgruppe teilen", "status.reblogged_by": "{name} teilte", + "status.reblogs": "{count, plural, one {Mal geteilt} other {Mal geteilt}}", "status.reblogs.empty": "Diesen Beitrag hat bisher noch niemand geteilt. Sobald es jemand tut, wird das Profil hier erscheinen.", "status.redraft": "Lรถschen und neu erstellen", "status.remove_bookmark": "Lesezeichen entfernen", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index a5ed320831..47a8df6200 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -154,9 +154,7 @@ "compose_form.spoiler.unmarked": "ฮ ฯฮฟฯƒฮธฮฎฮบฮท ฯ€ฯฮฟฮตฮนฮดฮฟฯ€ฮฟฮฏฮทฯƒฮทฯ‚ ฯ€ฮตฯฮนฮตฯ‡ฮฟฮผฮญฮฝฮฟฯ…", "compose_form.spoiler_placeholder": "ฮ ฯฮฟฮตฮนฮดฮฟฯ€ฮฟฮฏฮทฯƒฮท ฯ€ฮตฯฮนฮตฯ‡ฮฟฮผฮญฮฝฮฟฯ… (ฯ€ฯฮฟฮฑฮนฯฮตฯ„ฮนฮบฮฎ)", "confirmation_modal.cancel": "ฮ†ฮบฯ…ฯฮฟ", - "confirmations.block.block_and_report": "ฮ‘ฯ€ฮฟฮบฮปฮตฮนฯƒฮผฯŒฯ‚ & ฮ‘ฮฝฮฑฯ†ฮฟฯฮฌ", "confirmations.block.confirm": "ฮ‘ฯ€ฮฟฮบฮปฮตฮนฯƒฮผฯŒฯ‚", - "confirmations.block.message": "ฮฃฮฏฮณฮฟฯ…ฯฮฑ ฮธฮตฯ‚ ฮฝฮฑ ฮฑฯ€ฮฟฮบฮปฮตฮฏฯƒฮตฮนฯ‚ {name};", "confirmations.cancel_follow_request.confirm": "ฮ‘ฯ€ฯŒฯƒฯ…ฯฯƒฮท ฮฑฮนฯ„ฮฎฮผฮฑฯ„ฮฟฯ‚", "confirmations.cancel_follow_request.message": "ฮ•ฮฏฯƒฮฑฮน ฯƒฮฏฮณฮฟฯ…ฯฮฟฯ‚/ฮท ฯŒฯ„ฮน ฮธฮญฮปฮตฮนฯ‚ ฮฝฮฑ ฮฑฯ€ฮฟฯƒฯฯฮตฮนฯ‚ ฯ„ฮฟ ฮฑฮฏฯ„ฮทฮผฮฌ ฯƒฮฟฯ… ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ…ฮธฮตฮฏฯ‚ ฯ„ฮฟฮฝ/ฯ„ฮทฮฝ {name};", "confirmations.delete.confirm": "ฮ”ฮนฮฑฮณฯฮฑฯ†ฮฎ", @@ -165,15 +163,12 @@ "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": "ฮ‘ฮฝ ฯ„ฮฟ ฮตฯ€ฮตฮพฮตฯฮณฮฑฯƒฯ„ฮตฮฏฯ‚ ฯ„ฯŽฯฮฑ ฮธฮฑ ฮฑฮฝฯ„ฮนฮบฮฑฯ„ฮฑฯƒฯ„ฮฑฮธฮตฮฏ ฯ„ฮฟ ฮผฮฎฮฝฯ…ฮผฮฑ ฯ€ฮฟฯ… ฯƒฯ…ฮฝฮธฮญฯ„ฮตฮนฯ‚. ฮ•ฮฏฯƒฮฑฮน ฯƒฮฏฮณฮฟฯ…ฯฮฟฯ‚ ฯŒฯ„ฮน ฮธฮญฮปฮตฮนฯ‚ ฮฝฮฑ ฯƒฯ…ฮฝฮตฯ‡ฮฏฯƒฮตฮนฯ‚;", "confirmations.logout.confirm": "ฮ‘ฯ€ฮฟฯƒฯฮฝฮดฮตฯƒฮท", "confirmations.logout.message": "ฮฃฮฏฮณฮฟฯ…ฯฮฑ ฮธฮญฮปฮตฮนฯ‚ ฮฝฮฑ ฮฑฯ€ฮฟฯƒฯ…ฮฝฮดฮตฮธฮตฮฏฯ‚;", "confirmations.mute.confirm": "ฮ‘ฯ€ฮฟฯƒฮนฯŽฯ€ฮทฯƒฮท", - "confirmations.mute.explanation": "ฮ‘ฯ…ฯ„ฯŒ ฮธฮฑ ฮบฯฯฯˆฮตฮน ฯ„ฮนฯ‚ ฮดฮทฮผฮฟฯƒฮนฮตฯฯƒฮตฮนฯ‚ ฯ„ฮฟฯ…ฯ‚ ฮบฮฑฮน ฯ„ฮนฯ‚ ฮดฮทฮผฮฟฯƒฮนฮตฯฯƒฮตฮนฯ‚ ฯ€ฮฟฯ… ฯ„ฮฟฯ…ฯ‚ ฮฑฮฝฮฑฯ†ฮญฯฮฟฯ…ฮฝ, ฮฑฮปฮปฮฌ ฮธฮฑ ฯƒฯ…ฮฝฮตฯ‡ฮฏฯƒฮฟฯ…ฮฝ ฮฝฮฑ ฮผฯ€ฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฒฮปฮญฯ€ฮฟฯ…ฮฝ ฯ„ฮนฯ‚ ฮดฮทฮผฮฟฯƒฮนฮตฯฯƒฮตฮนฯ‚ ฯƒฮฟฯ… ฮบฮฑฮน ฮฝฮฑ ฯƒฮต ฮฑฮบฮฟฮปฮฟฯ…ฮธฮฟฯฮฝ.", - "confirmations.mute.message": "ฮฃฮฏฮณฮฟฯ…ฯฮฑ ฮธฮตฯ‚ ฮฝฮฑ ฮฑฯ€ฮฟฯƒฮนฯ‰ฯ€ฮฎฯƒฮตฮนฯ‚ {name};", "confirmations.redraft.confirm": "ฮ”ฮนฮฑฮณฯฮฑฯ†ฮฎ & ฮพฮฑฮฝฮฑฮณฯฮฌฯˆฮนฮผฮฟ", "confirmations.redraft.message": "ฮฃฮฏฮณฮฟฯ…ฯฮฑ ฮธฮญฮปฮตฮนฯ‚ ฮฝฮฑ ฯƒฮฒฮฎฯƒฮตฮนฯ‚ ฮฑฯ…ฯ„ฮฎ ฯ„ฮทฮฝ ฮฑฮฝฮฌฯฯ„ฮทฯƒฮท ฮบฮฑฮน ฮฝฮฑ ฯ„ฮทฮฝ ฮพฮฑฮฝฮฑฮณฯฮฌฯˆฮตฮนฯ‚; ฮŸฮน ฯ€ฯฮฟฯ„ฮนฮผฮฎฯƒฮตฮนฯ‚ ฮบฮฑฮน ฯ€ฯฮฟฯ‰ฮธฮฎฯƒฮตฮนฯ‚ ฮธฮฑ ฯ‡ฮฑฮธฮฟฯฮฝ ฮบฮฑฮน ฮฟฮน ฮฑฯ€ฮฑฮฝฯ„ฮฎฯƒฮตฮนฯ‚ ฯƒฯ„ฮทฮฝ ฮฑฯฯ‡ฮนฮบฮฎ ฮฑฮฝฮฌฯฯ„ฮทฯƒฮท ฮธฮฑ ฮผฮตฮฏฮฝฮฟฯ…ฮฝ ฮฟฯฯ†ฮฑฮฝฮญฯ‚.", "confirmations.reply.confirm": "ฮ‘ฯ€ฮฌฮฝฯ„ฮทฯƒฮต", @@ -289,7 +284,6 @@ "hashtag.column_settings.tag_toggle": "ฮ ฯฮฟฯƒฮธฮฎฮบฮท ฮตฯ€ฮนฯ€ฮปฮญฮฟฮฝ ฯ„ฮฑฮผฯ€ฮตฮปฯŽฮฝ ฮณฮนฮฑ ฯ„ฮทฮฝ ฮบฮฟฮปฯŽฮฝฮฑ", "hashtag.follow": "ฮ ฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯƒฮท ฮตฯ„ฮนฮบฮญฯ„ฮฑฯ‚", "hashtag.unfollow": "ฮ”ฮนฮฑฮบฮฟฯ€ฮฎ ฯ€ฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯƒฮทฯ‚ ฮตฯ„ฮนฮบฮญฯ„ฮฑฯ‚", - "home.column_settings.basic": "ฮ’ฮฑฯƒฮนฮบฮญฯ‚ ฯฯ…ฮธฮผฮฏฯƒฮตฮนฯ‚", "home.column_settings.show_reblogs": "ฮ•ฮผฯ†ฮฌฮฝฮนฯƒฮท ฯ€ฯฮฟฯ‰ฮธฮฎฯƒฮตฯ‰ฮฝ", "home.column_settings.show_replies": "ฮ•ฮผฯ†ฮฌฮฝฮนฯƒฮท ฮฑฯ€ฮฑฮฝฯ„ฮฎฯƒฮตฯ‰ฮฝ", "home.hide_announcements": "ฮ‘ฯ€ฯŒฮบฯฯ…ฯˆฮท ฮฑฮฝฮฑฮบฮฟฮนฮฝฯŽฯƒฮตฯ‰ฮฝ", @@ -367,9 +361,6 @@ "loading_indicator.label": "ฮฆฯŒฯฯ„ฯ‰ฯƒฮทโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ฮ‘ฯ€ฯŒฮบฯฯ…ฯˆฮท ฮตฮนฮบฯŒฮฝฮฑฯ‚} other {ฮ‘ฯ€ฯŒฮบฯฯ…ฯˆฮท ฮตฮนฮบฯŒฮฝฯ‰ฮฝ}}", "moved_to_account_banner.text": "ฮŸ ฮปฮฟฮณฮฑฯฮนฮฑฯƒฮผฯŒฯ‚ ฯƒฮฟฯ… {disabledAccount} ฮตฮฏฮฝฮฑฮน ฯ€ฯฮฟฯƒฯ‰ฯฮนฮฝฮฌ ฮฑฯ€ฮตฮฝฮตฯฮณฮฟฯ€ฮฟฮนฮทฮผฮญฮฝฮฟฯ‚ ฮตฯ€ฮตฮนฮดฮฎ ฮผฮตฯ„ฮฑฯ†ฮญฯฮธฮทฮบฮตฯ‚ ฯƒฯ„ฮฟฮฝ {movedToAccount}.", - "mute_modal.duration": "ฮ”ฮนฮฌฯฮบฮตฮนฮฑ", - "mute_modal.hide_notifications": "ฮ‘ฯ€ฯŒฮบฯฯ…ฯˆฮท ฮตฮนฮดฮฟฯ€ฮฟฮนฮฎฯƒฮตฯ‰ฮฝ ฮฑฯ…ฯ„ฮฟฯ ฯ„ฮฟฯ… ฯ‡ฯฮฎฯƒฯ„ฮท;", - "mute_modal.indefinite": "ฮ•ฯ€แพฝ ฮฑฯŒฯฮนฯƒฯ„ฮฟฮฝ", "navigation_bar.about": "ฮฃฯ‡ฮตฯ„ฮนฮบฮฌ ฮผฮต", "navigation_bar.blocks": "ฮ‘ฯ€ฮฟฮบฮปฮตฮนฯƒฮผฮญฮฝฮฟฮน ฯ‡ฯฮฎฯƒฯ„ฮตฯ‚", "navigation_bar.bookmarks": "ฮฃฮตฮปฮนฮดฮฟฮดฮตฮฏฮบฯ„ฮตฯ‚", @@ -411,9 +402,6 @@ "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.filter_bar.show_bar": "ฮ•ฮผฯ†ฮฌฮฝฮนฯƒฮท ฮผฯ€ฮฌฯฮฑฯ‚ ฯ†ฮฏฮปฯ„ฯฮฟฯ…", "notifications.column_settings.follow": "ฮฮญฮฟฮน ฮฑฮบฯŒฮปฮฟฯ…ฮธฮฟฮน:", "notifications.column_settings.follow_request": "ฮฮญฮฟ ฮฑฮฏฯ„ฮทฮผฮฑ ฮฑฮบฮฟฮปฮฟฯฮธฮทฯƒฮทฯ‚:", "notifications.column_settings.mention": "ฮ•ฯ€ฮนฯƒฮทฮผฮฌฮฝฯƒฮตฮนฯ‚:", @@ -570,13 +558,10 @@ "server_banner.about_active_users": "ฮ†ฯ„ฮฟฮผฮฑ ฯ€ฮฟฯ… ฯ‡ฯฮทฯƒฮนฮผฮฟฯ€ฮฟฮนฮฟฯฮฝ ฮฑฯ…ฯ„ฯŒฮฝ ฯ„ฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯƒฯ„ฮฎ ฮบฮฑฯ„ฮฌ ฯ„ฮนฯ‚ ฯ„ฮตฮปฮตฯ…ฯ„ฮฑฮฏฮตฯ‚ 30 ฮทฮผฮญฯฮตฯ‚ (ฮœฮทฮฝฮนฮฑฮฏฮฑ ฮ•ฮฝฮตฯฮณฮฟฮฏ ฮงฯฮฎฯƒฯ„ฮตฯ‚)", "server_banner.active_users": "ฮตฮฝฮตฯฮณฮฟฮฏ ฯ‡ฯฮฎฯƒฯ„ฮตฯ‚", "server_banner.administered_by": "ฮ”ฮนฮฑฯ‡ฮตฮนฯฮนฯƒฯ„ฮฎฯ‚:", - "server_banner.introduction": "ฮŸ {domain} ฮตฮฏฮฝฮฑฮน ฮผฮญฯฮฟฯ‚ ฯ„ฮฟฯ… ฮฑฯ€ฮฟฮบฮตฮฝฯ„ฯฯ‰ฮผฮญฮฝฮฟฯ… ฮบฮฟฮนฮฝฯ‰ฮฝฮนฮบฮฟฯ ฮดฮนฮบฯ„ฯฮฟฯ… ฯ€ฮฟฯ… ฯ€ฮฑฯฮญฯ‡ฮตฯ„ฮฑฮน ฮฑฯ€ฯŒ {mastodon}.", - "server_banner.learn_more": "ฮœฮฌฮธฮต ฯ€ฮตฯฮนฯƒฯƒฯŒฯ„ฮตฯฮฑ", "server_banner.server_stats": "ฮฃฯ„ฮฑฯ„ฮนฯƒฯ„ฮนฮบฮฌ ฮดฮนฮฑฮบฮฟฮผฮนฯƒฯ„ฮฎ:", "sign_in_banner.create_account": "ฮ”ฮทฮผฮนฮฟฯ…ฯฮณฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯƒฮผฮฟฯ", "sign_in_banner.sign_in": "ฮฃฯฮฝฮดฮตฯƒฮท", "sign_in_banner.sso_redirect": "ฮฃฯ…ฮฝฮดฮตฮธฮตฮฏฯ„ฮต ฮฎ ฮ•ฮณฮณฯฮฑฯ†ฮตฮฏฯ„ฮต", - "sign_in_banner.text": "ฮฃฯ…ฮฝฮดฮตฮธฮตฮฏฯ„ฮต ฮณฮนฮฑ ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ…ฮธฮฎฯƒฮตฯ„ฮต ฯ€ฯฮฟฯ†ฮฏฮป ฮฎ ฮตฯ„ฮนฮบฮญฯ„ฮตฯ‚, ฮฑฮณฮฑฯ€ฮฎฯƒฯ„ฮต, ฮผฮฟฮนฯฮฑฯƒฯ„ฮตฮฏฯ„ฮต ฮบฮฑฮน ฮฑฯ€ฮฑฮฝฯ„ฮฎฯƒฯ„ฮต ฯƒฮต ฮดฮทฮผฮฟฯƒฮนฮตฯฯƒฮตฮนฯ‚. ฮœฯ€ฮฟฯฮตฮฏฯ„ฮต ฮตฯ€ฮฏฯƒฮทฯ‚ ฮฝฮฑ ฮฑฮปฮปฮทฮปฮตฯ€ฮนฮดฯฮฌฯƒฮตฯ„ฮต ฮฑฯ€ฯŒ ฯ„ฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯƒฮผฯŒ ฯƒฮฑฯ‚ ฯƒฮต ฮดฮนฮฑฯ†ฮฟฯฮตฯ„ฮนฮบฯŒ ฮดฮนฮฑฮบฮฟฮผฮนฯƒฯ„ฮฎ.", "status.admin_account": "ฮ†ฮฝฮฟฮนฮณฮผฮฑ ฮดฮนฮตฯ€ฮฑฯ†ฮฎฯ‚ ฯƒฯ…ฮฝฯ„ฮฟฮฝฮนฯƒฮผฮฟฯ ฮณฮนฮฑ ฯ„ฮฟฮฝ/ฯ„ฮทฮฝ @{name}", "status.admin_domain": "ฮ†ฮฝฮฟฮนฮณฮผฮฑ ฮปฮตฮนฯ„ฮฟฯ…ฯฮณฮฏฮฑฯ‚ ฮดฮนฮฑฮผฮตฯƒฮฟฮปฮฌฮฒฮทฯƒฮทฯ‚ ฮณฮนฮฑ {domain}", "status.admin_status": "ฮ†ฮฝฮฟฮนฮณฮผฮฑ ฮฑฯ…ฯ„ฮฎฯ‚ ฯ„ฮทฯ‚ ฮฑฮฝฮฌฯฯ„ฮทฯƒฮทฯ‚ ฯƒฮต ฮดฮนฮตฯ€ฮฑฯ†ฮฎ ฯƒฯ…ฮฝฯ„ฮฟฮฝฮนฯƒฮผฮฟฯ", @@ -590,7 +575,6 @@ "status.direct": "ฮ™ฮดฮนฯ‰ฯ„ฮนฮบฮฎ ฮตฯ€ฮนฯƒฮฎฮผฮฑฮฝฯƒฮท @{name}", "status.direct_indicator": "ฮ™ฮดฮนฯ‰ฯ„ฮนฮบฮฎ ฮตฯ€ฮนฯƒฮฎฮผฮฑฮฝฯƒฮท", "status.edit": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฑฯƒฮฏฮฑ", - "status.edited": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฌฯƒฯ„ฮทฮบฮต ฯƒฯ„ฮนฯ‚ {date}", "status.edited_x_times": "ฮ•ฯ€ฮตฮพฮตฯฮณฮฌฯƒฯ„ฮทฮบฮต {count, plural, one {{count} ฯ†ฮฟฯฮฌ} other {{count} ฯ†ฮฟฯฮญฯ‚}}", "status.embed": "ฮ•ฮฝฯƒฯ‰ฮผฮฌฯ„ฯ‰ฯƒฮต", "status.favourite": "ฮ‘ฮณฮฑฯ€ฮทฮผฮญฮฝฮฑ", diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 3431d95cb6..108880cc97 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.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Add content warning", "compose_form.spoiler_placeholder": "Content warning (optional)", "confirmation_modal.cancel": "Cancel", - "confirmations.block.block_and_report": "Block & Report", "confirmations.block.confirm": "Block", - "confirmations.block.message": "Are you sure you want to block {name}?", "confirmations.cancel_follow_request.confirm": "Withdraw request", "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?", "confirmations.delete.confirm": "Delete", @@ -171,15 +177,13 @@ "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 entire domain", + "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?", "confirmations.logout.confirm": "Log out", "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", - "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", - "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", "confirmations.reply.confirm": "Reply", @@ -205,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", @@ -241,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.", @@ -271,16 +297,28 @@ "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": "Editors' Choice", + "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}.", + "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.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", @@ -308,8 +346,7 @@ "hashtag.counter_by_uses_today": "{count, plural, one {{counter} post} other {{counter} posts}} today", "hashtag.follow": "Follow hashtag", "hashtag.unfollow": "Unfollow hashtag", - "hashtags.and_other": "โ€ฆand {count, plural, one {}other {# more}}", - "home.column_settings.basic": "Basic", + "hashtags.and_other": "โ€ฆand {count, plural, one {one more} other {# more}}", "home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_replies": "Show replies", "home.hide_announcements": "Hide announcements", @@ -395,9 +432,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.duration": "Duration", - "mute_modal.hide_notifications": "Hide notifications from this user?", - "mute_modal.indefinite": "Indefinite", + "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", @@ -430,11 +473,29 @@ "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": "You 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 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:", @@ -443,7 +504,6 @@ "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.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -469,6 +529,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", @@ -625,13 +694,10 @@ "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.active_users": "active users", "server_banner.administered_by": "Administered by:", - "server_banner.introduction": "{domain} is part of the decentralised social network powered by {mastodon}.", - "server_banner.learn_more": "Learn more", "server_banner.server_stats": "Server stats:", "sign_in_banner.create_account": "Create account", "sign_in_banner.sign_in": "Sign in", "sign_in_banner.sso_redirect": "Login or Register", - "sign_in_banner.text": "Login to follow profiles or hashtags, favourite, share and reply to posts. You can also interact from your account on a different server.", "status.admin_account": "Open moderation interface for @{name}", "status.admin_domain": "Open moderation interface for {domain}", "status.admin_status": "Open this post in the moderation interface", @@ -645,10 +711,11 @@ "status.direct": "Privately mention @{name}", "status.direct_indicator": "Private mention", "status.edit": "Edit", - "status.edited": "Edited {date}", + "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", @@ -669,6 +736,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 12d0068d69..f0c27ad706 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.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.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Add content warning", "compose_form.spoiler_placeholder": "Content warning (optional)", "confirmation_modal.cancel": "Cancel", - "confirmations.block.block_and_report": "Block & Report", "confirmations.block.confirm": "Block", - "confirmations.block.message": "Are you sure you want to block {name}?", "confirmations.cancel_follow_request.confirm": "Withdraw request", "confirmations.cancel_follow_request.message": "Are you sure you want to withdraw your request to follow {name}?", "confirmations.delete.confirm": "Delete", @@ -171,15 +177,13 @@ "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 entire domain", + "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?", "confirmations.logout.confirm": "Log out", "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", - "confirmations.mute.explanation": "This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.", - "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", "confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favorites and boosts will be lost, and replies to the original post will be orphaned.", "confirmations.reply.confirm": "Reply", @@ -205,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 favorites are ranked higher.", "dismissable_banner.explore_tags": "These are hashtags that are gaining traction on the social web today. Hashtags that are used by more different people are ranked higher.", "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", @@ -241,6 +266,7 @@ "empty_column.list": "There is nothing in this list yet. When members of this list publish new posts, 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.", @@ -271,16 +297,28 @@ "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": "Authorize", "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": "Editors' Choice", + "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}.", + "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": "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Follow hashtag", "hashtag.unfollow": "Unfollow hashtag", "hashtags.and_other": "โ€ฆand {count, plural, other {# more}}", - "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_replies": "Show replies", "home.hide_announcements": "Hide announcements", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Show profile anyway", "limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.", "link_preview.author": "By {name}", + "link_preview.more_from_author": "More from {name}", + "link_preview.shares": "{count, plural, one {{counter} post} other {{counter} posts}}", "lists.account.add": "Add to list", "lists.account.remove": "Remove from list", "lists.delete": "Delete list", @@ -395,9 +434,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.duration": "Duration", - "mute_modal.hide_notifications": "Hide notifications from this user?", - "mute_modal.indefinite": "Indefinite", + "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", @@ -430,11 +475,29 @@ "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": "You 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.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:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "Favorites:", "notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show_bar": "Show filter bar", "notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow_request": "New follow requests:", "notifications.column_settings.mention": "Mentions:", @@ -469,6 +531,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", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.active_users": "active users", "server_banner.administered_by": "Administered by:", - "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.", - "server_banner.learn_more": "Learn more", + "server_banner.is_one_of_many": "{domain} is one of the many independent Mastodon servers you can use to participate in the fediverse.", "server_banner.server_stats": "Server stats:", "sign_in_banner.create_account": "Create account", + "sign_in_banner.follow_anyone": "Follow anyone across the fediverse and see it all in chronological order. No algorithms, ads, or clickbait in sight.", + "sign_in_banner.mastodon_is": "Mastodon is the best way to keep up with what's happening.", "sign_in_banner.sign_in": "Login", "sign_in_banner.sso_redirect": "Login or Register", - "sign_in_banner.text": "Login to follow profiles or hashtags, favorite, share and reply to posts. You can also interact from your account on a different server.", "status.admin_account": "Open moderation interface for @{name}", "status.admin_domain": "Open moderation interface for {domain}", "status.admin_status": "Open this post in the moderation interface", @@ -645,10 +716,11 @@ "status.direct": "Privately mention @{name}", "status.direct_indicator": "Private mention", "status.edit": "Edit", - "status.edited": "Edited {date}", + "status.edited": "Last edited {date}", "status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.favourite": "Favorite", + "status.favourites": "{count, plural, one {favorite} other {favorites}}", "status.filter": "Filter this post", "status.filtered": "Filtered", "status.hide": "Hide post", @@ -669,6 +741,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/eo.json b/app/javascript/mastodon/locales/eo.json index 887d754a40..bab277b483 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -115,7 +115,7 @@ "column.directory": "Foliumi la profilojn", "column.domain_blocks": "Blokitaj domajnoj", "column.favourites": "Stelumoj", - "column.firehose": "Vivantaj fluoj", + "column.firehose": "Rektaj fluoj", "column.follow_requests": "Petoj de sekvado", "column.home": "Hejmo", "column.lists": "Listoj", @@ -152,9 +152,7 @@ "compose_form.spoiler.marked": "Forigi la averton de enhavo", "compose_form.spoiler.unmarked": "Aldoni averton de enhavo", "confirmation_modal.cancel": "Nuligi", - "confirmations.block.block_and_report": "Bloki kaj raporti", "confirmations.block.confirm": "Bloki", - "confirmations.block.message": "ฤˆu vi certas, ke vi volas bloki {name}?", "confirmations.cancel_follow_request.confirm": "Eksigi peton", "confirmations.cancel_follow_request.message": "ฤˆu vi certas ke vi volas eksigi vian peton por sekvi {name}?", "confirmations.delete.confirm": "Forigi", @@ -163,15 +161,12 @@ "confirmations.delete_list.message": "ฤˆu vi certas, ke vi volas porฤ‰iame forigi ฤ‰i tiun liston?", "confirmations.discard_edit_media.confirm": "Forฤตeti", "confirmations.discard_edit_media.message": "Vi havas nekonservitajn ลanฤojn de la priskribo aลญ la antaลญmontro de la plurmedio, ฤ‰u vi forฤตetu ilin malgraลญe?", - "confirmations.domain_block.confirm": "Bloki la tutan domajnon", "confirmations.domain_block.message": "ฤˆu vi vere, vere certas, ke vi volas tute bloki {domain}? Plej ofte, trafa blokado kaj silentigado sufiฤ‰as kaj preferindas. Vi ne vidos enhavon de tiu domajno en publika templinio aลญ en viaj sciigoj. Viaj sekvantoj de tiu domajno estos forigitaj.", "confirmations.edit.confirm": "Redakti", "confirmations.edit.message": "Redakti nun anstataลญigos la skribatan afiลon. ฤˆu vi certas, ke vi volas daลญrigi?", "confirmations.logout.confirm": "Adiaลญi", "confirmations.logout.message": "ฤˆu vi certas ke vi volas adiaลญi?", "confirmations.mute.confirm": "Silentigi", - "confirmations.mute.explanation": "Tio kaลos la mesaฤojn de la uzanto kaj la mesaฤojn kiuj mencias rin, sed ri ankoraลญ rajtos vidi viajn mesaฤojn kaj sekvi vin.", - "confirmations.mute.message": "ฤˆu vi certas, ke vi volas silentigi {name}?", "confirmations.redraft.confirm": "Forigi kaj reskribi", "confirmations.redraft.message": "ฤˆu vi certas ke vi volas forigi tiun afiลon kaj reskribi ฤin? ฤˆiuj diskonigoj kaj stelumoj estos perditaj, kaj respondoj al la originala mesaฤo estos senparentaj.", "confirmations.reply.confirm": "Respondi", @@ -295,7 +290,6 @@ "hashtag.follow": "Sekvi la kradvorton", "hashtag.unfollow": "Ne plu sekvi la kradvorton", "hashtags.and_other": "โ€ฆkaj {count, plural,other {# pli}}", - "home.column_settings.basic": "Bazaj agordoj", "home.column_settings.show_reblogs": "Montri diskonigojn", "home.column_settings.show_replies": "Montri respondojn", "home.hide_announcements": "Kaลi la anoncojn", @@ -381,9 +375,6 @@ "loading_indicator.label": "ลœargadoโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Kaลi la bildon} other {Kaลi la bildojn}}", "moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ฤ‰ar vi movis ฤin al {movedToAccount}.", - "mute_modal.duration": "Daลญro", - "mute_modal.hide_notifications": "ฤˆu vi volas kaลi la sciigojn de ฤ‰i tiu uzanto?", - "mute_modal.indefinite": "Nedifinita", "navigation_bar.about": "Pri", "navigation_bar.advanced_interface": "Malfermi altnivelan retpaฤan interfacon", "navigation_bar.blocks": "Blokitaj uzantoj", @@ -427,9 +418,6 @@ "notifications.column_settings.admin.sign_up": "Novaj registriฤoj:", "notifications.column_settings.alert": "Sciigoj de la retumilo", "notifications.column_settings.favourite": "Stelumoj:", - "notifications.column_settings.filter_bar.advanced": "Montri ฤ‰iujn kategoriojn", - "notifications.column_settings.filter_bar.category": "Rapida filtra breto", - "notifications.column_settings.filter_bar.show_bar": "Montri la breton de filtrilo", "notifications.column_settings.follow": "Novaj sekvantoj:", "notifications.column_settings.follow_request": "Novaj petoj de sekvado:", "notifications.column_settings.mention": "Mencioj:", @@ -510,7 +498,14 @@ "poll_button.add_poll": "Aldoni balotenketon", "poll_button.remove_poll": "Forigi balotenketon", "privacy.change": "Agordi mesaฤan privatecon", + "privacy.direct.long": "ฤˆiuj menciitaj en la afiลo", + "privacy.direct.short": "Specifaj homoj", + "privacy.private.long": "Nur viaj sekvantoj", + "privacy.private.short": "Sekvantoj", + "privacy.public.long": "ฤˆiujn ajn ฤ‰e kaj ekster Mastodon", "privacy.public.short": "Publika", + "privacy.unlisted.long": "Malpli algoritmaj fanfaroj", + "privacy.unlisted.short": "Diskrete publika", "privacy_policy.last_updated": "Laste ฤisdatigita en {date}", "privacy_policy.title": "Politiko de privateco", "recommended": "Rekomendita", @@ -601,13 +596,10 @@ "server_banner.about_active_users": "Personoj uzantaj ฤ‰i tiun servilon dum la lastaj 30 tagoj (Aktivaj Uzantoj Monate)", "server_banner.active_users": "aktivaj uzantoj", "server_banner.administered_by": "Administrata de:", - "server_banner.introduction": "{domain} apartenas al la malcentra socia retejo povigita de {mastodon}.", - "server_banner.learn_more": "Lernu pli", "server_banner.server_stats": "Statistikoj de la servilo:", "sign_in_banner.create_account": "Krei konton", "sign_in_banner.sign_in": "Saluti", "sign_in_banner.sso_redirect": "Ensalutu aลญ Registriฤi", - "sign_in_banner.text": "Ensalutu por sekvi profilojn aลญ haลetikedojn, ลatatajn, dividi kaj respondi afiลojn. Vi ankaลญ povas interagi de via konto sur alia servilo.", "status.admin_account": "Malfermi fasadon de moderigado por @{name}", "status.admin_domain": "Malfermu moderigan interfacon por {domain}", "status.admin_status": "Malfermi ฤ‰i tiun mesaฤon en la kontrola interfaco", @@ -621,7 +613,6 @@ "status.direct": "Private mencii @{name}", "status.direct_indicator": "Privata mencio", "status.edit": "Redakti", - "status.edited": "Redaktita {date}", "status.edited_x_times": "Redactita {count, plural, one {{count} fojon} other {{count} fojojn}}", "status.embed": "Enkorpigi", "status.favourite": "ลœatata", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index 87ab62cda2..7da39b88cc 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -89,6 +89,14 @@ "announcement.announcement": "Anuncio", "attachments_list.unprocessed": "[sin procesar]", "audio.hide": "Ocultar audio", + "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisiรณn. Sin embargo, el cumplimiento no estรก garantizado, ya que algunos servidores pueden manejar los bloqueos de forma diferente. Los mensajes pรบblicos todavรญa podrรญan estar visibles para los usuarios no conectados.", + "block_modal.show_less": "Mostrar menos", + "block_modal.show_more": "Mostrar mรกs", + "block_modal.they_cant_mention": "No pueden mencionarte ni seguirte.", + "block_modal.they_cant_see_posts": "No pueden ver tus mensajes y vos no verรกs los suyos.", + "block_modal.they_will_know": "Pueden ver que estรกn bloqueados.", + "block_modal.title": "ยฟBloquear usuario?", + "block_modal.you_wont_see_mentions": "No verรกs mensajes que los mencionen.", "boost_modal.combo": "Podรฉs hacer clic en {combo} para saltar esto la prรณxima vez", "bundle_column_error.copy_stacktrace": "Copiar informe de error", "bundle_column_error.error.body": "La pรกgina solicitada no pudo ser cargada. Podrรญa deberse a un error de programaciรณn en nuestro cรณdigo o a un problema de compatibilidad con el navegador web.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Agregar advertencia de contenido", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear y denunciar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "ยฟEstรกs seguro que querรฉs bloquear a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar solicitud", "confirmations.cancel_follow_request.message": "ยฟEstรกs seguro que querรฉs retirar tu solicitud para seguir a {name}?", "confirmations.delete.confirm": "Eliminar", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ยฟEstรกs seguro que querรฉs eliminar permanentemente esta lista?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tenรฉs cambios sin guardar en la descripciรณn de medios o en la vista previa, ยฟquerรฉs descartarlos de todos modos?", - "confirmations.domain_block.confirm": "Bloquear dominio entero", + "confirmations.domain_block.confirm": "Bloquear servidor", "confirmations.domain_block.message": "ยฟEstรกs completamente seguro que querรฉs bloquear el {domain} entero? En la mayorรญa de los casos, unos cuantos bloqueos y silenciados puntuales son suficientes y preferibles. No vas a ver contenido de ese dominio en ninguna de tus lรญneas temporales o en tus notificaciones. Tus seguidores de ese dominio serรกn quitados.", "confirmations.edit.confirm": "Editar", "confirmations.edit.message": "Editar ahora sobreescribirรก el mensaje que estรกs redactando actualmente. ยฟEstรกs seguro que querรฉs seguir?", "confirmations.logout.confirm": "Cerrar sesiรณn", "confirmations.logout.message": "ยฟEstรกs seguro que querรฉs cerrar la sesiรณn?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Se ocultarรกn los mensajes de esta cuenta y los mensajes de otras cuentas que mencionen a รฉsta, pero todavรญa esta cuenta podrรก ver tus mensajes o seguirte.", - "confirmations.mute.message": "ยฟEstรกs seguro que querรฉs silenciar a {name}?", "confirmations.redraft.confirm": "Eliminar mensaje original y editarlo", "confirmations.redraft.message": "ยฟEstรกs seguro que querรฉs eliminar este mensaje y volver a editarlo? Se perderรกn las veces marcadas como favorito y sus adhesiones, y las respuestas al mensaje original quedarรกn huรฉrfanas.", "confirmations.reply.confirm": "Responder", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Estos son los mensajes que estรกn ganando popularidad en la web social, hoy mismo. Los mensajes mรกs recientes con mรกs adhesiones y marcados como favoritos obtienen mรกs exposiciรณn.", "dismissable_banner.explore_tags": "Estas son etiquetas que estรกn ganando popularidad en la web social, hoy mismo. Las etiquetas que son usadas por diferentes cuentas obtienen mรกs exposiciรณn.", "dismissable_banner.public_timeline": "Estos son los mensajes pรบblicos mรกs recientes de cuentas en la web social que las personas en {domain} siguen.", + "domain_block_modal.block": "Bloquear servidor", + "domain_block_modal.block_account_instead": "Bloquear @{name} en su lugar", + "domain_block_modal.they_can_interact_with_old_posts": "Las cuentas de este servidor pueden interactuar con tus mensajes antiguos.", + "domain_block_modal.they_cant_follow": "Nadie de este servidor puede seguirte.", + "domain_block_modal.they_wont_know": "No sabrรกn que fueron bloqueados.", + "domain_block_modal.title": "ยฟBloquear dominio?", + "domain_block_modal.you_will_lose_followers": "Se eliminarรกn todos tus seguidores de este servidor.", + "domain_block_modal.you_wont_see_posts": "No verรกs mensajes ni notificaciones de usuarios en este servidor.", + "domain_pill.activitypub_lets_connect": "Te permite conectar e interactuar con cuentas no solo en Mastodon, sino tambiรฉn a travรฉs de diferentes aplicaciones sociales.", + "domain_pill.activitypub_like_language": "ActivityPub es como el idioma que Mastodon habla con otras redes sociales.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "Su alias:", + "domain_pill.their_server": "Su hogar digital, donde residen todoas sus mensajes.", + "domain_pill.their_username": "Su identificador รบnico en su servidor. Es posible encontrar cuentas con el mismo nombre de usuario en diferentes servidores.", + "domain_pill.username": "Nombre de usuario", + "domain_pill.whats_in_a_handle": "ยฟEn quรฉ consiste el alias?", + "domain_pill.who_they_are": "Los alias indican quiรฉnes son y dรณnde se encuentran, y gracias a ellos podรฉs interactuar con otras cuentas a travรฉs de las redes sociales compatibles con .", + "domain_pill.who_you_are": "Los alias dicen quiรฉn sos y dรณnde estรกs, y gracias a ellos podรฉs interactuar con otras cuentas a travรฉs de las redes sociales compatibles con .", + "domain_pill.your_handle": "Tu alias:", + "domain_pill.your_server": "Tu hogar digital, donde residen todos tus mensajes. ยฟNo te gusta este sitio? Mudate a otro servidor en cualquier momento y llevate a tus seguidores.", + "domain_pill.your_username": "Tu identificador รบnico en este servidor. Es posible encontrar cuentas con el mismo nombre de usuario en diferentes servidores.", "embed.instructions": "Insertรก este mensaje a tu sitio web copiando el cรณdigo de abajo.", "embed.preview": "Asรญ es cรณmo se verรก:", "emoji_button.activity": "Actividad", @@ -216,7 +241,7 @@ "emoji_button.nature": "Naturaleza", "emoji_button.not_found": "No se encontraron emojis coincidentes", "emoji_button.objects": "Objetos", - "emoji_button.people": "Gente", + "emoji_button.people": "Cuentas", "emoji_button.recent": "Usados frecuentemente", "emoji_button.search": "Buscar...", "emoji_button.search_results": "Resultados de bรบsqueda", @@ -241,6 +266,7 @@ "empty_column.list": "Todavรญa no hay nada en esta lista. Cuando miembros de esta lista envรญen nuevos mensaje, se mostrarรกn acรก.", "empty_column.lists": "Todavรญa no tenรฉs ninguna lista. Cuando creรฉs una, se mostrarรก acรก.", "empty_column.mutes": "Todavรญa no silenciaste a ningรบn usuario.", + "empty_column.notification_requests": "ยกTodo limpio! No hay nada acรก. Cuando recibรกs nuevas notificaciones, aparecerรกn acรก, acorde a tu configuraciรณn.", "empty_column.notifications": "Todavรญa no tenรฉs ninguna notificaciรณn. Cuando otras cuentas interactรบen con vos, vas a ver la notificaciรณn acรก.", "empty_column.public": "ยกNaranja! Escribรญ algo pรบblicamente, o seguรญ usuarios manualmente de otros servidores para ir llenando esta lรญnea temporal", "error.unexpected_crash.explanation": "Debido a un error en nuestro cรณdigo o a un problema de compatibilidad con el navegador web, esta pรกgina no se pudo mostrar correctamente.", @@ -271,16 +297,28 @@ "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", - "firehose.all": "Todas", + "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", "firehose.local": "Este servidor", "firehose.remote": "Otros servidores", "follow_request.authorize": "Autorizar", "follow_request.reject": "Rechazar", "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el equipo de {domain} pensรณ que podrรญas querer revisar manualmente las solicitudes de seguimiento de estas cuentas.", - "follow_suggestions.curated_suggestion": "Cuentas elegidas del servidor", + "follow_suggestions.curated_suggestion": "Selecciรณn del equipo", "follow_suggestions.dismiss": "No mostrar de nuevo", + "follow_suggestions.featured_longer": "Seleccionada a mano por el equipo de {domain}", + "follow_suggestions.friends_of_friends_longer": "Populares entre las cuentas que seguรญs", + "follow_suggestions.hints.featured": "Este perfil fue seleccionado a mano por el equipo de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las cuentas que seguรญs.", + "follow_suggestions.hints.most_followed": "Este perfil es uno de los mรกs seguidos en {domain}.", + "follow_suggestions.hints.most_interactions": "Este perfil ha estado recibiendo recientemente mucha atenciรณn en {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los que comenzaste a seguir.", "follow_suggestions.personalized_suggestion": "Sugerencia personalizada", "follow_suggestions.popular_suggestion": "Sugerencia popular", + "follow_suggestions.popular_suggestion_longer": "Popular en {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Similares a perfiles que comenzaste a seguir recientemente", "follow_suggestions.view_all": "Ver todo", "follow_suggestions.who_to_follow": "A quiรฉn seguir", "followed_tags": "Etiquetas seguidas", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir etiqueta", "hashtag.unfollow": "Dejar de seguir etiqueta", "hashtags.and_other": "โ€ฆy {count, plural, other {# mรกs}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Mostrar adhesiones", "home.column_settings.show_replies": "Mostrar respuestas", "home.hide_announcements": "Ocultar anuncios", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Mostrar perfil de todos modos", "limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mรกs de {name}", + "link_preview.shares": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}}", "lists.account.add": "Agregar a lista", "lists.account.remove": "Quitar de lista", "lists.delete": "Eliminar lista", @@ -395,9 +434,15 @@ "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.duration": "Duraciรณn", - "mute_modal.hide_notifications": "ยฟQuerรฉs ocultar las notificaciones de este usuario?", - "mute_modal.indefinite": "Indefinida", + "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", + "mute_modal.they_can_mention_and_follow": "Pueden mencionarte y seguirte, pero no verรกs nada de ellos.", + "mute_modal.they_wont_know": "No sabrรกn que fueron silenciados.", + "mute_modal.title": "ยฟSilenciar usuario?", + "mute_modal.you_wont_see_mentions": "No verรกs mensajes que los mencionen.", + "mute_modal.you_wont_see_posts": "Todavรญa pueden ver tus mensajes, pero vos no verรกs los suyos.", "navigation_bar.about": "Informaciรณn", "navigation_bar.advanced_interface": "Abrir en interface web avanzada", "navigation_bar.blocks": "Usuarios bloqueados", @@ -430,11 +475,29 @@ "notification.follow": "{name} te empezรณ a seguir", "notification.follow_request": "{name} solicitรณ seguirte", "notification.mention": "{name} te mencionรณ", + "notification.moderation-warning.learn_more": "Aprendรฉ mรกs", + "notification.moderation_warning": "Recibiste una advertencia de moderaciรณn", + "notification.moderation_warning.action_delete_statuses": "Se eliminaron algunos de tus mensajes.", + "notification.moderation_warning.action_disable": "Se deshabilitรณ tu cuenta.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Se marcaron como sensibles a algunos de tus mensajes.", + "notification.moderation_warning.action_none": "Tu cuenta recibiรณ una advertencia de moderaciรณn.", + "notification.moderation_warning.action_sensitive": "A partir de ahora, tus mensajes serรกn marcados como sensibles.", + "notification.moderation_warning.action_silence": "Tu cuenta fue limitada.", + "notification.moderation_warning.action_suspend": "Tu cuenta fue suspendida.", "notification.own_poll": "Tu encuesta finalizรณ", "notification.poll": "Finalizรณ una encuesta en la que votaste", "notification.reblog": "{name} adhiriรณ a tu mensaje", + "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", + "notification_requests.dismiss": "Descartar", + "notification_requests.notifications_from": "Notificaciones de {name}", + "notification_requests.title": "Notificaciones filtradas", "notifications.clear": "Limpiar notificaciones", "notifications.clear_confirmation": "ยฟEstรกs seguro que querรฉs limpiar todas tus notificaciones permanentemente?", "notifications.column_settings.admin.report": "Nuevas denuncias:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Las notificaciones de escritorio no estรกn disponibles, debido a una solicitud de permiso del navegador web previamente denegada", "notifications.permission_denied_alert": "No se pueden habilitar las notificaciones de escritorio, ya que el permiso del navegador fue denegado antes", "notifications.permission_required": "Las notificaciones de escritorio no estรกn disponibles porque no se concediรณ el permiso requerido.", + "notifications.policy.filter_new_accounts.hint": "Creada hace {days, plural, one {un dรญa} other {# dรญas}}", + "notifications.policy.filter_new_accounts_title": "Nuevas cuentas", + "notifications.policy.filter_not_followers_hint": "Incluyendo cuentas que te han estado siguiendo menos de {days, plural, one {un dรญa} other {# dรญas}}", + "notifications.policy.filter_not_followers_title": "Cuentas que no te siguen", + "notifications.policy.filter_not_following_hint": "Hasta que las aprobรฉs manualmente", + "notifications.policy.filter_not_following_title": "Cuentas que no seguรญs", + "notifications.policy.filter_private_mentions_hint": "Filtradas, a menos que sea en respuesta a tu propia menciรณn o si seguรญs al remitente", + "notifications.policy.filter_private_mentions_title": "Menciones privadas no solicitadas", + "notifications.policy.title": "Filtrar notificaciones deโ€ฆ", "notifications_permission_banner.enable": "Habilitar notificaciones de escritorio", "notifications_permission_banner.how_to_control": "Para recibir notificaciones cuando Mastodon no estรก abierto, habilitรก las notificaciones de escritorio. Podรฉs controlar con precisiรณn quรฉ tipos de interacciones generan notificaciones de escritorio a travรฉs del botรณn {icon} de arriba, una vez que estรฉn habilitadas.", "notifications_permission_banner.title": "No te pierdas nada", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Personas usando este servidor durante los รบltimos 30 dรญas (Usuarios Activos Mensuales)", "server_banner.active_users": "usuarios activos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} es parte de la red social descentralizada con la tecnologรญa de {mastodon}.", - "server_banner.learn_more": "Aprendรฉ mรกs", + "server_banner.is_one_of_many": "{domain} es uno de los muchos servidores de Mastodon independientes que podรฉs usar para participar en el Fediverso.", "server_banner.server_stats": "Estadรญsticas del servidor:", "sign_in_banner.create_account": "Crear cuenta", + "sign_in_banner.follow_anyone": "Seguรญ a cualquiera cuenta a travรฉs del Fediverso y leรฉ todo en orden cronolรณgico. Nada de algoritmos, publicidad o titulares engaรฑosos.", + "sign_in_banner.mastodon_is": "Mastodon es la mejor manera de mantenerse al dรญa sobre lo que estรก sucediendo.", "sign_in_banner.sign_in": "Iniciar sesiรณn", "sign_in_banner.sso_redirect": "Iniciรก sesiรณn o registrate", - "sign_in_banner.text": "Iniciรก sesiรณn para seguir cuentas o etiquetas, marcar mensajes como favoritos, compartirlos y responderlos. Tambiรฉn podรฉs interactuar desde tu cuenta en un servidor diferente.", "status.admin_account": "Abrir interface de moderaciรณn para @{name}", "status.admin_domain": "Abrir interface de moderaciรณn para {domain}", "status.admin_status": "Abrir este mensaje en la interface de moderaciรณn", @@ -645,10 +716,11 @@ "status.direct": "Menciรณn privada a @{name}", "status.direct_indicator": "Menciรณn privada", "status.edit": "Editar", - "status.edited": "Editado {date}", + "status.edited": "รšltima ediciรณn: {date}", "status.edited_x_times": "Editado {count, plural, one {{count} vez} other {{count} veces}}", "status.embed": "Insertar", "status.favourite": "Marcar como favorito", + "status.favourites": "{count, plural, one {# voto} other {# votos}}", "status.filter": "Filtrar este mensaje", "status.filtered": "Filtrado", "status.hide": "Ocultar mensaje", @@ -669,6 +741,7 @@ "status.reblog": "Adherir", "status.reblog_private": "Adherir a la audiencia original", "status.reblogged_by": "{name} adhiriรณ", + "status.reblogs": "{count, plural, one {adhesiรณn} other {adhesiones}}", "status.reblogs.empty": "Todavรญa nadie adhiriรณ a este mensaje. Cuando alguien lo haga, se mostrarรก acรก.", "status.redraft": "Eliminar mensaje original y editarlo", "status.remove_bookmark": "Quitar marcador", diff --git a/app/javascript/mastodon/locales/es-MX.json b/app/javascript/mastodon/locales/es-MX.json index 95b87b26dd..d3e02cd6e1 100644 --- a/app/javascript/mastodon/locales/es-MX.json +++ b/app/javascript/mastodon/locales/es-MX.json @@ -89,6 +89,14 @@ "announcement.announcement": "Anuncio", "attachments_list.unprocessed": "(sin procesar)", "audio.hide": "Ocultar audio", + "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisiรณn. Sin embargo, el cumplimiento no estรก garantizado ya que algunos servidores pueden manejar bloques de forma diferente. Las publicaciones pรบblicas pueden ser todavรญa visibles para los usuarios no conectados.", + "block_modal.show_less": "Mostrar menos", + "block_modal.show_more": "Mostrar mรกs", + "block_modal.they_cant_mention": "No pueden mencionarte ni seguirte.", + "block_modal.they_cant_see_posts": "No pueden ver tus publicaciones y tรบ no verรกs las de ellos.", + "block_modal.they_will_know": "Pueden ver que estรกn bloqueados.", + "block_modal.title": "ยฟBloquear usuario?", + "block_modal.you_wont_see_mentions": "No verรกs publicaciones que los mencionen.", "boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la prรณxima vez", "bundle_column_error.copy_stacktrace": "Copiar informe de error", "bundle_column_error.error.body": "La pรกgina solicitada no pudo ser renderizada. Podrรญa deberse a un error en nuestro cรณdigo o a un problema de compatibilidad con el navegador.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Texto no oculto", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear y Denunciar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "ยฟEstรกs seguro de querer bloquear a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar solicitud", "confirmations.cancel_follow_request.message": "ยฟEstรกs seguro de que deseas retirar tu solicitud para seguir a {name}?", "confirmations.delete.confirm": "Eliminar", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ยฟSeguro que quieres borrar esta lista permanentemente?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripciรณn o vista previa del archivo, ยฟdeseas descartarlos de cualquier manera?", - "confirmations.domain_block.confirm": "Ocultar dominio entero", + "confirmations.domain_block.confirm": "Bloquear servidor", "confirmations.domain_block.message": "ยฟSeguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.", "confirmations.edit.confirm": "Editar", "confirmations.edit.message": "Editar sobrescribirรก el mensaje que estรกs escribiendo. ยฟEstรกs seguro de que deseas continuar?", "confirmations.logout.confirm": "Cerrar sesiรณn", "confirmations.logout.message": "ยฟEstรกs seguro de querer cerrar la sesiรณn?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Esto esconderรก las publicaciones de ellos y en las que los has mencionado, pero les permitirรก ver tus mensajes y seguirte.", - "confirmations.mute.message": "ยฟEstรกs seguro de que quieres silenciar a {name}?", "confirmations.redraft.confirm": "Borrar y volver a borrador", "confirmations.redraft.message": "ยฟEstรกs seguro que quieres borrar esta publicaciรณn y editarla? Los favoritos e impulsos se perderรกn, y las respuestas a la publicaciรณn original quedarรกn separadas.", "confirmations.reply.confirm": "Responder", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Estas son las publicaciones que estรกn en tendencia en la red ahora. Las publicaciones recientes con mรกs impulsos y favoritos se muestran mรกs arriba.", "dismissable_banner.explore_tags": "Se trata de hashtags que estรกn ganando adeptos en las redes sociales hoy en dรญa. Los hashtags que son utilizados por mรกs personas diferentes se clasifican mejor.", "dismissable_banner.public_timeline": "Estos son los toots pรบblicos mรกs recientes de personas en la web social a las que sigue la gente en {domain}.", + "domain_block_modal.block": "Bloquear servidor", + "domain_block_modal.block_account_instead": "Bloquear @{name} en su lugar", + "domain_block_modal.they_can_interact_with_old_posts": "Las personas de este servidor pueden interactuar con tus publicaciones antiguas.", + "domain_block_modal.they_cant_follow": "Nadie de este servidor puede seguirte.", + "domain_block_modal.they_wont_know": "No sabrรกn que han sido bloqueados.", + "domain_block_modal.title": "ยฟBloquear dominio?", + "domain_block_modal.you_will_lose_followers": "Todos tus seguidores de este servidor serรกn eliminados.", + "domain_block_modal.you_wont_see_posts": "No verรกs publicaciones ni notificaciones de usuarios en este servidor.", + "domain_pill.activitypub_lets_connect": "Te permite conectar e interactuar con personas no sรณlo en Mastodon, sino tambiรฉn a travรฉs de diferentes aplicaciones sociales.", + "domain_pill.activitypub_like_language": "ActivityPub es como el idioma que Mastodon habla con otras redes sociales.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "Su alias:", + "domain_pill.their_server": "Su hogar digital, donde residen todas sus publicaciones.", + "domain_pill.their_username": "Su identificador รบnico en su servidor. Es posible encontrar usuarios con el mismo nombre de usuario en diferentes servidores.", + "domain_pill.username": "Nombre de usuario", + "domain_pill.whats_in_a_handle": "ยฟEn quรฉ consiste el alias?", + "domain_pill.who_they_are": "Los alias indican quiรฉnes son y dรณnde se encuentran, puedes interactuar con personas a travรฉs de las redes sociales de .", + "domain_pill.who_you_are": "Los alias indican quiรฉn eres y dรณnde te encuentras, las personas pueden interactuar contigo a travรฉs de las redes sociales de .", + "domain_pill.your_handle": "Tu alias:", + "domain_pill.your_server": "Tu hogar digital, donde residen todas tus publicaciones. ยฟNo te gusta este sitio? Muรฉvete a otro servidor en cualquier momento y llรฉvate a tus seguidores.", + "domain_pill.your_username": "Tu identificador รบnico en este servidor. Es posible encontrar usuarios con el mismo nombre de usuario en diferentes servidores.", "embed.instructions": "Aรฑade este toot a tu sitio web con el siguiente cรณdigo.", "embed.preview": "Asรญ es como se verรก:", "emoji_button.activity": "Actividad", @@ -241,6 +266,7 @@ "empty_column.list": "No hay nada en esta lista aรบn. Cuando miembros de esta lista publiquen nuevos estatus, estos aparecerรกn qui.", "empty_column.lists": "No tienes ninguna lista. cuando crees una, se mostrarรก aquรญ.", "empty_column.mutes": "Aรบn no has silenciado a ningรบn usuario.", + "empty_column.notification_requests": "ยกTodo limpio! No hay nada aquรญ. Cuando recibas nuevas notificaciones, aparecerรกn aquรญ conforme a tu configuraciรณn.", "empty_column.notifications": "No tienes ninguna notificaciรณn aรบn. Interactรบa con otros para empezar una conversaciรณn.", "empty_column.public": "ยกNo hay nada aquรญ! Escribe algo pรบblicamente, o sigue usuarios de otras instancias manualmente para llenarlo", "error.unexpected_crash.explanation": "Debido a un error en nuestro cรณdigo o a un problema de compatibilidad con el navegador, esta pรกgina no se ha podido mostrar correctamente.", @@ -271,6 +297,9 @@ "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", "firehose.local": "Este servidor", "firehose.remote": "Otros servidores", @@ -279,10 +308,19 @@ "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizรกs deberรญas revisar manualmente las solicitudes de seguimiento de estas cuentas.", "follow_suggestions.curated_suggestion": "Recomendaciones del equipo", "follow_suggestions.dismiss": "No mostrar de nuevo", + "follow_suggestions.featured_longer": "Escogidos por el equipo de {domain}", + "follow_suggestions.friends_of_friends_longer": "Populares entre las personas a las que sigues", + "follow_suggestions.hints.featured": "Este perfil ha sido seleccionado a mano por el equipo de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.", + "follow_suggestions.hints.most_followed": "Este perfil es uno de los mรกs seguidos en {domain}.", + "follow_suggestions.hints.most_interactions": "Este perfil ha estado recibiendo mucha atenciรณn en {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.", "follow_suggestions.personalized_suggestion": "Sugerencia personalizada", "follow_suggestions.popular_suggestion": "Sugerencia popular", + "follow_suggestions.popular_suggestion_longer": "Populares en {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Similares a los perfiles que has seguido recientemente", "follow_suggestions.view_all": "Ver todo", - "follow_suggestions.who_to_follow": "A quiรฉn seguir", + "follow_suggestions.who_to_follow": "Recomendamos seguir", "followed_tags": "Hashtags seguidos", "footer.about": "Acerca de", "footer.directory": "Directorio de perfiles", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir etiqueta", "hashtag.unfollow": "Dejar de seguir etiqueta", "hashtags.and_other": "โ€ฆy {count, plural, other {# mรกs}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Mostrar retoots", "home.column_settings.show_replies": "Mostrar respuestas", "home.hide_announcements": "Ocultar anuncios", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Mostrar perfil de todos modos", "limited_account_hint.title": "Este perfil ha sido ocultado por los moderadores de {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mรกs de {name}", + "link_preview.shares": "{count, plural, one {{counter} publicaciรณn} other {{counter} publicaciones}}", "lists.account.add": "Aรฑadir a lista", "lists.account.remove": "Quitar de lista", "lists.delete": "Borrar lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Cargandoโ€ฆ", "media_gallery.toggle_visible": "Cambiar visibilidad", "moved_to_account_banner.text": "Tu cuenta {disabledAccount} estรก actualmente deshabilitada porque te has mudado a {movedToAccount}.", - "mute_modal.duration": "Duraciรณn", - "mute_modal.hide_notifications": "Ocultar notificaciones de este usuario?", - "mute_modal.indefinite": "Indefinida", + "mute_modal.hide_from_notifications": "Ocultar de las notificaciones", + "mute_modal.hide_options": "Ocultar opciones", + "mute_modal.indefinite": "Hasta que deje de silenciarlos", + "mute_modal.show_options": "Mostrar opciones", + "mute_modal.they_can_mention_and_follow": "Pueden mencionarte y seguirte, pero no verรกs nada de ellos.", + "mute_modal.they_wont_know": "No sabrรกn que han sido silenciados.", + "mute_modal.title": "ยฟSilenciar usuario?", + "mute_modal.you_wont_see_mentions": "No verรกs publicaciones que los mencionen.", + "mute_modal.you_wont_see_posts": "Todavรญa pueden ver tus publicaciones, pero tรบ no verรกs las de ellos.", "navigation_bar.about": "Acerca de", "navigation_bar.advanced_interface": "Abrir en interfaz web avanzada", "navigation_bar.blocks": "Usuarios bloqueados", @@ -430,11 +475,29 @@ "notification.follow": "{name} te empezรณ a seguir", "notification.follow_request": "{name} ha solicitado seguirte", "notification.mention": "{name} te ha mencionado", + "notification.moderation-warning.learn_more": "Saber mรกs", + "notification.moderation_warning": "Has recibido una advertencia de moderaciรณn", + "notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.", + "notification.moderation_warning.action_disable": "Tu cuenta ha sido desactivada.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Se han marcado como sensibles algunas de tus publicaciones.", + "notification.moderation_warning.action_none": "Tu cuenta ha recibido un aviso de moderaciรณn.", + "notification.moderation_warning.action_sensitive": "De ahora en adelante, todas tus publicaciones se marcarรกn como sensibles.", + "notification.moderation_warning.action_silence": "Tu cuenta ha sido limitada.", + "notification.moderation_warning.action_suspend": "Tu cuenta ha sido suspendida.", "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", + "notification_requests.dismiss": "Descartar", + "notification_requests.notifications_from": "Notificaciones de {name}", + "notification_requests.title": "Notificaciones filtradas", "notifications.clear": "Limpiar notificaciones", "notifications.clear_confirmation": "ยฟSeguro de querer borrar permanentemente todas tus notificaciones?", "notifications.column_settings.admin.report": "Nuevas denuncias:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "No se pueden habilitar las notificaciones de escritorio ya que se denegรณ el permiso.", "notifications.permission_denied_alert": "No se pueden habilitar las notificaciones de escritorio, ya que el permiso del navegador fue denegado anteriormente", "notifications.permission_required": "Las notificaciones de escritorio no estรกn disponibles porque no se ha concedido el permiso requerido.", + "notifications.policy.filter_new_accounts.hint": "Creadas durante {days, plural, one {el รบltimo dรญa} other {los รบltimos # dรญas}}", + "notifications.policy.filter_new_accounts_title": "Cuentas nuevas", + "notifications.policy.filter_not_followers_hint": "Incluyendo personas que te han estado siguiendo desde hace menos de {days, plural, one {un dรญa} other {# dรญas}}", + "notifications.policy.filter_not_followers_title": "Personas que no te siguen", + "notifications.policy.filter_not_following_hint": "Hasta que las apruebes manualmente", + "notifications.policy.filter_not_following_title": "Personas que no sigues", + "notifications.policy.filter_private_mentions_hint": "Filtrada, a menos que sea en respuesta a tu propia menciรณn, o si sigues al remitente", + "notifications.policy.filter_private_mentions_title": "Menciones privadas no solicitadas", + "notifications.policy.title": "Filtrar notificaciones deโ€ฆ", "notifications_permission_banner.enable": "Habilitar notificaciones de escritorio", "notifications_permission_banner.how_to_control": "Para recibir notificaciones cuando Mastodon no estรฉ abierto, habilite las notificaciones de escritorio. Puedes controlar con precisiรณn quรฉ tipos de interacciones generan notificaciones de escritorio a travรฉs del botรณn {icon} de arriba una vez que estรฉn habilitadas.", "notifications_permission_banner.title": "Nunca te pierdas nada", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Personas utilizando este servidor durante los รบltimos 30 dรญas (Usuarios Activos Mensuales)", "server_banner.active_users": "usuarios activos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} es parte de la red social descentralizada gestionada por {mastodon}.", - "server_banner.learn_more": "Saber mรกs", + "server_banner.is_one_of_many": "{domain} es uno de los varios servidores independientes de Mastodon que puedes usar para participar en el fediverso.", "server_banner.server_stats": "Estadรญsticas del servidor:", "sign_in_banner.create_account": "Crear cuenta", + "sign_in_banner.follow_anyone": "Sigue a cualquier persona en el fediverso y velo todo en orden cronolรณgico. Sin algoritmos, sin anuncios o titulares engaรฑosos.", + "sign_in_banner.mastodon_is": "Mastodon es el mejor modo de mantenerse al dรญa sobre quรฉ estรก ocurriendo.", "sign_in_banner.sign_in": "Iniciar sesiรณn", "sign_in_banner.sso_redirect": "Iniciar sesiรณn o Registrarse", - "sign_in_banner.text": "Inicia sesiรณn para seguir perfiles o etiquetas, asรญ como marcar como favoritas, compartir y responder a publicaciones. Tambiรฉn puedes interactuar desde tu cuenta en un servidor diferente.", "status.admin_account": "Abrir interfaz de moderaciรณn para @{name}", "status.admin_domain": "Abrir interfaz de moderaciรณn para {domain}", "status.admin_status": "Abrir este estado en la interfaz de moderaciรณn", @@ -645,10 +716,11 @@ "status.direct": "Menciรณn privada @{name}", "status.direct_indicator": "Menciรณn privada", "status.edit": "Editar", - "status.edited": "Editado {date}", + "status.edited": "รšltima ediciรณn {date}", "status.edited_x_times": "Editado {count, plural, one {{count} time} other {{count} veces}}", "status.embed": "Incrustado", "status.favourite": "Favorito", + "status.favourites": "{count, plural, one {favorito} other {favoritos}}", "status.filter": "Filtrar esta publicaciรณn", "status.filtered": "Filtrado", "status.hide": "Ocultar toot", @@ -669,6 +741,7 @@ "status.reblog": "Retootear", "status.reblog_private": "Implusar a la audiencia original", "status.reblogged_by": "Retooteado por {name}", + "status.reblogs": "{count, plural, one {impulso} other {impulsos}}", "status.reblogs.empty": "Nadie retooteรณ este toot todavรญa. Cuando alguien lo haga, aparecerรก aquรญ.", "status.redraft": "Borrar y volver a borrador", "status.remove_bookmark": "Eliminar marcador", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 3e4f36ba5a..849e0fa27f 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -89,6 +89,14 @@ "announcement.announcement": "Anuncio", "attachments_list.unprocessed": "(sin procesar)", "audio.hide": "Ocultar audio", + "block_modal.remote_users_caveat": "Le pediremos al servidor {domain} que respete tu decisiรณn. Sin embargo, el cumplimiento no estรก garantizado, ya que algunos servidores pueden manejar bloqueos de forma distinta. Los mensajes pรบblicos pueden ser todavรญa visibles para los usuarios que no hayan iniciado sesiรณn.", + "block_modal.show_less": "Mostrar menos", + "block_modal.show_more": "Mostrar mรกs", + "block_modal.they_cant_mention": "No pueden mencionarte ni seguirte.", + "block_modal.they_cant_see_posts": "No pueden ver tus publicaciones y tรบ no verรกs las suyas.", + "block_modal.they_will_know": "Pueden ver que estรกn bloqueados.", + "block_modal.title": "ยฟBloquear usuario?", + "block_modal.you_wont_see_mentions": "No verรกs mensajes que los mencionen.", "boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la prรณxima vez", "bundle_column_error.copy_stacktrace": "Copiar informe de error", "bundle_column_error.error.body": "La pรกgina solicitada no pudo ser renderizada. Podrรญa deberse a un error en nuestro cรณdigo o a un problema de compatibilidad con el navegador.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Aรฑadir advertencia de contenido", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear y Reportar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "ยฟEstรกs seguro de que quieres bloquear a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar solicitud", "confirmations.cancel_follow_request.message": "ยฟEstรกs seguro de que deseas retirar tu solicitud para seguir a {name}?", "confirmations.delete.confirm": "Eliminar", @@ -171,21 +177,19 @@ "confirmations.delete_list.message": "ยฟSeguro que quieres borrar esta lista permanentemente?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripciรณn o vista previa del archivo audiovisual, ยฟdescartarlos de todos modos?", - "confirmations.domain_block.confirm": "Bloquear dominio entero", - "confirmations.domain_block.message": "ยฟSeguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.", + "confirmations.domain_block.confirm": "Bloquear servidor", + "confirmations.domain_block.message": "ยฟSeguro que quieres bloquear todo el dominio {domain}? En general, unos cuantos bloqueos y silenciados concretos es suficiente y preferible. No verรกs contenido del dominio en ninguna cronologรญa pรบblica ni en tus notificaciones. Se eliminarรกn tus seguidores procedentes de ese dominio.", "confirmations.edit.confirm": "Editar", - "confirmations.edit.message": "Editar ahora reemplazarรก el mensaje que estรก escribiendo. ยฟEstรก seguro que quiere proceder?", + "confirmations.edit.message": "Editar ahora reemplazarรก el mensaje que estรกs escribiendo. ยฟSeguro que quieres proceder?", "confirmations.logout.confirm": "Cerrar sesiรณn", - "confirmations.logout.message": "ยฟEstรกs seguro de querer cerrar la sesiรณn?", + "confirmations.logout.message": "ยฟSeguro que quieres cerrar la sesiรณn?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Esto esconderรก las publicaciones de ellos y en las que los has mencionado, pero les permitirรก ver tus mensajes y seguirte.", - "confirmations.mute.message": "ยฟEstรกs seguro de que quieres silenciar a {name}?", "confirmations.redraft.confirm": "Borrar y volver a borrador", "confirmations.redraft.message": "ยฟEstรกs seguro de querer borrar esta publicaciรณn y reescribirla? Los favoritos e impulsos se perderรกn, y las respuestas a la publicaciรณn original quedarรกn sin contexto.", "confirmations.reply.confirm": "Responder", "confirmations.reply.message": "Responder sobrescribirรก el mensaje que estรกs escribiendo. ยฟSeguro que deseas continuar?", "confirmations.unfollow.confirm": "Dejar de seguir", - "confirmations.unfollow.message": "ยฟEstรกs seguro de que quieres dejar de seguir a {name}?", + "confirmations.unfollow.message": "ยฟSeguro que quieres dejar de seguir a {name}?", "conversation.delete": "Borrar conversaciรณn", "conversation.mark_as_read": "Marcar como leรญdo", "conversation.open": "Ver conversaciรณn", @@ -194,7 +198,7 @@ "copypaste.copied": "Copiado", "copypaste.copy_to_clipboard": "Copiar al portapapeles", "directory.federated": "Desde el fediverso conocido", - "directory.local": "Sรณlo de {domain}", + "directory.local": "Solo de {domain}", "directory.new_arrivals": "Reciรฉn llegados", "directory.recently_active": "Recientemente activo", "disabled_account_banner.account_settings": "Ajustes de la cuenta", @@ -205,16 +209,37 @@ "dismissable_banner.explore_statuses": "Estas son las publicaciones que estรกn ganando popularidad en la web social hoy. Las publicaciones recientes con mรกs impulsos y favoritos obtienen mรกs exposiciรณn.", "dismissable_banner.explore_tags": "Estas son las etiquetas que estรกn ganando popularidad hoy en la red. Etiquetas que se usan por personas diferentes se puntรบan mรกs alto.", "dismissable_banner.public_timeline": "Estas son las publicaciones mรกs recientes de personas en el Fediverso que siguen las personas de {domain}.", + "domain_block_modal.block": "Bloquear servidor", + "domain_block_modal.block_account_instead": "Bloquear @{name} en su lugar", + "domain_block_modal.they_can_interact_with_old_posts": "Las personas de este servidor pueden interactuar con tus publicaciones antiguas.", + "domain_block_modal.they_cant_follow": "Nadie de este servidor puede seguirte.", + "domain_block_modal.they_wont_know": "No sabrรกn que han sido bloqueados.", + "domain_block_modal.title": "ยฟBloquear dominio?", + "domain_block_modal.you_will_lose_followers": "Se eliminarรกn todos tus seguidores de este servidor.", + "domain_block_modal.you_wont_see_posts": "No verรกs mensajes ni notificaciones de usuarios en este servidor.", + "domain_pill.activitypub_lets_connect": "Te permite conectar e interactuar con personas no sรณlo en Mastodon, sino tambiรฉn a travรฉs de diferentes aplicaciones sociales.", + "domain_pill.activitypub_like_language": "ActivityPub es como el idioma que Mastodon habla con otras redes sociales.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "Su alias:", + "domain_pill.their_server": "Su hogar digital, donde residen todas sus publicaciones.", + "domain_pill.their_username": "Su identificador รบnico en su servidor. Es posible encontrar usuarios con el mismo nombre de usuario en diferentes servidores.", + "domain_pill.username": "Nombre de usuario", + "domain_pill.whats_in_a_handle": "ยฟEn quรฉ consiste el alias?", + "domain_pill.who_they_are": "Los alias indican quiรฉnes son y dรณnde se encuentran, y gracias a ellos puedes interactuar con personas a travรฉs de las redes sociales compatibles con .", + "domain_pill.who_you_are": "Los alias indican quiรฉn eres y dรณnde te encuentras, y gracias a ellos puedes interactuar con personas a travรฉs de las redes sociales compatibles con .", + "domain_pill.your_handle": "Tu alias:", + "domain_pill.your_server": "Tu hogar digital, donde residen todas tus publicaciones. ยฟNo te gusta este sitio? Muรฉvete a otro servidor en cualquier momento y llรฉvate a tus seguidores.", + "domain_pill.your_username": "Tu identificador รบnico en este servidor. Es posible encontrar usuarios con el mismo nombre de usuario en diferentes servidores.", "embed.instructions": "Aรฑade esta publicaciรณn a tu sitio web con el siguiente cรณdigo.", "embed.preview": "Asรญ es como se verรก:", "emoji_button.activity": "Actividad", "emoji_button.clear": "Limpiar", "emoji_button.custom": "Personalizado", - "emoji_button.flags": "Marcas", + "emoji_button.flags": "Banderas", "emoji_button.food": "Comida y bebida", "emoji_button.label": "Insertar emoji", "emoji_button.nature": "Naturaleza", - "emoji_button.not_found": "No hay emojis!! ยฏ\\_(ใƒ„)_/ยฏ", + "emoji_button.not_found": "No se encontrรณ ningรบn emoji coincidente", "emoji_button.objects": "Objetos", "emoji_button.people": "Personas", "emoji_button.recent": "Usados frecuentemente", @@ -230,18 +255,19 @@ "empty_column.bookmarked_statuses": "Aรบn no tienes ninguna publicaciรณn guardada como marcador. Cuando guardes una, se mostrarรก aquรญ.", "empty_column.community": "La lรญnea de tiempo local estรก vacรญa. ยกEscribe algo para empezar la fiesta!", "empty_column.direct": "Aรบn no tienes menciones privadas. Cuando envรญes o recibas una, aparecerรกn aquรญ.", - "empty_column.domain_blocks": "Todavรญa no hay dominios ocultos.", - "empty_column.explore_statuses": "Nada estรก en tendencia en este momento. ยกRevisa mรกs tarde!", + "empty_column.domain_blocks": "Todavรญa no hay dominios bloqueados.", + "empty_column.explore_statuses": "No hay nada en tendencia en este momento. ยกRevisa mรกs tarde!", "empty_column.favourited_statuses": "Todavรญa no tienes publicaciones favoritas. Cuando marques una publicaciรณn como favorita, se mostrarรกn aquรญ.", "empty_column.favourites": "Todavรญa nadie marcรณ esta publicaciรณn como favorita. Cuando alguien lo haga, se mostrarรกn aquรญ.", "empty_column.follow_requests": "No tienes ninguna peticiรณn de seguidor. Cuando recibas una, se mostrarรก aquรญ.", "empty_column.followed_tags": "No has seguido ninguna etiqueta todavรญa. Cuando lo hagas, se mostrarรกn aquรญ.", "empty_column.hashtag": "No hay nada en este hashtag aรบn.", "empty_column.home": "ยกTu lรญnea temporal estรก vacรญa! Sigue a mรกs personas para rellenarla.", - "empty_column.list": "No hay nada en esta lista aรบn. Cuando miembros de esta lista publiquen nuevos estatus, estos aparecerรกn qui.", - "empty_column.lists": "No tienes ninguna lista. cuando crees una, se mostrarรก aquรญ.", + "empty_column.list": "Aรบn no hay nada en esta lista. Cuando los miembros de esta lista publiquen nuevos estados, estos aparecerรกn aquรญ.", + "empty_column.lists": "No tienes ninguna lista. Cuando crees una, se mostrarรก aquรญ.", "empty_column.mutes": "Aรบn no has silenciado a ningรบn usuario.", - "empty_column.notifications": "No tienes ninguna notificaciรณn aรบn. Interactรบa con otros para empezar una conversaciรณn.", + "empty_column.notification_requests": "ยกTodo limpio! No hay nada aquรญ. Cuando recibas nuevas notificaciones, aparecerรกn aquรญ conforme a tu configuraciรณn.", + "empty_column.notifications": "Aรบn no tienes ninguna notificaciรณn. Cuando otras personas interactรบen contigo, aparecerรกn aquรญ.", "empty_column.public": "ยกNo hay nada aquรญ! Escribe algo pรบblicamente, o sigue usuarios de otras instancias manualmente para llenarlo", "error.unexpected_crash.explanation": "Debido a un error en nuestro cรณdigo o a un problema de compatibilidad con el navegador, esta pรกgina no se ha podido mostrar correctamente.", "error.unexpected_crash.explanation_addons": "No se pudo mostrar correctamente esta pรกgina. Este error probablemente fue causado por un complemento del navegador web o por herramientas de traducciรณn automรกtica.", @@ -257,7 +283,7 @@ "explore.trending_tags": "Etiquetas", "filter_modal.added.context_mismatch_explanation": "Esta categorรญa de filtro no se aplica al contexto en el que ha accedido a esta publlicaciรณn. Si quieres que la publicaciรณn sea filtrada tambiรฉn en este contexto, tendrรกs que editar el filtro.", "filter_modal.added.context_mismatch_title": "ยกEl contexto no coincide!", - "filter_modal.added.expired_explanation": "Esta categorรญa de filtro ha caducado, necesitarรก cambiar la fecha de caducidad para que se aplique.", + "filter_modal.added.expired_explanation": "Esta categorรญa de filtro ha caducado, tendrรกs que cambiar la fecha de caducidad para que se aplique.", "filter_modal.added.expired_title": "ยกFiltro caducado!", "filter_modal.added.review_and_configure": "Para revisar y configurar esta categorรญa de filtros, vaya a {settings_link}.", "filter_modal.added.review_and_configure_title": "Ajustes de filtro", @@ -271,6 +297,9 @@ "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", "firehose.local": "Este servidor", "firehose.remote": "Otros servidores", @@ -279,8 +308,17 @@ "follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizรกs deberรญas revisar manualmente las solicitudes de seguimiento de estas cuentas.", "follow_suggestions.curated_suggestion": "Recomendaciones del equipo", "follow_suggestions.dismiss": "No mostrar de nuevo", + "follow_suggestions.featured_longer": "Escogidos por el equipo de {domain}", + "follow_suggestions.friends_of_friends_longer": "Populares entre las personas a las que sigues", + "follow_suggestions.hints.featured": "Este perfil ha sido elegido a mano por el equipo de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.", + "follow_suggestions.hints.most_followed": "Este perfil es uno de los mรกs seguidos en {domain}.", + "follow_suggestions.hints.most_interactions": "Este perfil ha estado recibiendo recientemente mucha atenciรณn en {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.", "follow_suggestions.personalized_suggestion": "Sugerencia personalizada", "follow_suggestions.popular_suggestion": "Sugerencia popular", + "follow_suggestions.popular_suggestion_longer": "Populares en {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Similares a los perfiles que has seguido recientemente", "follow_suggestions.view_all": "Ver todo", "follow_suggestions.who_to_follow": "A quiรฉn seguir", "followed_tags": "Etiquetas seguidas", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir etiqueta", "hashtag.unfollow": "Dejar de seguir etiqueta", "hashtags.and_other": "โ€ฆy {count, plural, other {# mรกs}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Mostrar impulsos", "home.column_settings.show_replies": "Mostrar respuestas", "home.hide_announcements": "Ocultar anuncios", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Mostrar perfil de todos modos", "limited_account_hint.title": "Este perfil ha sido ocultado por los moderadores de {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mรกs de {name}", + "link_preview.shares": "{count, plural, one {{counter} publicaciรณn} other {{counter} publicaciones}}", "lists.account.add": "Aรฑadir a lista", "lists.account.remove": "Quitar de lista", "lists.delete": "Borrar lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Cargandoโ€ฆ", "media_gallery.toggle_visible": "Cambiar visibilidad", "moved_to_account_banner.text": "Tu cuenta {disabledAccount} estรก actualmente deshabilitada porque te has mudado a {movedToAccount}.", - "mute_modal.duration": "Duraciรณn", - "mute_modal.hide_notifications": "ยฟOcultar notificaciones de este usuario?", - "mute_modal.indefinite": "Indefinida", + "mute_modal.hide_from_notifications": "Ocultar de las notificaciones", + "mute_modal.hide_options": "Ocultar opciones", + "mute_modal.indefinite": "Hasta que deje de silenciarlos", + "mute_modal.show_options": "Mostrar opciones", + "mute_modal.they_can_mention_and_follow": "Pueden mencionarte y seguirte, pero no verรกs nada de ellos.", + "mute_modal.they_wont_know": "No sabrรกn que han sido silenciados.", + "mute_modal.title": "ยฟSilenciar usuario?", + "mute_modal.you_wont_see_mentions": "No verรกs mensajes que los mencionen.", + "mute_modal.you_wont_see_posts": "Todavรญa pueden ver tus publicaciones, pero tรบ no verรกs las suyas.", "navigation_bar.about": "Acerca de", "navigation_bar.advanced_interface": "Abrir en la interfaz web avanzada", "navigation_bar.blocks": "Usuarios bloqueados", @@ -430,11 +475,29 @@ "notification.follow": "{name} te empezรณ a seguir", "notification.follow_request": "{name} ha solicitado seguirte", "notification.mention": "{name} te ha mencionado", + "notification.moderation-warning.learn_more": "Saber mรกs", + "notification.moderation_warning": "Has recibido una advertencia de moderaciรณn", + "notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.", + "notification.moderation_warning.action_disable": "Tu cuenta ha sido desactivada.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Se han marcado como sensibles algunas de tus publicaciones.", + "notification.moderation_warning.action_none": "Tu cuenta ha recibido un aviso de moderaciรณn.", + "notification.moderation_warning.action_sensitive": "De ahora en adelante, todas tus publicaciones se marcarรกn como sensibles.", + "notification.moderation_warning.action_silence": "Tu cuenta ha sido limitada.", + "notification.moderation_warning.action_suspend": "Tu cuenta ha sido suspendida.", "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", + "notification_requests.dismiss": "Descartar", + "notification_requests.notifications_from": "Notificaciones de {name}", + "notification_requests.title": "Notificaciones filtradas", "notifications.clear": "Limpiar notificaciones", "notifications.clear_confirmation": "ยฟSeguro que quieres limpiar permanentemente todas tus notificaciones?", "notifications.column_settings.admin.report": "Nuevos informes:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Nuevos seguidores:", "notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:", "notifications.column_settings.mention": "Menciones:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "No se pueden habilitar las notificaciones de escritorio ya que se denegรณ el permiso.", "notifications.permission_denied_alert": "No se pueden habilitar las notificaciones de escritorio, ya que el permiso del navegador fue denegado anteriormente", "notifications.permission_required": "Las notificaciones de escritorio no estรกn disponibles porque no se ha concedido el permiso requerido.", + "notifications.policy.filter_new_accounts.hint": "Creadas durante {days, plural, one {el รบltimo dรญa} other {los รบltimos # dรญas}}", + "notifications.policy.filter_new_accounts_title": "Cuentas nuevas", + "notifications.policy.filter_not_followers_hint": "Incluyendo personas que te han estado siguiendo desde hace menos de {days, plural, one {un dรญa} other {# dรญas}}", + "notifications.policy.filter_not_followers_title": "Personas que no te siguen", + "notifications.policy.filter_not_following_hint": "Hasta que las apruebes manualmente", + "notifications.policy.filter_not_following_title": "Personas que no sigues", + "notifications.policy.filter_private_mentions_hint": "Filtradas a menos que sea en respuesta a tu propia menciรณn, o si sigues al remitente", + "notifications.policy.filter_private_mentions_title": "Menciones privadas no solicitadas", + "notifications.policy.title": "Filtrar notificaciones deโ€ฆ", "notifications_permission_banner.enable": "Habilitar notificaciones de escritorio", "notifications_permission_banner.how_to_control": "Para recibir notificaciones cuando Mastodon no estรฉ abierto, habilite las notificaciones de escritorio. Puedes controlar con precisiรณn quรฉ tipos de interacciones generan notificaciones de escritorio a travรฉs del botรณn {icon} de arriba una vez que estรฉn habilitadas.", "notifications_permission_banner.title": "Nunca te pierdas nada", @@ -524,15 +595,15 @@ "poll_button.add_poll": "Aรฑadir una encuesta", "poll_button.remove_poll": "Eliminar encuesta", "privacy.change": "Ajustar privacidad", - "privacy.direct.long": "Todos los mencionados en el post", + "privacy.direct.long": "Visible รบnicamente por los mencionados en la publicaciรณn", "privacy.direct.short": "Personas especรญficas", - "privacy.private.long": "Solo tus seguidores", + "privacy.private.long": "Visible รบnicamente por tus seguidores", "privacy.private.short": "Seguidores", - "privacy.public.long": "Cualquiera dentro y fuera de Mastodon", - "privacy.public.short": "Pรบblico", - "privacy.unlisted.additional": "Esto se comporta exactamente igual que el pรบblico, excepto que la publicaciรณn no aparecerรก en la cronologรญa en directo o en las etiquetas, la exploraciรณn o bรบsqueda de Mastodon, incluso si estรก optado por activar la cuenta de usuario.", - "privacy.unlisted.long": "Menos fanfares algorรญtmicos", - "privacy.unlisted.short": "Pรบblico tranquilo", + "privacy.public.long": "Visible por todo el mundo, dentro y fuera de Mastodon", + "privacy.public.short": "Pรบblica", + "privacy.unlisted.additional": "Se comporta exactamente igual que la visibilidad pรบblica, excepto que la publicaciรณn no aparecerรก en las cronologรญas pรบblicas o en las etiquetas, la secciรณn de Explorar o la bรบsqueda de Mastodon, incluso si has habilitado la opciรณn de bรบsqueda en tu perfil.", + "privacy.unlisted.long": "Sin algoritmos de descubrimiento", + "privacy.unlisted.short": "Pรบblica silenciosa", "privacy_policy.last_updated": "Actualizado por รบltima vez {date}", "privacy_policy.title": "Polรญtica de Privacidad", "recommended": "Recomendado", @@ -550,6 +621,7 @@ "relative_time.minutes": "{number} m", "relative_time.seconds": "{number} s", "relative_time.today": "hoy", + "reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}", "reply_indicator.cancel": "Cancelar", "reply_indicator.poll": "Encuesta", "report.block": "Bloquear", @@ -585,7 +657,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?", @@ -624,13 +696,13 @@ "server_banner.about_active_users": "Usuarios activos en el servidor durante los รบltimos 30 dรญas (Usuarios Activos Mensuales)", "server_banner.active_users": "usuarios activos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} es parte de la red social descentralizada liderada por {mastodon}.", - "server_banner.learn_more": "Saber mรกs", + "server_banner.is_one_of_many": "{domain} es uno de los varios servidores independientes de Mastodon que puedes usar para participar en el fediverso.", "server_banner.server_stats": "Estadรญsticas del servidor:", "sign_in_banner.create_account": "Crear cuenta", + "sign_in_banner.follow_anyone": "Sigue a cualquier persona en el fediverso y velo todo en orden cronolรณgico. Sin algoritmos, sin anuncios o titulares engaรฑosos.", + "sign_in_banner.mastodon_is": "Mastodon es el mejor modo de mantenerse al dรญa sobre quรฉ estรก ocurriendo.", "sign_in_banner.sign_in": "Iniciar sesiรณn", "sign_in_banner.sso_redirect": "Iniciar sesiรณn o Registrarse", - "sign_in_banner.text": "Inicia sesiรณn para seguir perfiles o etiquetas, asรญ como marcar como favoritas, compartir y responder a publicaciones. Tambiรฉn puedes interactuar desde tu cuenta en un servidor diferente.", "status.admin_account": "Abrir interfaz de moderaciรณn para @{name}", "status.admin_domain": "Abrir interfaz de moderaciรณn para {domain}", "status.admin_status": "Abrir esta publicaciรณn en la interfaz de moderaciรณn", @@ -644,10 +716,11 @@ "status.direct": "Menciรณn privada @{name}", "status.direct_indicator": "Menciรณn privada", "status.edit": "Editar", - "status.edited": "Editado {date}", + "status.edited": "รšltima ediciรณn {date}", "status.edited_x_times": "Editado {count, plural, one {{count} vez} other {{count} veces}}", "status.embed": "Incrustado", "status.favourite": "Favorito", + "status.favourites": "{count, plural, one {favorito} other {favoritos}}", "status.filter": "Filtrar esta publicaciรณn", "status.filtered": "Filtrado", "status.hide": "Ocultar publicaciรณn", @@ -668,6 +741,7 @@ "status.reblog": "Impulsar", "status.reblog_private": "Impulsar a la audiencia original", "status.reblogged_by": "Impulsado por {name}", + "status.reblogs": "{count, plural, one {impulso} other {impulsos}}", "status.reblogs.empty": "Nadie ha impulsado esta publicaciรณn todavรญa. Cuando alguien lo haga, aparecerรก aquรญ.", "status.redraft": "Borrar y volver a borrador", "status.remove_bookmark": "Eliminar marcador", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index be8bec616d..547a0fe61f 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -21,7 +21,7 @@ "account.blocked": "Blokeeritud", "account.browse_more_on_origin_server": "Vaata rohkem algsel profiilil", "account.cancel_follow_request": "Vรตta jรคlgimistaotlus tagasi", - "account.copy": "Kopeeri link profiili", + "account.copy": "Kopeeri profiili link", "account.direct": "Maini privaatselt @{name}", "account.disable_notifications": "Peata teavitused @{name} postitustest", "account.domain_blocked": "Domeen peidetud", @@ -89,6 +89,14 @@ "announcement.announcement": "Teadaanne", "attachments_list.unprocessed": "(tรถรถtlemata)", "audio.hide": "Peida audio", + "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.", @@ -139,14 +147,14 @@ "compose.published.body": "Postitus avaldatud.", "compose.published.open": "Ava", "compose.saved.body": "Postitus salvestatud.", - "compose_form.direct_message_warning_learn_more": "Vaata tรคpsemalt", + "compose_form.direct_message_warning_learn_more": "Vaata lisa", "compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krรผpteeritud. ร„ra jaga mingeid delikaatseid andmeid Mastodoni kaudu.", "compose_form.hashtag_warning": "See postitus ei ilmu รผhegi mรคrksรตna all, kuna pole avalik. Vaid avalikud postitused on mรคrksรตnade kaudu leitavad.", "compose_form.lock_disclaimer": "Su konto ei ole {locked}. Igaรผks saab sind jรคlgida, et nรคha su ainult-jรคlgijatele postitusi.", "compose_form.lock_disclaimer.lock": "lukus", "compose_form.placeholder": "Millest mรตtled?", "compose_form.poll.duration": "Kรผsitluse kestus", - "compose_form.poll.multiple": "Valikvastustega", + "compose_form.poll.multiple": "Mitu vastust", "compose_form.poll.option_placeholder": "Valik {number}", "compose_form.poll.single": "Vali รผks", "compose_form.poll.switch_to_multiple": "Muuda kรผsitlust mitmikvaliku lubamiseks", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Mรคrgi sisu tundlikuks", "compose_form.spoiler_placeholder": "Sisuhoiatus (valikuline)", "confirmation_modal.cancel": "Katkesta", - "confirmations.block.block_and_report": "Blokeeri ja teata", "confirmations.block.confirm": "Blokeeri", - "confirmations.block.message": "Oled kindel, et soovid blokeerida {name}?", "confirmations.cancel_follow_request.confirm": "Tรผhista taotlus", "confirmations.cancel_follow_request.message": "Oled kindel, et soovid kasutaja {name} jรคlgimistaotluse tagasi vรตtta?", "confirmations.delete.confirm": "Kustuta", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Oled kindel, et soovid selle loetelu pรถรถrdumatult kustutada?", "confirmations.discard_edit_media.confirm": "Hรผlga", "confirmations.discard_edit_media.message": "Sul on salvestamata muudatusi meediakirjelduses vรตi eelvaates, kas hรผlgad need?", - "confirmations.domain_block.confirm": "Peida terve domeen", + "confirmations.domain_block.confirm": "Blokeeri server", "confirmations.domain_block.message": "Oled ikka pรคris-pรคris kindel, et soovid blokeerida terve {domain}? Enamikel juhtudel piisab mรตnest sihitud blokist vรตi vaigistusest, mis on eelistatavam. Sa ei nรคe selle domeeni sisu รผhelgi avalikul ajajoonel vรตi enda teadetes. Su jรคlgijad sellest domeenist eemaldatakse.", "confirmations.edit.confirm": "Muuda", "confirmations.edit.message": "Muutes praegu kirjutatakse hetkel loodav sรตnum รผle. Kas oled kindel, et soovid jรคtkata?", "confirmations.logout.confirm": "Vรคlju", "confirmations.logout.message": "Kas oled kindel, et soovid vรคlja logida?", "confirmations.mute.confirm": "Vaigista", - "confirmations.mute.explanation": "See peidab tema postitused ning postitused, milles teda mainitakse, kuid lubab tal ikkagi sinu postitusi nรคha ning sind jรคlgida.", - "confirmations.mute.message": "Oled kindel, et soovid {name} vaigistada?", "confirmations.redraft.confirm": "Kustuta & taasalusta", "confirmations.redraft.message": "Kindel, et soovid postituse kustutada ja vรตtta uue aluseks? Lemmikuks mรคrkimised ja jagamised lรคhevad kaotsi ning vastused jรครคvad ilma algse postituseta.", "confirmations.reply.confirm": "Vasta", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Need postitused รผle sotsiaalse vรตrgu koguvad praegu tรคhelepanu. Uued postitused, millel on rohkem jagamisi ja lemmikuks mรคrkimisi, on kรตrgemal kohal.", "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", @@ -241,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.", @@ -271,12 +297,30 @@ "filter_modal.select_filter.subtitle": "Kasuta olemasolevat kategooriat vรตi loo uus", "filter_modal.select_filter.title": "Filtreeri seda postitust", "filter_modal.title.status": "Postituse filtreerimine", + "filtered_notifications_banner.mentions": "{count, plural, one {mainimine} other {mainimist}}", + "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", "follow_request.authorize": "Autoriseeri", "follow_request.reject": "Hรผlga", "follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jรคlgimistaotlused kรคsitsi รผle vaadata.", + "follow_suggestions.curated_suggestion": "Meeskonna valitud", + "follow_suggestions.dismiss": "ร„ra enam nรคita", + "follow_suggestions.featured_longer": "Kรคsitsi valitud {domain} meeskonna poolt", + "follow_suggestions.friends_of_friends_longer": "Populaarne inimeste hulgas, keda jรคlgid", + "follow_suggestions.hints.featured": "Selle kasutajaprofiili on soovitanud {domain} meeskond.", + "follow_suggestions.hints.friends_of_friends": "See kasutajaprofiil on sinu jรคlgitavate seas populaarne.", + "follow_suggestions.hints.most_followed": "See on {domain} enim jรคlgitud kasutajaprofiil.", + "follow_suggestions.hints.most_interactions": "See kasutajaprofiil on viimasel ajal {domain} saanud palju tรคhelepanu.", + "follow_suggestions.hints.similar_to_recently_followed": "See kasutajaprofiil sarnaneb neile, mida oled hiljuti jรคlgima asunud.", + "follow_suggestions.personalized_suggestion": "Isikupรคrastatud soovitus", + "follow_suggestions.popular_suggestion": "Popuplaarne soovitus", + "follow_suggestions.popular_suggestion_longer": "Populaarne kohas {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Sarnane profiilile, mida hiljuti jรคlgima hakkasid", + "follow_suggestions.view_all": "Vaata kรตiki", + "follow_suggestions.who_to_follow": "Keda jรคlgida", "followed_tags": "Jรคlgitavad mรคrksรตnad", "footer.about": "Teave", "footer.directory": "Profiilikataloog", @@ -303,7 +347,6 @@ "hashtag.follow": "Jรคlgi silti", "hashtag.unfollow": "Lรตpeta sildi jรคlgimine", "hashtags.and_other": "โ€ฆja {count, plural, one {}other {# veel}}", - "home.column_settings.basic": "Peamine", "home.column_settings.show_reblogs": "Nรคita jagamisi", "home.column_settings.show_replies": "Nรคita vastuseid", "home.hide_announcements": "Peida teadaanded", @@ -371,6 +414,8 @@ "limited_account_hint.action": "Nรคita profilli sellegipoolest", "limited_account_hint.title": "See profiil on peidetud {domain} moderaatorite poolt.", "link_preview.author": "{name} poolt", + "link_preview.more_from_author": "Veel kasutajalt {name}", + "link_preview.shares": "{count, plural, one {{counter} postitus} other {{counter} postitust}}", "lists.account.add": "Lisa nimekirja", "lists.account.remove": "Eemalda nimekirjast", "lists.delete": "Kustuta nimekiri", @@ -389,9 +434,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.duration": "Kestus", - "mute_modal.hide_notifications": "Kas peita teated sellelt kasutajalt?", - "mute_modal.indefinite": "Lรตpmatu", + "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", @@ -424,20 +475,37 @@ "notification.follow": "{name} alustas su jรคlgimist", "notification.follow_request": "{name} soovib sind jรคlgida", "notification.mention": "{name} mainis sind", + "notification.moderation-warning.learn_more": "Vaata lisa", + "notification.moderation_warning": "Said modereerimise hoiatuse", + "notification.moderation_warning.action_delete_statuses": "Mรตni su postitus on eemaldatud.", + "notification.moderation_warning.action_disable": "Su konto on keelatud.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Mรตni su postitustest on mรคrgitud kui tundlik.", + "notification.moderation_warning.action_none": "Su konto on saanud modereerimise hoiatuse.", + "notification.moderation_warning.action_sensitive": "Su postitused mรคrgitakse nรผรผdsest tundlikuks.", + "notification.moderation_warning.action_silence": "Su kontole pandi piirang.", + "notification.moderation_warning.action_suspend": "Su konto on peatatud.", "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": "Vaata lisa", + "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": "Kuva kรตik kategooriad", + "notifications.column_settings.filter_bar.advanced": "Nรคita kรตiki kategooriaid", "notifications.column_settings.filter_bar.category": "Kiirfiltri riba", - "notifications.column_settings.filter_bar.show_bar": "Nรคita filtririba", "notifications.column_settings.follow": "Uued jรคlgijad:", "notifications.column_settings.follow_request": "Uued jรคlgimistaotlused:", "notifications.column_settings.mention": "Mainimised:", @@ -463,6 +531,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", @@ -473,7 +550,7 @@ "onboarding.compose.template": "Tere, #Mastodon!", "onboarding.follows.empty": "Kahjuks ei saa hetkel tulemusi nรคidata. Proovi kasutada otsingut vรตi lehitse uurimise lehte, et leida inimesi, keda jรคlgida, vรตi proovi hiljem uuesti.", "onboarding.follows.lead": "Haldad ise oma koduvoogu. Mida rohkemaid inimesi jรคlgid, seda aktiivsem ja huvitavam see on. Need profiilid vรตiksid olla head alustamiskohad โ€” saad nende jรคlgimise alati lรตpetada!", - "onboarding.follows.title": "Populaarne Mastodonis", + "onboarding.follows.title": "Isikupรคrasta oma koduvoogu", "onboarding.profile.discoverable": "Muuda mu profiil avastatavaks", "onboarding.profile.discoverable_hint": "Kui nรตustud enda avastamisega Mastodonis, vรตivad sinu postitused ilmuda otsingutulemustes ja trendides ning sinu profiili vรตidakse soovitada sinuga sarnaste huvidega inimestele.", "onboarding.profile.display_name": "Nรคidatav nimi", @@ -493,11 +570,11 @@ "onboarding.start.skip": "Soovid kohe edasi hรผpata?", "onboarding.start.title": "Said valmis!", "onboarding.steps.follow_people.body": "Haldad oma koduvoogu. Tรคida see huvitavate inimestega.", - "onboarding.steps.follow_people.title": "Jรคlgi {count, plural, one {รผht inimest} other {# inimest}}", + "onboarding.steps.follow_people.title": "Isikupรคrasta oma koduvoogu", "onboarding.steps.publish_status.body": "รœtle maailmale tere.", "onboarding.steps.publish_status.title": "Tee oma esimene postitus", "onboarding.steps.setup_profile.body": "Tรคidetud profiili korral suhtlevad teised sinuga tรตenรคolisemalt.", - "onboarding.steps.setup_profile.title": "Kohanda oma profiili", + "onboarding.steps.setup_profile.title": "Isikupรคrasta oma profiili", "onboarding.steps.share_profile.body": "Anna sรตpradele teada, kuidas sind Mastodonist leida!", "onboarding.steps.share_profile.title": "Jaga oma profiili", "onboarding.tips.2fa": "Kas sa teadsid? Saad oma kontot muuta turvalisemaks valides konto seadetes kaheastmelise autoriseerimise. See tรถรถtab mistahes sinu valitud TOTP-รคpiga, telefoninumbrit pole vaja!", @@ -524,6 +601,7 @@ "privacy.private.short": "Jรคlgijad", "privacy.public.long": "Nii kasutajad kui mittekasutajad", "privacy.public.short": "Avalik", + "privacy.unlisted.additional": "See on olemuselt kรผll avalik, aga postitus ei ilmu voogudes ega mรคrksรตnades, lehitsedes ega Mastodoni otsingus, isegi kui konto on seadistustes avalik.", "privacy.unlisted.long": "Vรคhem algoritmilisi teavitusi", "privacy.unlisted.short": "Vaikselt avalik", "privacy_policy.last_updated": "Viimati uuendatud {date}", @@ -618,13 +696,13 @@ "server_banner.about_active_users": "Inimesed, kes kasutavad seda serverit viimase 30 pรคeva jooksul (kuu aktiivsed kasutajad)", "server_banner.active_users": "aktiivsed kasutajad", "server_banner.administered_by": "Administraator:", - "server_banner.introduction": "{domain} on osa detsentraliseeritud sotsiaalvรตrgustikust, mida vรตimaldab {mastodon}.", - "server_banner.learn_more": "Vaata tรคpsemalt", + "server_banner.is_one_of_many": "{domain} on รผks paljudest sรตltumatutest Mastodoni serveritest, mida saab fediversumis osalemiseks kasutada.", "server_banner.server_stats": "Serveri statistika:", "sign_in_banner.create_account": "Loo konto", + "sign_in_banner.follow_anyone": "Jรคlgi รผkskรตik keda kogu fediversumist ja nรคe kรตike ajalises jรคrjestuses. Ei mingeid algoritme, reklaame vรตi klikipรผรผdjaid segamas.", + "sign_in_banner.mastodon_is": "Mastodon on parim viis olemaks kursis sellega, mis toimub.", "sign_in_banner.sign_in": "Logi sisse", "sign_in_banner.sso_redirect": "Sisene vรตi registreeru", - "sign_in_banner.text": "Logi sisse, et jรคlgida profiile vรตi silte, mรคrkida lemmikuks, jagada ja vastata postitustele. Vรตid suhelda ka mรตne teise serveri konto kaudu.", "status.admin_account": "Ava @{name} moderaatorivaates", "status.admin_domain": "Ava {domain} modeereerimisliides", "status.admin_status": "Ava postitus moderaatorivaates", @@ -638,10 +716,11 @@ "status.direct": "Maini privaatselt @{name}", "status.direct_indicator": "Privaatne mainimine", "status.edit": "Muuda", - "status.edited": "{date} muudetud", + "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", @@ -662,6 +741,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 e80e7fcf46..5fbac270cf 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -89,6 +89,14 @@ "announcement.announcement": "Iragarpena", "attachments_list.unprocessed": "(prozesatu gabe)", "audio.hide": "Ezkutatu audioa", + "block_modal.remote_users_caveat": "{domain} zerbitzariari zure erabakia errespeta dezan eskatuko diogu. Halere, araua beteko den ezin da bermatu, zerbitzari batzuk modu desberdinean kudeatzen baitituzte blokeoak. Baliteke argitalpen publikoak saioa hasi ez duten erabiltzaileentzat ikusgai egotea.", + "block_modal.show_less": "Erakutsi gutxiago", + "block_modal.show_more": "Erakutsi gehiago", + "block_modal.they_cant_mention": "Ezin zaitu aipatu ezta jarraitu ere.", + "block_modal.they_cant_see_posts": "Ezin ditu zure bidalketak ikusi eta zuk ez dituzu bereak ikusiko.", + "block_modal.they_will_know": "Ezin du ikusi blokeatuta duzunik.", + "block_modal.title": "Erabiltzailea blokeatu nahi duzu?", + "block_modal.you_wont_see_mentions": "Ez duzu ikusiko bera aipatzen duen argitalpenik.", "boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko", "bundle_column_error.copy_stacktrace": "Kopiatu errore-txostena", "bundle_column_error.error.body": "Eskatutako orria ezin izan da bistaratu. Kodeko errore bategatik izan daiteke edo nabigatzailearen bateragarritasun arazo bategatik.", @@ -140,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", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Testua ez dago ezkutatuta", "compose_form.spoiler_placeholder": "Edukiaren abisua (aukerakoa)", "confirmation_modal.cancel": "Utzi", - "confirmations.block.block_and_report": "Blokeatu eta salatu", "confirmations.block.confirm": "Blokeatu", - "confirmations.block.message": "Ziur {name} blokeatu nahi duzula?", "confirmations.cancel_follow_request.confirm": "Baztertu eskaera", "confirmations.cancel_follow_request.message": "Ziur {name} jarraitzeko eskaera bertan behera utzi nahi duzula?", "confirmations.delete.confirm": "Ezabatu", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Ziur behin betiko ezabatu nahi duzula zerrenda hau?", "confirmations.discard_edit_media.confirm": "Baztertu", "confirmations.discard_edit_media.message": "Multimediaren deskribapen edo aurrebistan gorde gabeko aldaketak daude, baztertu nahi dituzu?", - "confirmations.domain_block.confirm": "Ezkutatu domeinu osoa", + "confirmations.domain_block.confirm": "Blokeatu zerbitzaria", "confirmations.domain_block.message": "Ziur, erabat ziur, {domain} domeinu osoa blokeatu nahi duzula? Gehienetan gutxi batzuk blokeatu edo mututzearekin nahikoa da. Ez duzu domeinu horretako edukirik ikusiko denbora lerroetan edo jakinarazpenetan. Domeinu horretako zure jarraitzaileak kenduko dira ere.", "confirmations.edit.confirm": "Editatu", "confirmations.edit.message": "Orain editatzen baduzu, une honetan idazten ari zaren mezua gainidatziko da. Ziur jarraitu nahi duzula?", "confirmations.logout.confirm": "Amaitu saioa", "confirmations.logout.message": "Ziur saioa amaitu nahi duzula?", "confirmations.mute.confirm": "Mututu", - "confirmations.mute.explanation": "Honek horko bidalketak eta aipamena egiten dietenak ezkutatuko ditu, baina beraiek zure bidalketak ikusi ahal izango dituzte eta zuri jarraitu.", - "confirmations.mute.message": "Ziur {name} mututu nahi duzula?", "confirmations.redraft.confirm": "Ezabatu eta berridatzi", "confirmations.redraft.message": "Ziur argitalpen hau ezabatu eta zirriborroa berriro egitea nahi duzula? Gogokoak eta bultzadak galduko dira, eta jatorrizko argitalpenaren erantzunak zurtz geratuko dira.", "confirmations.reply.confirm": "Erantzun", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Hauek dira gaur egun lekua hartzen ari diren sare sozial osoaren argitalpenak. Bultzada eta gogoko gehien dituzten argitalpen berrienek sailkapen altuagoa dute.", "dismissable_banner.explore_tags": "Traola hauek daude bogan orain zerbitzari honetan eta sare deszentralizatuko besteetan.", "dismissable_banner.public_timeline": "Hauek dira {domain}-(e)ko jendeak web sozialean jarraitzen dituen jendearen azkeneko argitalpen publikoak.", + "domain_block_modal.block": "Blokeatu zerbitzaria", + "domain_block_modal.block_account_instead": "Blokeatu @{name} bestela", + "domain_block_modal.they_can_interact_with_old_posts": "Zerbitzari honetako jendea zure argitalpen zaharrekin elkarreragin dezake.", + "domain_block_modal.they_cant_follow": "Zerbitzari honetako inork ezin zaitu jarraitu.", + "domain_block_modal.they_wont_know": "Ez dute jakingo blokeatuak izan direnik.", + "domain_block_modal.title": "Domeinua blokeatu nahi duzu?", + "domain_block_modal.you_will_lose_followers": "Zerbitzari honetako jarraitzaile guztiak kenduko dira.", + "domain_block_modal.you_wont_see_posts": "Ez dituzu zerbitzari honetako erabiltzaileen argitalpenik edota jakinarazpenik ikusiko.", + "domain_pill.activitypub_lets_connect": "Mastodon-en ez ezik, beste sare sozialen aplikazioetako jendearekin konektatzea eta harremanetan jartzea uzten dizu.", + "domain_pill.activitypub_like_language": "ActivityPub, Mastodon-ek beste sare sozialekin hitz egiteko erabiltzen duen hizkuntza bezalakoxea da.", + "domain_pill.server": "Zerbitzaria", + "domain_pill.their_handle": "Bere helbidea:", + "domain_pill.their_server": "Bere etxe digitala, non bere argitalpenak dauden.", + "domain_pill.their_username": "Zerbitzarian duen identifikatzaile bakarra. Baliteke erabiltzaile-izen bera duten erabiltzaileak zerbitzari desberdinetan aurkitzea.", + "domain_pill.username": "Erabiltzaile-izena", + "domain_pill.whats_in_a_handle": "Zer dago helbide batean?", + "domain_pill.who_they_are": "Helbideek norbait nor den eta non dagoen adierazten dute, sare sozialeko jendearekin jar zaitezke harremanetan.", + "domain_pill.who_you_are": "Zure helbideak nor zaren eta non zauden adierazten duenez, jendea sare sozialen bitartez jar daiteke zurekin harremanetan.", + "domain_pill.your_handle": "Zure helbidea:", + "domain_pill.your_server": "Zure etxe digitala, non zure bidalketak dauden. Ez al zaizu gustatzen? Transferitu zerbitzariak edonoiz eta ekarri zure jarraitzaileak ere.", + "domain_pill.your_username": "Zerbitzarian duzun identifikatzaile bakarra. Baliteke erabiltzaile-izen bera duten erabiltzaileak zerbitzari desberdinetan aurkitzea.", "embed.instructions": "Txertatu bidalketa hau zure webgunean beheko kodea kopiatuz.", "embed.preview": "Hau da izango duen itxura:", "emoji_button.activity": "Jarduera", @@ -241,6 +266,7 @@ "empty_column.list": "Ez dago ezer zerrenda honetan. Zerrenda honetako kideek bidalketa berriak argitaratzean, hemen agertuko dira.", "empty_column.lists": "Ez duzu zerrendarik oraindik. Baten bat sortzen duzunean hemen agertuko da.", "empty_column.mutes": "Ez duzu erabiltzailerik mututu oraindik.", + "empty_column.notification_requests": "Garbi-garbi! Ezertxo ere ez hemen. Jakinarazpenak jasotzen dituzunean, hemen agertuko dira zure ezarpenen arabera.", "empty_column.notifications": "Ez duzu jakinarazpenik oraindik. Jarri besteekin harremanetan elkarrizketa abiatzeko.", "empty_column.public": "Ez dago ezer hemen! Idatzi zerbait publikoki edo jarraitu eskuz beste zerbitzari batzuetako erabiltzaileei hau betetzen joateko", "error.unexpected_crash.explanation": "Gure kodean arazoren bat dela eta, edo nabigatzailearekin bateragarritasun arazoren bat dela eta, orri hau ezin izan da ongi bistaratu.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Zerbitzari hau", "firehose.remote": "Beste zerbitzariak", "follow_request.authorize": "Baimendu", "follow_request.reject": "Ukatu", "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": "Zerbitzariaren iradokizunak", + "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.", + "follow_suggestions.hints.most_interactions": "Profil hau arreta handia jasotzen ari da berriki {domain} domeinuan.", + "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", @@ -309,11 +347,10 @@ "hashtag.follow": "Jarraitu traolari", "hashtag.unfollow": "Utzi traola jarraitzeari", "hashtags.and_other": "โ€ฆeta {count, plural, one {}other {# gehiago}}", - "home.column_settings.basic": "Oinarrizkoa", "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", @@ -376,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", @@ -395,9 +432,15 @@ "loading_indicator.label": "Kargatzenโ€ฆ", "media_gallery.toggle_visible": "Txandakatu ikusgaitasuna", "moved_to_account_banner.text": "Zure {disabledAccount} kontua desgaituta dago une honetan, {movedToAccount} kontura aldatu zinelako.", - "mute_modal.duration": "Iraupena", - "mute_modal.hide_notifications": "Ezkutatu erabiltzaile honen jakinarazpenak?", - "mute_modal.indefinite": "Zehaztu gabe", + "mute_modal.hide_from_notifications": "Ezkutatu jakinarazpenetatik", + "mute_modal.hide_options": "Ezkutatu aukerak", + "mute_modal.indefinite": "Desmututua izan arte", + "mute_modal.show_options": "Erakutsi aukerak", + "mute_modal.they_can_mention_and_follow": "Aipa eta jarrai zaitzakete, baina ez dituzu ikusiko.", + "mute_modal.they_wont_know": "Ez dute jakingo mututuak izan direnik.", + "mute_modal.title": "Erabiltzailea mututu nahi duzu?", + "mute_modal.you_wont_see_mentions": "Ez duzu ikusiko bera aipatzen duen argitalpenik.", + "mute_modal.you_wont_see_posts": "Zure argitalpenak ikus ditzake, baina ez dituzu bereak ikusiko.", "navigation_bar.about": "Honi buruz", "navigation_bar.advanced_interface": "Ireki web interfaze aurreratuan", "navigation_bar.blocks": "Blokeatutako erabiltzaileak", @@ -430,20 +473,35 @@ "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.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", + "notification_requests.dismiss": "Baztertu", + "notification_requests.notifications_from": "{name} erabiltzailearen jakinarazpenak", + "notification_requests.title": "Iragazitako jakinarazpenak", "notifications.clear": "Garbitu jakinarazpenak", "notifications.clear_confirmation": "Ziur zure jakinarazpen guztiak behin betirako garbitu nahi dituzula?", "notifications.column_settings.admin.report": "Txosten berriak:", "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": "Erakutsi kategoria guztiak", - "notifications.column_settings.filter_bar.category": "Iragazki azkarraren barra", - "notifications.column_settings.filter_bar.show_bar": "Erakutsi iragazki-barra", + "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:", @@ -469,6 +527,15 @@ "notifications.permission_denied": "Mahaigaineko jakinarazpenak ez daude erabilgarri, nabigatzaileari baimen eskaera ukatu zitzaiolako", "notifications.permission_denied_alert": "Mahaigaineko jakinarazpenak ezin dira gaitu, nabigatzaileari baimena ukatu zitzaiolako", "notifications.permission_required": "Mahaigaineko jakinarazpenak ez daude erabilgarri, horretarako behar den baimena ez delako eman.", + "notifications.policy.filter_new_accounts.hint": "Azken {days, plural, one {egunean} other {# egunetan}} sortua", + "notifications.policy.filter_new_accounts_title": "Kontu berriak", + "notifications.policy.filter_not_followers_hint": "{days, plural, one {Egun batez} other {# egunez}} baino gutxiago jarraitu zaituen jendea barne", + "notifications.policy.filter_not_followers_title": "Jarraitzen ez zaituen jendea", + "notifications.policy.filter_not_following_hint": "Eskuz onartzen dituzun arte", + "notifications.policy.filter_not_following_title": "Jarraitzen ez duzun jendea", + "notifications.policy.filter_private_mentions_hint": "Iragazita, baldin eta zure aipamenaren erantzuna bada edo bidaltzailea jarraitzen baduzu", + "notifications.policy.filter_private_mentions_title": "Eskatu gabeko aipamen pribatuak", + "notifications.policy.title": "Ez iragazi hemengo jakinarazpenakโ€ฆ", "notifications_permission_banner.enable": "Gaitu mahaigaineko jakinarazpenak", "notifications_permission_banner.how_to_control": "Mastodon irekita ez dagoenean jakinarazpenak jasotzeko, gaitu mahaigaineko jakinarazpenak. Mahaigaineko jakinarazpenak ze elkarrekintzak eragingo dituzten zehazki kontrolatu dezakezu goiko {icon} botoia erabiliz, gaituta daudenean.", "notifications_permission_banner.title": "Ez galdu ezer inoiz", @@ -495,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": "Zure Mastodoneko kontu berria prest dago. Jakin nola atera diezaioekun etekin handiena hemen:", + "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.", @@ -509,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", @@ -625,13 +692,10 @@ "server_banner.about_active_users": "Azken 30 egunetan zerbitzari hau erabili duen jendea (hilabeteko erabiltzaile aktiboak)", "server_banner.active_users": "erabiltzaile aktibo", "server_banner.administered_by": "Administratzailea(k):", - "server_banner.introduction": "{domain} zerbitzaria {mastodon} erabiltzen duen sare sozial deszentralizatuko parte da.", - "server_banner.learn_more": "Ikasi gehiago", "server_banner.server_stats": "Zerbitzariaren estatistikak:", "sign_in_banner.create_account": "Sortu kontua", "sign_in_banner.sign_in": "Hasi saioa", "sign_in_banner.sso_redirect": "Hasi saioa edo izena eman", - "sign_in_banner.text": "Hasi saioa profilak edo traolak jarraitzeko, bidalketak gogokoetara gehitzeko, partekatzeko edo erantzuteko. Zure kontutik ere komunika zaitezke beste zerbitzari ezberdin batean.", "status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea", "status.admin_domain": "{domain}-(r)en moderazio-interfazea ireki", "status.admin_status": "Ireki bidalketa hau moderazio interfazean", @@ -645,10 +709,11 @@ "status.direct": "Aipatu pribatuki @{name}", "status.direct_indicator": "Aipamen pribatua", "status.edit": "Editatu", - "status.edited": "Editatua {date}", + "status.edited": "Azken edizioa: {date}", "status.edited_x_times": "{count, plural, one {behin} other {{count} aldiz}} editatua", "status.embed": "Txertatu", "status.favourite": "Gogokoa", + "status.favourites": "{count, plural, one {gogoko} other {gogoko}}", "status.filter": "Iragazi bidalketa hau", "status.filtered": "Iragazita", "status.hide": "Tuta ezkutatu", @@ -669,6 +734,7 @@ "status.reblog": "Bultzada", "status.reblog_private": "Bultzada jatorrizko hartzaileei", "status.reblogged_by": "{name}(r)en bultzada", + "status.reblogs": "{count, plural, one {bultzada} other {bultzada}}", "status.reblogs.empty": "Inork ez dio bultzada eman bidalketa honi oraindik. Inork egiten badu, hemen agertuko da.", "status.redraft": "Ezabatu eta berridatzi", "status.remove_bookmark": "Kendu laster-marka", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 4050ca9f9f..072a67421a 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -110,7 +110,7 @@ "column.about": "ุฏุฑุจุงุฑู‡", "column.blocks": "ฺฉุงุฑุจุฑุงู† ู…ุณุฏูˆุฏ ุดุฏู‡", "column.bookmarks": "ู†ุดุงู†ฺฉโ€Œู‡ุง", - "column.community": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„ู‘Œ", + "column.community": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„Œ", "column.direct": "ุงุดุงุฑู‡โ€Œู‡ุงŒ ุฎุตูˆุตŒ", "column.directory": "ู…ุฑูˆุฑ ู†ู…ุงŒู‡โ€Œู‡ุง", "column.domain_blocks": "ุฏุงู…ู†ู‡โ€Œู‡ุงŒ ู…ุณุฏูˆุฏ ุดุฏู‡", @@ -131,7 +131,7 @@ "column_header.show_settings": "ู†ู…ุงŒุด ุชู†ุธŒู…ุงุช", "column_header.unpin": "ุจุฑุฏุงุดุชู† ุณู†ุฌุงู‚", "column_subheading.settings": "ุชู†ุธŒู…ุงุช", - "community.column_settings.local_only": "ูู‚ุท ู…ุญู„ู‘Œ", + "community.column_settings.local_only": "ูู‚ุท ู…ุญู„Œ", "community.column_settings.media_only": "ูู‚ุท ุฑุณุงู†ู‡", "community.column_settings.remote_only": "ุชู†ู‡ุง ุฏูˆุฑุฏุณุช", "compose.language.change": "ุชุบŒŒุฑ ุฒุจุงู†", @@ -160,9 +160,7 @@ "compose_form.spoiler.unmarked": "ุงูุฒูˆุฏู† ู‡ุดุฏุงุฑ ู…ุญุชูˆุง", "compose_form.spoiler_placeholder": "ู‡ุดุฏุงุฑ ู…ุญุชูˆุง (ุงุฎุชŒุงุฑŒ)", "confirmation_modal.cancel": "ู„ุบูˆ", - "confirmations.block.block_and_report": "ุงู†ุณุฏุงุฏ ูˆ ฺฏุฒุงุฑุด", "confirmations.block.confirm": "ุงู†ุณุฏุงุฏ", - "confirmations.block.message": "ู…ุทู…ุฆู†Œุฏ ฺฉู‡ ู…Œโ€Œุฎูˆุงู‡Œุฏ {name} ุฑุง ู…ุณุฏูˆุฏ ฺฉู†ŒุฏุŸ", "confirmations.cancel_follow_request.confirm": "ุฑุฏ ฺฉุฑุฏู† ุฏุฑุฎูˆุงุณุช", "confirmations.cancel_follow_request.message": "ู…ุทู…ุฆู†Œุฏ ฺฉู‡ ู…Œ ุฎูˆุงู‡Œุฏ ุฏุฑุฎูˆุงุณุช ูพŒโ€ŒฺฏŒุฑŒ {name} ุฑุง ู„ุบูˆ ฺฉู†ŒุฏุŸ", "confirmations.delete.confirm": "ุญุฐู", @@ -171,15 +169,12 @@ "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": "ุฏุฑ ุตูˆุฑุช ูˆŒุฑุงŒุดุŒ ูพŒุงู…Œ ฺฉู‡ ุฏุฑ ุญุงู„ ู†ูˆุดุชู†ุด ุจูˆุฏŒุฏ ุงุฒ ุจŒู† ุฎูˆุงู‡ุฏ ุฑูุช. ู…Œโ€Œุฎูˆุงู‡Œุฏ ุงุฏุงู…ู‡ ุฏู‡ŒุฏุŸ", "confirmations.logout.confirm": "ุฎุฑูˆุฌ ุงุฒ ุญุณุงุจ", "confirmations.logout.message": "ู…ุทู…ุฆู†Œุฏ ู…Œโ€Œุฎูˆุงู‡Œุฏ ุฎุงุฑุฌ ุดูˆŒุฏุŸ", "confirmations.mute.confirm": "ุฎู…ูˆุด", - "confirmations.mute.explanation": "ุงŒู† ฺฉุงุฑ ูุฑุณุชู‡โ€Œู‡ุงŒ ุขู†โ€Œู‡ุง ูˆ ูุฑุณุชู‡โ€Œู‡ุงŒŒ ุฑุง ฺฉู‡ ุงุฒ ุขู†โ€Œู‡ุง ู†ุงู… ุจุฑุฏู‡ ูพู†ู‡ุงู† ู…Œโ€Œฺฉู†ุฏุŒ ูˆู„Œ ุขู†โ€Œู‡ุง ู‡ู…ฺ†ู†ุงู† ุงุฌุงุฒู‡ ุฏุงุฑู†ุฏ ูุฑุณุชู‡โ€Œู‡ุงŒ ุดู…ุง ุฑุง ุจุจŒู†ู†ุฏ ูˆ ุดู…ุง ุฑุง ูพŒโ€ŒฺฏŒุฑŒ ฺฉู†ู†ุฏ.", - "confirmations.mute.message": "ู…ุทู…ุฆู†Œุฏ ู…Œโ€Œุฎูˆุงู‡Œุฏ {name} ุฑุง ุจุฎู…ูˆุดุงู†ŒุฏุŸ", "confirmations.redraft.confirm": "ุญุฐู ูˆ ุจุงุฒู†ูˆŒุณŒ", "confirmations.redraft.message": "ู…ุทู…ุฆู†Œุฏ ฺฉู‡ ู…Œโ€Œุฎูˆุงู‡Œุฏ ุงŒู† ูุฑุณุชู‡ ุฑุง ุญุฐู ฺฉู†Œุฏ ูˆ ุงุฒ ู†ูˆ ุจู†ูˆŒุณŒุฏุŸ ุจุง ุงŒู† ฺฉุงุฑ ุชู‚ูˆŒุชโ€Œู‡ุง ูˆ ูพุณู†ุฏู‡ุงŒุด ุงุฒ ุฏุณุช ุฑูุชู‡ ูˆ ูพุงุณุฎโ€Œู‡ุง ุจู‡ ุขู† ุจŒโ€Œู…ุฑุฌุน ู…Œโ€Œุดูˆุฏ.", "confirmations.reply.confirm": "ูพุงุณุฎ", @@ -228,7 +223,7 @@ "empty_column.account_unavailable": "ู†ู…ุงŒู‡ู” ู…ูˆุฌูˆุฏ ู†Œุณุช", "empty_column.blocks": "ู‡ู†ูˆุฒ ฺฉุณŒ ุฑุง ู…ุณุฏูˆุฏ ู†ฺฉุฑุฏู‡โ€ŒุงŒุฏ.", "empty_column.bookmarked_statuses": "ู‡ู†ูˆุฒ ู‡Œฺ† ูุฑุณุชู‡ู” ู†ุดุงู†ู‡โ€ŒฺฏุฐุงุฑŒ ุดุฏู‡โ€ŒุงŒ ู†ุฏุงุฑŒุฏ. ู‡ู†ฺฏุงู…Œ ฺฉู‡ ูุฑุณุชู‡โ€ŒุงŒ ุฑุง ู†ุดุงู†ู‡โ€ŒฺฏุฐุงุฑŒ ฺฉู†ŒุฏุŒ ุงŒู†โ€Œุฌุง ู†ุดุงู† ุฏุงุฏู‡ ุฎูˆุงู‡ุฏ ุดุฏ.", - "empty_column.community": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„ู‘Œ ุฎุงู„Œ ุงุณุช. ฺ†ŒุฒŒ ุจู†ูˆŒุณŒุฏ ุชุง ฺ†ุฑุฎุด ุจฺ†ุฑุฎุฏ!", + "empty_column.community": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„Œ ุฎุงู„Œุณุช. ฺ†ŒุฒŒ ู†ูˆุดุชู‡ ุชุง ฺ†ุฑุฎุด ุจฺ†ุฑุฎุฏ!", "empty_column.direct": "ู‡ู†ูˆุฒ ู‡Œฺ† ุงุดุงุฑู‡ ุฎุตูˆุตŒโ€ŒุงŒ ู†ุฏุงุฑŒุฏ. ู‡ู†ฺฏุงู…Œ ฺฉู‡ ฺ†ู†Œู† ูพŒุงู…Œ ุจฺฏŒุฑŒุฏ Œุง ุจูุฑุณุชŒุฏ ุงŒู†โ€Œุฌุง ู†ุดุงู† ุฏุงุฏู‡ ุฎูˆุงู‡ุฏ ุดุฏ.", "empty_column.domain_blocks": "ู‡ู†ูˆุฒ ู‡Œฺ† ุฏุงู…ู†ู‡โ€ŒุงŒ ู…ุณุฏูˆุฏ ู†ุดุฏู‡ ุงุณุช.", "empty_column.explore_statuses": "ุงู„ุขู† ฺ†ŒุฒŒ ูพุฑุทุฑูุฏุงุฑ ู†Œุณุช. ุจุนุฏุงู‹ ุฏูˆุจุงุฑู‡ ุจุฑุฑุณŒ ฺฉู†Œุฏ!", @@ -277,6 +272,17 @@ "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": "ุฏŒุฏู† ู‡ู…ู‡", + "follow_suggestions.who_to_follow": "ุงูุฑุงุฏŒ ุจุฑุงŒ ูพŒโ€ŒฺฏŒุฑŒ", "followed_tags": "ุจุฑฺ†ุณุจโ€Œู‡ุงŒ ูพŒโ€Œฺฏุฑูุชู‡", "footer.about": "ุฏุฑุจุงุฑู‡", "footer.directory": "ูู‡ุฑุณุช ู†ู…ุงŒู‡โ€Œู‡ุง", @@ -303,7 +309,6 @@ "hashtag.follow": "ูพŒโ€Œฺฏุฑูุชู† ุจุฑฺ†ุณุจ", "hashtag.unfollow": "ูพŒโ€Œู†ฺฏุฑูุชู† ุจุฑฺ†ุณุจ", "hashtags.and_other": "โ€ฆูˆ {count, plural, other {# ุจŒุดโ€Œุชุฑ}}", - "home.column_settings.basic": "ูพุงŒู‡โ€ŒุงŒ", "home.column_settings.show_reblogs": "ู†ู…ุงŒุด ุชู‚ูˆŒุชโ€Œู‡ุง", "home.column_settings.show_replies": "ู†ู…ุงŒุด ูพุงุณุฎโ€Œู‡ุง", "home.hide_announcements": "ู†ู‡ูุชู† ุงุนู„ุงู…Œู‡โ€Œู‡ุง", @@ -315,8 +320,8 @@ "interaction_modal.description.follow": "ุจุง ุญุณุงุจŒ ุฑูˆŒ ู…ุงุณุชูˆุฏูˆู† ู…Œโ€Œุชูˆุงู†Œุฏ {name} ุฑุง ุจุฑุงŒ ุฏุฑŒุงูุช ูุฑุณุชู‡โ€Œู‡ุงŒุด ุฏุฑ ุฎูˆุฑุงฺฉ ุฎุงู†ฺฏŒุชุงู† ุฏู†ุจุงู„ ฺฉู†Œุฏ.", "interaction_modal.description.reblog": "ุจุง ุญุณุงุจŒ ุฑูˆŒ ู…ุงุณุชูˆุฏูˆู† ู…Œโ€Œุชูˆุงู†Œุฏ ุงŒู† ูุฑุณุชู‡ ุฑุง ุจุง ูพŒโ€ŒฺฏŒุฑุงู† ุฎูˆุฏุชุงู† ู‡ู…โ€Œุฑุณุงู†Œ ฺฉู†Œุฏ.", "interaction_modal.description.reply": "ุจุง ุญุณุงุจŒ ุฑูˆŒ ู…ุงุณุชูˆุฏูˆู† ู…Œโ€Œุชูˆุงู†Œุฏ ุจู‡ ุงŒู† ูุฑุณุชู‡ ูพุงุณุฎ ุฏู‡Œุฏ.", - "interaction_modal.login.action": "ู…ู† ุฑูˆ ุจุจุฑ ุฎูˆู†ู‡", - "interaction_modal.login.prompt": "ุฏุงู…ู†ู‡ ุณุฑูˆุฑ ุดุฎุตŒ ุดู…ุงุŒ ุจู‡ ุนู†ูˆุงู† ู…ุซุงู„. mastodon.social", + "interaction_modal.login.action": "ุฑูุชู† ุจู‡ ุฎุงู†ู‡", + "interaction_modal.login.prompt": "ุฏุงู…ู†ู‡ู” ฺฉุงุฑุณุงุฒ ุดุฎุตŒุชุงู† ฺ†ูˆู† mastodon.social", "interaction_modal.no_account_yet": "ุฏุฑ ู…ุงุณุชูˆุฏูˆู† ู†ŒุณุชุŸ", "interaction_modal.on_another_server": "ุฑูˆŒ ฺฉุงุฑุณุงุฒŒ ุฏŒฺฏุฑ", "interaction_modal.on_this_server": "ุฑูˆŒ ุงŒู† ฺฉุงุฑุณุงุฒ", @@ -345,7 +350,7 @@ "keyboard_shortcuts.home": "ฺฏุดูˆุฏู† ุฎุท ุฒู…ุงู†Œ ุฎุงู†ฺฏŒ", "keyboard_shortcuts.hotkey": "ู…Œุงู†โ€Œุจุฑ", "keyboard_shortcuts.legend": "ู†ู…ุงŒุด ุงŒู† ู†ุดุงู†ู‡", - "keyboard_shortcuts.local": "ฺฏุดูˆุฏู† ุฎุท ุฒู…ุงู†Œ ู…ุญู„ู‘Œ", + "keyboard_shortcuts.local": "ฺฏุดูˆุฏู† ุฎุท ุฒู…ุงู†Œ ู…ุญู„Œ", "keyboard_shortcuts.mention": "ุงุดุงุฑู‡ ุจู‡ ู†ูˆŒุณู†ุฏู‡", "keyboard_shortcuts.muted": "ฺฏุดูˆุฏู† ูู‡ุฑุณุช ฺฉุงุฑุจุฑุงู† ุฎู…ูˆุด", "keyboard_shortcuts.my_profile": "ฺฏุดูˆุฏู† ู†ู…ุงŒู‡โ€Œุชุงู†", @@ -389,14 +394,11 @@ "loading_indicator.label": "ุฏุฑ ุญุงู„ ุจุงุฑฺฏุฐุงุฑŒโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ู†ู‡ูุชู† ุชุตูˆŒุฑ} other {ู†ู‡ูุชู† ุชุตุงูˆŒุฑ}}", "moved_to_account_banner.text": "ุญุณุงุจุชุงู† {disabledAccount} ุงฺฉู†ูˆู† ุงุฒ ฺฉุงุฑ ุงูุชุงุฏู‡ุ› ฺ†ุฑุง ฺฉู‡ ุจู‡ {movedToAccount} ู…ู†ุชู‚ู„ ุดุฏŒุฏ.", - "mute_modal.duration": "ู…ุฏุช ุฒู…ุงู†", - "mute_modal.hide_notifications": "ู†ู‡ูุชู† ุขฺฏุงู‡Œโ€Œู‡ุง ุงุฒ ุงŒู† ฺฉุงุฑุจุฑุŸ", - "mute_modal.indefinite": "ู†ุงู…ุนู„ูˆู…", "navigation_bar.about": "ุฏุฑุจุงุฑู‡", "navigation_bar.advanced_interface": "ุจุงุฒฺฉุฑุฏู† ุฏุฑ ุฑุงุจุท ฺฉุงุฑุจุฑŒ ูˆุจ ูพŒุดุฑูุชู‡", "navigation_bar.blocks": "ฺฉุงุฑุจุฑุงู† ู…ุณุฏูˆุฏ ุดุฏู‡", "navigation_bar.bookmarks": "ู†ุดุงู†ฺฉโ€Œู‡ุง", - "navigation_bar.community_timeline": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„ู‘Œ", + "navigation_bar.community_timeline": "ุฎุท ุฒู…ุงู†Œ ู…ุญู„Œ", "navigation_bar.compose": "ู†ูˆุดุชู† ูุฑุณุชู‡ู” ุชุงุฒู‡", "navigation_bar.direct": "ุงุดุงุฑู‡โ€Œู‡ุงŒ ุฎุตูˆุตŒ", "navigation_bar.discover": "ฺฏุดุช ูˆ ฺฏุฐุงุฑ", @@ -435,9 +437,6 @@ "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.filter_bar.show_bar": "ู†ู…ุงŒุด ู†ูˆุงุฑ ูพุงู„ุงŒู‡", "notifications.column_settings.follow": "ูพŒโ€ŒฺฏŒุฑู†ุฏฺฏุงู† ุฌุฏŒุฏ:", "notifications.column_settings.follow_request": "ุฏุฑุฎูˆุงุณุชโ€Œู‡ุงŒ ุฌุฏŒุฏ ูพŒโ€ŒฺฏŒุฑŒ:", "notifications.column_settings.mention": "ุงุดุงุฑู‡โ€Œู‡ุง:", @@ -463,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": "ู‡ุฑฺฏุฒ ฺ†ŒุฒŒ ุฑุง ุงุฒ ุฏุณุช ู†ุฏู‡Œุฏ", @@ -475,8 +476,10 @@ "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.title": "Popular on Mastodon", "onboarding.profile.discoverable": "ู†ู…ุงŒู‡ ุฎูˆุฏ ุฑุง ู‚ุงุจู„ ู†ู…ุงŒุด ฺฉู†Œุฏ", + "onboarding.profile.discoverable_hint": "ุฎูˆุงุณุชู‡โ€ŒุงŒุฏ ุฑูˆŒ ู…ุงุณุชูˆุฏูˆู† ฺฉุดู ุดูˆŒุฏ. ู…ู…ฺฉู† ุงุณุช ูุฑุณุชู‡โ€Œู‡ุงŒุชุงู† ุฏุฑ ู†ุชŒุญู‡ู” ุฌุณุชโ€Œูˆุฌูˆู‡ุง ูˆ ูุฑุณุชู‡โ€Œู‡ุงŒ ุฏุงุบ ุธุงู‡ุฑ ุดุฏู‡ ูˆ ู†ู…ุงŒู‡โ€Œุชุงู† ุจู‡ ุงูุฑุงุฏŒ ุจุง ุนู„ุงŒู‚ ู…ุดุงุจู‡ุชุงู† ูพŒุดู†ู‡ุงุฏ ุดูˆุฏ.", "onboarding.profile.display_name": "ู†ุงู… ู†ู…ุงŒุดŒ", "onboarding.profile.display_name_hint": "ู†ุงู… ฺฉุงู…ู„ Œุง ู†ุงู… ุจุงุญุงู„ุชุงู†โ€ฆ", + "onboarding.profile.lead": "ู‡ู…ูˆุงุฑู‡ ู…Œโ€Œุชูˆุงู†Œุฏ ุงŒู† ู…ูˆุฑุฏ ุฑุง ุฏุฑ ุชู†ุธŒู…ุงุช ฺฉู‡ ฺฏุฒŒู†ู‡โ€Œู‘ุงŒ ุดุฎุตŒย ุณุงุฒŒ ุจŒุดโ€ŒุชุฑŒ ู†Œุฒ ุฏุงุฑุฏ ฺฉุงู…ู„ ฺฉู†Œุฏ.", "onboarding.profile.note": "ุฏุฑุจุงุฑู‡ ุดู…ุง", "onboarding.profile.note_hint": "ู…Œโ€Œุชูˆุงู†Œุฏ ุงูุฑุงุฏ ุฏŒฺฏุฑ ุฑุง @ู†ุงู…โ€Œุจุฑุฏู† Œุง #ุจุฑฺ†ุณุจ ุจุฒู†Œุฏโ€ฆ", "onboarding.profile.save_and_continue": "ุฐุฎŒุฑู‡ ฺฉู† ูˆ ุงุฏุงู…ู‡ ุจุฏู‡", @@ -522,6 +525,7 @@ "privacy.private.short": "ูพŒโ€ŒฺฏŒุฑู†ุฏฺฏุงู†", "privacy.public.long": "ู‡ุฑฺฉุณŒ ุฏุฑ ูˆ ุจŒุฑูˆู† ุงุฒ ู…ุงุณุชูˆุฏูˆู†", "privacy.public.short": "ุนู…ูˆู…Œ", + "privacy.unlisted.additional": "ุฏุฑุณุช ู…ุซู„ ุนู…ูˆู…Œ ุฑูุชุงุฑ ู…Œโ€Œฺฉู†ุฏุ› ุฌุฒ ุงŒู† ฺฉู‡ ูุฑุณุชู‡ ุฏุฑ ุจุฑฺ†ุณุจโ€Œู‡ุง Œุง ุฎูˆุฑุงฺฉโ€Œู‡ุงŒ ุฒู†ุฏู‡ุŒ ฺฉุดู Œุง ุฌุณุชโ€ŒูˆุฌูˆŒ ู…ุงุณุชูˆุฏูˆู† ุธุงู‡ุฑ ู†ุฎูˆุงู‡ุฏ ุดุฏ. ุญุชุง ุงฺฏุฑ ฺฉู„Œู‘ุช ู†ู…ุงŒู‡โ€Œุชุงู† ุงุฌุงุฒู‡ ุฏุงุฏู‡ ุจุงุดุฏ.", "privacy.unlisted.long": "ุณุฑูˆุตุฏุงŒ ุงู„ฺฏูˆุฑŒุชู…Œ ฺฉู…โ€Œุชุฑ", "privacy.unlisted.short": "ุนู…ูˆู…Œ ุณุงฺฉุช", "privacy_policy.last_updated": "ุขุฎุฑŒู† ุจู‡โ€Œุฑูˆุฒ ุฑุณุงู†Œ ุฏุฑ {date}", @@ -541,6 +545,7 @@ "relative_time.minutes": "{number} ุฏู‚Œู‚ู‡", "relative_time.seconds": "{number} ุซุงู†Œู‡", "relative_time.today": "ุงู…ุฑูˆุฒ", + "reply_indicator.attachments": "{count, plural, one {# ูพŒูˆุณุช} other {# ูพŒูˆุณุช}}", "reply_indicator.cancel": "ู„ุบูˆ", "reply_indicator.poll": "ู†ุธุฑุณู†ุฌŒ", "report.block": "ุงู†ุณุฏุงุฏ", @@ -615,13 +620,10 @@ "server_banner.about_active_users": "ุงูุฑุงุฏŒ ฺฉู‡ ุฏุฑ ณฐ ุฑูˆุฒ ฺฏุฐุดุชู‡ ุงุฒ ุงŒู† ฺฉุงุฑุณุงุฒ ุงุณุชูุงุฏู‡ ฺฉุฑุฏู‡โ€Œุงู†ุฏ (ฺฉุงุฑุจุฑุงู† ูุนู‘ุงู„ ู…ุงู‡ุงู†ู‡)", "server_banner.active_users": "ฺฉุงุฑุจุฑ ูุนู‘ุงู„", "server_banner.administered_by": "ุจู‡ ู…ุฏŒุฑŒุช:", - "server_banner.introduction": "{domain} ุจุฎุดŒ ุงุฒ ุดุจฺฉู‡ู” ุงุฌุชู…ุงุนŒ ู†ุงู…ุชู…ุฑฺฉุฒŒุณุช ฺฉู‡ ุงุฒ {mastodon} ู†Œุฑูˆ ฺฏุฑูุชู‡.", - "server_banner.learn_more": "ุจŒุดโ€Œุชุฑ ุจŒุงู…ูˆุฒŒุฏ", "server_banner.server_stats": "ุขู…ุงุฑ ฺฉุงุฑุณุงุฒ:", "sign_in_banner.create_account": "ุงŒุฌุงุฏ ุญุณุงุจ", "sign_in_banner.sign_in": "ูˆุฑูˆุฏ", "sign_in_banner.sso_redirect": "ูˆุฑูˆุฏ Œุง ุซุจุช ู†ุงู…", - "sign_in_banner.text": "ุจุฑุงŒ ูพŒโ€ŒฺฏŒุฑŒ ู†ู…ุงŒู‡โ€Œู‡ุง Œุง ุจุฑฺ†ุณุจโ€Œู‡ุงุŒ ูพุณู†ุฏŒุฏู†ุŒ ู‡ู…โ€Œุฑุณุงู†Œ ูˆ Œุง ูพุงุณุฎ ุจู‡ ูุฑุณุชู‡โ€Œู‡ุง ูˆุงุฑุฏ ุดูˆŒุฏ. ู‡ู…ฺ†ู†Œู† ู…Œโ€Œุชูˆุงู†Œุฏ ุงŒู† ฺฉุงุฑู‡ุง ุฑุง ุจุง ุญุณุงุจุชุงู† ุฏุฑ ฺฉุงุฑุณุงุฒŒ ุฏŒฺฏุฑ ุงู†ุฌุงู… ุฏู‡Œุฏ.", "status.admin_account": "ฺฏุดูˆุฏู† ูˆุงุณุท ู…ุฏŒุฑŒุช ุจุฑุงŒ โ€Ž@{name}", "status.admin_domain": "ฺฏุดูˆุฏู† ูˆุงุณุท ู…ุฏŒุฑŒุช ุจุฑุงŒ โ€Ž{domain}", "status.admin_status": "ฺฏุดูˆุฏู† ุงŒู† ูุฑุณุชู‡ ุฏุฑ ูˆุงุณุท ู…ุฏŒุฑŒุช", @@ -635,7 +637,6 @@ "status.direct": "ุงุดุงุฑู‡ู” ุฎุตูˆุตŒ ุจู‡ โ€ช@{name}โ€ฌ", "status.direct_indicator": "ุงุดุงุฑู‡ู” ุฎุตูˆุตŒ", "status.edit": "ูˆŒุฑุงŒุด", - "status.edited": "ูˆŒุฑุงŒุด ุดุฏู‡ ุฏุฑ {date}", "status.edited_x_times": "{count, plural, one {{count} ู…ุฑุชุจู‡} other {{count} ู…ุฑุชุจู‡}} ูˆŒุฑุงŒุด ุดุฏ", "status.embed": "ุฌุงุณุงุฒŒ", "status.favourite": "ุจุฑฺฏุฒŒุฏู‡โ€Œ", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 277f0f2e72..67e2b72b86 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -89,6 +89,14 @@ "announcement.announcement": "Tiedote", "attachments_list.unprocessed": "(kรคsittelemรคtรถn)", "audio.hide": "Piilota รครคni", + "block_modal.remote_users_caveat": "Pyydรคmme palvelinta {domain} kunnioittamaan pรครคtรถstรคsi. Myรถtรคmielisyyttรค ei kuitenkaan taata, koska jotkin palvelimet voivat kรคsitellรค estoja eri tavalla. Julkiset julkaisut voivat silti nรคkyรค kirjautumattomille kรคyttรคjille.", + "block_modal.show_less": "Nรคytรค vรคhemmรคn", + "block_modal.show_more": "Nรคytรค enemmรคn", + "block_modal.they_cant_mention": "Hรคn ei voi enรครค mainita eikรค seurata sinua.", + "block_modal.they_cant_see_posts": "Hรคn ei voi enรครค nรคhdรค julkaisujasi, etkรค sinรค voi nรคhdรค hรคnen.", + "block_modal.they_will_know": "Hรคn voi nรคhdรค, ettรค hรคnet on estetty.", + "block_modal.title": "Estetรครคnkรถ kรคyttรคjรค?", + "block_modal.you_wont_see_mentions": "Et tule enรครค nรคkemรครคn julkaisuja, joissa hรคnet mainitaan.", "boost_modal.combo": "Ensi kerralla voit ohittaa tรคmรคn painamalla {combo}", "bundle_column_error.copy_stacktrace": "Kopioi virheraportti", "bundle_column_error.error.body": "Pyydettyรค sivua ei voitu hahmontaa. Se voi johtua virheestรค koodissamme tai selaimen yhteensopivuudessa.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Lisรครค sisรคltรถvaroitus", "compose_form.spoiler_placeholder": "Sisรคltรถvaroitus (valinnainen)", "confirmation_modal.cancel": "Peruuta", - "confirmations.block.block_and_report": "Estรค ja raportoi", "confirmations.block.confirm": "Estรค", - "confirmations.block.message": "Haluatko varmasti estรครค kรคyttรคjรคn {name}?", "confirmations.cancel_follow_request.confirm": "Peruuta pyyntรถ", "confirmations.cancel_follow_request.message": "Haluatko varmasti perua pyyntรถsi seurata kรคyttรคjรคtiliรค {name}?", "confirmations.delete.confirm": "Poista", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Haluatko varmasti poistaa tรคmรคn listan pysyvรคsti?", "confirmations.discard_edit_media.confirm": "Hylkรครค", "confirmations.discard_edit_media.message": "Sinulla on tallentamattomia muutoksia median kuvaukseen tai esikatseluun. Hylรคtรครคnkรถ ne silti?", - "confirmations.domain_block.confirm": "Estรค koko verkkotunnus", + "confirmations.domain_block.confirm": "Estรค palvelin", "confirmations.domain_block.message": "Haluatko aivan varmasti estรครค koko verkkotunnuksen {domain}? Useimmiten muutama kohdistettu esto tai mykistys on riittรคvรค ja suositeltava toimi. Et nรคe sisรคltรถรค tรคstรค verkkotunnuksesta millรครคn julkisilla aikajanoilla tai ilmoituksissa. Tรคhรคn verkkotunnukseen kuuluvat seuraajasi poistetaan.", "confirmations.edit.confirm": "Muokkaa", "confirmations.edit.message": "Jos muokkaat viestiรค nyt, se korvaa parhaillaan tyรถstรคmรคsi viestin. Haluatko varmasti jatkaa?", "confirmations.logout.confirm": "Kirjaudu ulos", "confirmations.logout.message": "Haluatko varmasti kirjautua ulos?", "confirmations.mute.confirm": "Mykistรค", - "confirmations.mute.explanation": "Tรคmรค toiminto piilottaa heidรคn julkaisunsa sinulta โ€“ mukaan lukien ne, joissa heidรคt mainitaan โ€“ sallien heidรคn yhรค nรคhdรค julkaisusi ja seurata sinua.", - "confirmations.mute.message": "Haluatko varmasti mykistรครค kรคyttรคjรคn {name}?", "confirmations.redraft.confirm": "Poista ja palauta muokattavaksi", "confirmations.redraft.message": "Haluatko varmasti poistaa julkaisun ja tehdรค siitรค luonnoksen? Suosikit ja tehostukset menetetรครคn, ja alkuperรคisen julkaisun vastaukset jรครคvรคt orvoiksi.", "confirmations.reply.confirm": "Vastaa", @@ -201,10 +205,31 @@ "disabled_account_banner.text": "Tilisi {disabledAccount} on tรคllรค hetkellรค poissa kรคytรถstรค.", "dismissable_banner.community_timeline": "Nรคmรค ovat tuoreimpia julkaisuja kรคyttรคjiltรค, joiden tili on palvelimella {domain}.", "dismissable_banner.dismiss": "Hylkรครค", - "dismissable_banner.explore_links": "Nรคitรค uutisia jaetaan tรคnรครคn sosiaalisessa verkossa eniten. Uusimmat ja eri kรคyttรคjien eniten lรคhettรคmรคt uutiset nousevat listauksessa korkeimmalle.", - "dismissable_banner.explore_statuses": "Tรคnรครคn nรคmรค sosiaalisen verkon julkaisut kerรครคvรคt eniten huomiota. Uusimmat, tehostetuimmat ja suosikeiksi lisรคtyimmรคt julkaisut nousevat listauksessa korkeammalle.", - "dismissable_banner.explore_tags": "Nรคmรค sosiaalisen verkon aihetunnisteet kerรครคvรคt tรคnรครคn eniten huomiota. Useimman kรคyttรคjรคn kรคyttรคmรคt aihetunnisteet nousevat listauksessa korkeimmalle.", + "dismissable_banner.explore_links": "Nรคitรค uutisia jaetaan tรคnรครคn sosiaalisessa verkossa eniten. Uusimmat ja eri kรคyttรคjien eniten lรคhettรคmรคt uutiset nousevat listauksessa korkeammalle.", + "dismissable_banner.explore_statuses": "Nรคmรค sosiaalisen verkon julkaisut kerรครคvรคt tรคnรครคn eniten huomiota. Uusimmat, tehostetuimmat ja suosikeiksi lisรคtyimmรคt julkaisut nousevat listauksessa korkeammalle.", + "dismissable_banner.explore_tags": "Nรคmรค sosiaalisen verkon aihetunnisteet kerรครคvรคt tรคnรครคn eniten huomiota. Useimman kรคyttรคjรคn kรคyttรคmรคt aihetunnisteet nousevat listauksessa korkeammalle.", "dismissable_banner.public_timeline": "Nรคmรค ovat viimeisimpiรค julkaisuja sosiaalisen verkon kรคyttรคjiltรค, joita seurataan palvelimella {domain}.", + "domain_block_modal.block": "Estรค palvelin", + "domain_block_modal.block_account_instead": "Estรค sen sijaan @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Ihmiset tรคltรค palvelimelta eivรคt voi olla vuorovaikutuksessa vanhojen julkaisujesi kanssa.", + "domain_block_modal.they_cant_follow": "Kukaan tรคltรค palvelimelta ei voi seurata sinua.", + "domain_block_modal.they_wont_know": "Hรคn ei saa ilmoitusta tulleensa estetyksi.", + "domain_block_modal.title": "Estetรครคnkรถ verkkotunnus?", + "domain_block_modal.you_will_lose_followers": "Kaikki seuraajasi tรคltรค palvelimelta poistetaan.", + "domain_block_modal.you_wont_see_posts": "Et enรครค nรคe julkaisuja etkรค ilmoituksia tรคmรคn palvelimen kรคyttรคjiltรค.", + "domain_pill.activitypub_lets_connect": "Sen avulla voit muodostaa yhteyden ja olla vuorovaikutuksessa ihmisten kanssa, ei vain Mastodonissa vaan myรถs muissa sosiaalisissa sovelluksissa.", + "domain_pill.activitypub_like_language": "ActivityPub on kuin kieli, jota Mastodon puhuu muiden sosiaalisten verkostojen kanssa.", + "domain_pill.server": "Palvelin", + "domain_pill.their_handle": "Hรคnen kรคyttรคjรคnimensรค:", + "domain_pill.their_server": "Hรคnen digitaalinen kotinsa, jossa kaikki hรคnen julkaisunsa sijaitsevat.", + "domain_pill.their_username": "Hรคnen yksilรถllinen tunnisteensa omalla palvelimellaan. Eri palvelimilta on mahdollista lรถytรครค kรคyttรคjiรค, joilla on sama kรคyttรคjรคnimi.", + "domain_pill.username": "Kรคyttรคjรคnimi", + "domain_pill.whats_in_a_handle": "Mitรค kรคyttรคjรคnimessรค on?", + "domain_pill.who_they_are": "Koska kรคyttรคjรคtunnukset kertovat, kuka ja missรค joku on, voit olla vuorovaikutuksessa ihmisten kanssa lรคpi sosiaalisen verkon, joka koostuu .", + "domain_pill.who_you_are": "Koska kรคyttรคjรคtunnuksesi kertoo, kuka ja missรค olet, ihmiset voivat olla vaikutuksessa kanssasi lรคpi sosiaalisen verkon, joka koostuu .", + "domain_pill.your_handle": "Kรคyttรคjรคnimesi:", + "domain_pill.your_server": "Digitaalinen kotisi, jossa kaikki julkaisusi sijaitsevat. Etkรถ pidรค tรคstรค? Siirry palvelimelta toiselle milloin tahansa ja tuo myรถs seuraajasi mukanasi.", + "domain_pill.your_username": "Yksilรถllinen tunnisteesi tรคllรค palvelimella. Eri palvelimilta on mahdollista lรถytรครค kรคyttรคjiรค, joilla on sama kรคyttรคjรคnimi.", "embed.instructions": "Upota julkaisu verkkosivullesi kopioimalla alla oleva koodi.", "embed.preview": "Tรคltรค se nรคyttรครค:", "emoji_button.activity": "Aktiviteetit", @@ -241,6 +266,7 @@ "empty_column.list": "Tรคllรค listalla ei ole vielรค mitรครคn. Kun tรคmรคn listan jรคsenet lรคhettรคvรคt uusia julkaisuja, ne nรคkyvรคt tรคssรค.", "empty_column.lists": "Sinulla ei ole vielรค yhtรครคn listaa. Kun luot sellaisen, nรคkyy se tรคssรค.", "empty_column.mutes": "Et ole mykistรคnyt vielรค yhtรครคn kรคyttรคjรครค.", + "empty_column.notification_requests": "Olet ajan tasalla! Tรครคllรค ei ole mitรครคn uutta kerrottavaa. Kun saat uusia ilmoituksia, ne nรคkyvรคt tรครคllรค asetustesi mukaisesti.", "empty_column.notifications": "Sinulla ei ole vielรค ilmoituksia. Kun keskustelet muille, nรคet sen tรครคllรค.", "empty_column.public": "Tรครคllรค ei ole mitรครคn! Kirjoita jotain julkisesti. Voit myรถs seurata muiden palvelimien kรคyttรคjiรค", "error.unexpected_crash.explanation": "Sivua ei voida nรคyttรครค oikein ohjelmointivirheen tai selaimen yhteensopivuusvajeen vuoksi.", @@ -271,16 +297,28 @@ "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.mentions": "{count, plural, one {maininta} other {mainintaa}}", + "filtered_notifications_banner.pending_requests": "Ilmoituksia {count, plural, =0 {ei ole} one {1 henkilรถltรค} other {# henkilรถltรค}}, jonka saatat tuntea", + "filtered_notifications_banner.title": "Suodatetut ilmoitukset", "firehose.all": "Kaikki", "firehose.local": "Tรคmรค palvelin", "firehose.remote": "Muut palvelimet", "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": "Pรครคtoimittajan valinta", + "follow_suggestions.curated_suggestion": "Ehdotus yllรคpidolta", "follow_suggestions.dismiss": "ร„lรค nรคytรค uudelleen", - "follow_suggestions.personalized_suggestion": "Personoitu ehdotus", + "follow_suggestions.featured_longer": "Palvelimen {domain} tiimin poimintoja", + "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": "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Seuraa aihetunnistetta", "hashtag.unfollow": "Lopeta aihetunnisteen seuraaminen", "hashtags.and_other": "โ€ฆja {count, plural, other {# lisรครค}}", - "home.column_settings.basic": "Perusasetukset", "home.column_settings.show_reblogs": "Nรคytรค tehostukset", "home.column_settings.show_replies": "Nรคytรค vastaukset", "home.hide_announcements": "Piilota tiedotteet", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Nรคytรค profiili joka tapauksessa", "limited_account_hint.title": "Palvelimen {domain} valvojat ovat piilottaneet tรคmรคn kรคyttรคjรคtilin.", "link_preview.author": "Julkaissut {name}", + "link_preview.more_from_author": "Lisรครค kรคyttรคjรคltรค {name}", + "link_preview.shares": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}", "lists.account.add": "Lisรครค listalle", "lists.account.remove": "Poista listalta", "lists.delete": "Poista lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Ladataanโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Piilota kuva} other {Piilota kuvat}}", "moved_to_account_banner.text": "Tilisi {disabledAccount} on tรคllรค hetkellรค poissa kรคytรถstรค, koska teit siirron tiliin {movedToAccount}.", - "mute_modal.duration": "Kesto", - "mute_modal.hide_notifications": "Piilotetaanko tรคltรค kรคyttรคjรคltรค tulevat ilmoitukset?", - "mute_modal.indefinite": "Ikuisesti", + "mute_modal.hide_from_notifications": "Piilota ilmoituksista", + "mute_modal.hide_options": "Piilota vaihtoehdot", + "mute_modal.indefinite": "Kunnes perun hรคntรค koskevan mykistyksen", + "mute_modal.show_options": "Nรคytรค vaihtoehdot", + "mute_modal.they_can_mention_and_follow": "Hรคn voi mainita sinut ja seurata sinua, mutta sinรค et nรคe hรคntรค.", + "mute_modal.they_wont_know": "Hรคn ei saa ilmoitusta tulleensa mykistetyksi.", + "mute_modal.title": "Mykistetรครคnkรถ kรคyttรคjรค?", + "mute_modal.you_wont_see_mentions": "Et tule enรครค nรคkemรครคn julkaisuja, joissa hรคnet mainitaan.", + "mute_modal.you_wont_see_posts": "Hรคn voi yhรค nรคhdรค julkaisusi, mutta sinรค et nรคe hรคnen.", "navigation_bar.about": "Tietoja", "navigation_bar.advanced_interface": "Avaa edistyneessรค selainkรคyttรถliittymรคssรค", "navigation_bar.blocks": "Estetyt kรคyttรคjรคt", @@ -430,11 +475,29 @@ "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.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", + "notification_requests.dismiss": "Hylkรครค", + "notification_requests.notifications_from": "Ilmoitukset kรคyttรคjรคltรค {name}", + "notification_requests.title": "Suodatetut ilmoitukset", "notifications.clear": "Tyhjennรค ilmoitukset", "notifications.clear_confirmation": "Haluatko varmasti poistaa kaikki ilmoitukset pysyvรคsti?", "notifications.column_settings.admin.report": "Uudet ilmoitukset:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Nรคytรค suodatinpalkki", "notifications.column_settings.follow": "Uudet seuraajat:", "notifications.column_settings.follow_request": "Uudet seuraamispyynnรถt:", "notifications.column_settings.mention": "Maininnat:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Tyรถpรถytรคilmoitukset eivรคt ole kรคytettรคvissรค, koska selaimen kรคyttรถoikeuspyyntรถ on aiemmin evรคtty", "notifications.permission_denied_alert": "Tyรถpรถytรคilmoituksia ei voi ottaa kรคyttรถรถn, koska selaimen kรคyttรถoikeus on aiemmin estetty", "notifications.permission_required": "Tyรถpรถytรคilmoitukset eivรคt ole kรคytettรคvissรค, koska siihen tarvittavaa lupaa ei ole myรถnnetty.", + "notifications.policy.filter_new_accounts.hint": "Luotu {days, plural, one {viimeisimmรคn pรคivรคn aikana} other {# viime pรคivรคn aikana}}", + "notifications.policy.filter_new_accounts_title": "Uudet tilit", + "notifications.policy.filter_not_followers_hint": "Mukaan lukien alle {days, plural, one {pรคivรคn} other {# pรคivรคn}} verran sinua seuranneet", + "notifications.policy.filter_not_followers_title": "Henkilรถt, jotka eivรคt seuraa sinua", + "notifications.policy.filter_not_following_hint": "Kunnes hyvรคksyt ne omin kรคsin", + "notifications.policy.filter_not_following_title": "Henkilรถt, joita et seuraa", + "notifications.policy.filter_private_mentions_hint": "Suodatetaan, ellei se vastaa omaan mainintaasi tai ellet seuraa lรคhettรคjรครค", + "notifications.policy.filter_private_mentions_title": "Ei-toivotut yksityismaininnat", + "notifications.policy.title": "Suodata ilmoitukset pois kohteestaโ€ฆ", "notifications_permission_banner.enable": "Ota tyรถpรถytรคilmoitukset kรคyttรถรถn", "notifications_permission_banner.how_to_control": "Saadaksesi ilmoituksia, kun Mastodon ei ole auki, ota tyรถpรถytรคilmoitukset kรคyttรถรถn. Voit hallita tarkasti, mistรค saat tyรถpรถytรคilmoituksia kun ilmoitukset on otettu kรคyttรถรถn yllรค olevan {icon}-painikkeen kautta.", "notifications_permission_banner.title": "ร„lรค anna minkรครคn mennรค ohi", @@ -499,7 +570,7 @@ "onboarding.start.skip": "Haluatko hypรคtรค suoraan eteenpรคin ilman alkuunpรครคsyohjeistuksia?", "onboarding.start.title": "Olet tehnyt sen!", "onboarding.steps.follow_people.body": "Mastodon perustuu sinua kiinnostavien henkilรถjen julkaisujen seuraamiseen.", - "onboarding.steps.follow_people.title": "Mukauta kotisyรถtteesi", + "onboarding.steps.follow_people.title": "Mukauta kotisyรถtettรคsi", "onboarding.steps.publish_status.body": "Tervehdi maailmaa sanoin, kuvin tai รครคnestyksin {emoji}", "onboarding.steps.publish_status.title": "Laadi ensimmรคinen julkaisusi", "onboarding.steps.setup_profile.body": "Tรคydentรคmรคllรค profiilisi tietoja tehostat vuorovaikutteisuutta.", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Palvelimen kรคyttรคjรคt viimeisten 30 pรคivรคn ajalta (kuukauden aktiiviset kรคyttรคjรคt)", "server_banner.active_users": "aktiivista kรคyttรคjรครค", "server_banner.administered_by": "Yllรคpitรคjรค:", - "server_banner.introduction": "{domain} kuuluu hajautettuun sosiaaliseen verkostoon, jonka voimanlรคhde on {mastodon}.", - "server_banner.learn_more": "Lue lisรครค", + "server_banner.is_one_of_many": "{domain} on yksi monista itsenรคisistรค Mastodon-palvelimista, joiden vรคlityksellรค voit toimia fediversumissa.", "server_banner.server_stats": "Palvelimen tilastot:", "sign_in_banner.create_account": "Luo tili", + "sign_in_banner.follow_anyone": "Seuraa kenen tahansa julkaisuja fediversumissa ja nรคe ne kaikki aikajรคrjestyksessรค. Ei algoritmejรค, mainoksia tai klikkikalastelua.", + "sign_in_banner.mastodon_is": "Mastodon on paras tapa pysyรค ajan tasalla siitรค, mitรค ympรคrillรค tapahtuu.", "sign_in_banner.sign_in": "Kirjaudu", "sign_in_banner.sso_redirect": "Kirjaudu tai rekisterรถidy", - "sign_in_banner.text": "Kirjaudu sisรครคn, niin voit seurata profiileja tai aihetunnisteita, lisรคtรค julkaisuja suosikkeihin, jakaa julkaisuja ja vastata niihin. Voit olla vuorovaikutuksessa myรถs eri palvelimella olevalta tililtรคsi.", "status.admin_account": "Avaa tilin @{name} valvontanรคkymรค", "status.admin_domain": "Avaa palvelimen {domain} valvontanรคkymรค", "status.admin_status": "Avaa julkaisu valvontanรคkymรคssรค", @@ -645,14 +716,15 @@ "status.direct": "Mainitse @{name} yksityisesti", "status.direct_indicator": "Yksityinen maininta", "status.edit": "Muokkaa", - "status.edited": "Muokattu {date}", + "status.edited": "Viimeksi muokattu {date}", "status.edited_x_times": "Muokattu {count, plural, one {{count} kerran} other {{count} kertaa}}", "status.embed": "Upota", "status.favourite": "Suosikki", + "status.favourites": "{count, plural, one {suosikki} other {suosikkia}}", "status.filter": "Suodata tรคmรค julkaisu", "status.filtered": "Suodatettu", "status.hide": "Piilota julkaisu", - "status.history.created": "{name} luotu {date}", + "status.history.created": "{name} loi {date}", "status.history.edited": "{name} muokkasi {date}", "status.load_more": "Lataa lisรครค", "status.media.open": "Avaa napsauttamalla", @@ -669,6 +741,7 @@ "status.reblog": "Tehosta", "status.reblog_private": "Tehosta alkuperรคiselle yleisรถlle", "status.reblogged_by": "{name} tehosti", + "status.reblogs": "{count, plural, one {tehostus} other {tehostusta}}", "status.reblogs.empty": "Kukaan ei ole vielรค tehostanut tรคtรค julkaisua. Kun joku tekee niin, tulee hรคn tรคhรคn nรคkyviin.", "status.redraft": "Poista ja palauta muokattavaksi", "status.remove_bookmark": "Poista kirjanmerkki", diff --git a/app/javascript/mastodon/locales/fil.json b/app/javascript/mastodon/locales/fil.json index b677f9d197..9e459f7671 100644 --- a/app/javascript/mastodon/locales/fil.json +++ b/app/javascript/mastodon/locales/fil.json @@ -46,7 +46,13 @@ "account.report": "I-ulat si/ang @{name}", "account.requested_follow": "Hinihiling ni {name} na sundan ka", "account.show_reblogs": "Ipakita ang mga pagpapalakas mula sa/kay {name}", + "account.unendorse": "Huwag itampok sa profile", "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.show_less": "Magpakita ng mas kaunti", + "block_modal.show_more": "Magpakita ng higit pa", + "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", @@ -98,18 +104,23 @@ "compose_form.encryption_warning": "Ang mga post sa Mastodon ay hindi naka-encrypt nang dulo-dulo. Huwag magbahagi ng anumang sensitibong impormasyon sa Mastodon.", "compose_form.hashtag_warning": "Hindi maililista ang post na ito sa anumang hashtag dahil hindi ito nakapubliko. Mga nakapublikong post lamang ang mahahanap ayon sa hashtag.", "compose_form.placeholder": "Anong nangyari?", + "compose_form.poll.duration": "Tagal ng botohan", + "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.block_and_report": "Harangan at i-ulat", "confirmations.block.confirm": "Harangan", - "confirmations.block.message": "Sigurado ka bang gusto mong harangan si {name}?", "confirmations.cancel_follow_request.confirm": "Bawiin ang kahilingan", "confirmations.cancel_follow_request.message": "Sigurdo ka bang gusto mong bawiin ang kahilingang sundan si/ang {name}?", - "confirmations.domain_block.confirm": "Harangan ang buong domain", + "confirmations.delete.message": "Sigurado ka bang gusto mong burahin ang post na ito?", + "confirmations.delete_list.confirm": "Tanggalin", + "confirmations.delete_list.message": "Sigurado ka bang gusto mong burahin ang listahang ito?", + "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", @@ -125,6 +136,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", @@ -161,6 +176,10 @@ "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.suggested_follows": "Mga tao", + "explore.title": "Tuklasin", + "explore.trending_links": "Mga balita", + "filter_modal.select_filter.search": "Hanapin o gumawa", "firehose.all": "Lahat", "firehose.local": "Itong serbiro", "firehose.remote": "Ibang mga serbiro", @@ -171,50 +190,142 @@ "follow_suggestions.who_to_follow": "Sinong maaaring sundan", "footer.about": "Tungkol dito", "footer.get_app": "Kunin ang app", + "footer.status": "Katayuan", "generic.saved": "Nakaimbak", "hashtag.column_header.tag_mode.all": "at {additional}", "hashtag.column_header.tag_mode.any": "o {additional}", + "hashtag.column_settings.tag_mode.all": "Lahat ng nandito", + "hashtag.column_settings.tag_mode.any": "Ilan dito", + "hashtag.column_settings.tag_mode.none": "Wala dito", + "hashtags.and_other": "โ€ฆat {count, plural, one {# iba pa} other {# na iba pa}}", + "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?", "interaction_modal.on_another_server": "Sa ibang serbiro", "interaction_modal.on_this_server": "Sa serbirong ito", "interaction_modal.title.follow": "Sundan si {name}", + "intervals.full.days": "{number, plural, one {# araw} other {# na araw}}", + "intervals.full.hours": "{number, plural, one {# oras} other {# na oras}}", + "intervals.full.minutes": "{number, plural, one {# minuto} other {# na minuto}}", + "keyboard_shortcuts.blocked": "Buksan ang talaan ng mga nakaharang na mga tagagamit", "keyboard_shortcuts.description": "Paglalarawan", "keyboard_shortcuts.down": "Ilipat pababa sa talaan", + "keyboard_shortcuts.mention": "Banggitin ang may-akda", "keyboard_shortcuts.requests": "Buksan ang talaan ng mga kahilingan sa pagsunod", "keyboard_shortcuts.up": "Ilipat pataas sa talaan", "lightbox.close": "Isara", "lightbox.next": "Susunod", "lightbox.previous": "Nakaraan", + "link_preview.author": "Ni/ng {name}", + "lists.account.add": "Idagdag sa talaan", + "lists.account.remove": "Tanggalin mula sa talaan", "lists.new.create": "Idagdag sa talaan", "lists.new.title_placeholder": "Bagong pangalan ng talaan", "lists.replies_policy.title": "Ipakita ang mga tugon sa:", "lists.subheading": "Iyong mga talaan", + "loading_indicator.label": "Kumakargaโ€ฆ", + "mute_modal.hide_from_notifications": "Itago mula sa mga abiso", "navigation_bar.about": "Tungkol dito", "navigation_bar.blocks": "Nakaharang na mga tagagamit", + "navigation_bar.direct": "Mga palihim na banggit", + "navigation_bar.discover": "Tuklasin", + "navigation_bar.explore": "Tuklasin", "navigation_bar.favourites": "Mga paborito", + "navigation_bar.follow_requests": "Mga hiling sa pagsunod", + "navigation_bar.follows_and_followers": "Mga sinusundan at tagasunod", "navigation_bar.lists": "Mga listahan", + "navigation_bar.public_timeline": "Pinagsamang timeline", + "navigation_bar.search": "Maghanap", "notification.admin.report": "Iniulat ni {name} si {target}", "notification.follow": "Sinundan ka ni {name}", "notification.follow_request": "Hinihiling ni {name} na sundan ka", + "notification.mention": "Binanggit ka ni {name}", + "notification.moderation_warning": "Mayroong kang natanggap na babala sa pagtitimpi", + "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.poll": "Resulta ng botohan:", + "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.filter.polls": "Resulta ng botohan", + "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โ€ฆ", + "onboarding.profile.save_and_continue": "Iimbak at magpatuloy", "onboarding.share.next_steps": "Mga posibleng susunod na hakbang:", + "picture_in_picture.restore": "Ilagay ito pabalik", + "poll.closed": "Sarado", + "poll.reveal": "Ipakita ang mga resulta", "poll.voted": "Binoto mo para sa sagot na ito", + "poll_button.remove_poll": "Tanggalin ang boto", + "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", "relative_time.full.just_now": "ngayon lang", + "relative_time.full.minutes": "{number, plural, one {# minuto} other {# na minuto}} ang nakalipas", + "relative_time.full.seconds": "{number, plural, one {# segundo} other {# na segundo}} ang nakalipas", + "relative_time.hours": "{number}o", "relative_time.just_now": "ngayon", + "relative_time.minutes": "{number}m", + "relative_time.seconds": "{number}s", "reply_indicator.cancel": "Ipagpaliban", "report.block": "Harangan", "report.categories.other": "Iba pa", + "report.category.title": "Sabihin mo sa amin kung anong nangyari sa {type} na ito", "report.close": "Tapos na", "report.next": "Sunod", - "server_banner.learn_more": "Matuto nang higit pa", + "report.reasons.violation": "Lumalabag ito sa mga panuntunan ng serbiro", + "report.reasons.violation_description": "Alam mo na lumalabag ito sa mga partikular na panuntunan", + "report.rules.title": "Aling mga patakaran ang nilabag?", + "report.submit": "Isumite", + "report.target": "Iniulat si/ang {target}", + "report.thanks.take_action_actionable": "Habang sinusuri namin ito, maaari kang gumawa ng aksyon laban kay/sa {name}:", + "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", + "report_notification.categories.violation": "Paglabag sa patakaran", + "report_notification.open": "Buksan ang ulat", + "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_popout.recent": "Kamakailang mga paghahanap", + "search_results.all": "Lahat", + "search_results.see_all": "Ipakita lahat", + "server_banner.server_stats": "Katayuan ng serbiro:", + "status.block": "Harangan si @{name}", + "status.delete": "Tanggalin", + "status.direct": "Palihim na banggitin si/ang @{name}", + "status.direct_indicator": "Palihim na banggit", + "status.edit": "Baguhin", + "status.edited_x_times": "Binago {count, plural, one {{count} beses} other {{count} na beses}}", + "status.history.created": "Nilikha ni/ng {name} {date}", + "status.history.edited": "Binago ni/ng {name} {date}", + "status.media.open": "Pindutin upang buksan", + "status.media.show": "Pindutin upang ipakita", + "status.mention": "Banggitin ang/si @{name}", "status.more": "Higit pa", + "status.read_more": "Basahin ang higit pa", + "status.reblogs.empty": "Wala pang nagpalakas ng post na ito. Kung may sinumang nagpalakas, makikita sila rito.", "status.reply": "Tumugon", + "status.report": "I-ulat si/ang @{name}", + "status.sensitive_warning": "Sensitibong nilalaman", "status.share": "Ibahagi", "status.show_less": "Magpakita ng mas kaunti", "status.show_less_all": "Magpakita ng mas kaunti para sa lahat", @@ -222,5 +333,13 @@ "status.show_more_all": "Magpakita ng higit pa para sa lahat", "status.translate": "Isalin", "status.translated_from_with": "Isalin mula sa {lang} gamit ang {provider}", - "status.uncached_media_warning": "Hindi makuha ang paunang tigin" + "status.uncached_media_warning": "Hindi makuha ang paunang tigin", + "tabs_bar.notifications": "Mga abiso", + "time_remaining.days": "{number, plural, one {# araw} other {# na araw}} ang natitira", + "time_remaining.hours": "{number, plural, one {# oras} other {# na oras}} ang natitira", + "time_remaining.minutes": "{number, plural, one {# minuto} other {# na minuto}} ang natitira", + "time_remaining.seconds": "{number, plural, one {# segundo} other {# na segundo}} ang natitira", + "timeline_hint.remote_resource_not_displayed": "Hindi ipinapakita ang {resource} mula sa ibang mga serbiro.", + "timeline_hint.resources.followers": "Mga tagasunod", + "timeline_hint.resources.follows": "Mga sinusundan" } diff --git a/app/javascript/mastodon/locales/fo.json b/app/javascript/mastodon/locales/fo.json index abd2ab2681..7a317820bb 100644 --- a/app/javascript/mastodon/locales/fo.json +++ b/app/javascript/mastodon/locales/fo.json @@ -7,7 +7,7 @@ "about.domain_blocks.silenced.explanation": "Yvirhรธvur, so sรฆrt tรบ ikki vangar og innihald frรก hesum ambรฆtaranum, uttan so at tรบ skilliga leitar hesi upp ella velur tey viรฐ at fylgja teimum.", "about.domain_blocks.silenced.title": "Avmarkaรฐ", "about.domain_blocks.suspended.explanation": "Ongar dรกtur frรก hesum ambรฆtara verรฐa viรฐgjรธrd, goymd ella deild, taรฐ ger, at samskifti viรฐ aรฐrar ambรฆtarar er iki mรธguligt.", - "about.domain_blocks.suspended.title": "Koyrdur frรก", + "about.domain_blocks.suspended.title": "Gjรธrt รณvirkiรฐ", "about.not_available": "Hetta er ikki tรธkt รก fรธroyska servaranum enn.", "about.powered_by": "Miรฐfirra almennur miรฐil koyrandi รก {mastodon}", "about.rules": "Ambรฆtarareglur", @@ -89,6 +89,14 @@ "announcement.announcement": "Kunngerรฐ", "attachments_list.unprocessed": "(รณviรฐgjรธrt)", "audio.hide": "Fjal ljรณรฐ", + "block_modal.remote_users_caveat": "Vit biรฐja ambรฆtaran {domain} virรฐa tรญna avgerรฐ. Kortini er eingin vissa um samsvar, av tรญ at fleiri ambรฆtarar handfara blokkar ymiskt. Almennir postar kunnu framvegis vera sjรณnligir fyri brรบkarar, sum ikki eru innritaรฐir.", + "block_modal.show_less": "Vรญs minni", + "block_modal.show_more": "Vรญs meiri", + "block_modal.they_cant_mention": "Tey kunnu hvรธrki nevna teg ella fylgja tรฆr.", + "block_modal.they_cant_see_posts": "Tey sรญggja ikki tรญnar postar og tรบ sรฆrt ikki teirra.", + "block_modal.they_will_know": "Tey sรญggja, at tey eru bannaรฐ.", + "block_modal.title": "Banna brรบkara?", + "block_modal.you_wont_see_mentions": "Tรบ sรฆrt ikki postar, sum nevna tey.", "boost_modal.combo": "Tรบ kanst trรฝsta รก {combo} fyri at loypa uppum hetta nรฆstu ferรฐ", "bundle_column_error.copy_stacktrace": "Avrita feilfrรกboรฐan", "bundle_column_error.error.body": "Umbidna sรญรฐan kann ikki vรญsast. Taรฐ kann vera orsakaรฐ av einum feili รญ koduni hjรก okkum ella taรฐ kann vera orsakaรฐ av kaganum, sum tรบ brรบkar.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Skriva รกvaring um innihald", "compose_form.spoiler_placeholder": "Innihaldsรกvaring (valfrรญ)", "confirmation_modal.cancel": "Strika", - "confirmations.block.block_and_report": "Banna og melda", "confirmations.block.confirm": "Banna", - "confirmations.block.message": "Ert tรบ vรญs/ur รญ, at tรบ vilt banna {name}?", "confirmations.cancel_follow_request.confirm": "Tak umbรธnina aftur", "confirmations.cancel_follow_request.message": "Er taรฐ tilรฆtlaรฐ, at tรบ tekur umbรธnina at fylgja {name} aftur?", "confirmations.delete.confirm": "Strika", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Ert tรบ vรญs/ur รญ, at tรบ vilt strika hetta uppslagiรฐ?", "confirmations.discard_edit_media.confirm": "Vraka", "confirmations.discard_edit_media.message": "Tรบ hevur broytingar รญ miรฐlalรฝsingini ella undansรฝningini, sum ikki eru goymdar. Vilt tรบ kortini vraka?", - "confirmations.domain_block.confirm": "Banna heilum รธkisnavni", + "confirmations.domain_block.confirm": "Banna ambรฆtara", "confirmations.domain_block.message": "Ert tรบ pรบra, pรบra vรญs/ur รญ, at tรบ vilt banna รธllum {domain}? ร flestu fรธrum er nรณg mikiรฐ og betri, bert at banna ella doyva onkrum รกvรญsum. Tรบ fert eingi evni at sรญggja frรก รธkisnavninum รก nakrari almennari tรญรฐarrรกs ella รญ tรญnum frรกboรฐanum. Tรญnir fylgjarar undir รธkisnavninum verรฐa eisini strikaรฐir.", "confirmations.edit.confirm": "Rรฆtta", "confirmations.edit.message": "Rรฆttingar, sum verรฐa gjรธrdar nรบ, skriva yvir boรฐini, sum tรบ ert รญ holt viรฐ. Ert tรบ vรญs/ur รญ, at tรบ vilt halda fram?", "confirmations.logout.confirm": "Rita รบt", "confirmations.logout.message": "Ert tรบ vรญs/ur รญ, at tรบ vilt รบtrita teg?", "confirmations.mute.confirm": "Doyv", - "confirmations.mute.explanation": "Henda atgerรฐ fjalir teirra postar og postar, iรฐ nevna tey; men tey kunnu framvegis sรญggja tรญnar postar og fylgja tรฆr.", - "confirmations.mute.message": "Ert tรบ vรญs/ur รญ, at tรบ vilt doyva {name}?", "confirmations.redraft.confirm": "Sletta og skriva umaftur", "confirmations.redraft.message": "Vilt tรบ veruliga strika hendan postin og รญ staรฐin gera hann til eina nรฝggja kladdu? Yndisfrรกmerki og framhevjanir blรญva burtur, og svar til upprunapostin missa tilknรฝtiรฐ.", "confirmations.reply.confirm": "Svara", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Hesi uppslรธg, frรก hesum og รธรฐrum ambรฆtarum รก miรฐspjadda netverkinum, hava framgongd รก hesum ambรฆtara jรบst nรบ. Nรฝggjari postar, sum fleiri hava framhevja og dรกma, verรฐa raรฐfestir hรฆgri.", "dismissable_banner.explore_tags": "Hesi frรกmerki vinna รญ lรธtuni fรณtafesti millum fรณlk รก hesum og รธรฐrum ambรฆtarum รญ desentrala netverkinum beint nรบ.", "dismissable_banner.public_timeline": "Hetta eru teir nรฝggjast postarnir frรก fรณlki รก sosialu vevinum, sum fรณlk รก {domain} fylgja.", + "domain_block_modal.block": "Banna ambรฆtara", + "domain_block_modal.block_account_instead": "Banna @{name} รญstaรฐin", + "domain_block_modal.they_can_interact_with_old_posts": "Fรณlk frรก hesum ambรฆtara kunnu svara tรญnum gomlu postum.", + "domain_block_modal.they_cant_follow": "Eingin frรก hesum ambรฆtara kann fylgja tรฆr.", + "domain_block_modal.they_wont_know": "Tey vita ikki, at tey eru bannaรฐ.", + "domain_block_modal.title": "Banna รธkisnavni?", + "domain_block_modal.you_will_lose_followers": "Allir tรญnir fylgjarar รก hesum ambรฆtara hvรธrva.", + "domain_block_modal.you_wont_see_posts": "Tรบ sรฆrt ongar postar ella boรฐ frรก brรบkarum รก hesum ambรฆtara.", + "domain_pill.activitypub_lets_connect": "Taรฐ letur teg fรกa samband og samvirka viรฐ fรณlki ikki bara รก Mastodon, men รก รธรฐrum sosialum appum eisini.", + "domain_pill.activitypub_like_language": "ActivityPub er mรกliรฐ, sum Mastodon tosar viรฐ onnur sosial netverk.", + "domain_pill.server": "Ambรฆtari", + "domain_pill.their_handle": "Teirra hald:", + "domain_pill.their_server": "Teirra talgilda heim, har allir teirra postar liva.", + "domain_pill.their_username": "Teirra eyรฐmerki รก teirra ambรฆtara. Taรฐ er mรธguligt at finna brรบkarar viรฐ tรญ sama brรบkaranavninum รก ymiskum ambรฆtarum.", + "domain_pill.username": "Brรบkaranavn", + "domain_pill.whats_in_a_handle": "Hvat er รญ einum haldi?", + "domain_pill.who_they_are": "Eftirsum at hald siga, hvรธr onkur er og hvar tey eru, so kanst tรบ samvirka viรฐ fรณlk รก รธllum .", + "domain_pill.who_you_are": "Av tรญ at tรญni hald siga, hvรธr tรบ er og hvar tรบ eru, so kunnu onnur samvirka viรฐ teg รก รธllum .", + "domain_pill.your_handle": "Tรญtt hald:", + "domain_pill.your_server": "Tรญtt talgilda heim, har allir tรญnir postar liva. Dรกmar taรฐ ikki hendan? Flyt til ein annan ambรฆtara tรก tรบ hevur hug til tess og tak fylgjarar tรญnar viรฐ eisini.", + "domain_pill.your_username": "Tรญtt eyรฐmerki รก hesum ambรฆtaranum. Taรฐ er mรธguligt at finna brรบkarar viรฐ tรญ sama brรบkaranavninum รก ymiskum ambรฆtarum.", "embed.instructions": "Fell hendan postin innรญ รก tรญnum vevstaรฐi viรฐ at taka avrit av koduni niรฐanfyri.", "embed.preview": "Soleiรฐis fer taรฐ at sรญggja รบt:", "emoji_button.activity": "Virksemi", @@ -241,6 +266,7 @@ "empty_column.list": "Einki er รญ hesum listanum enn. Tรก limir รญ hesum listanum posta nรฝggjar postar, so sรญggjast teir her.", "empty_column.lists": "Tรบ hevur ongar goymdar listar enn. Tรก tรบ gert ein lista, so sรฆrt tรบ hann her.", "empty_column.mutes": "Tรบ hevur enn ikki doyvt nakran brรบkara.", + "empty_column.notification_requests": "Alt er klรกrt! Her er einki. Tรก tรบ fรฆrt nรฝggjar frรกboรฐanir, sรญggjast tรฆr her sambรฆrt tรญnum stillingum.", "empty_column.notifications": "Tรบ hevur ongar frรกboรฐanir enn. Tรก onnur samskifta viรฐ teg, so sรฆr tรบ frรกboรฐaninar her.", "empty_column.public": "Einki er her! Skriva okkurt alment ella fylg brรบkarum frรก รธรฐrum ambรฆtarum fyri at fylla tilfar รญ", "error.unexpected_crash.explanation": "Orsakaรฐ av einum feili รญ okkara kotu ella orsakaรฐ av at kagin hjรก tรฆr ikki er sambรฆriligur viรฐ skipanina, so bar ikki til at vรญsa hesa sรญรฐuna rรฆtt.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Hesin ambรฆtarin", "firehose.remote": "Aรฐrir ambรฆtarar", "follow_request.authorize": "Veit myndugleika", "follow_request.reject": "Nokta", "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 umsjรณnarfรณlksins", + "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}.", + "follow_suggestions.hints.most_interactions": "Nรฝliga hava nรณgv lagt merki til hendan vangan รก {domain}.", + "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Fylg frรกmerki", "hashtag.unfollow": "Gevst at fylgja frรกmerki", "hashtags.and_other": "โ€ฆog {count, plural, other {# afturat}}", - "home.column_settings.basic": "Grundleggjandi", "home.column_settings.show_reblogs": "Vรญs lyft", "home.column_settings.show_replies": "Vรญs svar", "home.hide_announcements": "Fjal kunngerรฐir", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Vรญs vangamynd kortini", "limited_account_hint.title": "Hesin vangin er fjaldur av kjakleiรฐarunum รก {domain}.", "link_preview.author": "Av {name}", + "link_preview.more_from_author": "Meira frรก {name}", + "link_preview.shares": "{count, plural, one {{counter} postur} other {{counter} postar}}", "lists.account.add": "Legg afturat lista", "lists.account.remove": "Tak av lista", "lists.delete": "Strika lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Innlesurโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Fjal mynd} other {Fjal myndir}}", "moved_to_account_banner.text": "Konta tรญn {disabledAccount} er รญ lรธtuni รณvirkin, tรญ tรบ flutti til {movedToAccount}.", - "mute_modal.duration": "Tรญรฐarbil", - "mute_modal.hide_notifications": "Fjal frรกboรฐanir frรก hesum brรบkaranum?", - "mute_modal.indefinite": "ร“รกsett tรญรฐarskeiรฐ", + "mute_modal.hide_from_notifications": "Fjal boรฐ", + "mute_modal.hide_options": "Fjal valmรธguleikar", + "mute_modal.indefinite": "Inntil eg tendri tey aftur", + "mute_modal.show_options": "Vรญs valmรธguleikar", + "mute_modal.they_can_mention_and_follow": "Tey kunnu bรฆรฐi nevna og fylgja tรฆr, men tรบ sรฆrt ikki tey.", + "mute_modal.they_wont_know": "Tey vita ikki, at tey eru slรธkt.", + "mute_modal.title": "Slรธkk brรบkara?", + "mute_modal.you_wont_see_mentions": "Tรบ sรฆrt ikki postar, sum nevna tey.", + "mute_modal.you_wont_see_posts": "Tey sรญggja framvegis tรญnar postar, men tรบ sรฆrt ikki teirra.", "navigation_bar.about": "Um", "navigation_bar.advanced_interface": "Lat upp รญ framkomnum vevmarkamรณti", "navigation_bar.blocks": "Bannaรฐir brรบkarar", @@ -430,11 +475,29 @@ "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รกvaring", + "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รกvaring.", + "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.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", + "notification_requests.dismiss": "Avvรญs", + "notification_requests.notifications_from": "Frรกboรฐanir frรก {name}", + "notification_requests.title": "Sรกldaรฐar frรกboรฐanir", "notifications.clear": "Rudda frรกboรฐanir", "notifications.clear_confirmation": "Ert tรบ vรญs/ur รญ, at tรบ vilt strika allar tรญnar frรกboรฐanir?", "notifications.column_settings.admin.report": "Nรฝggjar frรกboรฐanir:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Vรญs filturbjรกlka", "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:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Skriviborรฐsfrรกboรฐanir eru ikki tรธkar tรญ at ein kaga-umbรธn รกรฐur bleiv noktaรฐ", "notifications.permission_denied_alert": "Taรฐ ber ikki til at slรกa skriviborรฐsfrรกboรฐanir til, tรญ at kagarรฆttindi รกรฐur eru noktaรฐi", "notifications.permission_required": "Skriviborรฐsfrรกboรฐanir eru ikki tรธkar, tรญ at neyรฐugu rรฆttindini eru ikki latin.", + "notifications.policy.filter_new_accounts.hint": "Stovnaรฐar {days, plural, one {seinasta dagin} other {seinastu # dagarnar}}", + "notifications.policy.filter_new_accounts_title": "Nรฝggjar kontur", + "notifications.policy.filter_not_followers_hint": "รroknaรฐ fรณlk, sum hava fylgt tรฆr styttri enn {days, plural, one {ein dag} other {# dagar}}", + "notifications.policy.filter_not_followers_title": "Fรณlk, sum ikki fylgja tรฆr", + "notifications.policy.filter_not_following_hint": "Til tรบ gรณรฐkennir tey manuelt", + "notifications.policy.filter_not_following_title": "Fรณlk, sum tรบ ikki fylgir", + "notifications.policy.filter_private_mentions_hint": "Sรกldaรฐi, uttan so at taรฐ er รญ svari til tรญnar egnu nevningar ella um tรบ fylgir sendaranum", + "notifications.policy.filter_private_mentions_title": "ร“bidnar privatar umrรธรฐur", + "notifications.policy.title": "Sรกlda burtur frรกboรฐanir frรกโ€ฆ", "notifications_permission_banner.enable": "Ger skriviborรฐsfrรกboรฐanir virknar", "notifications_permission_banner.how_to_control": "Ger skriviborรฐsfrรกboรฐanir virknar fyri at mรณttaka frรกboรฐanir, tรก Mastodon ikki er opiรฐ. Tรก tรฆr eru gjรธrdar virknar, kanst tรบ stรฝra, hvรธrji slรธg av samvirkni geva skriviborรฐsfrรกboรฐanir. Hetta umvegis {icon} knรธttin omanfyri.", "notifications_permission_banner.title": "Miss einki", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Fรณlk, sum hava brรบkt hendan ambรฆtaran seinastu 30 dagarnar (mรกnaรฐarligir virknir brรบkarar)", "server_banner.active_users": "virknir brรบkarar", "server_banner.administered_by": "Umsitari:", - "server_banner.introduction": "{domain} er partur av desentrala sosiala netverkinum, sum er driviรฐ av {mastodon}.", - "server_banner.learn_more": "Lรฆr meira", + "server_banner.is_one_of_many": "{domain} er ein av nรณgvum รณheftum Mastodon ambรฆtarum, sum tรบ kanst brรบka at luttaka รญ fediversinum.", "server_banner.server_stats": "Ambรฆtarahagtรธl:", "sign_in_banner.create_account": "Stovna kontu", + "sign_in_banner.follow_anyone": "Fylg ein og hvรธnn รญ fediversinum og sรญggj alt รญ tรญรฐarrรธรฐ. Ongar algoritmur, ongar lรฝsingar og einki klikkbeit รญ eygsjรณn.", + "sign_in_banner.mastodon_is": "Mastodon er best mรกtin at fylgja viรฐ รญ tรญ, sum hendir.", "sign_in_banner.sign_in": "Rita inn", "sign_in_banner.sso_redirect": "Rita inn ella Skrรกset teg", - "sign_in_banner.text": "Innrita fyri at fylgja vangum og frรกmerkjum, dรกma, deila og svara postum. Tรบ kanst eisini brรบka kontuna til at samvirka รก einum รธรฐrum ambรฆtara.", "status.admin_account": "Lat kjakleiรฐaramarkamรณt upp fyri @{name}", "status.admin_domain": "Lat umsjรณnarmarkamรณt upp fyri {domain}", "status.admin_status": "Lat hendan postin upp รญ kjakleiรฐaramarkamรณtinum", @@ -645,10 +716,11 @@ "status.direct": "Umrรธรฐ @{name} privat", "status.direct_indicator": "Privat umrรธรฐa", "status.edit": "Rรฆtta", - "status.edited": "Rรฆttaรฐ {date}", + "status.edited": "Seinast broytt {date}", "status.edited_x_times": "Rรฆttaรฐ {count, plural, one {{count} ferรฐ} other {{count} ferรฐ}}", "status.embed": "Legg innรญ", "status.favourite": "Dรกmdur postur", + "status.favourites": "{count, plural, one {yndispostur} other {yndispostar}}", "status.filter": "Filtrera hendan postin", "status.filtered": "Filtreraรฐ", "status.hide": "Fjal post", @@ -669,6 +741,7 @@ "status.reblog": "Stimbra", "status.reblog_private": "Stimbra viรฐ upprunasรฝni", "status.reblogged_by": "{name} stimbraรฐ", + "status.reblogs": "{count, plural, one {stimbran} other {stimbranir}}", "status.reblogs.empty": "Eingin hevur stimbraรฐ hendan postin enn. Tรก onkur stimbrar postin, verรฐur hann sjรณnligur her.", "status.redraft": "Strika & ger nรฝggja kladdu", "status.remove_bookmark": "Gloym", diff --git a/app/javascript/mastodon/locales/fr-CA.json b/app/javascript/mastodon/locales/fr-CA.json index 49db30d75e..50b7dcf90d 100644 --- a/app/javascript/mastodon/locales/fr-CA.json +++ b/app/javascript/mastodon/locales/fr-CA.json @@ -89,6 +89,14 @@ "announcement.announcement": "Annonce", "attachments_list.unprocessed": "(non traitรฉ)", "audio.hide": "Masquer l'audio", + "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre dรฉcision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gรฉrer diffรฉremment les blocages. Les messages publics peuvent rester visibles par les utilisateurs non connectรฉs.", + "block_modal.show_less": "Afficher moins", + "block_modal.show_more": "Afficher plus", + "block_modal.they_cant_mention": "Il ne peut pas vous mentionner ou vous suivre.", + "block_modal.they_cant_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.", + "block_modal.they_will_know": "Il peut voir qu'il est bloquรฉ.", + "block_modal.title": "Bloquer l'utilisateur ?", + "block_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.", "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour sauter ceci la prochaine fois", "bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur", "bundle_column_error.error.body": "La page demandรฉe n'a pas pu รชtre affichรฉe. Cela pourrait รชtre dรป ร  un bogue dans notre code, ou ร  un problรจme de compatibilitรฉ avec le navigateur.", @@ -148,7 +156,7 @@ "compose_form.poll.duration": "Durรฉe du sondage", "compose_form.poll.multiple": "Choix multiple", "compose_form.poll.option_placeholder": "Option {number}", - "compose_form.poll.single": "Choisissez-en un", + "compose_form.poll.single": "Choix unique", "compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "compose_form.poll.switch_to_single": "Changer le sondage pour n'autoriser qu'un seul choix", "compose_form.poll.type": "Style", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu", "compose_form.spoiler_placeholder": "Avertissement de contenu (optionnel)", "confirmation_modal.cancel": "Annuler", - "confirmations.block.block_and_report": "Bloquer et signaler", "confirmations.block.confirm": "Bloquer", - "confirmations.block.message": "Voulez-vous vraiment bloquer {name}?", "confirmations.cancel_follow_request.confirm": "Retirer cette demande", "confirmations.cancel_follow_request.message": "รŠtes-vous sรปr de vouloir retirer votre demande pour suivre {name}?", "confirmations.delete.confirm": "Supprimer", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Voulez-vous vraiment supprimer dรฉfinitivement cette liste?", "confirmations.discard_edit_media.confirm": "Rejeter", "confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrรฉes de la description ou de l'aperรงu du mรฉdia, voulez-vous quand mรชme les supprimer?", - "confirmations.domain_block.confirm": "Bloquer ce domaine entier", + "confirmations.domain_block.confirm": "Bloquer le serveur", "confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier? Dans la plupart des cas, quelques blocages ou masquages ciblรฉs sont suffisants et prรฉfรฉrables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans vos fils publics, ni dans vos notifications. Vos abonnรฉยทeยทs utilisant ce domaine seront retirรฉยทeยทs.", "confirmations.edit.confirm": "ร‰diter", "confirmations.edit.message": "Modifier maintenant รฉcrasera votre message en cours de rรฉdaction. Voulez-vous vraiment continuerย ?", "confirmations.logout.confirm": "Se dรฉconnecter", "confirmations.logout.message": "Voulez-vous vraiment vous dรฉconnecter?", "confirmations.mute.confirm": "Masquer", - "confirmations.mute.explanation": "Cela masquera ses publications et celle le/la mentionnant, mais cela lui permettra toujours de voir vos messages et de vous suivre.", - "confirmations.mute.message": "Voulez-vous vraiment masquer {name}?", "confirmations.redraft.confirm": "Supprimer et rรฉรฉcrire", "confirmations.redraft.message": "รŠtes-vous sรปrยทe de vouloir effacer cette publication pour la rรฉรฉcrire? Ses ses mises en favori et boosts seront perdus et ses rรฉponses seront orphelines.", "confirmations.reply.confirm": "Rรฉpondre", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Voici des publications venant de tout le web social gagnant en popularitรฉ aujourdโ€™hui. Les nouvelles publications avec plus de boosts et de favoris sont classรฉs plus haut.", "dismissable_banner.explore_tags": "Ces hashtags sont prรฉsentement en train de gagner de l'ampleur parmi des personnes sur les serveurs du rรฉseau dรฉcentralisรฉ dont celui-ci.", "dismissable_banner.public_timeline": "Ce sont les messages publics les plus rรฉcents de personnes sur le web social que les gens de {domain} suivent.", + "domain_block_modal.block": "Bloquer le serveur", + "domain_block_modal.block_account_instead": "Bloquer @{name} ร  la place", + "domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciennes publications.", + "domain_block_modal.they_cant_follow": "Personne de ce serveur ne peut vous suivre.", + "domain_block_modal.they_wont_know": "Il ne saura pas qu'il a รฉtรฉ bloquรฉ.", + "domain_block_modal.title": "Bloquer le domaine ?", + "domain_block_modal.you_will_lose_followers": "Tous vos abonnรฉs de ce serveur seront supprimรฉs.", + "domain_block_modal.you_wont_see_posts": "Vous ne verrez plus les publications ou les notifications des utilisateurs de ce serveur.", + "domain_pill.activitypub_lets_connect": "Cela vous permet de vous connecter et d'interagir avec les autres non seulement sur Mastodon, mais รฉgalement sur d'autres applications de rรฉseaux sociaux.", + "domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres rรฉseaux sociaux.", + "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 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 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รฉ", @@ -241,6 +266,7 @@ "empty_column.list": "Il nโ€™y a rien dans cette liste pour lโ€™instant. Quand des membres de cette liste publieront de nouvelles publications, elles apparaรฎtront ici.", "empty_column.lists": "Vous nโ€™avez pas encore de liste. Lorsque vous en crรฉerez une, elle apparaรฎtra ici.", "empty_column.mutes": "Vous nโ€™avez masquรฉ aucun compte pour le moment.", + "empty_column.notification_requests": "C'est fini ! Il n'y a plus rien ici. Lorsque vous recevez de nouvelles notifications, elles apparaitront ici conformรฉment ร  vos prรฉfรฉrences.", "empty_column.notifications": "Vous n'avez pas encore de notifications. Quand d'autres personnes interagissent avec vous, vous en verrez ici.", "empty_column.public": "Il nโ€™y a rien ici! ร‰crivez quelque chose publiquement, ou bien suivez manuellement des personnes dโ€™autres serveurs pour remplir le fil public", "error.unexpected_crash.explanation": "En raison dโ€™un bogue dans notre code ou dโ€™un problรจme de compatibilitรฉ avec votre navigateur, cette page nโ€™a pas pu รชtre affichรฉe correctement.", @@ -271,12 +297,25 @@ "filter_modal.select_filter.subtitle": "Utilisez une catรฉgorie existante ou en crรฉer une nouvelle", "filter_modal.select_filter.title": "Filtrer cette publication", "filter_modal.title.status": "Filtrer une publication", + "filtered_notifications_banner.pending_requests": "Notifications {count, plural, =0 {de personne} one {dโ€™une personne} other {de # personnes}} que vous pouvez connaitre", + "filtered_notifications_banner.title": "Notifications filtrรฉes", "firehose.all": "Tout", "firehose.local": "Ce serveur", "firehose.remote": "Autres serveurs", "follow_request.authorize": "Autoriser", "follow_request.reject": "Rejeter", "follow_requests.unlocked_explanation": "Mรชme si votre compte nโ€™est pas privรฉ, lโ€™รฉquipe de {domain} a pensรฉ que vous pourriez vouloir peut-รชtre consulter manuellement les demandes d'abonnement de ces comptes.", + "follow_suggestions.curated_suggestion": "Choix du staff", + "follow_suggestions.dismiss": "Ne plus afficher", + "follow_suggestions.hints.featured": "Ce profil a รฉtรฉ sรฉlectionnรฉ par l'รฉquipe de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Ce profil est populaire parmi les personnes que vous suivez.", + "follow_suggestions.hints.most_followed": "Ce profil est l'un des plus suivis sur {domain}.", + "follow_suggestions.hints.most_interactions": "Ce profil a rรฉcemment fait l'objet d'une grande attention sur {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Ce profil est similaire aux profils que vous avez suivis le plus rรฉcemment.", + "follow_suggestions.personalized_suggestion": "Suggestion personnalisรฉe", + "follow_suggestions.popular_suggestion": "Suggestion populaire", + "follow_suggestions.view_all": "Tout afficher", + "follow_suggestions.who_to_follow": "Qui suivre", "followed_tags": "Hashtags suivis", "footer.about": "ร€ propos", "footer.directory": "Annuaire des profils", @@ -303,7 +342,6 @@ "hashtag.follow": "Suivre ce hashtag", "hashtag.unfollow": "Ne plus suivre ce hashtag", "hashtags.and_other": "โ€ฆet {count, plural, other {# de plus}}", - "home.column_settings.basic": "Basique", "home.column_settings.show_reblogs": "Afficher boosts", "home.column_settings.show_replies": "Afficher rรฉponses", "home.hide_announcements": "Masquer les annonces", @@ -389,9 +427,15 @@ "loading_indicator.label": "Chargementโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Cacher lโ€™image} other {Cacher les images}}", "moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement dรฉsactivรฉ parce que vous avez dรฉmรฉnagรฉ sur {movedToAccount}.", - "mute_modal.duration": "Durรฉe", - "mute_modal.hide_notifications": "Masquer les notifications de ce compte?", - "mute_modal.indefinite": "Indรฉfinie", + "mute_modal.hide_from_notifications": "Cacher des notifications", + "mute_modal.hide_options": "Masquer les options", + "mute_modal.indefinite": "Jusqu'ร  ce que je les rรฉactive", + "mute_modal.show_options": "Afficher les options", + "mute_modal.they_can_mention_and_follow": "Ils peuvent vous mentionner et vous suivre, mais vous ne les verrez pas.", + "mute_modal.they_wont_know": "Ils ne sauront pas qu'ils ont รฉtรฉ rendus silencieux.", + "mute_modal.title": "Rendre cet utilisateur silencieux ?", + "mute_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.", + "mute_modal.you_wont_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.", "navigation_bar.about": "ร€ propos", "navigation_bar.advanced_interface": "Ouvrir dans lโ€™interface avancรฉe", "navigation_bar.blocks": "Comptes bloquรฉs", @@ -427,8 +471,17 @@ "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.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", + "notification_requests.dismiss": "Rejeter", + "notification_requests.notifications_from": "Notifications de {name}", + "notification_requests.title": "Notifications filtrรฉes", "notifications.clear": "Effacer notifications", "notifications.clear_confirmation": "Voulez-vous vraiment effacer toutes vos notifications?", "notifications.column_settings.admin.report": "Nouveaux signalements:", @@ -436,8 +489,7 @@ "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 filtrage rapide", - "notifications.column_settings.filter_bar.show_bar": "Afficher la barre de filtre", + "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:", @@ -463,6 +515,15 @@ "notifications.permission_denied": "Les notifications de bureau ne sont pas disponibles en raison d'une demande de permission de navigateur prรฉcรฉdemment refusรฉe", "notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas รชtre activรฉes, car lโ€™autorisation du navigateur a prรฉcedemment รฉtรฉ refusรฉe", "notifications.permission_required": "Les notifications de bureau ne sont pas disponibles car lโ€™autorisation requise nโ€™a pas รฉtรฉ accordรฉe.", + "notifications.policy.filter_new_accounts.hint": "Crรฉรฉs au cours des derniers {days, plural, one {un jour} other {# jours}}", + "notifications.policy.filter_new_accounts_title": "Nouveaux comptes", + "notifications.policy.filter_not_followers_hint": "Incluant les personnes qui vous suivent depuis moins de {days, plural, one {un jour} other {# jours}}", + "notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas", + "notifications.policy.filter_not_following_hint": "Jusqu'ร  ce que vous les validiez manuellement", + "notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas", + "notifications.policy.filter_private_mentions_hint": "Filtrรฉ sauf si c'est en rรฉponse ร  une mention de vous ou si vous suivez l'expรฉditeur", + "notifications.policy.filter_private_mentions_title": "Mentions privรฉes non sollicitรฉes", + "notifications.policy.title": "Filtrer les notifications deโ€ฆ", "notifications_permission_banner.enable": "Activer les notifications de bureau", "notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon nโ€™est pas ouvert, activez les notifications de bureau. Vous pouvez contrรดler prรฉcisรฉment quels types dโ€™interactions gรฉnรจrent des notifications de bureau via le bouton {icon} ci-dessus une fois quโ€™elles sont activรฉes.", "notifications_permission_banner.title": "Ne rien rater", @@ -524,9 +585,9 @@ "privacy.private.short": "Abonnรฉs", "privacy.public.long": "Tout le monde sur et en dehors de Mastodon", "privacy.public.short": "Public", - "privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaรฎtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, mรชme si vous avez optรฉ pour l'option publique pour l'ensemble de votre compte.", + "privacy.unlisted.additional": "Se comporte exactement comme ยซย publicย ยป, sauf que le message n'apparaรฎtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, mรชme si vous les avez activรฉ au niveau de votre compte.", "privacy.unlisted.long": "Moins de fanfares algorithmiques", - "privacy.unlisted.short": "Public calme", + "privacy.unlisted.short": "Public discret", "privacy_policy.last_updated": "Derniรจre mise ร  jour {date}", "privacy_policy.title": "Politique de confidentialitรฉ", "recommended": "Recommandรฉ", @@ -619,13 +680,10 @@ "server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)", "server_banner.active_users": "comptes actifs", "server_banner.administered_by": "Administrรฉ par:", - "server_banner.introduction": "{domain} fait partie du rรฉseau social dรฉcentralisรฉ propulsรฉ par {mastodon}.", - "server_banner.learn_more": "En savoir plus", "server_banner.server_stats": "Statistiques du serveur:", "sign_in_banner.create_account": "Crรฉer un compte", "sign_in_banner.sign_in": "Se connecter", "sign_in_banner.sso_redirect": "Se connecter ou sโ€™inscrire", - "sign_in_banner.text": "Identifiez-vous pour suivre des profils ou des hashtags, ajouter des favoris, partager et rรฉpondre ร  des publications. Vous pouvez รฉgalement interagir depuis votre compte sur un autre serveur.", "status.admin_account": "Ouvrir lโ€™interface de modรฉration pour @{name}", "status.admin_domain": "Ouvrir lโ€™interface de modรฉration pour {domain}", "status.admin_status": "Ouvrir ce message dans lโ€™interface de modรฉration", @@ -639,10 +697,11 @@ "status.direct": "Mention privรฉe @{name}", "status.direct_indicator": "Mention privรฉe", "status.edit": "Modifier", - "status.edited": "Modifiรฉe le {date}", + "status.edited": "Derniรจre modification leย {date}", "status.edited_x_times": "Modifiรฉe {count, plural, one {{count} fois} other {{count} fois}}", "status.embed": "Intรฉgrer", "status.favourite": "Ajouter aux favoris", + "status.favourites": "{count, plural, one {favori} other {favoris}}", "status.filter": "Filtrer cette publication", "status.filtered": "Filtrรฉe", "status.hide": "Masquer le message", @@ -663,6 +722,7 @@ "status.reblog": "Booster", "status.reblog_private": "Booster avec visibilitรฉ originale", "status.reblogged_by": "{name} a boostรฉ", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "Personne nโ€™a encore boostรฉ cette publication. Lorsque quelquโ€™un le fera, elle apparaรฎtra ici.", "status.redraft": "Supprimer et rรฉรฉcrire", "status.remove_bookmark": "Retirer des signets", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 1f657c8185..2e565c200f 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -89,6 +89,14 @@ "announcement.announcement": "Annonce", "attachments_list.unprocessed": "(non traitรฉ)", "audio.hide": "Masquer l'audio", + "block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre dรฉcision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gรฉrer diffรฉremment les blocages. Les messages publics peuvent rester visibles par les utilisateurs non connectรฉs.", + "block_modal.show_less": "Afficher moins", + "block_modal.show_more": "Afficher plus", + "block_modal.they_cant_mention": "Il ne peut pas vous mentionner ou vous suivre.", + "block_modal.they_cant_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.", + "block_modal.they_will_know": "Il peut voir qu'il est bloquรฉ.", + "block_modal.title": "Bloquer l'utilisateur ?", + "block_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.", "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois", "bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur", "bundle_column_error.error.body": "La page demandรฉe n'a pas pu รชtre affichรฉe. Cela peut รชtre dรป ร  un bogue dans notre code, ou ร  un problรจme de compatibilitรฉ avec le navigateur.", @@ -148,7 +156,7 @@ "compose_form.poll.duration": "Durรฉe du sondage", "compose_form.poll.multiple": "Choix multiple", "compose_form.poll.option_placeholder": "Option {number}", - "compose_form.poll.single": "Choisissez-en un", + "compose_form.poll.single": "Choix unique", "compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "compose_form.poll.switch_to_single": "Modifier le sondage pour autoriser qu'un seul choix", "compose_form.poll.type": "Style", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu", "compose_form.spoiler_placeholder": "Avertissement de contenu (optionnel)", "confirmation_modal.cancel": "Annuler", - "confirmations.block.block_and_report": "Bloquer et signaler", "confirmations.block.confirm": "Bloquer", - "confirmations.block.message": "Voulez-vous vraiment bloquer {name}โ€ฏ?", "confirmations.cancel_follow_request.confirm": "Retirer la demande", "confirmations.cancel_follow_request.message": "รŠtes-vous sรปr de vouloir retirer votre demande pour suivre {name} ?", "confirmations.delete.confirm": "Supprimer", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Voulez-vous vraiment supprimer dรฉfinitivement cette listeโ€ฏ?", "confirmations.discard_edit_media.confirm": "Rejeter", "confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrรฉes de la description ou de l'aperรงu du mรฉdia, les supprimer quand mรชme ?", - "confirmations.domain_block.confirm": "Bloquer tout le domaine", + "confirmations.domain_block.confirm": "Bloquer le serveur", "confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entierโ€ฏ? Dans la plupart des cas, quelques blocages ou masquages ciblรฉs sont suffisants et prรฉfรฉrables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans vos fils publics, ni dans vos notifications. Vos abonnรฉยทeยทs utilisant ce domaine seront retirรฉยทeยทs.", "confirmations.edit.confirm": "Modifier", "confirmations.edit.message": "Modifier maintenant รฉcrasera votre message en cours de rรฉdaction. Voulez-vous vraiment continuerย ?", "confirmations.logout.confirm": "Se dรฉconnecter", "confirmations.logout.message": "Voulez-vous vraiment vous dรฉconnecter ?", "confirmations.mute.confirm": "Masquer", - "confirmations.mute.explanation": "Cela masquera ses messages et les messages le ou la mentionnant, mais cela lui permettra quand mรชme de voir vos messages et de vous suivre.", - "confirmations.mute.message": "Voulez-vous vraiment masquer {name}ย ?", "confirmations.redraft.confirm": "Supprimer et rรฉ-รฉcrire", "confirmations.redraft.message": "รŠtes-vous sรปrยทe de vouloir effacer cette publication pour la rรฉรฉcrireโ€ฏ? Ses partages ainsi que ses mises en favori seront perdus et ses rรฉponses seront orphelines.", "confirmations.reply.confirm": "Rรฉpondre", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Ces messages venant de tout le web social gagnent en popularitรฉ aujourdโ€™hui. Les nouveaux messages avec plus de boosts et de favoris sont classรฉs plus haut.", "dismissable_banner.explore_tags": "Ces hashtags sont actuellement en train de gagner de l'ampleur parmi les personnes sur les serveurs du rรฉseau dรฉcentralisรฉ dont celui-ci.", "dismissable_banner.public_timeline": "Ce sont les posts publics les plus rรฉcents de personnes sur le web social que les gens sur {domain} suivent.", + "domain_block_modal.block": "Bloquer le serveur", + "domain_block_modal.block_account_instead": "Bloquer @{name} ร  la place", + "domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciennes publications.", + "domain_block_modal.they_cant_follow": "Personne de ce serveur ne peut vous suivre.", + "domain_block_modal.they_wont_know": "Il ne saura pas qu'il a รฉtรฉ bloquรฉ.", + "domain_block_modal.title": "Bloquer le domaine ?", + "domain_block_modal.you_will_lose_followers": "Tous vos abonnรฉs de ce serveur seront supprimรฉs.", + "domain_block_modal.you_wont_see_posts": "Vous ne verrez plus les publications ou les notifications des utilisateurs de ce serveur.", + "domain_pill.activitypub_lets_connect": "Cela vous permet de vous connecter et d'interagir avec les autres non seulement sur Mastodon, mais รฉgalement sur d'autres applications de rรฉseaux sociaux.", + "domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres rรฉseaux sociaux.", + "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 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 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", @@ -241,6 +266,7 @@ "empty_column.list": "Il nโ€™y a rien dans cette liste pour lโ€™instant. Quand des membres de cette liste publieront de nouveaux messages, ils apparaรฎtront ici.", "empty_column.lists": "Vous nโ€™avez pas encore de liste. Lorsque vous en crรฉerez une, elle apparaรฎtra ici.", "empty_column.mutes": "Vous nโ€™avez masquรฉ aucun compte pour le moment.", + "empty_column.notification_requests": "C'est fini ! Il n'y a plus rien ici. Lorsque vous recevez de nouvelles notifications, elles apparaitront ici conformรฉment ร  vos prรฉfรฉrences.", "empty_column.notifications": "Vous nโ€™avez pas encore de notification. Interagissez avec dโ€™autres personnes pour dรฉbuter la conversation.", "empty_column.public": "Il nโ€™y a rien iciโ€ฏ! ร‰crivez quelque chose publiquement, ou bien suivez manuellement des personnes dโ€™autres serveurs pour remplir le fil public", "error.unexpected_crash.explanation": "En raison dโ€™un bug dans notre code ou dโ€™un problรจme de compatibilitรฉ avec votre navigateur, cette page nโ€™a pas pu รชtre affichรฉe correctement.", @@ -271,12 +297,25 @@ "filter_modal.select_filter.subtitle": "Utilisez une catรฉgorie existante ou en crรฉer une nouvelle", "filter_modal.select_filter.title": "Filtrer ce message", "filter_modal.title.status": "Filtrer un message", + "filtered_notifications_banner.pending_requests": "Notifications {count, plural, =0 {de personne} one {dโ€™une personne} other {de # personnes}} que vous pouvez connaitre", + "filtered_notifications_banner.title": "Notifications filtrรฉes", "firehose.all": "Tout", "firehose.local": "Ce serveur", "firehose.remote": "Autres serveurs", "follow_request.authorize": "Accepter", "follow_request.reject": "Rejeter", "follow_requests.unlocked_explanation": "Mรชme si votre compte nโ€™est pas privรฉ, lโ€™รฉquipe de {domain} a pensรฉ que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.", + "follow_suggestions.curated_suggestion": "Choix du staff", + "follow_suggestions.dismiss": "Ne plus afficher", + "follow_suggestions.hints.featured": "Ce profil a รฉtรฉ sรฉlectionnรฉ par l'รฉquipe de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Ce profil est populaire parmi les personnes que vous suivez.", + "follow_suggestions.hints.most_followed": "Ce profil est l'un des plus suivis sur {domain}.", + "follow_suggestions.hints.most_interactions": "Ce profil a rรฉcemment fait l'objet d'une grande attention sur {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Ce profil est similaire aux profils que vous avez suivis le plus rรฉcemment.", + "follow_suggestions.personalized_suggestion": "Suggestion personnalisรฉe", + "follow_suggestions.popular_suggestion": "Suggestion populaire", + "follow_suggestions.view_all": "Tout afficher", + "follow_suggestions.who_to_follow": "Qui suivre", "followed_tags": "Hashtags suivis", "footer.about": "ร€ propos", "footer.directory": "Annuaire des profils", @@ -303,7 +342,6 @@ "hashtag.follow": "Suivre le hashtag", "hashtag.unfollow": "Ne plus suivre le hashtag", "hashtags.and_other": "โ€ฆet {count, plural, other {# de plus}}", - "home.column_settings.basic": "Basique", "home.column_settings.show_reblogs": "Afficher les partages", "home.column_settings.show_replies": "Afficher les rรฉponses", "home.hide_announcements": "Masquer les annonces", @@ -389,9 +427,15 @@ "loading_indicator.label": "Chargementโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Cacher lโ€™image} other {Cacher les images}}", "moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement dรฉsactivรฉ parce que vous l'avez dรฉplacรฉ ร  {movedToAccount}.", - "mute_modal.duration": "Durรฉe", - "mute_modal.hide_notifications": "Masquer les notifications de cette personneโ€ฏ?", - "mute_modal.indefinite": "Indรฉfinie", + "mute_modal.hide_from_notifications": "Cacher des notifications", + "mute_modal.hide_options": "Masquer les options", + "mute_modal.indefinite": "Jusqu'ร  ce que je les rรฉactive", + "mute_modal.show_options": "Afficher les options", + "mute_modal.they_can_mention_and_follow": "Ils peuvent vous mentionner et vous suivre, mais vous ne les verrez pas.", + "mute_modal.they_wont_know": "Ils ne sauront pas qu'ils ont รฉtรฉ rendus silencieux.", + "mute_modal.title": "Rendre cet utilisateur silencieux ?", + "mute_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.", + "mute_modal.you_wont_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.", "navigation_bar.about": "ร€ propos", "navigation_bar.advanced_interface": "Ouvrir dans lโ€™interface avancรฉe", "navigation_bar.blocks": "Comptes bloquรฉs", @@ -427,8 +471,17 @@ "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.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", + "notification_requests.dismiss": "Rejeter", + "notification_requests.notifications_from": "Notifications de {name}", + "notification_requests.title": "Notifications filtrรฉes", "notifications.clear": "Effacer les notifications", "notifications.clear_confirmation": "Voulez-vous vraiment effacer toutes vos notificationsโ€ฏ?", "notifications.column_settings.admin.report": "Nouveaux signalements :", @@ -436,8 +489,7 @@ "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 filtrage rapide", - "notifications.column_settings.filter_bar.show_bar": "Afficher la barre de filtre", + "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โ€ฏ:", @@ -463,6 +515,15 @@ "notifications.permission_denied": "Impossible dโ€™activer les notifications de bureau car lโ€™autorisation a รฉtรฉ refusรฉe.", "notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas รชtre activรฉes, car lโ€™autorisation du navigateur a รฉtรฉ refusรฉe avant", "notifications.permission_required": "Les notifications de bureau ne sont pas disponibles car lโ€™autorisation requise nโ€™a pas รฉtรฉ accordรฉe.", + "notifications.policy.filter_new_accounts.hint": "Crรฉรฉs au cours des derniers {days, plural, one {un jour} other {# jours}}", + "notifications.policy.filter_new_accounts_title": "Nouveaux comptes", + "notifications.policy.filter_not_followers_hint": "Incluant les personnes qui vous suivent depuis moins de {days, plural, one {un jour} other {# jours}}", + "notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas", + "notifications.policy.filter_not_following_hint": "Jusqu'ร  ce que vous les validiez manuellement", + "notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas", + "notifications.policy.filter_private_mentions_hint": "Filtrรฉ sauf si c'est en rรฉponse ร  une mention de vous ou si vous suivez l'expรฉditeur", + "notifications.policy.filter_private_mentions_title": "Mentions privรฉes non sollicitรฉes", + "notifications.policy.title": "Filtrer les notifications deโ€ฆ", "notifications_permission_banner.enable": "Activer les notifications de bureau", "notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon nโ€™est pas ouvert, activez les notifications du bureau. Vous pouvez contrรดler prรฉcisรฉment quels types dโ€™interactions gรฉnรจrent des notifications de bureau via le bouton {icon} ci-dessus une fois quโ€™elles sont activรฉes.", "notifications_permission_banner.title": "Toujours au courant", @@ -472,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.", @@ -489,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", @@ -524,9 +585,9 @@ "privacy.private.short": "Abonnรฉs", "privacy.public.long": "Tout le monde sur et en dehors de Mastodon", "privacy.public.short": "Public", - "privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaรฎtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, mรชme si vous avez optรฉ pour l'option publique pour l'ensemble de votre compte.", + "privacy.unlisted.additional": "Se comporte exactement comme ยซย publicย ยป, sauf que le message n'apparaรฎtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, mรชme si vous les avez activรฉ au niveau de votre compte.", "privacy.unlisted.long": "Moins de fanfares algorithmiques", - "privacy.unlisted.short": "Public calme", + "privacy.unlisted.short": "Public discret", "privacy_policy.last_updated": "Derniรจre mise ร  jour {date}", "privacy_policy.title": "Politique de confidentialitรฉ", "recommended": "Recommandรฉ", @@ -619,13 +680,10 @@ "server_banner.about_active_users": "Personnes utilisant ce serveur au cours des 30 derniers jours (Comptes actifs mensuellement)", "server_banner.active_users": "comptes actifs", "server_banner.administered_by": "Administrรฉ par :", - "server_banner.introduction": "{domain} fait partie du rรฉseau social dรฉcentralisรฉ propulsรฉ par {mastodon}.", - "server_banner.learn_more": "En savoir plus", "server_banner.server_stats": "Statistiques du serveur :", "sign_in_banner.create_account": "Crรฉer un compte", "sign_in_banner.sign_in": "Se connecter", "sign_in_banner.sso_redirect": "Se connecter ou sโ€™inscrire", - "sign_in_banner.text": "Identifiez-vous pour suivre des profils ou des hashtags, ajouter des favoris, partager et rรฉpondre ร  des messages. Vous pouvez รฉgalement interagir depuis votre compte sur un autre serveur.", "status.admin_account": "Ouvrir lโ€™interface de modรฉration pour @{name}", "status.admin_domain": "Ouvrir lโ€™interface de modรฉration pour {domain}", "status.admin_status": "Ouvrir ce message dans lโ€™interface de modรฉration", @@ -639,10 +697,11 @@ "status.direct": "Mention privรฉe @{name}", "status.direct_indicator": "Mention privรฉe", "status.edit": "Modifier", - "status.edited": "Modifiรฉ le {date}", + "status.edited": "Derniรจre modification leย {date}", "status.edited_x_times": "Modifiรฉ {count, plural, one {{count} fois} other {{count} fois}}", "status.embed": "Intรฉgrer", "status.favourite": "Ajouter aux favoris", + "status.favourites": "{count, plural, one {favori} other {favoris}}", "status.filter": "Filtrer ce message", "status.filtered": "Filtrรฉ", "status.hide": "Masquer le message", @@ -663,6 +722,7 @@ "status.reblog": "Partager", "status.reblog_private": "Partager ร  lโ€™audience originale", "status.reblogged_by": "{name} a partagรฉ", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "Personne nโ€™a encore partagรฉ ce message. Lorsque quelquโ€™un le fera, il apparaรฎtra ici.", "status.redraft": "Supprimer et rรฉรฉcrire", "status.remove_bookmark": "Retirer des marque-pages", diff --git a/app/javascript/mastodon/locales/fy.json b/app/javascript/mastodon/locales/fy.json index 9bd5327c8f..11b11ff819 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,14 @@ "announcement.announcement": "Oankundiging", "attachments_list.unprocessed": "(net ferwurke)", "audio.hide": "Audio ferstopje", + "block_modal.remote_users_caveat": "Wy freegje de server {domain} om jo beslรบt te respektearjen. It neilibben hjirfan is echter net garandearre, omdat guon servers blokkaden oars ynterpretearje kinne. Iepenbiere berjochten binne mooglik noch hieltyd sichtber foar net-oanmelde brรปkers.", + "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.they_cant_see_posts": "De persoan kin jo berjochten net sjen en jo ek net harren berjochten.", + "block_modal.they_will_know": "De persoan kin sjen dat dy blokkearre wurdt.", + "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.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Ynhรขldswarskรดging tafoegje", "compose_form.spoiler_placeholder": "Ynhรขldswarskรดging (opsjoneel)", "confirmation_modal.cancel": "Annulearje", - "confirmations.block.block_and_report": "Blokkearje en rapportearje", "confirmations.block.confirm": "Blokkearje", - "confirmations.block.message": "Binne jo wis dat jo {name} blokkearje wolle?", "confirmations.cancel_follow_request.confirm": "Fersyk annulearje", "confirmations.cancel_follow_request.message": "Binne jo wis dat jo jo fersyk om {name} te folgjen annulearje wolle?", "confirmations.delete.confirm": "Fuortsmite", @@ -171,15 +177,13 @@ "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": "Alles fan dit domein blokkearje", + "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?", "confirmations.logout.confirm": "Ofmelde", "confirmations.logout.message": "Binne jo wis dat jo รดfmelde wolle?", "confirmations.mute.confirm": "Negearje", - "confirmations.mute.explanation": "Dit sil berjochten fan harren en berjochten dรชrโ€™t se yn fermeld wurde รปnsichtber meitsje, mar se sille jo berjochten noch hieltyd sjen kinne en jo folgje kinne.", - "confirmations.mute.message": "Binne jo wis dat jo {name} negearje wolle?", "confirmations.redraft.confirm": "Fuortsmite en opnij opstelle", "confirmations.redraft.message": "Binne jo wis dat jo dit berjocht fuortsmite en opnij opstelle wolle? Favoriten en boosts geane dan ferlern en reaksjes op it oarspronklike berjocht reitsje jo kwyt.", "confirmations.reply.confirm": "Reagearje", @@ -205,6 +209,24 @@ "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.activitypub_lets_connect": "It soarget derfoar dat jo net allinnich mar ferbine en kommunisearje kinne mei minsken op Mastodon, mar ek mei oare sosjale apps.", + "domain_pill.activitypub_like_language": "ActivityPub is de taal dyโ€™t Mastodon mei oare sosjale netwurken sprekt.", + "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.their_username": "Harren unike identifikaasje-adres op harren server. It is mooglik dat der brรปkers mei deselde brรปkersnamme op ferskate servers te finen binne.", + "domain_pill.username": "Brรปkersnamme", + "domain_pill.whats_in_a_handle": "Wat is in fediverse-adres?", + "domain_pill.who_they_are": "Omdat jo oan in fediverse-adres sjen kinne hoeโ€™t ien hjit en op hokker server dy sit, kinne jo mei minsken op it troch sosjale web (fediverse) kommunisearje.", + "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", @@ -271,14 +293,20 @@ "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", "follow_request.authorize": "Goedkarre", "follow_request.reject": "Wegerje", "follow_requests.unlocked_explanation": "Ek al is jo account net besletten, de meiwurkers fan {domain} tinke dat jo miskien de folgjende folchfersiken hรขnmjittich kontrolearje.", - "follow_suggestions.curated_suggestion": "Kar fan de moderator", + "follow_suggestions.curated_suggestion": "Spesjaal selektearre", "follow_suggestions.dismiss": "Net mear werjaan", + "follow_suggestions.hints.featured": "Dit profyl is hรขnmjittich troch it {domain}-team selektearre.", + "follow_suggestions.hints.friends_of_friends": "Dit profyl is populรชr รปnder de minsken dyโ€™t jo folgje.", + "follow_suggestions.hints.most_followed": "Dit profyl is ien fan de meast folge op {domain}.", + "follow_suggestions.hints.most_interactions": "Dit profyl hat de lรชste tiid in protte oandacht krigen op {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Dit profyl is hast lyk oan de profilen dyโ€™t jo koartlyn folge hawwe.", "follow_suggestions.personalized_suggestion": "Personalisearre suggestje", "follow_suggestions.popular_suggestion": "Populรชre suggestje", "follow_suggestions.view_all": "Alles werjaan", @@ -309,7 +337,6 @@ "hashtag.follow": "Hashtag folgje", "hashtag.unfollow": "Hashtag รปntfolgje", "hashtags.and_other": "โ€ฆen {count, plural, one {}other {# mear}}", - "home.column_settings.basic": "Algemien", "home.column_settings.show_reblogs": "Boosts toane", "home.column_settings.show_replies": "Reaksjes toane", "home.hide_announcements": "Meidielingen ferstopje", @@ -395,9 +422,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.duration": "Doer", - "mute_modal.hide_notifications": "Meldingen fan dizze brรปker ferstopje?", - "mute_modal.indefinite": "Foar รปnbepaalde tiid", + "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", @@ -433,8 +460,13 @@ "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:", @@ -442,8 +474,6 @@ "notifications.column_settings.alert": "Desktopmeldingen", "notifications.column_settings.favourite": "Favoriten:", "notifications.column_settings.filter_bar.advanced": "Alle kategoryen toane", - "notifications.column_settings.filter_bar.category": "Flugge filterbalke", - "notifications.column_settings.filter_bar.show_bar": "Filterbalke toane", "notifications.column_settings.follow": "Nije folgers:", "notifications.column_settings.follow_request": "Nij folchfersyk:", "notifications.column_settings.mention": "Fermeldingen:", @@ -625,13 +655,10 @@ "server_banner.about_active_users": "Oantal brรปkers yn de รดfrรปne 30 dagen (MAU)", "server_banner.active_users": "warbere brรปkers", "server_banner.administered_by": "Beheard troch:", - "server_banner.introduction": "{domain} is รปnderdiel fan it desintralisearre sosjale netwurk {mastodon}.", - "server_banner.learn_more": "Mear ynfo", "server_banner.server_stats": "Serverstatistiken:", "sign_in_banner.create_account": "Account registrearje", "sign_in_banner.sign_in": "Oanmelde", "sign_in_banner.sso_redirect": "Oanmelde of Registrearje", - "sign_in_banner.text": "Meld jo oan, om profilen of hashtags te folgjen, berjochten favoryt te meitsjen, te dielen en te beรคntwurdzjen of om fan jo account รบt op in oare server mei oaren ynteraksje te hawwen.", "status.admin_account": "Moderaasje-omjouwing fan @{name} iepenje", "status.admin_domain": "Moderaasje-omjouwing fan {domain} iepenje", "status.admin_status": "Open this status in the moderation interface", @@ -645,7 +672,6 @@ "status.direct": "Privee fermelde @{name}", "status.direct_indicator": "Priveefermelding", "status.edit": "Bewurkje", - "status.edited": "Bewurke op {date}", "status.edited_x_times": "{count, plural, one {{count} kear} other {{count} kearen}} bewurke", "status.embed": "Ynslute", "status.favourite": "Favoryt", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json index 329286277d..97dcc752b8 100644 --- a/app/javascript/mastodon/locales/ga.json +++ b/app/javascript/mastodon/locales/ga.json @@ -133,9 +133,7 @@ "compose_form.spoiler.marked": "Bain rabhadh รกbhair", "compose_form.spoiler.unmarked": "Cuir rabhadh รกbhair", "confirmation_modal.cancel": "Cealaigh", - "confirmations.block.block_and_report": "Bac โŠ Tuairiscigh", "confirmations.block.confirm": "Bac", - "confirmations.block.message": "An bhfuil tรบ cinnte gur mhaith leat {name} a bhac?", "confirmations.cancel_follow_request.confirm": "ร‰irigh as iarratas", "confirmations.cancel_follow_request.message": "An bhfuil tรบ cinnte gur mhaith leat รฉirigh as an iarratas leanta {name}?", "confirmations.delete.confirm": "Scrios", @@ -144,13 +142,10 @@ "confirmations.delete_list.message": "An bhfuil tรบ cinnte gur mhaith leat an liosta seo a scriosadh go buan?", "confirmations.discard_edit_media.confirm": "Faigh rรฉidh de", "confirmations.discard_edit_media.message": "Tรก athruithe neamhshlรกnaithe don tuarascรกil gnรฉ nรณ rรฉamhamharc agat, faigh rรฉidh dรณibh ar aon nรณs?", - "confirmations.domain_block.confirm": "Bac fearann go hiomlรกn", "confirmations.domain_block.message": "An bhfuil tรบ iontach cinnte gur mhaith leat bac an t-ainm fearainn {domain} in iomlรกn? I bhformhรณr na gcรกsanna, is leor agus is fearr cรบpla baic a cur i bhfeidhm nรณ cรบpla รบsรกideoirรญ a balbhรบ. Nรญ fheicfidh tรบ รกbhair รณn t-ainm fearainn sin in amlรญne ar bith, nรณ i d'fhรณgraรญ. Scaoilfear do leantรณirรญ รณn ainm fearainn sin.", "confirmations.logout.confirm": "Logรกil amach", "confirmations.logout.message": "An bhfuil tรบ cinnte gur mhaith leat logรกil amach?", "confirmations.mute.confirm": "Balbhaigh", - "confirmations.mute.explanation": "Cuiridh seo teachtaireachtaรญ uathu agus fรบthu i bhfolach, ach beidh siad in ann fรณs do theachtaireachtaรญ a fheiceรกil agus tรบ a leanรบint.", - "confirmations.mute.message": "An bhfuil tรบ cinnte gur mhaith leat {name} a bhalbhรบ?", "confirmations.redraft.confirm": "Scrios โŠ athdhrรฉachtaigh", "confirmations.reply.confirm": "Freagair", "confirmations.reply.message": "Scriosfaidh freagra lรกithreach an teachtaireacht atรก a chumadh anois agat. An bhfuil tรบ cinnte gur mhaith leat leanรบint leat?", @@ -226,7 +221,6 @@ "follow_request.authorize": "Ceadaigh", "follow_request.reject": "Diรบltaigh", "follow_requests.unlocked_explanation": "Cรฉ nach bhfuil do chuntas faoi ghlas, cheap foireann {domain} gur mhaith leat sรบil siar ar iarratais leanรบnaรญ as na cuntais seo.", - "follow_suggestions.curated_suggestion": "Rogha an eagarthรณra", "follow_suggestions.dismiss": "Nรก taispeรกin arรญs", "follow_suggestions.personalized_suggestion": "Nod pearsantaithe", "follow_suggestions.popular_suggestion": "Nod coiteann", @@ -250,7 +244,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "Lean haischlib", "hashtag.unfollow": "Nรก lean haischlib", - "home.column_settings.basic": "Bunรบsach", "home.column_settings.show_reblogs": "Taispeรกin moltaรญ", "home.column_settings.show_replies": "Taispeรกn freagraรญ", "home.hide_announcements": "Cuir fรณgraรญ i bhfolach", @@ -313,9 +306,6 @@ "lists.replies_policy.title": "Taispeรกin freagraรญ:", "lists.search": "Cuardaigh i measc daoine atรก รก leanรบint agat", "lists.subheading": "Do liostaรญ", - "mute_modal.duration": "Trรฉimhse", - "mute_modal.hide_notifications": "Cuir pรณstalacha รณn t-รบsรกideoir seo i bhfolach?", - "mute_modal.indefinite": "Gan tรฉarma", "navigation_bar.about": "Maidir le", "navigation_bar.blocks": "Cuntais bhactha", "navigation_bar.bookmarks": "Leabharmharcanna", @@ -350,9 +340,6 @@ "notifications.clear": "Glan fรณgraรญ", "notifications.column_settings.admin.report": "Tuairiscรญ nua:", "notifications.column_settings.alert": "Fรณgraรญ deisce", - "notifications.column_settings.filter_bar.advanced": "Taispeรกin na catagรณirรญ go lรฉir", - "notifications.column_settings.filter_bar.category": "Barra scagaire tapa", - "notifications.column_settings.filter_bar.show_bar": "Taispeรกin barra scagaire", "notifications.column_settings.follow": "Leantรณirรญ nua:", "notifications.column_settings.follow_request": "Iarratais leanรบnaรญ nua:", "notifications.column_settings.mention": "Trรกchtanna:", @@ -451,7 +438,6 @@ "search_results.statuses": "Postรกlacha", "search_results.title": "Cuardaigh ar thรณir {q}", "server_banner.active_users": "รบsรกideoirรญ gnรญomhacha", - "server_banner.learn_more": "Tuilleadh eolais", "server_banner.server_stats": "Staitisticรญ freastalaรญ:", "sign_in_banner.create_account": "Cruthaigh cuntas", "sign_in_banner.sign_in": "Sinigh isteach", @@ -463,7 +449,6 @@ "status.copy": "Copy link to status", "status.delete": "Scrios", "status.edit": "Cuir in eagar", - "status.edited": "Curtha in eagar in {date}", "status.edited_x_times": "Curtha in eagar {count, plural, one {{count} uair amhรกin} two {{count} uair} few {{count} uair} many {{count} uair} other {{count} uair}}", "status.embed": "Leabaigh", "status.filter": "Dรฉan scagadh ar an bpostรกil seo", diff --git a/app/javascript/mastodon/locales/gd.json b/app/javascript/mastodon/locales/gd.json index 47b1e23192..714fa6e364 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}", @@ -89,6 +89,14 @@ "announcement.announcement": "Brath-fios", "attachments_list.unprocessed": "(gun phrรฒiseasadh)", "audio.hide": "Falaich an fhuaim", + "block_modal.remote_users_caveat": "Iarraidh sinn air an fhrithealaiche {domain} gun gรจill iad ri do cho-dhรนnadh. Gidheadh, chan eil barantas gun gรจill iad on a lร imhsicheas cuid a fhrithealaichean bacaidhean air dรฒigh eadar-dhealaichte. Dhโ€™fhaoidte gum faic daoine gun chlร radh a-steach na postaichean poblach agad fhathast.", + "block_modal.show_less": "Seall nas lugha dheth", + "block_modal.show_more": "Seall barrachd dheth", + "block_modal.they_cant_mention": "Chan urrainn dhaibh iomradh a thoirt ort no do leantainn.", + "block_modal.they_cant_see_posts": "Chan fhaic iad na postaichean agad โ€™s chan fhaic thu na postaichean aca-san.", + "block_modal.they_will_know": "Chรฌ iad gun deach am bacadh.", + "block_modal.title": "A bheil thu airson an cleachdaiche a bhacadh?", + "block_modal.you_wont_see_mentions": "Chan fhaic thu na postaichean a bheir iomradh orra.", "boost_modal.combo": "Brรนth air {combo} nam bโ€™ fheร rr leat leum a ghearradh thar seo an ath-thuras", "bundle_column_error.copy_stacktrace": "Dรจan lethbhreac de aithris na mearachd", "bundle_column_error.error.body": "Cha bโ€™ urrainn dhuinn an duilleag a dhโ€™iarr thu a reandaradh. Dhโ€™fhaoidte gu bheil buga sa chรฒd againn no duilgheadas co-chรฒrdalachd leis aโ€™ bhrabhsair.", @@ -145,10 +153,10 @@ "compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. โ€™S urrainn do dhuine sam bith โ€™gad leantainn is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhร in a shealltainn.", "compose_form.lock_disclaimer.lock": "glaiste", "compose_form.placeholder": "Dรจ tha air dโ€™ aire?", - "compose_form.poll.duration": "Faide aโ€™ chunntais-bheachd", - "compose_form.poll.multiple": "Iomadh roghainn", + "compose_form.poll.duration": "Faide aโ€™ chunntais", + "compose_form.poll.multiple": "Iomadh-roghainn", "compose_form.poll.option_placeholder": "Roghainn {number}", - "compose_form.poll.single": "Tagh aonan", + "compose_form.poll.single": "Aonan", "compose_form.poll.switch_to_multiple": "Atharraich an cunntas-bheachd ach an gabh iomadh roghainn a thaghadh", "compose_form.poll.switch_to_single": "Atharraich an cunntas-bheachd gus nach gabh ach aon roghainn a thaghadh", "compose_form.poll.type": "Stoidhle", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Cuir rabhadh susbainte ris", "compose_form.spoiler_placeholder": "Rabhadh susbainte (roghainneil)", "confirmation_modal.cancel": "Sguir dheth", - "confirmations.block.block_and_report": "Bac โŠ dรจan gearan", "confirmations.block.confirm": "Bac", - "confirmations.block.message": "A bheil thu cinnteach gu bheil thu airson {name} a bhacadh?", "confirmations.cancel_follow_request.confirm": "Cuir dโ€™ iarrtas dhan dร rna taobh", "confirmations.cancel_follow_request.message": "A bheil thu cinnteach gu bheil thu airson dโ€™ iarrtas airson {name} a leantainn a chur dhan dร rna taobh?", "confirmations.delete.confirm": "Sguab ร s", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "A bheil thu cinnteach gu bheil thu airson an liosta seo a sguabadh ร s gu buan?", "confirmations.discard_edit_media.confirm": "Tilg air falbh", "confirmations.discard_edit_media.message": "Tha atharraichean gun sร bhaladh agad ann an tuairisgeul no ro-shealladh aโ€™ mheadhain, a bheil thu airson an tilgeil air falbh co-dhiรน?", - "confirmations.domain_block.confirm": "Bac an ร rainn uile gu lรจir", + "confirmations.domain_block.confirm": "Bac am frithealaiche", "confirmations.domain_block.message": "A bheil thu cinnteach dha-rรฌribh gu bheil thu airson an ร rainn {domain} a bhacadh uile gu lรจir? Mar as trice, foghnaidh gun dรจan thu bacadh no mรนchadh no dhร  gu sรฒnraichte agus bhiodh sin na bโ€™ fheร rr. Chan fhaic thu susbaint on ร rainn ud air loidhne-ama phoblach sam bith no am measg nam brathan agad. Thรจid an luchd-leantainn agad on ร rainn ud a thoirt air falbh.", "confirmations.edit.confirm": "Deasaich", "confirmations.edit.message": "Ma nรฌ thu deasachadh an-drร sta, thรจid seo a sgrรฌobhadh thairis air an teachdaireachd a tha thu aโ€™ sgrรฌobhadh an-drร sta. A bheil thu cinnteach gu bheil thu airson leantainn air adhart?", "confirmations.logout.confirm": "Clร raich a-mach", "confirmations.logout.message": "A bheil thu cinnteach gu bheil thu airson clร radh a-mach?", "confirmations.mute.confirm": "Mรนch", - "confirmations.mute.explanation": "Cuiridh seo na postaichean uapa โ€™s na postaichean a bheir iomradh orra am falach ach chรฌ iad-san na postaichean agad fhathast is faodaidh iad โ€™gad leantainn.", - "confirmations.mute.message": "A bheil thu cinnteach gu bheil thu airson {name} a mhรนchadh?", "confirmations.redraft.confirm": "Sguab ร s โŠ dรจan dreachd รนr", "confirmations.redraft.message": "A bheil thu cinnteach gu bheil thu airson am post seo a sguabadh ร s agus dreachd รนr a thรฒiseachadh? Caillidh tu gach annsachd is brosnachadh air agus thรจid freagairtean dhan phost thรนsail โ€™nan dรฌlleachdanan.", "confirmations.reply.confirm": "Freagair", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Tha fรจill air na postaichean seo aโ€™ fร s thar an lรฌona shรฒisealta an-diugh. Gheibh postaichean nas รนire le barrachd brosnaichean is annsachdan rangachadh nas ร irde.", "dismissable_banner.explore_tags": "Tha fรจill air na tagaichean hais seo aโ€™ fร s air an fhrithealaiche seo is frithealaichean eile dhen lรฌonra sgaoilte an-diugh. Gheibh tagaichean hais a tha โ€™gan cleachdadh le daoine eadar-dhealaichte rangachadh nas ร irde.", "dismissable_banner.public_timeline": "Seo na postaichean poblach as รนire o dhaoine air an lรฌonra sรฒisealta tha โ€™gan leantainn le daoine air {domain}.", + "domain_block_modal.block": "Bac am frithealaiche", + "domain_block_modal.block_account_instead": "Bac @{name} โ€™na ร ite", + "domain_block_modal.they_can_interact_with_old_posts": "โ€™S urrainn do dhaoine a thโ€™ air an fhrithealaiche seo eadar-ghabhail leis na seann-phostaichean agad.", + "domain_block_modal.they_cant_follow": "Chan urrainn do neach sam bith a thโ€™ air an fhrithealaiche seo do leantainn.", + "domain_block_modal.they_wont_know": "Cha bhi fios aca gun deach am bacadh.", + "domain_block_modal.title": "A bheil thu airson an ร rainn a bhacadh?", + "domain_block_modal.you_will_lose_followers": "Thรจid a h-uile neach-leantainn agad a thโ€™ air an fhrithealaiche seo a thoirt air falbh.", + "domain_block_modal.you_wont_see_posts": "Chan fhaic thu postaichean no brathan o chleachdaichean a thโ€™ air an fhrithealaiche seo.", + "domain_pill.activitypub_lets_connect": "Leigidh e leat ceangal a dhรจanamh ri daoine chan ann air Mastodon a-mhร in ach air feadh aplacaidean sรฒisealta eile cuideachd agus conaltradh leotha.", + "domain_pill.activitypub_like_language": "Tha ActivityPub coltach ri cร nan a bhruidhneas Mastodon ri lรฌonraidhean sรฒisealta eile.", + "domain_pill.server": "Frithealaiche", + "domain_pill.their_handle": "An t-aithnichear aca:", + "domain_pill.their_server": "An dachaigh dhigiteach far a bheil na postaichean uile aca aโ€™ fuireach.", + "domain_pill.their_username": "Seo an t-aithnichear ร raidh aca air an fhrithealaiche aca. Dhโ€™fhaoidte gu bheil luchd-cleachdaidh air a bheil an t-aon ainm air frithealaichean eile.", + "domain_pill.username": "Ainm-cleachdaiche", + "domain_pill.whats_in_a_handle": "Dรจ thโ€™ ann an aithnichear?", + "domain_pill.who_they_are": "On a dhโ€™innseas aithnichearan cรฒ cuideigin agus cร it a bheil iad, โ€™s urrainn dhut conaltradh le daoine thar an lรฌonraidh shรฒisealta de .", + "domain_pill.who_you_are": "On a dhโ€™innseas dโ€™ aithnichear cรฒ thusa agus cร it a bheil thu, โ€™s urrainn do dhaoine conaltradh leat thar an lรฌonraidh shรฒisealta de .", + "domain_pill.your_handle": "An t-aithnichear agad:", + "domain_pill.your_server": "Do dhachaigh dhigiteach far a bheil na postaichean uile agad aโ€™ fuireach. Nach toigh leat an tรจ seo? Dรจan imrich gu frithealaiche eile uair sam bith is thoir an luchd-leantainn agad leat cuideachd.", + "domain_pill.your_username": "Seo an t-aithnichear ร raidh agad air an fhrithealaiche seo. Dhโ€™fhaoidte gu bheil luchd-cleachdaidh air a bheil an t-aon ainm air frithealaichean eile.", "embed.instructions": "Leabaich am post seo san lร rach-lรฌn agad is tu aโ€™ dรจanamh lethbhreac dhen chรฒd gu h-รฌosal.", "embed.preview": "Seo an coltas a bhios air:", "emoji_button.activity": "Gnรฌomhachd", @@ -241,6 +266,7 @@ "empty_column.list": "Chan eil dad air an liosta seo fhathast. Nuair a phostaicheas buill a tha air an liosta seo postaichean รนra, nochdaidh iad an-seo.", "empty_column.lists": "Chan eil liosta agad fhathast. Nuair chruthaicheas tu tรจ, nochdaidh i an-seo.", "empty_column.mutes": "Cha do mhรนch thu cleachdaiche sam bith fhathast.", + "empty_column.notification_requests": "Glan! Chan eil dad an-seo. Nuair a gheibh thu brathan รนra, nochdaidh iad an-seo a-rรจir nan roghainnean agad.", "empty_column.notifications": "Cha dโ€™ fhuair thu brath sam bith fhathast. Nuair a nรฌ cร ch conaltradh leat, chรฌ thu an-seo e.", "empty_column.public": "Chan eil dad an-seo! Sgrรฌobh rudeigin gu poblach no lean cร ch o fhrithealaichean eile a lร imh airson seo a lรฌonadh", "error.unexpected_crash.explanation": "Air sร illeibh buga sa chรฒd againn no duilgheadas co-chรฒrdalachd leis aโ€™ bhrabhsair, chan urrainn dhuinn an duilleag seo a shealltainn mar bu chรฒir.", @@ -271,18 +297,28 @@ "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", "firehose.local": "Am frithealaiche seo", "firehose.remote": "Frithealaichean eile", "follow_request.authorize": "ร™ghdarraich", "follow_request.reject": "Diรนlt", "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 deasaiche", + "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}.", + "follow_suggestions.hints.most_interactions": "Chaidh mรฒran aire a thoirt air aโ€™ phrรฒifil seo air {domain} o chionn goirid.", + "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": "Cรฒ a leanas tu", + "follow_suggestions.who_to_follow": "Molaidhean leantainn", "followed_tags": "Tagaichean hais โ€™gan leantainn", "footer.about": "Mu dhรจidhinn", "footer.directory": "Eรฒlaire nam prรฒifil", @@ -309,7 +345,6 @@ "hashtag.follow": "Lean an taga hais", "hashtag.unfollow": "Na lean an taga hais tuilleadh", "hashtags.and_other": "โ€ฆagus {count, plural, one {# eile} two {# eile} few {# eile} other {# eile}}", - "home.column_settings.basic": "Bunasach", "home.column_settings.show_reblogs": "Seall na brosnachaidhean", "home.column_settings.show_replies": "Seall na freagairtean", "home.hide_announcements": "Falaich na brathan-fios", @@ -395,9 +430,15 @@ "loading_indicator.label": "โ€™Ga luchdadhโ€ฆ", "media_gallery.toggle_visible": "{number, plural, 1 {Falaich an dealbh} one {Falaich na dealbhan} two {Falaich na dealbhan} few {Falaich na dealbhan} other {Falaich na dealbhan}}", "moved_to_account_banner.text": "Tha an cunntas {disabledAccount} agad ร  comas on a rinn thu imrich gu {movedToAccount}.", - "mute_modal.duration": "Faide", - "mute_modal.hide_notifications": "A bheil thu airson na brathan fhalach on chleachdaiche seo?", - "mute_modal.indefinite": "Gun chrรฌoch", + "mute_modal.hide_from_notifications": "Falaich o na brathan", + "mute_modal.hide_options": "Roghainnean falaich", + "mute_modal.indefinite": "Gus an dรฌ-mhรนch mi iad", + "mute_modal.show_options": "Seall na roghainnean", + "mute_modal.they_can_mention_and_follow": "โ€™S urrainn dhaibh iomradh a thoirt ort agus do leantainn ach chan fhaic thu iad-san.", + "mute_modal.they_wont_know": "Cha bhi fios aca gun deach am mรนchadh.", + "mute_modal.title": "A bheil thu airson an cleachdaiche a mhรนchadh?", + "mute_modal.you_wont_see_mentions": "Chan fhaic thu na postaichean a bheir iomradh orra.", + "mute_modal.you_wont_see_posts": "Chรฌ iad na postaichean agad fhathast ach chan fhaic thu na postaichean aca-san.", "navigation_bar.about": "Mu dhรจidhinn", "navigation_bar.advanced_interface": "Fosgail san eadar-aghaidh-lรฌn adhartach", "navigation_bar.blocks": "Cleachdaichean bacte", @@ -430,11 +471,21 @@ "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.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", + "notification_requests.dismiss": "Leig seachad", + "notification_requests.notifications_from": "Brathan o {name}", + "notification_requests.title": "Brathan criathraichte", "notifications.clear": "Falamhaich na brathan", "notifications.clear_confirmation": "A bheil thu cinnteach gu bheil thu airson na brathan uile agad fhalamhachadh gu buan?", "notifications.column_settings.admin.report": "Gearanan รนra:", @@ -443,7 +494,6 @@ "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.filter_bar.show_bar": "Seall am bร r-criathraidh", "notifications.column_settings.follow": "Luchd-leantainn รนr:", "notifications.column_settings.follow_request": "Iarrtasan leantainn รนra:", "notifications.column_settings.mention": "Iomraidhean:", @@ -469,6 +519,15 @@ "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": "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", + "notifications.policy.filter_not_following_hint": "Gus an aontaich thu riutha a lร imh", + "notifications.policy.filter_not_following_title": "Daoine nach eil thu aโ€™ leantainn", + "notifications.policy.filter_private_mentions_hint": "Criathraichte ach ma tha e aโ€™ freagairt do dhโ€™iomradh agad fhรจin no ma tha thu aโ€™ leantainn an t-seรฒladair", + "notifications.policy.filter_private_mentions_title": "Iomraidhean prรฌobhaideach o choigrich", + "notifications.policy.title": "Falamhaich na brathan oโ€ฆ", "notifications_permission_banner.enable": "Cuir brathan deasga an comas", "notifications_permission_banner.how_to_control": "Airson brathan fhaighinn nuair nach eil Mastodon fosgailte, cuir na brathan deasga an comas. Tha an smachd agad fhรจin air dรจ na seรฒrsaichean de chonaltradh a ghineas brathan deasga leis aโ€™ phutan {icon} gu h-ร rd nuair a bhios iad air an cur an comas.", "notifications_permission_banner.title": "Na caill dad gu brร th tuilleadh", @@ -480,9 +539,11 @@ "onboarding.follows.empty": "Gu mรฌ-fhortanach, chan urrainn dhuinn toradh a shealltainn an-drร sta. Feuch gleus an luirg no duilleag an rรนrachaidh airson daoine ri leantainn a lorg no feuch ris a-rithist an ceann tamaill.", "onboarding.follows.lead": "โ€™S e do prรฌomh-doras do Mhastodon a thโ€™ ann san dachaigh. Mar as motha an t-uiread de dhaoine a leanas tu โ€™s ann nas beรฒthaile inntinniche a bhios i. Seo moladh no dhร  dhut airson tรฒiseachadh:", "onboarding.follows.title": "Cuir dreach pearsanta air do dhachaigh", - "onboarding.profile.discoverable": "Bu mhath leam gun gabh aโ€™ phrรฒifil agam a lorg", + "onboarding.profile.discoverable": "Bu mhath leam gun gabh aโ€™ phrรฒifil agam a rรนrachadh", + "onboarding.profile.discoverable_hint": "Ma chuir thu romhad gun gabh aโ€™ phrรฒifil agad a rรนrachadh air Mastodon, faodaidh na postaichean agad nochdadh ann an toraidhean luirg agus treandaichean agus dhโ€™fhaoidte gun dรจid aโ€™ phrรฒifil agad a mholadh dhan fheadhainn aig a bheil รนidhean coltach ri dโ€™ รนidhean-sa.", "onboarding.profile.display_name": "Ainm-taisbeanaidh", "onboarding.profile.display_name_hint": "Dโ€™ ainm slร n no spรฒrsailโ€ฆ", + "onboarding.profile.lead": "โ€™S urrainn dhut seo a choileanadh uair sam bith eile sna roghainnean far am bi roghainnean gnร thachaidh eile ri lร imh dhut cuideachd.", "onboarding.profile.note": "Cunntas-beatha", "onboarding.profile.note_hint": "โ€™S urrainn dhut @iomradh a thoirt air cร ch no air #tagaicheanHaisโ€ฆ", "onboarding.profile.save_and_continue": "Sร bhail โ€™s lean air adhart", @@ -528,6 +589,8 @@ "privacy.private.short": "Luchd-leantainn", "privacy.public.long": "Duine sam bith taobh a-staigh no a-muigh Mhastodon", "privacy.public.short": "Poblach", + "privacy.unlisted.additional": "Tha seo coltach ris an fhaicsinneachd phoblach ach cha nochd am post air loidhnichean-ama an t-saoghail phoblaich, nan tagaichean hais no an rรนrachaidh no ann an toraidhean luirg Mhastodon fiรน โ€™s ma thug thu ro-aonta airson sin seachad.", + "privacy.unlisted.long": "รŒre bheag an algairim", "privacy.unlisted.short": "Poblach ach sร mhach", "privacy_policy.last_updated": "An t-รนrachadh mu dheireadh {date}", "privacy_policy.title": "Poileasaidh prรฌobhaideachd", @@ -621,13 +684,10 @@ "server_banner.about_active_users": "Daoine a chleachd am frithealaiche seo rรจ an 30 latha mu dheireadh (Cleachdaichean gnรฌomhach gach mรฌos)", "server_banner.active_users": "cleachdaichean gnรฌomhach", "server_banner.administered_by": "Rianachd le:", - "server_banner.introduction": "Tha {domain} am measg an lรฌonraidh shรฒisealta sgaoilte le cumhachd {mastodon}.", - "server_banner.learn_more": "Barrachd fiosrachaidh", "server_banner.server_stats": "Stadastaireachd an fhrithealaiche:", "sign_in_banner.create_account": "Cruthaich cunntas", "sign_in_banner.sign_in": "Clร raich a-steach", "sign_in_banner.sso_redirect": "Clร raich a-steach no clร raich leinn", - "sign_in_banner.text": "Clร raich a-steach a leantainn phrรฒifilean no thagaichean hais, aโ€™ cur postaichean ris na h-annsachdan โ€™s โ€™gan co-roinneadh is freagairt dhaibh. โ€™S urrainn dhut gnรฌomh a ghabhail le cunntas o fhrithealaiche eile cuideachd.", "status.admin_account": "Fosgail eadar-aghaidh na maorsainneachd dha @{name}", "status.admin_domain": "Fosgail eadar-aghaidh na maorsainneachd dha {domain}", "status.admin_status": "Fosgail am post seo ann an eadar-aghaidh na maorsainneachd", @@ -641,10 +701,11 @@ "status.direct": "Thoir iomradh air @{name} gu prรฌobhaideach", "status.direct_indicator": "Iomradh prรฌobhaideach", "status.edit": "Deasaich", - "status.edited": "Air a dheasachadh {date}", - "status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{counter} turas} two {{counter} thuras} few {{counter} tursan} other {{counter} turas}}", + "status.edited": "An deasachadh mu dheireadh {date}", + "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.filter": "Criathraich am post seo", "status.filtered": "Criathraichte", "status.hide": "Falaich am post", @@ -665,6 +726,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.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 7512740c5e..7b77f98034 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -2,7 +2,7 @@ "about.blocks": "Servidores suxeitos a moderaciรณn", "about.contact": "Contacto:", "about.disclaimer": "Mastodon รฉ software libre, de cรณdigo aberto, e unha marca comercial de Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Motivo non indicado. ", + "about.domain_blocks.no_reason_available": "Motivo non indicado", "about.domain_blocks.preamble": "Mastodon de xeito xeral permรญteche ver contidos doutros servidores do fediverso e interactuar coas sรบas usuarias. Estas son as excepciรณns que se estabeleceron neste servidor en particular.", "about.domain_blocks.silenced.explanation": "Por defecto non verรกs perfรญs e contido desde este servidor, a menos que mires de xeito explรญcito ou optes por seguir ese contido ou usuaria.", "about.domain_blocks.silenced.title": "Limitado", @@ -89,6 +89,14 @@ "announcement.announcement": "Anuncio", "attachments_list.unprocessed": "(sen procesar)", "audio.hide": "Agochar audio", + "block_modal.remote_users_caveat": "รmoslle pedir ao servidor {domain} que respecte a tรบa decisiรณn. Emporiso, non hai garantรญa de que atenda a peticiรณn xa que os servidores xestionan os bloqueos de formas diferentes. As publicaciรณns pรบblicas poderรญan aรญnda ser visibles para usuarias que non iniciaron sesiรณn.", + "block_modal.show_less": "Mostrar menos", + "block_modal.show_more": "Mostrar mรกis", + "block_modal.they_cant_mention": "Non te poden seguir nin mencionar.", + "block_modal.they_cant_see_posts": "Non pode ver as tรบas publicaciรณns nin ti as de ela.", + "block_modal.they_will_know": "Pode ver que a bloqueaches.", + "block_modal.title": "Bloquear usuaria?", + "block_modal.you_wont_see_mentions": "Non verรกs publicaciรณns que a mencionen.", "boost_modal.combo": "Preme {combo} para ignorar isto na seguinte vez", "bundle_column_error.copy_stacktrace": "Copiar informe do erro", "bundle_column_error.error.body": "Non se puido mostrar a pรกxina solicitada. Poderรญa deberse a un problema no cรณdigo, ou incompatiblidade co navegador.", @@ -107,7 +115,7 @@ "closed_registrations_modal.find_another_server": "Atopa outro servidor", "closed_registrations_modal.preamble": "Mastodon รฉ descentralizado, asรญ que non importa onde crees a conta, poderรกs seguir e interactuar con calquera conta deste servidor. Incluso podes ter o teu servidor!", "closed_registrations_modal.title": "Crear conta en Mastodon", - "column.about": "Acerca de", + "column.about": "Sobre", "column.blocks": "Usuarias bloqueadas", "column.bookmarks": "Marcadores", "column.community": "Cronoloxรญa local", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Engadir aviso sobre o contido", "compose_form.spoiler_placeholder": "Aviso sobre o contido (optativo)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear e denunciar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "Tes a certeza de querer bloquear a {name}?", "confirmations.cancel_follow_request.confirm": "Retirar solicitude", "confirmations.cancel_follow_request.message": "Tes a certeza de querer retirar a solicitude para seguir a {name}?", "confirmations.delete.confirm": "Eliminar", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Tes a certeza de querer eliminar de xeito permanente esta listaxe?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tes cambios sen gardar para a vista previa ou descriciรณn do multimedia, descartamos os cambios?", - "confirmations.domain_block.confirm": "Agochar dominio enteiro", + "confirmations.domain_block.confirm": "Bloquear servidor", "confirmations.domain_block.message": "Tes a certeza de querer bloquear todo de {domain}? Na meirande parte dos casos uns bloqueos ou silenciados especรญficos son suficientes. Non verรกs mรกis o contido deste dominio en ningunha cronoloxรญa pรบblica ou nas tรบas notificaciรณns. As tรบas seguidoras deste dominio serรกn eliminadas.", "confirmations.edit.confirm": "Editar", "confirmations.edit.message": "Ao editar sobrescribirรกs a mensaxe que estรกs a compor. Tes a certeza de que queres continuar?", "confirmations.logout.confirm": "Pechar sesiรณn", "confirmations.logout.message": "Desexas pechar a sesiรณn?", "confirmations.mute.confirm": "Acalar", - "confirmations.mute.explanation": "Isto agocharรก as sรบas publicaciรณns ou as que a mencionen, mais poderรก ler as tรบas publicaciรณns e ser seguidora tรบa.", - "confirmations.mute.message": "Tes a certeza de querer acalar a {name}?", "confirmations.redraft.confirm": "Eliminar e reescribir", "confirmations.redraft.message": "Tes a certeza de querer eliminar esta publicaciรณn e reescribila? Perderรกs as promociรณns e favorecementos, e as respostas รก publicaciรณn orixinal ficarรกn orfas.", "confirmations.reply.confirm": "Responder", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Estas son as publicaciรณns da web social que hoxe estรกn gaรฑando popularidade. As publicaciรณns con mรกis promociรณns e favorecemento teรฑen puntuaciรณn mรกis alta.", "dismissable_banner.explore_tags": "Estes cancelos estรกn gaรฑando popularidade entre as persoas deste servidor e noutros servidores da rede descentralizada.", "dismissable_banner.public_timeline": "Estas son as publicaciรณns pรบblicas mรกis recentes das persoas que as usuarias de {domain} estรกn a seguir.", + "domain_block_modal.block": "Bloquear servidor", + "domain_block_modal.block_account_instead": "Prefiro bloquear a @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "As persoas deste servidor poden interactuar coas tรบas publicaciรณns antigas.", + "domain_block_modal.they_cant_follow": "Ninguรฉn deste servidor pode seguirte.", + "domain_block_modal.they_wont_know": "Non saberรก que a bloqueaches.", + "domain_block_modal.title": "Bloquear dominio?", + "domain_block_modal.you_will_lose_followers": "Vanse eliminar todas as tรบas seguidoras deste servidor.", + "domain_block_modal.you_wont_see_posts": "Non verรกs publicaciรณns ou notificaciรณn das usuarias neste servidor.", + "domain_pill.activitypub_lets_connect": "Permรญteche conectar e interactuar con persoas non sรณ de Mastodon, se non tamรฉn con outras apps sociais.", + "domain_pill.activitypub_like_language": "ActivityPub รฉ algo asรญ como o idioma que Mastodon fala con outras redes sociais.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "O seu alcume:", + "domain_pill.their_server": "O seu fogar dixital, onde estรกn as sรบas publicaciรณns.", + "domain_pill.their_username": "O seu identificador รบnico no seu servidor. ร‰ posible atopar usuarias co mesmo nome de usuaria en diferentes servidores.", + "domain_pill.username": "Nome de usuaria", + "domain_pill.whats_in_a_handle": "Que รฉ o alcume?", + "domain_pill.who_they_are": "O alcume dinos quen รฉ esa persoa e onde estรก, para que poidas interactuar con ela en toda a web social de .", + "domain_pill.who_you_are": "Como o teu alcume informa de quen es e onde estรกs, as persoas poden interactuar contigo desde toda a web social de .", + "domain_pill.your_handle": "O teu alcume:", + "domain_pill.your_server": "O teu fogar dixital, onde estรกn as tรบas publicaciรณns. Non รฉ do teu agrado? Podes cambiar de servidor cando queiras levando as tรบas seguidoras contigo.", + "domain_pill.your_username": "O teu identificador รบnico neste servidor. ร‰ posible que atopes usuarias co mesmo nome de usuaria en outros servidores.", "embed.instructions": "Engade esta publicaciรณn รณ teu sitio web copiando o seguinte cรณdigo.", "embed.preview": "Asรญ serรก mostrado:", "emoji_button.activity": "Actividade", @@ -241,6 +266,7 @@ "empty_column.list": "Aรญnda non hai nada nesta listaxe. Cando as usuarias incluรญdas na listaxe publiquen mensaxes, amosaranse aquรญ.", "empty_column.lists": "Aรญnda non tes listaxes. Cando crees unha, amosarase aquรญ.", "empty_column.mutes": "Aรญnda non silenciaches a ningรบnha usuaria.", + "empty_column.notification_requests": "Todo ben! Nada por aquรญ. Cando recibas novas notificaciรณn aparecerรกn aquรญ seguindo o criterio dos teus axustes.", "empty_column.notifications": "Aรญnda non tes notificaciรณns. Aparecerรกn cando outras persoas interactรบen contigo.", "empty_column.public": "Nada por aquรญ! Escribe algo de xeito pรบblico, ou segue de xeito manual usuarias doutros servidores para ir enchรฉndoo", "error.unexpected_crash.explanation": "Debido a un erro no noso cรณdigo ou a unha compatilidade co teu navegador, esta pรกxina non pode ser amosada correctamente.", @@ -271,20 +297,32 @@ "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", "firehose.local": "Este servidor", "firehose.remote": "Outros servidores", "follow_request.authorize": "Autorizar", "follow_request.reject": "Rexeitar", "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": "O servidor suxรญreche", + "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}.", + "follow_suggestions.hints.most_interactions": "Este perfil tivo moitas interacciรณns รบltimamente en {domain}.", + "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", - "footer.about": "Acerca de", + "footer.about": "Sobre", "footer.directory": "Directorio de perfรญs", "footer.get_app": "Descarga a app", "footer.invite": "Convidar persoas", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir cancelo", "hashtag.unfollow": "Deixar de seguir cancelo", "hashtags.and_other": "โ€ฆe {count, plural, one {}other {# mรกis}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Amosar compartidos", "home.column_settings.show_replies": "Amosar respostas", "home.hide_announcements": "Agochar anuncios", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Mostrar perfil igualmente", "limited_account_hint.title": "Este perfil foi agochado pola moderaciรณn de {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mรกis de {name}", + "link_preview.shares": "{count, plural, one {{counter} publicaciรณn} other {{counter} publicaciรณns}}", "lists.account.add": "Engadir รก listaxe", "lists.account.remove": "Eliminar da listaxe", "lists.delete": "Eliminar listaxe", @@ -395,10 +434,16 @@ "loading_indicator.label": "Estase a cargarโ€ฆ", "media_gallery.toggle_visible": "Agochar {number, plural, one {imaxe} other {imaxes}}", "moved_to_account_banner.text": "A tรบa conta {disabledAccount} estรก actualmente desactivada porque movรฉchela a {movedToAccount}.", - "mute_modal.duration": "Duraciรณn", - "mute_modal.hide_notifications": "Agochar notificaciรณns desta persoa?", - "mute_modal.indefinite": "Indefinida", - "navigation_bar.about": "Acerca de", + "mute_modal.hide_from_notifications": "Ocultar nas notificaciรณns", + "mute_modal.hide_options": "Opciรณns ao ocultar", + "mute_modal.indefinite": "Ata que as reactive", + "mute_modal.show_options": "Mostrar opciรณns", + "mute_modal.they_can_mention_and_follow": "Pรณdete mencionar e seguirte, pero non o verรกs.", + "mute_modal.they_wont_know": "Non saberรก que a acalaches.", + "mute_modal.title": "Acalar usuaria?", + "mute_modal.you_wont_see_mentions": "Non verรกs as publicaciรณns que a mencionen.", + "mute_modal.you_wont_see_posts": "Seguirรก podendo ler as tรบas publicaciรณns, pero non verรกs as sรบas.", + "navigation_bar.about": "Sobre", "navigation_bar.advanced_interface": "Abrir coa interface web avanzada", "navigation_bar.blocks": "Usuarias bloqueadas", "navigation_bar.bookmarks": "Marcadores", @@ -430,20 +475,37 @@ "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.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", + "notification_requests.dismiss": "Desbotar", + "notification_requests.notifications_from": "Notificaciรณns de {name}", + "notification_requests.title": "Notificaciรณns filtradas", "notifications.clear": "Limpar notificaciรณns", "notifications.clear_confirmation": "Tes a certeza de querer limpar de xeito permanente todas as tรบas notificaciรณns?", "notifications.column_settings.admin.report": "Novas denuncias:", "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": "Amosar todas as categorรญas", + "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.filter_bar.show_bar": "Amosar barra de filtros", "notifications.column_settings.follow": "Novas seguidoras:", "notifications.column_settings.follow_request": "Novas peticiรณns de seguimento:", "notifications.column_settings.mention": "Menciรณns:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Non se activaron as notificaciรณns de escritorio porque se denegou o permiso", "notifications.permission_denied_alert": "Non se poden activar as notificaciรณns de escritorio, xa que o permiso para o navegador foi denegado previamente", "notifications.permission_required": "As notificaciรณns de escritorio non estรกn dispoรฑibles porque non se concedeu o permiso necesario.", + "notifications.policy.filter_new_accounts.hint": "Creadas desde {days, plural, one {onte} other {fai # dรญas}}", + "notifications.policy.filter_new_accounts_title": "Novas contas", + "notifications.policy.filter_not_followers_hint": "Inclรบe a persoas que te seguen desde fai menos de {days, plural, one {1 dรญa} other {# dรญas}}", + "notifications.policy.filter_not_followers_title": "Persoas que non te seguen", + "notifications.policy.filter_not_following_hint": "Ata que as autorices", + "notifications.policy.filter_not_following_title": "Persoas que ti non segues", + "notifications.policy.filter_private_mentions_hint": "Filtradas a non ser que sexa unha resposta รก tรบa propia menciรณn ou se ti segues รก remitente", + "notifications.policy.filter_private_mentions_title": "Menciรณns privadas non solicitadas", + "notifications.policy.title": "Desbotar notificaciรณns deโ€ฆ", "notifications_permission_banner.enable": "Activar notificaciรณns de escritorio", "notifications_permission_banner.how_to_control": "Activa as notificaciรณns de escritorio para recibir notificaciรณns mentras Mastodon non estรก aberto. Podes controlar de xeito preciso o tipo de interacciรณns que crean as notificaciรณns de escritorio a travรฉs da {icon} superior unha vez estรกn activadas.", "notifications_permission_banner.title": "Non perder nada", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Persoas que usaron este servidor nos รบltimos 30 dรญas (Usuarias Activas Mensuais)", "server_banner.active_users": "usuarias activas", "server_banner.administered_by": "Administrada por:", - "server_banner.introduction": "{domain} รฉ parte da rede social descentralizada que funciona grazas a {mastodon}.", - "server_banner.learn_more": "Saber mรกis", + "server_banner.is_one_of_many": "{domain} รฉ un dos moitos servidores Mastodon independentes que podes usar para participar do Fediverso.", "server_banner.server_stats": "Estatรญsticas do servidor:", "sign_in_banner.create_account": "Crear conta", + "sign_in_banner.follow_anyone": "Sigue a quen queiras no Fediverso e le as publicaciรณns en orde cronolรณxica. Sen algoritmos, publicidade nin titulares engaรฑosos.", + "sign_in_banner.mastodon_is": "Mastodon รฉ o mellor xeito de estar ao dรญa do que acontece.", "sign_in_banner.sign_in": "Iniciar sesiรณn", "sign_in_banner.sso_redirect": "Acceder ou Crear conta", - "sign_in_banner.text": "Inicia sesiรณn para seguir perfรญs ou cancelos, marcar como favorita e responder a publicaciรณns. Tamรฉn podes interactuar coa tรบa conta noutro servidor.", "status.admin_account": "Abrir interface de moderaciรณn para @{name}", "status.admin_domain": "Abrir interface de moderaciรณn para {domain}", "status.admin_status": "Abrir esta publicaciรณn na interface de moderaciรณn", @@ -645,10 +716,11 @@ "status.direct": "Mencionar de xeito privado a @{name}", "status.direct_indicator": "Menciรณn privada", "status.edit": "Editar", - "status.edited": "Editado {date}", + "status.edited": "รšltima ediciรณn {date}", "status.edited_x_times": "Editado {count, plural, one {{count} vez} other {{count} veces}}", "status.embed": "Incrustar", "status.favourite": "Favorecer", + "status.favourites": "{count, plural, one {favorecemento} other {favorecementos}}", "status.filter": "Filtrar esta publicaciรณn", "status.filtered": "Filtrado", "status.hide": "Agochar publicaciรณn", @@ -669,6 +741,7 @@ "status.reblog": "Promover", "status.reblog_private": "Compartir coa audiencia orixinal", "status.reblogged_by": "{name} promoveu", + "status.reblogs": "{count, plural, one {promociรณn} other {promociรณns}}", "status.reblogs.empty": "Aรญnda ninguรฉn promoveu esta publicaciรณn. Cando alguรฉn o faga, amosarase aquรญ.", "status.redraft": "Eliminar e reescribir", "status.remove_bookmark": "Eliminar marcador", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index bf182a1657..1c50ba8e1f 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.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": "ื”ื“ืฃ ื”ืžื‘ื•ืงืฉ ืื™ื ื• ื–ืžื™ืŸ. ื–ื” ืขืฉื•ื™ ืœื”ื™ื•ืช ื‘ืื’ ื‘ืงื•ื“ ืื• ื‘ืขื™ื™ื” ื‘ืชืื™ืžื•ืช ื”ื“ืคื“ืคืŸ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ื”ื•ืกืฃ ืื–ื”ืจืช ืชื•ื›ืŸ", "compose_form.spoiler_placeholder": "ืื–ื”ืจืช ืชื•ื›ืŸ (ืœื ื—ื•ื‘ื”)", "confirmation_modal.cancel": "ื‘ื™ื˜ื•ืœ", - "confirmations.block.block_and_report": "ืœื—ืกื•ื ื•ืœื“ื•ื•ื—", "confirmations.block.confirm": "ืœื—ืกื•ื", - "confirmations.block.message": "ื”ืื ืืช/ื” ื‘ื˜ื•ื—/ื” ืฉื‘ืจืฆื•ื ืš ืœืžื—ื•ืง ืืช \"{name}\"?", "confirmations.cancel_follow_request.confirm": "ื•ื™ืชื•ืจ ืขืœ ื‘ืงืฉื”", "confirmations.cancel_follow_request.message": "ืœื‘ื˜ืœ ืืช ื‘ืงืฉืช ื”ืžืขืงื‘ ืื—ืจื™ {name}?", "confirmations.delete.confirm": "ืœืžื—ื•ืง", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ื”ืื ืืชื ื‘ื˜ื•ื—ื™ื ืฉืืชื ืจื•ืฆื™ื ืœืžื—ื•ืง ืืช ื”ืจืฉื™ืžื” ืœืฆืžื™ืชื•ืช?", "confirmations.discard_edit_media.confirm": "ื”ืฉืœืš", "confirmations.discard_edit_media.message": "ื™ืฉ ืœืš ืฉื™ื ื•ื™ื™ื ืœื ืฉืžื•ืจื™ื ืœืชื™ืื•ืจ ื”ืžื“ื™ื”. ืœื”ืฉืœื™ืš ืื•ืชื ื‘ื›ืœ ื–ืืช?", - "confirmations.domain_block.confirm": "ื—ืกืžื• ืœื’ืžืจื™ ืืช ืฉื ื”ืžืชื—ื (ื“ื•ืžื™ื™ืŸ)", + "confirmations.domain_block.confirm": "ื—ืกื™ืžืช ืฉืจืช", "confirmations.domain_block.message": "ื‘ื˜ื•ื—ื” ืฉื‘ืจืฆื•ื ืš ื‘ืืžืช ืœื—ืกื•ื ืืช ืงื”ื™ืœืช {domain}? ื‘ืจื‘ ื”ืžืงืจื™ื ื”ืฉืชืงื” ื•ื—ืกื™ืžื” ืฉืœ ืžืกืคืจ ืžืฉืชืžืฉื™ื ืขืฉื•ื™ื™ื” ืœื”ืกืคื™ืง. ืœื ืชืจืื™ ืชื•ื›ืœ ืžื›ืœืœ ืฉื ื”ืžืชื—ื ื‘ืคื™ื“ื™ื ื”ืฆื™ื‘ื•ืจื™ื™ื ืื• ื‘ื”ืชืจืื•ืช ืฉืœืš. ื”ืขื•ืงื‘ื™ื ืฉืœืš ืžื”ืงื”ื™ืœื” ื”ื–ืืช ื™ื•ืกืจื•", "confirmations.edit.confirm": "ืขืจื™ื›ื”", "confirmations.edit.message": "ืขืจื™ื›ื” ืชื“ืจื•ืก ืืช ื”ื”ื•ื“ืขื” ืฉื›ื‘ืจ ื”ืชื—ืœืช ืœื›ืชื•ื‘. ื”ืื ืœื”ืžืฉื™ืš?", "confirmations.logout.confirm": "ื”ืชื ืชืงื•ืช", "confirmations.logout.message": "ื”ืื ืืชื ื‘ื˜ื•ื—ื™ื ืฉืืชื ืจื•ืฆื™ื ืœื”ืชื ืชืง?", "confirmations.mute.confirm": "ืœื”ืฉืชื™ืง", - "confirmations.mute.explanation": "ื–ื” ื™ืกืชื™ืจ ื”ื•ื“ืขื•ืช ืฉืœื”ื ื•ื”ื•ื“ืขื•ืช ืฉืžืื–ื›ืจื•ืช ืื•ืชื, ืื‘ืœ ืขื“ื™ื™ืŸ ื™ืชื™ืจ ืœื”ื ืœืจืื•ืช ื”ื•ื“ืขื•ืช ืฉืœืš ื•ืœืขืงื•ื‘ ืื—ืจื™ืš.", - "confirmations.mute.message": "ื‘ื˜ื•ื—/ื” ืฉื‘ืจืฆื•ื ืš ืœื”ืฉืชื™ืง ืืช {name}?", "confirmations.redraft.confirm": "ืžื—ื™ืงื” ื•ืขืจื™ื›ื” ืžื—ื“ืฉ", "confirmations.redraft.message": "ืœืžื—ื•ืง ื•ืœื”ืชื—ื™ืœ ื˜ื™ื•ื˜ื” ื—ื“ืฉื”? ื—ื™ื‘ื•ื‘ื™ื ื•ื”ื“ื”ื•ื“ื™ื ื™ืื‘ื“ื•, ื•ืชื’ื•ื‘ื•ืช ืœื”ื•ื“ืขื” ื”ืžืงื•ืจื™ืช ื™ืฉืืจื• ื™ืชื•ืžื•ืช.", "confirmations.reply.confirm": "ืชื’ื•ื‘ื”", @@ -205,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": "ืžืืคืฉืจ ืœืš ืœื”ืชื—ื‘ืจ ื•ืœื”ืชืจื•ืขืข ืขื ืื—ืจื™ื ืœื ืจืง ื‘ืžืกื˜ื•ื“ื•ืŸ, ืืœื ื’ื ื‘ื™ื™ืฉื•ืžื™ื ื—ื‘ืจืชื™ื™ื ืฉื•ื ื™ื ืื—ืจื™ื.", + "domain_pill.activitypub_like_language": "ืืงื˜ื™ื‘ื™ื˜ื™ืคืื‘ ื”ื™ื ืœืžืขืฉื” ื”ืฉืคื” ื‘ื” ืžืกื˜ื•ื“ื•ืŸ ืžื“ื‘ืจ ืขื ืจืฉืชื•ืช ื—ื‘ืจืชื™ื•ืช ืื—ืจื•ืช.", + "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": "ืคืขื™ืœื•ืช", @@ -223,7 +248,7 @@ "emoji_button.symbols": "ืกืžืœื™ื", "emoji_button.travel": "ื˜ื™ื•ืœื™ื ื•ืืชืจื™ื", "empty_column.account_hides_collections": "ื”ืžืฉืชืžืฉ.ืช ื‘ื—ืจ.ื” ืœื”ืกืชื™ืจ ืžื™ื“ืข ื–ื”", - "empty_column.account_suspended": "ื—ืฉื‘ื•ืŸ ืžื•ืฉื”ื”", + "empty_column.account_suspended": "ื—ืฉื‘ื•ืŸ ืžื•ืฉืขื”", "empty_column.account_timeline": "ืื™ืŸ ืขื“ื™ื™ืŸ ืืฃ ื”ื•ื“ืขื”!", "empty_column.account_unavailable": "ืคืจื•ืคื™ืœ ืœื ื–ืžื™ืŸ", "empty_column.blocks": "ืขื“ื™ื™ืŸ ืœื ื—ืกืžืชื ืžืฉืชืžืฉื™ื ืื—ืจื™ื.", @@ -241,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": "ืขืงื‘ ืชืงืœื” ื‘ืงื•ื“ ืฉืœื ื• ืื• ื‘ืขื™ื™ืช ืชืื™ืžื•ืช ื“ืคื“ืคืŸ, ืœื ื ื™ืชืŸ ืœื”ืฆื™ื’ ื“ืฃ ื–ื” ื›ืจืื•ื™.", @@ -271,16 +297,28 @@ "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": "ื”ื›ืœ", "firehose.local": "ืฉืจืช ื–ื”", "firehose.remote": "ืฉืจืชื™ื ืื—ืจื™ื", "follow_request.authorize": "ื”ืจืฉืื”", "follow_request.reject": "ื“ื—ื™ื”", "follow_requests.unlocked_explanation": "ืœืžืจื•ืช ืฉื—ืฉื‘ื•ื ืš ืื™ื ื• ื ืขื•ืœ, ืฆื•ื•ืช {domain} ื—ื•ืฉื‘ ืฉืื•ืœื™ ื›ื“ืื™ ืœื•ื•ื“ื ืืช ื‘ืงืฉื•ืช ื”ืžืขืงื‘ ื”ืืœื” ื™ื“ื ื™ืช.", - "follow_suggestions.curated_suggestion": "ื‘ื—ื™ืจืช ื”ืขื•ืจื›ื™ื", + "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}.", + "follow_suggestions.hints.most_interactions": "ื—ืฉื‘ื•ืŸ ื–ื” ืงื™ื‘ืœ ืœืื—ืจื•ื ื” ื”ืจื‘ื” ืชืฉื•ืžืช ืœื‘ ืขืœ ืฉืจืช {domain}.", + "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": "ื”ืชื’ื™ื•ืช ืฉื”ื—ืฉื‘ื•ืŸ ืฉืœืš ืขื•ืงื‘ ืื—ืจื™ื”ืŸ", @@ -309,7 +347,6 @@ "hashtag.follow": "ืœืขืงื•ื‘ ืื—ืจื™ ืชื’ื™ืช", "hashtag.unfollow": "ืœื”ืคืกื™ืง ืœืขืงื•ื‘ ืื—ืจื™ ืชื’ื™ืช", "hashtags.and_other": "โ€ฆ{count, plural,other {ื•ืขื•ื“ #}}", - "home.column_settings.basic": "ืœืžืชื—ื™ืœื™ื", "home.column_settings.show_reblogs": "ื”ืฆื’ืช ื”ื“ื”ื•ื“ื™ื", "home.column_settings.show_replies": "ื”ืฆื’ืช ืชื’ื•ื‘ื•ืช", "home.hide_announcements": "ื”ืกืชืจ ื”ื›ืจื–ื•ืช", @@ -377,6 +414,8 @@ "limited_account_hint.action": "ื”ืฆื’ ื—ืฉื‘ื•ืŸ ื‘ื›ืœ ื–ืืช", "limited_account_hint.title": "ืคืจื•ืคื™ืœ ื”ืžืฉืชืžืฉ ื”ื–ื” ื”ื•ืกืชืจ ืขืœ ื™ื“ื™ ื”ืžื ื—ื™ื ืฉืœ {domain}.", "link_preview.author": "ืžืืช {name}", + "link_preview.more_from_author": "ืขื•ื“ ืžืืช {name}", + "link_preview.shares": "{count, plural, one {ื”ื•ื“ืขื” ืื—ืช} two {ื”ื•ื“ืขื•ืชื™ื™ื} many {{count} ื”ื•ื“ืขื•ืช} other {{count} ื”ื•ื“ืขื•ืช}}", "lists.account.add": "ื”ื•ืกืฃ ืœืจืฉื™ืžื”", "lists.account.remove": "ื”ืกืจ ืžืจืฉื™ืžื”", "lists.delete": "ืžื—ื™ืงืช ืจืฉื™ืžื”", @@ -395,9 +434,15 @@ "loading_indicator.label": "ื‘ื˜ืขื™ื ื”โ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ืœื”ืกืชื™ืจ ืชืžื•ื ื”} two {ืœื”ืกืชื™ืจ ืชืžื•ื ื•ืชื™ื™ื} many {ืœื”ืกืชื™ืจ ืชืžื•ื ื•ืช} other {ืœื”ืกืชื™ืจ ืชืžื•ื ื•ืช}}", "moved_to_account_banner.text": "ื—ืฉื‘ื•ื ืš {disabledAccount} ืื™ื ื• ืคืขื™ืœ ื›ืจื’ืข ืขืงื‘ ืžืขื‘ืจ ืœ{movedToAccount}.", - "mute_modal.duration": "ืžืฉืš ื”ื–ืžืŸ", - "mute_modal.hide_notifications": "ืœื”ืกืชื™ืจ ื”ืชืจืื•ืช ืžื—ืฉื‘ื•ืŸ ื–ื”?", - "mute_modal.indefinite": "ืœืœื ืชืืจื™ืš ืกื™ื•ื", + "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": "ืžืฉืชืžืฉื™ื ื—ืกื•ืžื™ื", @@ -430,20 +475,37 @@ "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.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": "ืœืงื‘ืœ", + "notification_requests.dismiss": "ืœื‘ื˜ืœ", + "notification_requests.notifications_from": "ื”ืชืจืื•ืช ืžึพ {name}", + "notification_requests.title": "ื”ืชืจืื•ืช ืžืกื•ื ื ื•ืช", "notifications.clear": "ื”ืกืจืช ื”ืชืจืื•ืช", "notifications.clear_confirmation": "ืœื”ืกื™ืจ ืืช ื›ืœ ื”ื”ืชืจืื•ืช ืœืฆืžื™ืชื•ืช ? ", "notifications.column_settings.admin.report": "ื“ื•\"ื—ื•ืช ื—ื“ืฉื™ื", "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.advanced": "ืœื”ืฆื™ื’ ืืช ื›ืœ ื”ืงื˜ื’ื•ืจื™ื•ืช", "notifications.column_settings.filter_bar.category": "ืฉื•ืจืช ืกื™ื ื•ืŸ ืžื”ื™ืจ", - "notifications.column_settings.filter_bar.show_bar": "ื”ืฆื’ ืฉื•ืจืช ืกื™ื ื•ืŸ", "notifications.column_settings.follow": "ืขื•ืงื‘ื™ื ื—ื“ืฉื™ื:", "notifications.column_settings.follow_request": "ื‘ืงืฉื•ืช ืžืขืงื‘ ื—ื“ืฉื•ืช:", "notifications.column_settings.mention": "ืคื ื™ื•ืช:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "ืœื ื ื™ืชืŸ ืœื”ืฆื™ื’ ื”ืชืจืื•ืช ืžืกืš ื›ื™ื•ื•ืŸ ื›ื™ื•ื•ืŸ ืฉื”ืจืฉืื•ืช ื“ืคื“ืคืŸ ื ืฉืœืœื• ื‘ืขื‘ืจ", "notifications.permission_denied_alert": "ืœื ื ื™ืชืŸ ืœืืคืฉืจ ื ื•ื˜ื™ืคื™ืงืฆื™ื•ืช ืžืกืš ืฉื›ืŸ ื”ื“ืคื“ืคืŸ ืกื•ืจื‘ ื”ืจืฉืื” ื‘ืขื‘ืจ", "notifications.permission_required": "ืœื ื ื™ืชืŸ ืœืืคืฉืจ ื ื•ื˜ื™ืคื™ืงืฆื™ื•ืช ืžืกืš ื›ื™ื•ื•ืŸ ืฉื”ืจืฉืื” ื“ืจื•ืฉื” ืœื ื ื™ืชื ื”.", + "notifications.policy.filter_new_accounts.hint": "ื ื•ืฆืจ {days, plural,one {ื‘ื™ื•ื ื”ืื—ืจื•ืŸ} two {ื‘ื™ื•ืžื™ื™ื ื”ืื—ืจื•ื ื™ื} other {ื‘ึพ# ื”ื™ืžื™ื ื”ืื—ืจื•ื ื™ื}}", + "notifications.policy.filter_new_accounts_title": "ื—ืฉื‘ื•ื ื•ืช ื—ื“ืฉื™ื", + "notifications.policy.filter_not_followers_hint": "ื›ื•ืœืœ ืžืฉืชืžืฉื™ื ืฉืขืงื‘ื• ืื—ืจื™ืš ืคื—ื•ืช ืž{days, plural,one {ื™ื•ื} two {ื™ื•ืžื™ื™ื} other {ึพ# ื™ืžื™ื}}", + "notifications.policy.filter_not_followers_title": "ืžืฉืชืžืฉื™ื ืฉืœื ืขื•ืงื‘ื•ืช.ื™ื ืื—ืจื™ืš", + "notifications.policy.filter_not_following_hint": "ืขื“ ืฉื™ืื•ืฉืจื• ื™ื“ื ื™ืช ืขืœ ื™ื“ื™ืš", + "notifications.policy.filter_not_following_title": "ืžืฉืชืžืฉื™ื ืฉืื™ื ืš ืขื•ืงื‘(ืช) ืื—ืจื™ื”ืืŸ", + "notifications.policy.filter_private_mentions_hint": "ืžืกื•ื ืŸ ืืœื ืื ื–ื• ืชืฉื•ื‘ื” ืœืžื™ื ืฉื•ืŸ ืฉืœืš ืื• ืื ืืชื ืขื•ืงื‘ื™ื ืื—ืจื™ ื”ืขื•ื ื”", + "notifications.policy.filter_private_mentions_title": "ืžื™ื ืฉื•ื ื™ื ื‘ืคืจื˜ื™ ืฉืœื ื”ื•ื–ืžื ื•", + "notifications.policy.title": "ืœื”ืกืชื™ืจ ื”ืชืจืื•ืช ืžโ€ฆ", "notifications_permission_banner.enable": "ืœืืคืฉืจ ื ื•ื˜ื™ืคื™ืงืฆื™ื•ืช ืžืกืš", "notifications_permission_banner.how_to_control": "ื›ื“ื™ ืœืงื‘ืœ ื”ืชืจืื•ืช ื’ื ื›ืืฉืจ ืžืกื˜ื•ื“ื•ืŸ ืกื’ื•ืจ ื™ืฉ ืœืืคืฉืจ ื”ืชืจืื•ืช ืžืกืš. ื ื™ืชืŸ ืœืฉืœื•ื˜ ื‘ื“ื™ื•ืง ืื™ื–ื” ืกื•ื’ ืฉืœ ืื™ื ื˜ืจืืงืฆื™ื•ืช ื™ื‘ื™ื ืœื”ืชืจืื•ืช ืžืกืš ื“ืจืš ื›ืคืชื•ืจ ื”- {icon} ืžืจื’ืข ืฉื”ืŸ ืžืื•ืคืฉืจื•ืช.", "notifications_permission_banner.title": "ืœืขื•ืœื ืืœ ืชื—ืžื™ืฅ ื“ื‘ืจ", @@ -625,13 +696,10 @@ "server_banner.about_active_users": "ืžืฉืชืžืฉื™ื ืคืขื™ืœื™ื ื‘ืฉืจืช ื‘ึพ30 ื”ื™ืžื™ื ื”ืื—ืจื•ื ื™ื (ืžืฉืชืžืฉื™ื ืคืขื™ืœื™ื ื—ื•ื“ืฉื™ื™ื)", "server_banner.active_users": "ืžืฉืชืžืฉื™ื ืคืขื™ืœื™ื", "server_banner.administered_by": "ืžื ื•ื”ืœ ืข\"ื™:", - "server_banner.introduction": "{domain} ื”ื•ื ืฉืจืช ื‘ืจืฉืช ื”ืžื‘ื•ื–ืจืช {mastodon}.", - "server_banner.learn_more": "ืžื™ื“ืข ื ื•ืกืฃ", "server_banner.server_stats": "ืกื˜ื˜ื™ืกื˜ื™ืงื•ืช ืฉืจืช:", "sign_in_banner.create_account": "ื™ืฆื™ืจืช ื—ืฉื‘ื•ืŸ", "sign_in_banner.sign_in": "ื”ืชื—ื‘ืจื•ืช", "sign_in_banner.sso_redirect": "ื”ืชื—ื‘ืจื•ืช/ื”ืจืฉืžื”", - "sign_in_banner.text": "ื™ืฉ ืœื”ืชื—ื‘ืจ ื›ื“ื™ ืœืขืงื•ื‘ ืื—ืจื™ ืžืฉืชืžืฉื™ื ืื• ืชื’ื™ื•ืช, ืœื—ื‘ื‘, ืœืฉืชืฃ ื•ืœืขื ื•ืช ืœื”ื•ื“ืขื•ืช. ื ื™ืชืŸ ื’ื ืœืชืงืฉืจ ืžื”ื—ืฉื‘ื•ืŸ ืฉืœืš ืขื ืฉืจืช ืื—ืจ.", "status.admin_account": "ืคืชื—/ื™ ืžืžืฉืง ื ื™ื”ื•ืœ ืขื‘ื•ืจ @{name}", "status.admin_domain": "ืคืชื™ื—ืช ืžืžืฉืง ื ื™ื”ื•ืœ ืขื‘ื•ืจ {domain}", "status.admin_status": "Open this status in the moderation interface", @@ -645,10 +713,11 @@ "status.direct": "ื”ื•ื“ืขื” ืคืจื˜ื™ืช ืืœ @{name}", "status.direct_indicator": "ื”ื•ื“ืขื” ืคืจื˜ื™ืช", "status.edit": "ืขืจื™ื›ื”", - "status.edited": "ื ืขืจืš ื‘{date}", + "status.edited": "ื ืขืจืš ืœืื—ืจื•ื ื” {date}", "status.edited_x_times": "ื ืขืจืš {count, plural, one {ืคืขื {count}} other {{count} ืคืขืžื™ื}}", "status.embed": "ื”ื˜ืžืขื”", "status.favourite": "ื—ื™ื‘ื•ื‘", + "status.favourites": "{count, plural, one {ื—ื™ื‘ื•ื‘ ืื—ื“} two {ื–ื•ื’ ื—ื™ื‘ื•ื‘ื™ื} other {# ื—ื™ื‘ื•ื‘ื™ื}}", "status.filter": "ืกื ืŸ ื”ื•ื“ืขื” ื–ื•", "status.filtered": "ืกื•ื ืŸ", "status.hide": "ื”ืกืชืจืช ื—ื™ืฆืจื•ืฅ", @@ -669,6 +738,7 @@ "status.reblog": "ื”ื“ื”ื•ื“", "status.reblog_private": "ืœื”ื“ื”ื“ ื‘ืจืžืช ื”ื ืจืื•ืช ื”ืžืงื•ืจื™ืช", "status.reblogged_by": "{name} ื”ื™ื“ื”ื“/ื”:", + "status.reblogs": "{count, plural, one {ื”ื“ื”ื•ื“ ืื—ื“} two {ืฉื ื™ ื”ื“ื”ื•ื“ื™ื} other {# ื”ื“ื”ื•ื“ื™ื}}", "status.reblogs.empty": "ืขื•ื“ ืœื ื”ื™ื“ื”ื“ื• ืืช ื”ื”ื•ื“ืขื” ื”ื–ื•. ื›ืืฉืจ ื–ื” ื™ืงืจื”, ื”ื”ื“ื”ื•ื“ื™ื ื™ื•ืคื™ืขื• ื›ืืŸ.", "status.redraft": "ืžื—ื™ืงื” ื•ืขืจื™ื›ื” ืžื—ื“ืฉ", "status.remove_bookmark": "ื”ืกืจืช ืกื™ืžื ื™ื”", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index f88fe19569..a2da55da85 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -21,6 +21,7 @@ "account.blocked": "เคฌเฅเคฒเฅ‰เค•", "account.browse_more_on_origin_server": "เคฎเฅ‚เคฒ เคชเฅเคฐเฅ‹เคซเคผเคพเค‡เคฒ เคชเคฐ เค…เคงเคฟเค• เคฌเฅเคฐเคพเค‰เคœเคผ เค•เคฐเฅ‡เค‚", "account.cancel_follow_request": "เคซเฅ‰เคฒเฅ‹ เคฐเคฟเค•เฅเคตเฅ‡เคธเฅเคŸ เคตเคพเคชเคธ เคฒเฅ‡เค‚", + "account.copy": "เคชเฅเคฐเฅ‹เคซเคพเค‡เคฒ เคชเคฐ เคฒเคฟเค‚เค• เค•เฅ‰เคชเฅ€ เค•เคฐเฅ‡เค‚", "account.direct": "เคจเคฟเคœเคฟ เคคเคฐเฅ€เค•เฅ‡ เคธเฅ‡ เค‰เคฒเฅเคฒเฅ‡เค– เค•เคฐเฅ‡ @{name}", "account.disable_notifications": "@{name} เคชเฅ‹เคธเฅเคŸ เค•เฅ‡ เคฒเคฟเค เคฎเฅเคเฅ‡ เคธเฅ‚เคšเคฟเคค เคฎเคค เค•เคฐเฅ‹", "account.domain_blocked": "เค›เคฟเคชเคพ เคนเฅเค† เคกเฅ‹เคฎเฅ‡เคจ", @@ -31,6 +32,7 @@ "account.featured_tags.last_status_never": "เค•เฅ‹เคˆ เคชเฅ‹เคธเฅเคŸ เคจเคนเฅ€เค‚ เคนเฅˆ", "account.featured_tags.title": "{name} เค•เฅ‡ เคšเฅเคจเคฟเค‚เคฆเคพ เคนเฅˆเคถเคŸเฅˆเค—", "account.follow": "เคซเฅ‰เคฒเฅ‹ เค•เคฐเฅ‡เค‚", + "account.follow_back": "เคซเฅ‰เคฒเฅ‹ เค•เคฐเฅ‡เค‚", "account.followers": "เคซเฅ‰เคฒเฅ‹เคตเคฐ", "account.followers.empty": "เค•เฅ‹เคˆ เคญเฅ€ เค‡เคธ เคฏเฅ‚เฅ›เคฐเฅ เค•เฅ‹ เฅžเฅ‰เคฒเฅ‹ เคจเคนเฅ€เค‚ เค•เคฐเคคเคพ เคนเฅˆ", "account.followers_counter": "{count, plural, one {{counter} เค…เคจเฅเค—เคพเคฎเฅ€} other {{counter} เคธเคฎเคฐเฅเคฅเค•}}", @@ -51,6 +53,7 @@ "account.mute_notifications_short": "เคธเฅ‚เคšเคจเคพเค“ เค•เฅ‹ เคถเคพเค‚เคค เค•เคฐเฅ‡", "account.mute_short": "เคถเคพเค‚เคค เค•เคฐเฅ‡", "account.muted": "เคฎเฅเคฏเฅ‚เคŸ เคนเฅˆ", + "account.mutual": "เค†เคชเคธเฅ€", "account.no_bio": "เค•เฅ‹เคˆ เคตเคฟเคตเคฐเคฃ เคจเคนเคฟ เคฆเคฟเคฏเคพ เค—เคฏเคพ เคนเฅ‡", "account.open_original_page": "เค“เคฐเคฟเคœเคฟเคจเคฒ เคชเฅ‹เคธเฅเคŸ เค–เฅ‹เคฒเฅ‡เค‚", "account.posts": "เคŸเฅ‚เคŸเฅเคธ", @@ -75,6 +78,9 @@ "admin.dashboard.retention.average": "เค”เคธเคค", "admin.dashboard.retention.cohort": "เคธเคพเคˆเคจ-เค…เคช เคฎเคนเคฟเคจเคพ", "admin.dashboard.retention.cohort_size": "เคจเคฏเฅ‡ เค‰เคชเคฏเฅ‹เค—เค•เคฐเฅเคคเคพ", + "admin.impact_report.instance_accounts": "เคฏเฅ‡ เค…เค•เคพเค‰เค‚เคŸ เคชเฅเคฐเฅ‹เคซเคพเค‡เคฒ เคฎเคฟเคŸเคพ เคฆเฅ‡เค—เคพ", + "admin.impact_report.instance_followers": "เคนเคฎเคพเคฐเฅ‡ เคฏเฅ‚เคœเคฐเฅเคธ เค‡เคจ เคซเฅ‰เคฒเฅ‹เค…เคฐเฅเคธ เค•เฅ‹ เค–เฅ‹ เคฆเฅ‡เค‚เค—เฅ‡", + "admin.impact_report.instance_follows": "เค‰เคจเค•เฅ‡ เค‰เคชเคฏเฅ‹เค—เค•เคฐเฅเคคเคพ เค‡เคคเคจเฅ‡ เฅžเฅ‰เคฒเฅ‹เค…เคฐ เค–เฅ‹ เคฆเฅ‡เค‚เค—เฅ‡", "admin.impact_report.title": "เคชเฅเคฐเคญเคพเคตเค•เคพเค‚ เคธเคพเคฐเคพเค‚เคถ", "alert.rate_limited.message": "เค•เฅƒเคชเฅเคฏเคพ {retry_time, time, medium} เค•เฅ‡ เคฌเคพเคฆ เคฆเฅเคฌเคพเคฐเคพ เค•เฅ‹เคถเคฟเคถ เค•เคฐเฅ‡เค‚", "alert.rate_limited.title": "เคธเฅ€เคฎเคฟเคค เคฆเคฐ", @@ -83,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": "เค…เคจเฅเคฐเฅ‹เคงเคฟเคค เคชเฅ‡เคœ เคชเฅเคฐเคธเฅเคคเฅเคค เคจเคนเฅ€เค‚ เค•เคฟเคฏเคพ เคœเคพ เคธเค•เคพเฅค เคฏเคน เคนเคฎเคพเคฐเฅ‡ เค•เฅ‹เคก เคฎเฅ‡เค‚ เคฌเค— เคฏเคพ เคฌเฅเคฐเคพเค‰เคœเคผเคฐ เคธเค‚เค—เคคเคคเคพ เคธเคฎเคธเฅเคฏเคพ เค•เฅ‡ เค•เคพเคฐเคฃ เคนเฅ‹ เคธเค•เคคเคพ เคนเฅˆเฅค", @@ -130,7 +144,9 @@ "community.column_settings.remote_only": "เค•เฅ‡เคตเคฒ เคธเฅเคฆเฅ‚เคฐ", "compose.language.change": "เคญเคพเคทเคพ เคฌเคฆเคฒเฅ‡เค‚", "compose.language.search": "เคญเคพเคทเคพเคเค เค–เฅ‹เคœเฅ‡เค‚...", + "compose.published.body": "เคชเฅ‹เคธเฅเคŸ เคชเฅเคฐเค•เคพเคถเคฟเคค เคนเฅเค†เฅค", "compose.published.open": "เค–เฅ‹เคฒเฅ‡เค‚", + "compose.saved.body": "เคชเฅ‹เคธเฅเคŸ เคธเฅเคฐเค•เฅเคทเคฟเคค เค•เคฟเคฏเคพ เค—เคฏเคพเฅค", "compose_form.direct_message_warning_learn_more": "เค”เคฐ เคœเคพเคจเฅ‡เค‚", "compose_form.encryption_warning": "เคฎเคพเคธเฅเคŸเฅ‹เคกเฅ‰เคจ เคชเคฐ เคชเฅ‹เคธเฅเคŸ เคเคจเฅเคก-เคŸเฅ‚-เคเคจเฅเคก เคเคจเฅเค•เฅเคฐเคฟเคชเฅเคŸเฅ‡เคก เคจเคนเฅ€เค‚ เคนเฅˆเฅค เค•เฅ‹เคˆ เคญเฅ€ เคตเฅเคฏเค•เฅเคคเคฟเค—เคค เคœเคพเคจเค•เคพเคฐเฅ€ เคฎเคพเคธเฅเคŸเฅ‹เคกเฅ‰เคจ เคชเคฐ เคฎเคค เคญเฅ‡เคœเฅ‡เค‚เฅค", "compose_form.hashtag_warning": "เคฏเฅ‡ เคชเฅ‹เคธเฅเคŸ เค•เคฟเคธเฅ€ เคญเฅ€ เคนเฅˆเคถเคŸเฅˆเค— เคฎเฅ‡เค‚ เคฒเคฟเคธเฅเคŸ เคจเคนเฅ€เค‚ เค•เคฟเคฏเคพ เคœเคพเคเค—เคพ เค•เฅเคฏเฅ‹เค‚เค•เคฟ เคฏเฅ‡ เคชเคฌเฅเคฒเคฟเค• เคจเคนเฅ€เค‚ เคนเฅˆเฅค เคธเคฟเคฐเฅเคซ เคชเคฌเฅเคฒเคฟเค• เคชเฅ‹เคธเฅเคŸ เคนเฅ€ เคนเฅˆเคถเคŸเฅˆเค— เคธเฅ‡ เค–เฅ‹เคœเฅ‡ เคœเคพ เคธเค•เคคเฅ‡ เคนเฅˆเค‚เฅค", @@ -138,15 +154,21 @@ "compose_form.lock_disclaimer.lock": "เคฒเฅ‰เค•เฅเคก", "compose_form.placeholder": "What is on your mind?", "compose_form.poll.duration": "เคšเฅเคจเคพเคต เค•เฅ€ เค…เคตเคงเคฟ", + "compose_form.poll.multiple": "เคฌเคนเฅเคตเคฟเค•เคฒเฅเคชเฅ€", + "compose_form.poll.option_placeholder": "เคตเคฟเค•เคฒเฅเคช {number}", + "compose_form.poll.single": "เค•เฅ‹เคˆ เคเค• เคšเฅเคจเฅ‡เค‚", "compose_form.poll.switch_to_multiple": "เค•เคˆ เคตเคฟเค•เคฒเฅเคชเฅ‹เค‚ เค•เฅ€ เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เคชเฅ‹เคฒ เคฌเคฆเคฒเฅ‡เค‚", "compose_form.poll.switch_to_single": "เคเค• เคนเฅ€ เคตเคฟเค•เคฒเฅเคช เค•เฅ‡ เคฒเคฟเค เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เคชเฅ‹เคฒ เคฌเคฆเคฒเฅ‡เค‚", + "compose_form.poll.type": "เคธเฅเคŸเคพเค‡เคฒ", + "compose_form.publish": "เคชเฅ‹เคธเฅเคŸ เค•เคฐเฅ‡เค‚", "compose_form.publish_form": "เคชเคฌเฅเคฒเคฟเคถ", + "compose_form.reply": "เคœเคตเคพเคฌ เคฆเฅ‡เค‚", + "compose_form.save_changes": "เค…เคชเคกเฅ‡เคŸ เค•เคฐเฅ‡เค‚", "compose_form.spoiler.marked": "เคšเฅ‡เคคเคพเคตเคจเฅ€ เค•เฅ‡ เคชเฅ€เค›เฅ‡ เคŸเฅ‡เค•เฅเคธเฅเคŸ เค›เคฟเคชเคพ เคนเฅˆ", "compose_form.spoiler.unmarked": "เคŸเฅ‡เค•เฅเคธเฅเคŸ เค›เคฟเคชเคพ เคจเคนเฅ€เค‚ เคนเฅˆ", + "compose_form.spoiler_placeholder": "เคธเคพเคฎเค—เฅเคฐเฅ€ เคšเฅ‡เคคเคพเคตเคจเฅ€ (เคตเฅˆเค•เคฒเฅเคชเคฟเค•)", "confirmation_modal.cancel": "เคฐเคฆเฅเคฆ เค•เคฐเฅ‡เค‚", - "confirmations.block.block_and_report": "เคฌเฅเคฒเฅ‰เค• เคเคตเค‚ เคฐเคฟเคชเฅ‹เคฐเฅเคŸ", "confirmations.block.confirm": "เคฌเฅเคฒเฅ‰เค•", - "confirmations.block.message": "เค•เฅเคฏเคพ เค†เคช เคตเคพเค•เคˆ {name} เค•เฅ‹ เคฌเฅเคฒเฅ‰เค• เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.cancel_follow_request.confirm": "เคฐเคฟเค•เฅเคตเฅ‡เคธเฅเคŸ เคตเคพเคชเคธ เคฒเฅ‡เค‚", "confirmations.cancel_follow_request.message": "เค•เฅเคฏเคพ เค†เคช เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เคนเฅˆ เค•เฅ€ เค†เคช {name} เค•เคพ เคซเฅ‰เคฒเฅ‹ เคฐเคฟเค•เฅเคตเฅ‡เคธเฅเคŸ เคตเคพเคชเคฟเคธ เคฒเฅ‡เคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.delete.confirm": "เคฎเคฟเคŸเคพเค", @@ -155,15 +177,13 @@ "confirmations.delete_list.message": "เค•เฅเคฏเคพ เค†เคช เคตเคพเค•เคˆ เค‡เคธ เคฒเคฟเคธเฅเคŸ เค•เฅ‹ เคนเคฎเฅ‡เคถเคพ เค•เฅ‡ เคฒเคฟเคฏเฅ‡ เคฎเคฟเคŸเคพเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.discard_edit_media.confirm": "เคกเคฟเคธเฅเค•เคพเคฐเฅเคก", "confirmations.discard_edit_media.message": "เคฒเคฟเคธเฅเคŸ เคฎเฅ‡เค‚ เคœเฅ‹เฅœเฅ‡เค‚", - "confirmations.domain_block.confirm": "เคธเค‚เคชเฅ‚เคฐเฅเคฃ เคกเฅ‹เคฎเฅ‡เคจ เค›เคฟเคชเคพเคเค‚", + "confirmations.domain_block.confirm": "เคธเคฐเฅเคตเคฐ เคฌเฅเคฒเฅ‰เค• เค•เคฐเฅ‡เค‚", "confirmations.domain_block.message": "เค•เฅเคฏเคพ เค†เคช เคตเคพเคธเฅเคคเคต เคฎเฅ‡เค‚, เคตเคพเคธเฅเคคเคต เคฎเฅ‡เค‚ เค†เคช เคชเฅ‚เคฐเฅ‡ {domain} เค•เฅ‹ เคฌเฅเคฒเฅ‰เค• เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚? เคœเฅเคฏเคพเคฆเคพเคคเคฐ เคฎเคพเคฎเคฒเฅ‹เค‚ เคฎเฅ‡เค‚ เค•เฅเค› เคฒเค•เฅเคทเคฟเคค เคฌเฅเคฒเฅ‰เค• เคฏเคพ เคฎเฅเคฏเฅ‚เคŸ เคชเคฐเฅเคฏเคพเคชเฅเคค เค”เคฐ เคฌเฅ‡เคนเคคเคฐ เคนเฅˆเค‚เฅค เค†เคช เค•เคฟเคธเฅ€ เคญเฅ€ เคธเคพเคฐเฅเคตเคœเคจเคฟเค• เคธเคฎเคฏ-เคธเฅ€เคฎเคพ เคฏเคพ เค…เคชเคจเฅ€ เคธเฅ‚เคšเคจเคพเค“เค‚ เคฎเฅ‡เค‚ เค‰เคธ เคกเฅ‹เคฎเฅ‡เคจ เค•เฅ€ เคธเคพเคฎเค—เฅเคฐเฅ€ เคจเคนเฅ€เค‚ เคฆเฅ‡เค–เฅ‡เค‚เค—เฅ‡เฅค เค‰เคธ เคกเฅ‹เคฎเฅ‡เคจ เคธเฅ‡ เค†เคชเค•เฅ‡ เคซเฅ‰เคฒเฅ‹เคตเคฐเฅเคธ เค•เฅ‹ เคนเคŸเคพ เคฆเคฟเคฏเคพ เคœเคพเคเค—เคพเฅค", "confirmations.edit.confirm": "เคธเค‚เคถเฅ‹เคงเคฟเคค เค•เคฐเฅ‡เค‚", "confirmations.edit.message": "เค…เคญเฅ€ เคธเค‚เคชเคพเคฆเคจ เค•เคฟเคฏเคพ เคคเฅ‹ เคตเฅ‹ เคธเค‚เคฆเฅ‡เคถ เคฎเคฟเคŸ เคœเคพเคฏเฅ‡เค—เคพ เคœเคฟเคธเฅ‡ เค†เคช เคฒเคฟเค– เคฐเคนเฅ‡ เคฅเฅ‡เฅค เค•เฅเคฏเคพ เค†เคช เคœเคพเคฐเฅ€ เคฐเค–เคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.logout.confirm": "เคฒเฅ‰เค— เค†เค‰เคŸ เค•เคฐเฅ‡เค‚", "confirmations.logout.message": "เค†เคช เคธเฅเคจเคฟเคถเฅเคšเคฟเคค เคนเฅˆเค‚ เค•เคฟ เคฒเฅ‰เค—เค†เค‰เคŸ เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.mute.confirm": "เคถเคพเค‚เคค", - "confirmations.mute.explanation": "เคฏเคน เค‰เคจเคธเฅ‡ เค”เคฐ เคชเฅ‹เคธเฅเคŸเฅ‹เค‚ เค•เคพ เค‰เคฒเฅเคฒเฅ‡เค– เค•เคฐเคคเฅ‡ เคนเฅเค เค‰เคจเคธเฅ‡ เค›เคฟเคชเคพเคเค—เคพ, เคฒเฅ‡เค•เคฟเคจ เคฏเคน เค…เคญเฅ€ เคญเฅ€ เค‰เคจเฅเคนเฅ‡เค‚ เค†เคชเค•เฅ€ เคชเฅ‹เคธเฅเคŸ เคฆเฅ‡เค–เคจเฅ‡ เค”เคฐ เค†เคชเค•เฅ‹ เคซเฅ‰เคฒเฅ‹ เค•เคฐเคจเฅ‡ เค•เฅ€ เค…เคจเฅเคฎเคคเคฟ เคฆเฅ‡เค—เคพเฅค", - "confirmations.mute.message": "เค•เฅเคฏเคพ เค†เคช เคตเคพเค•เคˆ {name} เค•เฅ‹ เคถเคพเค‚เคค เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚?", "confirmations.redraft.confirm": "เคฎเคฟเคŸเคพเคฏเฅ‡เค‚ เค”เคฐ เคชเฅเคจเคƒเคชเฅเคฐเคพเคฐเฅ‚เคชเคฃ เค•เคฐเฅ‡เค‚", "confirmations.redraft.message": "เค•เฅเคฏเคพ เค†เคช เคตเคพเค•เคˆ เค‡เคธ เคธเฅเคŸเฅ‡เคŸเคธ เค•เฅ‹ เคนเคŸเคพเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚ เค”เคฐ เค‡เคธเฅ‡ เคซเคฟเคฐ เคธเฅ‡ เคกเฅเคฐเคพเคซเฅเคŸ เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚? เคชเคธเค‚เคฆเฅ€เคฆเคพ เค”เคฐ เคฌเฅ‚เคธเฅเคŸ เค–เฅ‹ เคœเคพเคเค‚เค—เฅ‡, เค”เคฐ เคฎเฅ‚เคฒ เคชเฅ‹เคธเฅเคŸ เค•เฅ‡ เค‰เคคเฅเคคเคฐ เค…เคจเคพเคฅ เคนเฅ‹ เคœเคพเคเค‚เค—เฅ‡เฅค", "confirmations.reply.confirm": "เค‰เคคเฅเคคเคฐ เคฆเฅ‡เค‚", @@ -174,6 +194,7 @@ "conversation.mark_as_read": "เคชเฅเคพ เค—เคฏเคพ เค•เฅ‡ เคฐเฅ‚เคช เคฎเฅ‡เค‚ เคšเคฟเคนเฅเคจเคฟเคค เค•เคฐเฅ‡เค‚", "conversation.open": "เคตเคพเคฐเฅเคคเคพเคฒเคพเคช เคฆเฅ‡เค–เฅ‡เค‚", "conversation.with": "{names} เค•เฅ‡ เคธเคพเคฅ", + "copy_icon_button.copied": "เค•เฅเคฒเคฟเคชเคฌเฅ‹เคฐเฅเคก เคชเคฐ เค•เฅ‰เคชเฅ€ เค•เคฟเคฏเคพ เค—เคฏเคพ", "copypaste.copied": "เค•เฅ‰เคชเฅ€ เค•เคฟเค† เคœเคพ เคšเฅ‚เค•เคพ เคนเฅˆ", "copypaste.copy_to_clipboard": "เค•เฅเคฒเคฟเคชเคฌเฅ‹เคฐเฅเคก เคชเคฐ เค•เฅ‰เคชเฅ€ เค•เคฐเฅ‡เค‚", "directory.federated": "เคœเฅเคžเคพเคค เคซเฅ‡เคกเฅ€เคตเคฐเฅเคธ เคธเฅ‡", @@ -186,6 +207,15 @@ "dismissable_banner.dismiss": "เคกเคฟเคธเคฎเคฟเคธ", "dismissable_banner.explore_links": "เค‡เคจ เคธเคฎเคพเคšเคพเคฐเฅ‹เค‚ เค•เฅ‡ เคฌเคพเคฐเฅ‡ เคฎเฅ‡เค‚ เคฒเฅ‹เค—เฅ‹เค‚ เคฆเฅเคตเคพเคฐเคพ เค‡เคธ เคชเคฐ เค”เคฐ เคกเฅ‡เคธเฅ‡เค‚เคŸเฅเคฐเคฒเฅ€เคธเฅ‡เคก เคจเฅ‡เคŸเคตเคฐเฅเค• เค•เฅ‡ เค…เคจเฅเคฏ เคธเคฐเฅเคตเคฐเฅ‹เค‚ เคชเคฐ เค…เคญเฅ€ เคฌเคพเคค เค•เฅ€ เคœเคพ เคฐเคนเฅ€ เคนเฅˆเฅค", "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": "เค‡เคธ เคธเคฐเฅเคตเคฐ เค•เฅ€ เคฒเฅ‹เค— เค†เคชเค•เฅ€ เคชเฅ‚เคฐเคพเคจเฅ€ เคชเฅ‹เคธเฅเคŸเฅเคธ เค•เคพ เค…เคจเฅเคธเคฐเคฃ เค•เคฟเคฏเคพ เคœเคพ sakta เคนเฅˆเฅค", + "domain_block_modal.they_cant_follow": "เค‡เคธ เคธเคฐเฅเคตเคฐ เคฎเฅ‡เคธเฅ‡ เค•เฅ‹เคˆ เคญเฅ€ เค†เคชเค•เคพ เค…เคจเฅเคธเคฐเคฃ เคจเคนเฅ€เค‚ เค•เคฐ เคธเค•เคคเคพเฅค", + "domain_block_modal.they_wont_know": "เค‰เคจเค•เฅ‹ เคชเคคเคพ เคจเคนเฅ€เค‚ เคšเคฒเฅ‡เค—เคพ เค•เคฟ เคตเฅ‡ เค…เคตเคฐเฅ‹เคงเคฟเคค เค•เคฟเค เค—เค เคนเฅˆเฅค", + "domain_block_modal.title": "เคกเฅ‹เคฎเฅ‡เคจ เคฌเฅเคฒเฅ‰เค• เค•เคฐเฅ‡เค‚", + "domain_pill.server": "เคธเคฐเฅเคตเคฐ", + "domain_pill.username": "เคฏเฅ‚เคœเคผเคฐเคจเฅ‡เคฎ", "embed.instructions": "เค…เคชเคจเฅ‡ เคตเฅ‡เคฌเคธเคพเค‡เคŸ เคชเคฐ, เคจเคฟเคšเฅ‡ เคฆเคฟเค เค•เฅ‹เคก เค•เฅ‹ เค•เฅ‰เคชเฅ€ เค•เคฐเค•เฅ‡, เค‡เคธ เคธเฅเคŸเฅ‡เคŸเคธ เค•เฅ‹ เคเคฎเฅเคฌเฅ‡เคก เค•เคฐเฅ‡เค‚", "embed.preview": "เคฏเคน เคเคธเคพ เคฆเคฟเค–เฅ‡เค—เคพ :", "emoji_button.activity": "เค—เคคเคฟเคตเคฟเคงเคฟ", @@ -255,6 +285,7 @@ "follow_request.authorize": "เค…เคงเคฟเค•เคพเคฐ เคฆเฅ‡เค‚", "follow_request.reject": "เค…เคธเฅเคตเฅ€เค•เคพเคฐ เค•เคฐเฅ‡เค‚", "follow_requests.unlocked_explanation": "เคนเคพเคฒเคพเคเค•เคฟ เค†เคชเค•เคพ เค–เคพเคคเคพ เคฒเฅ‰เค• เคจเคนเฅ€เค‚ เคนเฅˆ, เคซเคฟเคฐ เคญเฅ€ {domain} เคกเฅ‹เคฎเฅ‡เคจ เคธเฅเคŸเคพเคซ เคจเฅ‡ เคธเฅ‹เคšเคพ เค•เคฟ เค†เคช เค‡เคจ เค–เคพเคคเฅ‹เค‚ เค•เฅ‡ เคฎเฅˆเคจเฅเคฏเฅเค…เคฒ เค…เคจเฅเคฐเฅ‹เคงเฅ‹เค‚ เค•เฅ€ เคธเคฎเฅ€เค•เฅเคทเคพ เค•เคฐเคจเคพ เคšเคพเคนเคคเฅ‡ เคนเฅˆเค‚เฅค", + "follow_suggestions.dismiss": "เคฆเฅ‹เคฌเคพเคฐเคพ เคจ เคฆเคฟเค–เคพเคเค‚", "followed_tags": "เคซเฅ‰เคฒเฅ‹ เค•เคฟเค เค—เค เคนเฅˆเคถเคŸเฅˆเค—เฅเคธ", "footer.about": "เค…เคฌเคพเค‰เคŸ", "footer.directory": "เคชเฅเคฐเฅ‹เคซเคพเค‡เคฒเฅเคธ เคกเคพเคฏเคฐเฅ‡เค•เฅเคŸเคฐเฅ€", @@ -277,7 +308,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "เคนเฅˆเคถเคŸเฅˆเค— เค•เฅ‹ เคซเฅ‰เคฒเฅ‹ เค•เคฐเฅ‡เค‚", "hashtag.unfollow": "เคนเฅˆเคถเคŸเฅˆเค— เค•เฅ‹ เค‰เคจเฅžเฅ‹เคฒเฅเคฒเฅ‹เคต เค•เคฐเฅ‡เค‚", - "home.column_settings.basic": "เคฌเฅเคจเคฟเคฏเคพเคฆเฅ€", "home.column_settings.show_reblogs": "เคฌเฅ‚เคธเฅเคŸ เคฆเคฟเค–เคพเค", "home.column_settings.show_replies": "เคœเคตเคพเคฌเฅ‹เค‚ เค•เฅ‹ เคฆเคฟเค–เคพเค", "home.hide_announcements": "เค˜เฅ‹เคทเคฃเคพเคเค เค›เคฟเคชเคพเคเค", @@ -346,9 +376,6 @@ "lists.replies_policy.none": "เค•เฅ‹เคˆ เคจเคนเฅ€เค‚", "lists.replies_policy.title": "เค‡เคธเค•เฅ‡ เคœเคตเคพเคฌ เคฆเคฟเค–เคพเคเค‚:", "lists.subheading": "เค†เคชเค•เฅ€ เคธเฅ‚เคšเคฟเคฏเคพเค", - "mute_modal.duration": "เค…เคตเคงเคฟ", - "mute_modal.hide_notifications": "เค‡เคธ เคธเคญเฅเคฏ เค•เฅ€ เค“เคฐเคธเฅ‡ เค†เคจเฅ‡เคตเคพเคฒเฅ€ เคธเฅ‚เคšเคจเคพเค เคถเคพเค‚เคค เค•เคฐเฅ‡", - "mute_modal.indefinite": "เค…เคจเคฟเคถเฅเคšเคฟเคคเค•เคพเคฒเฅ€เคจ", "navigation_bar.about": "เคตเคฟเคตเคฐเคฃ", "navigation_bar.blocks": "เคฌเฅเคฒเฅ‰เค•เฅเคก เคฏเฅ‚เฅ›เคฐเฅเคธ", "navigation_bar.bookmarks": "เคชเฅเคธเฅเคคเค•เคšเคฟเคนเฅเคจ:", @@ -376,8 +403,6 @@ "notifications.clear": "เคธเฅ‚เคšเคจเคพเคเค‚ เคนเคŸเคพเค", "notifications.column_settings.admin.report": "เคจเคˆ เคฐเคฟเคชเฅ‹เคฐเฅเคŸ:", "notifications.column_settings.favourite": "เคชเคธเค‚เคฆเฅ€เคฆเคพ:", - "notifications.column_settings.filter_bar.advanced": "เคธเคญเฅ€ เคถเฅเคฐเฅ‡เคฃเคฟเคฏเคพเค เคฆเคฟเค–เคพเคเค‚", - "notifications.column_settings.filter_bar.category": "เคซเคผเคฟเคฒเฅเคŸเคฐ เคฌเคพเคฐ", "notifications.column_settings.follow": "เคจเค เคซเคผเฅ‰เคฒเฅ‹เค…เคฐเฅเคธ", "notifications.column_settings.mention": "เค‰เคฒเฅเคฒเฅ‡เค–:", "notifications.column_settings.poll": "เคšเฅเคจเคพเคต เคชเคฐเคฟเคฃเคพเคฎ", @@ -483,6 +508,7 @@ "status.delete": "เคนเคŸเคพเคเค‚", "status.detailed_status": "เคตเคฟเคธเฅเคคเฅƒเคค เคตเคพเคฐเฅเคคเคพ เคฆเฅƒเคถเฅเคฏ", "status.direct": "เคจเคฟเคœเฅ€ เคธเค‚เคฆเฅ‡เคถ @{name} เคธเฅ‡", + "status.edited": "เคชเคฟเค›เคฒเคพ เคธเค‚เคถเฅ‹เคงเคจ {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.media.open": "เค–เฅ‹เคฒเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅเคฒเคฟเค• เค•เคฐเฅ‡เค‚", "status.media.show": "เคฆเคฟเค–เคพเคจเฅ‡ เค•เฅ‡ เคฒเคฟเค เค•เฅเคฒเคฟเค• เค•เคฐเฅ‡เค‚", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index 9fe15f5a2d..d952945c46 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -146,9 +146,7 @@ "compose_form.spoiler.marked": "Tekst je skriven iza upozorenja", "compose_form.spoiler.unmarked": "Tekst nije skriven", "confirmation_modal.cancel": "Otkaลพi", - "confirmations.block.block_and_report": "Blokiraj i prijavi", "confirmations.block.confirm": "Blokiraj", - "confirmations.block.message": "Sigurno ลพelite blokirati {name}?", "confirmations.cancel_follow_request.confirm": "Povuci zahtjev", "confirmations.delete.confirm": "Obriลกi", "confirmations.delete.message": "Stvarno ลพelite obrisati ovaj toot?", @@ -156,14 +154,11 @@ "confirmations.delete_list.message": "Jeste li sigurni da ลพelite trajno obrisati ovu listu?", "confirmations.discard_edit_media.confirm": "Odbaciti", "confirmations.discard_edit_media.message": "Postoje nespremljene promjene u opisu medija ili u pretpregledu, svejedno ih odbaciti?", - "confirmations.domain_block.confirm": "Blokiraj cijelu domenu", "confirmations.domain_block.message": "Jeste li zaista, zaista sigurni da ลพelite blokirati cijelu domenu {domain}? U veฤ‡ini sluฤajeva dovoljno je i preferirano nekoliko ciljanih blokiranja ili utiลกavanja. Neฤ‡ete vidjeti sadrลพaj s te domene ni u kojim javnim vremenskim crtama ili Vaลกim obavijestima. Vaลกi pratitelji s te domene bit ฤ‡e uklonjeni.", "confirmations.edit.confirm": "Uredi", "confirmations.logout.confirm": "Odjavi se", "confirmations.logout.message": "Jeste li sigurni da se ลพelite odjaviti?", "confirmations.mute.confirm": "Utiลกaj", - "confirmations.mute.explanation": "Ovo ฤ‡e sakriti njihove objave i objave koje ih spominju, ali i dalje ฤ‡e im dopuลกtati da vide Vaลกe objave i da Vas prate.", - "confirmations.mute.message": "Jeste li sigurni da ลพelite utiลกati {name}?", "confirmations.redraft.confirm": "Izbriลกi i ponovno uredi", "confirmations.reply.confirm": "Odgovori", "confirmations.reply.message": "Odgovaranje sada ฤ‡e prepisati poruku koju upravo piลกete. Jeste li sigurni da ลพelite nastaviti?", @@ -261,7 +256,6 @@ "hashtag.column_settings.tag_toggle": "Ukljuฤi dodatne oznake za ovaj stupac", "hashtag.follow": "Prati hashtag", "hashtag.unfollow": "Prestani pratiti hashtag", - "home.column_settings.basic": "Osnovno", "home.column_settings.show_reblogs": "Pokaลพi boostove", "home.column_settings.show_replies": "Pokaลพi odgovore", "home.hide_announcements": "Sakrij najave", @@ -324,8 +318,6 @@ "lists.search": "Traลพi meฤ‘u praฤ‡enim ljudima", "lists.subheading": "Vaลกe liste", "media_gallery.toggle_visible": "Sakrij {number, plural, one {sliku} other {slike}}", - "mute_modal.duration": "Trajanje", - "mute_modal.hide_notifications": "Sakrij obavijesti ovog korisnika?", "navigation_bar.about": "O aplikaciji", "navigation_bar.advanced_interface": "Otvori u naprednom web suฤelju", "navigation_bar.blocks": "Blokirani korisnici", @@ -358,8 +350,6 @@ "notifications.clear": "Oฤisti obavijesti", "notifications.clear_confirmation": "ลฝelite li zaista trajno oฤistiti sve Vaลกe obavijesti?", "notifications.column_settings.alert": "Obavijesti radne povrลกine", - "notifications.column_settings.filter_bar.advanced": "Prikaลพi sve kategorije", - "notifications.column_settings.filter_bar.category": "Brza traka filtera", "notifications.column_settings.follow": "Novi pratitelji:", "notifications.column_settings.follow_request": "Novi zahtjevi za praฤ‡enje:", "notifications.column_settings.mention": "Spominjanja:", @@ -465,8 +455,6 @@ "server_banner.about_active_users": "Popis aktivnih korisnika proลกli mjesec", "server_banner.active_users": "aktivni korisnici", "server_banner.administered_by": "Administrator je:", - "server_banner.introduction": "{domain} je dio decentralizirane socijalne mreลพe koju pokreฤ‡e {mastodon}.", - "server_banner.learn_more": "Saznaj viลกe", "server_banner.server_stats": "Statistike posluลพitelja:", "sign_in_banner.create_account": "Stvori raฤun", "sign_in_banner.sign_in": "Prijavi se", @@ -478,7 +466,6 @@ "status.copy": "Copy link to status", "status.delete": "Obriลกi", "status.edit": "Uredi", - "status.edited": "Ureฤ‘eno {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "Umetni", "status.filter": "Filtriraj ovu objavu", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 8f979e5558..6164335da8 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -16,7 +16,7 @@ "account.badges.bot": "Automatizรกlt", "account.badges.group": "Csoport", "account.block": "@{name} letiltรกsa", - "account.block_domain": "Domain blokkolรกsa: {domain}", + "account.block_domain": "Domain letiltรกsa: {domain}", "account.block_short": "Letiltรกs", "account.blocked": "Letiltva", "account.browse_more_on_origin_server": "Tovรกbbi bรถngรฉszรฉs az eredeti profilon", @@ -89,6 +89,14 @@ "announcement.announcement": "Kรถzlemรฉny", "attachments_list.unprocessed": "(feldolgozatlan)", "audio.hide": "Hang elrejtรฉse", + "block_modal.remote_users_caveat": "Arra kรฉrjรผk a {domain} kiszolgรกlรณt, hogy tartsa tiszteletben a dรถntรฉsedet. Ugyanakkor az egyรผttmลฑkรถdรฉs nem garantรกlt, mivel nรฉhรกny kiszolgรกlรณ mรกskรฉpp kezelheti a letiltรกsokat. A nyilvรกnos bejegyzรฉsek a be nem jelentkezett felhasznรกlรณk szรกmรกra tovรกbbra is lรกtszรณdhatnak.", + "block_modal.show_less": "Kevesebb mutatรกsa", + "block_modal.show_more": "Tรถbb mutatรกsa", + "block_modal.they_cant_mention": "Nem emlรญthet meg รฉs nem kรถvethet tรฉged.", + "block_modal.they_cant_see_posts": "Nem lรกthatja a bejegyzรฉseidet, รฉs te sem fogod lรกtni az รถvรฉit.", + "block_modal.they_will_know": "Lรกthatja, hogy le van tiltva.", + "block_modal.title": "Letiltsuk a felhasznรกlรณt?", + "block_modal.you_wont_see_mentions": "Nem lรกtsz majd ล‘t emlรญtล‘ bejegyzรฉseket.", "boost_modal.combo": "Hogy รกtugord ezt kรถvetkezล‘ alkalommal, hasznรกld {combo}", "bundle_column_error.copy_stacktrace": "Hibajelentรฉs mรกsolรกsa", "bundle_column_error.error.body": "A kรฉrt lap nem jelenรญthetล‘ meg. Ez lehet, hogy kรณdhiba, vagy bรถngรฉszล‘kompatibitรกsi hiba.", @@ -113,10 +121,10 @@ "column.community": "Helyi idล‘vonal", "column.direct": "Szemรฉlyes emlรญtรฉsek", "column.directory": "Profilok bรถngรฉszรฉse", - "column.domain_blocks": "Letiltott tartomรกnynevek", + "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", @@ -125,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", @@ -135,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.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Tartalmi figyelmeztetรฉs hozzรกadรกsa", "compose_form.spoiler_placeholder": "Tartalmi figyelmeztetรฉs (opcionรกlis)", "confirmation_modal.cancel": "Mรฉgsem", - "confirmations.block.block_and_report": "Letiltรกs รฉs jelentรฉs", "confirmations.block.confirm": "Letiltรกs", - "confirmations.block.message": "Biztos, hogy letiltod: {name}?", "confirmations.cancel_follow_request.confirm": "Kรฉrรฉs visszavonรกsa", "confirmations.cancel_follow_request.message": "Biztos, hogy visszavonod a(z) {name} felhasznรกlรณra vonatkozรณ kรถvetรฉsi kรฉrรฉsedet?", "confirmations.delete.confirm": "Tรถrlรฉs", @@ -170,16 +176,14 @@ "confirmations.delete_list.confirm": "Tรถrlรฉs", "confirmations.delete_list.message": "Biztos, hogy vรฉglegesen tรถrรถlni szeretnรฉd ezt a listรกt?", "confirmations.discard_edit_media.confirm": "Elvetรฉs", - "confirmations.discard_edit_media.message": "Elmentetlen vรกltoztatรกsaid vannak a mรฉdia leรญrรกsรกban vagy elล‘nรฉzetรฉben. Eldobjuk ล‘ket?", - "confirmations.domain_block.confirm": "Teljes tartomรกny tiltรกsa", + "confirmations.discard_edit_media.message": "Mentetlen vรกltoztatรกsaid vannak a mรฉdia leรญrรกsรกban vagy elล‘nรฉzetรฉben, mindenkรฉpp elveted?", + "confirmations.domain_block.confirm": "Kiszolgรกlรณ letiltรกsa", "confirmations.domain_block.message": "Biztos, hogy le szeretnรฉd tiltani a teljes {domain} domaint? A legtรถbb esetben nรฉhรกny cรฉlzott tiltรกs vagy nรฉmรญtรกs elegendล‘, รฉs kรญvรกnatosabb megoldรกs. Semmilyen tartalmat nem fogsz lรกtni ebbล‘l a domainbล‘l se az idล‘vonalakon, se az รฉrtesรญtรฉsekben. Az ebben a domainben lรฉvล‘ kรถvetล‘idet is eltรกvolรญtjuk.", "confirmations.edit.confirm": "Szerkesztรฉs", "confirmations.edit.message": "Ha most szerkeszted, ez felรผlรญrja a most szerkesztรฉs alatt รกllรณ รผzenetet. Mรฉgis ezt szeretnรฉd?", "confirmations.logout.confirm": "Kijelentkezรฉs", "confirmations.logout.message": "Biztos, hogy kijelentkezel?", "confirmations.mute.confirm": "Nรฉmรญtรกs", - "confirmations.mute.explanation": "Ez elrejti a tล‘lรผk รฉrkezล‘ bejegyzรฉseket, valamint az ล‘ket megemlรญtล‘ket, de ล‘k tovรกbbra is lรกthatjรกk a te bejegyzรฉseid, รฉs kรถvethetnek is tรฉged.", - "confirmations.mute.message": "Biztos, hogy nรฉmรญtod: {name}?", "confirmations.redraft.confirm": "Tรถrlรฉs รฉs รบjraรญrรกs", "confirmations.redraft.message": "Biztos, hogy ezt a bejegyzรฉst szeretnรฉd tรถrรถlni รฉs รบjraรญrni? Minden megtolรกst รฉs kedvencnek jelรถlรฉst elvesztesz, az eredetire adott vรกlaszok pedig elรกrvulnak.", "confirmations.reply.confirm": "Vรกlasz", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Ezek jelenleg nรฉpszerลฑvรฉ vรกlรณ bejegyzรฉsek a hรกlรณ kรผlรถnbรถzล‘ szegleteibล‘l. Az รบjabb vagy tรถbb megtolรกssal rendelkezล‘ bejegyzรฉseket, illetve a kedvencnek jelรถlรฉssel rendelkezล‘eket rangsoroljuk elล‘rรฉbb.", "dismissable_banner.explore_tags": "Jelenleg ezek a hashtagek hรณdรญtanak teret a kรถzรถssรฉgi weben. Azokat a hashtageket, amelyeket tรถbb kรผlรถnbรถzล‘ ember hasznรกl, magasabbra rangsoroljรกk.", "dismissable_banner.public_timeline": "Ezek a legfrissebb nyilvรกnos bejegyzรฉsek a kรถzรถssรฉgi weben, amelyeket {domain} domain felhasznรกlรณi kรถvetnek.", + "domain_block_modal.block": "Kiszolgรกlรณ letiltรกsa", + "domain_block_modal.block_account_instead": "Helyette @{name} letiltรกsa", + "domain_block_modal.they_can_interact_with_old_posts": "Az ezen a kiszolgรกlรณn lรฉvล‘ emberek interaktรกlhatnak a rรฉgi bejegyzรฉseiddel.", + "domain_block_modal.they_cant_follow": "Errล‘l a kiszolgรกlรณrรณl senki sem kรถvethet.", + "domain_block_modal.they_wont_know": "Nem fogja tudni, hogy letiltottรกk.", + "domain_block_modal.title": "Letiltsuk a domaint?", + "domain_block_modal.you_will_lose_followers": "Az ezen a kiszolgรกlรณn lรฉvล‘ รถsszes kรถvetล‘det tรถrรถlni fogjuk.", + "domain_block_modal.you_wont_see_posts": "Nem lรกtsz majd bejegyzรฉseket vagy รฉrtesรญtรฉseket ennek a kiszolgรกlรณnak a felhasznรกlรณitรณl.", + "domain_pill.activitypub_lets_connect": "Lehetล‘vรฉ teszi, hogy kapcsolatba lรฉpj nem csak a Mastodonon, hanem a mรกs kรถzรถssรฉgi alkalmazรกsokon lรฉvล‘ emberekkel is.", + "domain_pill.activitypub_like_language": "Az ActivityPub olyan mint egy nyelv, amelyet a Mastodon a mรกs kรถzรถssรฉgi hรกlรณzatokkal valรณ kommunikรกciรณra hasznรกl.", + "domain_pill.server": "Kiszolgรกlรณ", + "domain_pill.their_handle": "A fiรณkneve:", + "domain_pill.their_server": "A digitรกlis otthona, ahol a bejegyzรฉsei talรกlhatรณk.", + "domain_pill.their_username": "Az egyedi azonosรญtรณja a kiszolgรกlรณjรกn. Lehet, hogy ugyanazon felhasznรกlรณnรฉv kรผlรถnbรถzล‘ kiszolgรกlรณkon is megtalรกlhatรณ.", + "domain_pill.username": "Felhasznรกlรณnรฉv", + "domain_pill.whats_in_a_handle": "Mi is egy fiรณknรฉv?", + "domain_pill.who_they_are": "Mivel a fiรณknevek mondjรกk meg, hogy valaki kicsoda รฉs hol talรกlhatรณ, รญgy ezek hasznรกlatรกval lรฉphetsz kapcsolatba az kรถzรถssรฉgi hรกlรณzatรกn lรฉvล‘ emberekkel.", + "domain_pill.who_you_are": "Mivel a fiรณkneved mondja meg, hogy ki vagy รฉs hol, รญgy ezek hasznรกlatรกval lรฉphetnek kapcsolatba veled az kรถzรถssรฉgi hรกlรณzatรกn lรฉvล‘ emberek.", + "domain_pill.your_handle": "Sajรกt fiรณknรฉv:", + "domain_pill.your_server": "A digitรกlis otthonod, ahol a bejegyzรฉseid talรกlhatรณk. Nem tetszik a mostani? Vรกlts kiszolgรกlรณt bรกrmikor, รฉs vidd magaddal a kรถvetล‘idet is.", + "domain_pill.your_username": "Az egyedi azonosรญtรณd ezen a kiszolgรกlรณn. Lehet, hogy ugyanazon felhasznรกlรณnรฉv kรผlรถnbรถzล‘ kiszolgรกlรณkon is megtalรกlhatรณ.", "embed.instructions": "รgyazd be ezt a bejegyzรฉst a weboldaladba az alรกbbi kรณd kimรกsolรกsรกval.", "embed.preview": "รgy fog kinรฉzni:", "emoji_button.activity": "Tevรฉkenysรฉg", @@ -230,7 +255,7 @@ "empty_column.bookmarked_statuses": "Mรฉg nincs egyetlen kรถnyvjelzล‘zรถtt bejegyzรฉsed sem. Ha kรถnyvjelzล‘zรถl egyet, itt fog megjelenni.", "empty_column.community": "A helyi idล‘vonal รผres. Tรฉgy kรถzzรฉ valamit nyilvรกnosan, hogy elindรญtsd az esemรฉnyeket!", "empty_column.direct": "Mรฉg nincs egy szemรฉlyes emlรญtรฉsed sem. Kรผldรฉskor vagy fogadรกskor itt fognak megjelenni.", - "empty_column.domain_blocks": "Mรฉg nem lett letiltva egyetlen tartomรกny sem.", + "empty_column.domain_blocks": "Mรฉg nem lett letiltva egyetlen domain sem.", "empty_column.explore_statuses": "Jelenleg semmi sem felkapott. Nรฉzz vissza kรฉsล‘bb!", "empty_column.favourited_statuses": "Mรฉg nincs egyetlen kedvenc bejegyzรฉsed sem. Ha kedvencnek jelรถlsz egyet, itt fog megjelenni.", "empty_column.favourites": "Mรฉg senki sem jelรถlte ezt a bejegyzรฉst kedvencnek. Ha valaki mรฉgis megteszi, itt fogjuk mutatni.", @@ -241,6 +266,7 @@ "empty_column.list": "A lista jelenleg รผres. Ha a listatagok bejegyzรฉst tesznek kรถzzรฉ, itt fog megjelenni.", "empty_column.lists": "Mรฉg nincs egyetlen listรกd sem. Ha lรฉtrehozol egyet, itt fog megjelenni.", "empty_column.mutes": "Mรฉg egy felhasznรกlรณt sem nรฉmรญtottรกl le.", + "empty_column.notification_requests": "Minden tiszta! Itt nincs semmi. Ha รบj รฉrtesรญtรฉseket kapsz, azok itt jelennek meg a beรกllรญtรกsoknak megfelelล‘en.", "empty_column.notifications": "Jelenleg mรฉg nincsenek รฉrtesรญtรฉseid. Ha mรกsok kapcsolatba lรฉpnek veled, ezek itt lesznek lรกthatรณak.", "empty_column.public": "Jelenleg itt nincs semmi! รrj valamit nyilvรกnosan vagy kรถvess mรกs kiszolgรกlรณn levล‘ felhasznรกlรณkat, hogy megtรถltsd.", "error.unexpected_crash.explanation": "Egy kรณd- vagy bรถngรฉszล‘kompatibilitรกsi hiba miatt ez az oldal nem jelenรญthetล‘ meg helyesen.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Ez a kiszolgรกlรณ", "firehose.remote": "Egyรฉb kiszolgรกlรณk", "follow_request.authorize": "Hitelesรญtรฉs", "follow_request.reject": "Elutasรญtรกs", "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": "Szerkesztล‘i ajรกnlat", + "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 รกltalad 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.", + "follow_suggestions.hints.most_interactions": "Ez a profil mostanรกban sok figyelmet kap a(z) {domain} oldalon.", + "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รณ azokhoz a profilokhoz, melyeket nemrรฉg kรถvettรฉl be", "follow_suggestions.view_all": "ร–sszes megtekintรฉse", "follow_suggestions.who_to_follow": "Kit รฉrdemes kรถvetni", "followed_tags": "Kรถvetett hashtagek", @@ -309,7 +347,6 @@ "hashtag.follow": "Hashtag kรถvetรฉse", "hashtag.unfollow": "Hashtag kรถvetรฉsรฉnek megszรผntetรฉse", "hashtags.and_other": "โ€ฆรฉs {count, plural, other {# tovรกbbi}}", - "home.column_settings.basic": "รltalรกnos", "home.column_settings.show_reblogs": "Megtolรกsok megjelenรญtรฉse", "home.column_settings.show_replies": "Vรกlaszok megjelenรญtรฉse", "home.hide_announcements": "Kรถzlemรฉnyek elrejtรฉse", @@ -318,7 +355,7 @@ "home.pending_critical_update.title": "Kritikus biztonsรกgi frissรญtรฉs รฉrhetล‘ el!", "home.show_announcements": "Kรถzlemรฉnyek megjelenรญtรฉse", "interaction_modal.description.favourite": "Egy Mastodon fiรณkkal kedvencnek jelรถlheted ezt a bejegyzรฉst, tudatva a szerzล‘vel, hogy รฉrtรฉkeled รฉs elteszed kรฉsล‘bbre.", - "interaction_modal.description.follow": "Egy Mastodon fiรณkkal bekรถvetheted {name} fiรณkot, hogy lรกsd a bejegyzรฉseit a sajรกt hรญrfolyamodban.", + "interaction_modal.description.follow": "Egy Mastodon-fiรณkkal kรถvetheted {name} fiรณkjรกt, hogy lรกsd a bejegyzรฉseit a kezdล‘lapodon.", "interaction_modal.description.reblog": "Egy Mastodon fiรณkkal megtolhatod ezt a bejegyzรฉst, hogy megoszd a sajรกt kรถvetล‘iddel.", "interaction_modal.description.reply": "Egy Mastodon fiรณkkal vรกlaszolhatsz erre a bejegyzรฉsre.", "interaction_modal.login.action": "Vigyen haza", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Profil megjelenรญtรฉse mindenkรฉppen", "limited_account_hint.title": "Ezt a profilt {domain} moderรกtorai elrejtettรฉk.", "link_preview.author": "{name} szerint", + "link_preview.more_from_author": "Tรถbb tล‘le: {name}", + "link_preview.shares": "{count, plural, one {{counter} bejegyzรฉs} other {{counter} bejegyzรฉs}}", "lists.account.add": "Hozzรกadรกs a listรกhoz", "lists.account.remove": "Eltรกvolรญtรกs a listรกbรณl", "lists.delete": "Lista tรถrlรฉse", @@ -395,9 +434,15 @@ "loading_indicator.label": "Betรถltรฉsโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Kรฉp elrejtรฉse} other {Kรฉpek elrejtรฉse}}", "moved_to_account_banner.text": "A(z) {disabledAccount} fiรณkod jelenleg le van tiltva, mert รกtkรถltรถztรฉl ide: {movedToAccount}.", - "mute_modal.duration": "Idล‘tartam", - "mute_modal.hide_notifications": "Rejtsรผk el a felhasznรกlรณtรณl szรกrmazรณ รฉrtesรญtรฉseket?", - "mute_modal.indefinite": "Hatรกrozatlan", + "mute_modal.hide_from_notifications": "Elrejtรฉs az รฉrtesรญtรฉsek kรถzรผl", + "mute_modal.hide_options": "Beรกllรญtรกsok elrejtรฉse", + "mute_modal.indefinite": "Amรญg nem oldom fel a nรฉmรญtรกst", + "mute_modal.show_options": "Beรกllรญtรกsok megjelenรญtรฉse", + "mute_modal.they_can_mention_and_follow": "Megemlรญthet vagy kรถvethet tรฉged, de te nem fogod ezeket lรกtni.", + "mute_modal.they_wont_know": "Nem fogja tudni, hogy lenรฉmรญtottad.", + "mute_modal.title": "Elnรฉmรญtsuk a felhasznรกlรณt?", + "mute_modal.you_wont_see_mentions": "Nem lรกtsz majd ล‘t emlรญtล‘ bejegyzรฉseket.", + "mute_modal.you_wont_see_posts": "Tovรกbbra is lรกtni fogja a bejegyzรฉseidet, de te nem fogod lรกtni az รถvรฉit.", "navigation_bar.about": "Nรฉvjegy", "navigation_bar.advanced_interface": "Megnyitรกs a speciรกlis webes felรผletben", "navigation_bar.blocks": "Letiltott felhasznรกlรณk", @@ -406,7 +451,7 @@ "navigation_bar.compose": "รšj bejegyzรฉs รญrรกsa", "navigation_bar.direct": "Szemรฉlyes emlรญtรฉsek", "navigation_bar.discover": "Felfedezรฉs", - "navigation_bar.domain_blocks": "Letiltott tartomรกnyok", + "navigation_bar.domain_blocks": "Letiltott domainek", "navigation_bar.explore": "Felfedezรฉs", "navigation_bar.favourites": "Kedvencek", "navigation_bar.filters": "Nรฉmรญtott szavak", @@ -430,11 +475,29 @@ "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รณ", + "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.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", + "notification_requests.dismiss": "Elvetรฉs", + "notification_requests.notifications_from": "{name} รฉrtesรญtรฉsei", + "notification_requests.title": "Szลฑrt รฉrtesรญtรฉsek", "notifications.clear": "ร‰rtesรญtรฉsek tรถrlรฉse", "notifications.clear_confirmation": "Biztos, hogy vรฉglegesen tรถrรถlni akarod az รถsszes รฉrtesรญtรฉsed?", "notifications.column_settings.admin.report": "รšj jelentรฉsek:", @@ -443,9 +506,8 @@ "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.filter_bar.show_bar": "Szลฑrล‘sรกv megjelenรญtรฉse", "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", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Az asztali รฉrtesรญtรฉsek nem รฉrhetล‘k el a korรกbban elutasรญtott bรถngรฉszล‘engedรฉly-kรฉrelem miatt", "notifications.permission_denied_alert": "Az asztali รฉrtesรญtรฉsek nem engedรฉlyezhetล‘k a korรกbban elutasรญtott bรถngรฉszล‘ engedรฉly miatt", "notifications.permission_required": "Az asztali รฉrtesรญtรฉsek nem รฉrhetล‘ek el, mivel a szรผksรฉges engedรฉly nem lett megadva.", + "notifications.policy.filter_new_accounts.hint": "Az elmรบlt {days, plural, one {napban} other {# napban}} lรฉtrehozva", + "notifications.policy.filter_new_accounts_title": "รšj fiรณkok", + "notifications.policy.filter_not_followers_hint": "Beleรฉrtve azokat, akik kevesebb mint {days, plural, one {egy napja} other {# napja}} kรถvetnek", + "notifications.policy.filter_not_followers_title": "Olyan emberek, akik nem kรถvetnek", + "notifications.policy.filter_not_following_hint": "Amรญg kรฉzileg jรณvรก nem hagyod ล‘ket", + "notifications.policy.filter_not_following_title": "Nem kรถvetett emberek", + "notifications.policy.filter_private_mentions_hint": "Kiszลฑrve, hacsak nem a sajรกt emlรญtรฉsedre vรกlaszol, vagy ha nem kรถveted a feladรณt", + "notifications.policy.filter_private_mentions_title": "Kรฉretlen szemรฉlyes emlรญtรฉsek", + "notifications.policy.title": "Feladรณ รฉrtesรญtรฉseinek kiszลฑrรฉseโ€ฆ", "notifications_permission_banner.enable": "Asztali รฉrtesรญtรฉsek engedรฉlyezรฉse", "notifications_permission_banner.how_to_control": "Ahhoz, hogy รฉrtesรญtรฉseket kapj akkor, amikor a Mastodon nincs megnyitva, engedรฉlyezd az asztali รฉrtesรญtรฉseket. Pontosan be tudod รกllรญtani, hogy milyen interakciรณkrรณl รฉrtesรผlj a fenti {icon} gombon keresztรผl, ha egyszer mรกr engedรฉlyezted ล‘ket.", "notifications_permission_banner.title": "Soha ne mulassz el semmit", @@ -496,14 +567,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!", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Az elmรบlt 30 napban ezt a kiszolgรกlรณt hasznรกlรณk szรกma (Havi aktรญv felhasznรกlรณk)", "server_banner.active_users": "aktรญv felhasznรกlรณ", "server_banner.administered_by": "Adminisztrรกtor:", - "server_banner.introduction": "{domain} rรฉsze egy decentralizรกlt kรถzรถssรฉgi hรกlรณnak, melyet a {mastodon} hajt meg.", - "server_banner.learn_more": "Tudj meg tรถbbet", + "server_banner.is_one_of_many": "{domain} egy a jelentล‘s, fรผggetlen Mastodon kiszolgรกlรณk kรถzรผl, melyet a fediverzumban valรณ rรฉszvรฉtelre hasznรกlhatsz.", "server_banner.server_stats": "Kiszolgรกlรณstatisztika:", "sign_in_banner.create_account": "Fiรณk lรฉtrehozรกsa", + "sign_in_banner.follow_anyone": "Kรถvess bรกrkit a fediverzumon keresztรผl, รฉs lรกss mindent idล‘rendi sorrendben. Algoritmusok, hirdetรฉsek, kattintรกsvadรกszat nรฉlkรผl.", + "sign_in_banner.mastodon_is": "A Mastodon a legjobb mรณdja annak, hogy a tรถrtรฉnรฉsekkel kapcsolatban naprakรฉsz maradj.", "sign_in_banner.sign_in": "Bejelentkezรฉs", "sign_in_banner.sso_redirect": "Bejelentkezรฉs vagy regisztrรกciรณ", - "sign_in_banner.text": "Jelentkezz be profilok vagy hashtagek kรถvetรฉsรฉhez, kedvencnek jelรถlรฉsรฉhez, bejegyzรฉsek megosztรกsรกhoz, megvรกlaszolรกsรกhoz. A fiรณkodbรณl mรกs kiszolgรกlรณkon is kommunikรกlhatsz.", "status.admin_account": "Moderรกciรณs felรผlet megnyitรกsa @{name} fiรณkhoz", "status.admin_domain": "Moderรกciรณs felรผlet megnyitรกsa {domain} esetรฉben", "status.admin_status": "Bejegyzรฉs megnyitรกsa a moderรกciรณs felรผleten", @@ -645,10 +716,11 @@ "status.direct": "@{name} szemรฉlyes emlรญtรฉse", "status.direct_indicator": "Szemรฉlyes emlรญtรฉs", "status.edit": "Szerkesztรฉs", - "status.edited": "Szerkesztve: {date}", + "status.edited": "Utoljรกra szerkesztve {date}", "status.edited_x_times": "{count, plural, one {{count} alkalommal} other {{count} alkalommal}} szerkesztve", "status.embed": "Beรกgyazรกs", "status.favourite": "Kedvenc", + "status.favourites": "{count, plural, one {kedvenc} other {kedvenc}}", "status.filter": "E bejegyzรฉs szลฑrรฉse", "status.filtered": "Megszลฑrt", "status.hide": "Bejegyzรฉs elrejtรฉse", @@ -669,6 +741,7 @@ "status.reblog": "Megtolรกs", "status.reblog_private": "Megtolรกs az eredeti kรถzรถnsรฉgnek", "status.reblogged_by": "{name} megtolta", + "status.reblogs": "{count, plural, one {megtolรกs} other {megtolรกs}}", "status.reblogs.empty": "Senki sem tolta mรฉg meg ezt a bejegyzรฉst. Ha valaki megteszi, itt fog megjelenni.", "status.redraft": "Tรถrlรฉs รฉs รบjraรญrรกs", "status.remove_bookmark": "Kรถnyvjelzล‘ eltรกvolรญtรกsa", @@ -729,9 +802,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", @@ -741,5 +814,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/hy.json b/app/javascript/mastodon/locales/hy.json index 6ddcfcdb21..cd29f441df 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -123,23 +123,18 @@ "compose_form.spoiler.marked": "ีีฅึ„ีฝีฟีจ ีฉีกึ„ึีธึ‚ีกีฎ ีง ีฆีฃีธึ‚ีทีกึีดีกีถ ีฅีฟีฅึ‚ีธึ‚ีด", "compose_form.spoiler.unmarked": "ีีฅึ„ีฝีฟีจ ีฉีกึ„ึีธึ‚ีกีฎ ีนีง", "confirmation_modal.cancel": "ี‰ีฅีฒีกึ€ีฏีฅีฌ", - "confirmations.block.block_and_report": "ิฑึ€ีฃีฅีฌีกึƒีกีฏีฅีฌ ีฅึ‚ ีขีธีฒีธึ„ีฅีฌ", "confirmations.block.confirm": "ิฑึ€ีฃีฅีฌีกึƒีกีฏีฅีฌ", - "confirmations.block.message": "ีŽีฝีฟีกีžีฐ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ ีกึ€ีฃีฅีฌีกึƒีกีฏีฅีฌ {name}ึŠีซีถึ‰", "confirmations.cancel_follow_request.confirm": "ิฟีกีฝีฅึีถีฅีฌ ีฐีกีตึีจ", "confirmations.delete.confirm": "ี‹ีถีปีฅีฌ", "confirmations.delete.message": "ีŽีฝีฟีกีžีฐ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ ีปีถีปีฅีฌ ีกีตีฝ ีฃึ€ีกีผีธึ‚ีดีจึ‰", "confirmations.delete_list.confirm": "ี‹ีถีปีฅีฌ", "confirmations.delete_list.message": "ีŽีฝีฟีกีžีฐ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ ีดีทีฟีกีบีงีฝ ีปีถีปีฅีฌ ีกีตีฝ ึีกีถีฏีจึ‰", "confirmations.discard_edit_media.confirm": "ี‰ีฅีฒีกึ€ีฏีฅีฌ", - "confirmations.domain_block.confirm": "ินีกึ„ึีถีฅีฌ ีกีดีขีธีฒีป ีฟีซึ€ีธึ‚ีตีฉีจ", "confirmations.domain_block.message": "ี€ีกีฝีฟีกีฟึŠีฐีกีฝีฟีกีžีฟ ีพีฝีฟีกีฐ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ ีกึ€ีฃีฅีฌีกึƒีกีฏีฅีฌ ีกีดีขีธีฒีป {domain} ีฟีซึ€ีธีตีฉีจึ‰ ีีธีพีธึ€ีกีขีกึ€ ีดีซ ีฅึ€ีฏีธึ‚ ีฉีซึ€ีกีญีกึ‚ีธึ€ีธึ‚ีกีฎ ีกึ€ีฃีฅีฌีกึƒีกีฏีธึ‚ีด ีฏีกีด ีฌีผีฅึีธึ‚ีด ีขีกึ‚ีกีฏีกีถ ีง ีธึ‚ ีถีกีญีจีถีฟึ€ีฅีฌีซึ‰", "confirmations.edit.confirm": "ิฝีดีขีกีฃึ€ีฅีฌ", "confirmations.logout.confirm": "ิตีฌึ„", "confirmations.logout.message": "ี€ีกีดีธีฆีธีžึ‚ีกีฎ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ ีคีธึ‚ึ€ีฝ ีฃีกีฌ", "confirmations.mute.confirm": "ิผีผีฅึีถีฅีฌ", - "confirmations.mute.explanation": "ีีก ีฉีกึ„ึีถีฅีฌีธึ‚ ีก ีซึ€ีฅีถึ ีฃึ€ีกีผีธึ‚ีดีถีฅึ€ีถ, ีซีถีนีบีงีฝ ีถีกีฅึ‚ ีซึ€ีฅีถึ ีถีทีธีฒ ีฃึ€ีกีผีธึ‚ีดีถีฅึ€ีถ, ีขีกีตึ ีซึ€ีฅีถึ„ ีดีซีฅึ‚ีถีธีตีถ ีง ีฏีจ ีฏีกึ€ีธีฒีกีถีกีถ ีฐีฅีฟีฅึ‚ีฅีฌ ีฑีฅีฆ ีฅึ‚ ีฟีฅีฝีถีฅีฌ ีฑีฅึ€ ีฃึ€ีกีผีธึ‚ีดีถีฅึ€ีจึ‰", - "confirmations.mute.message": "ีŽีฝีฟีกีžีฐ ีฅีฝ, ีธึ€ ีธึ‚ีฆีธึ‚ีด ีฅีฝ {name}ึŠีซีถ ีฌีผีฅึีถีฅีฌึ‰", "confirmations.redraft.confirm": "ี‹ีถีปีฅีฌ ีฅึ‚ ีญีดีขีกีฃึ€ีฅีฌ ีถีธึ€ีซึ", "confirmations.reply.confirm": "ีŠีกีฟีกีฝีญีกีถีฅีฌ", "confirmations.reply.message": "ิฑีตีฝ ีบีกีฐีซีถ ีบีกีฟีกีฝีญีกีถีฅีฌีจ ีฏีจ ีนีฅีฒีกึ€ีฏีซ ีฑีฅึ€ี ีกีตีฝ ีบีกีฐีซีถ ีกีถีกึ‚ีกึ€ีฟ ีฐีกีฒีธึ€ีคีกีฃึ€ีธึ‚ีฉีซึ‚ีถีจึ‰ ี€ีกีดีธีฆีธึ‚ีกีžีฎ ีงึ„ึ‰", @@ -235,7 +230,6 @@ "hashtag.column_settings.tag_toggle": "ี†ีฅึ€ีกีผีฅีฌ ีฌึ€ีกึีธึ‚ึีซีน ีบีซีฟีกีฏีถีฅึ€ีจ ีกีตีฝ ีฝีซึ‚ีถีกีฏีธึ‚ีด ", "hashtag.follow": "ี€ีฅีฟีฅึ‚ีฅีฌ ีบีซีฟีกีฏีซีถ", "hashtag.unfollow": "ี‰ีฐีฅีฟีฅึ‚ีฅีฌ ีบีซีฟีกีฏีซีถ", - "home.column_settings.basic": "ี€ีซีดีถีกีฏีกีถ", "home.column_settings.show_reblogs": "ี‘ีธึ‚ึีกีคึ€ีฅีฌ ีฟีกึ€ีกีฎีกีฎีถีฅึ€ีจ", "home.column_settings.show_replies": "ี‘ีธึ‚ึีกีคึ€ีฅีฌ ีบีกีฟีกีฝีญีกีถีถีฅึ€ีจ", "home.hide_announcements": "ินีกึ„ึีถีฅีฌ ีตีกีตีฟีกึ€ีกึ€ีธึ‚ีฉีซึ‚ีถีถีฅึ€ีจ", @@ -303,9 +297,6 @@ "lists.subheading": "ี”ีธ ึีกีถีฏีฅึ€ีจ", "load_pending": "{count, plural, one {# ีถีธึ€ ีถีซึ‚ีฉ} other {# ีถีธึ€ ีถีซึ‚ีฉ}}", "media_gallery.toggle_visible": "ี‘ีธึ‚ึีกีคึ€ีฅีฌ/ีฉีกึ„ึีถีฅีฌ", - "mute_modal.duration": "ีีฅึ‚ีธีฒีธึ‚ีฉีซึ‚ีถ", - "mute_modal.hide_notifications": "ินีกึ„ึีถีฅีžีฌ ีฎีกีถีธึ‚ึีธึ‚ีดีถีฅึ€ีถ ีกีตีฝ ึ…ีฃีฟีกีฟีซึ€ีธีปีซึึ‰", - "mute_modal.indefinite": "ิฑีถีชีกีดีฏีงีฟ", "navigation_bar.about": "ี„ีกีฝีซีถ", "navigation_bar.blocks": "ิฑึ€ีฃีฅีฌีกึƒีกีฏีธึ‚ีกีฎ ึ…ีฃีฟีกีฟีงึ€ีฅึ€", "navigation_bar.bookmarks": "ิทีปีกีถีซีทีฅึ€", @@ -345,9 +336,6 @@ "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.filter_bar.show_bar": "ี‘ีธีตึ ีฟีกีฌ ีฆีฟีดีกีถ ีบีกีถีฅีฌีจ", "notifications.column_settings.follow": "ี†ีธึ€ ีฐีฅีฟีฅึ‚ีธีฒีถีฅึ€ี", "notifications.column_settings.follow_request": "ี†ีธึ€ ีฐีฅีฟีฅึ‚ีฅีฌีธึ‚ ีฐีกีตึีฅึ€:", "notifications.column_settings.mention": "ี†ีทีธึ‚ีดีถีฅึ€ี", @@ -453,8 +441,6 @@ "search_results.title": "ีˆึ€ีธีถีฅีฌ {q}-ีถ", "server_banner.active_users": "ีกีฏีฟีซึ‚ ีดีกึ€ีคีซีฏ", "server_banner.administered_by": "ิฟีกีผีกึ‚ีกึ€ีธีฒ", - "server_banner.introduction": "{domain}-ีจ ีฐีกีถีคีซีกีฝีถีธึ‚ีด ีง ีกีบีกีฏีฅีถีฟึ€ีธีถ ีฝีธึ. ึีกีถึีซ ีดีกีฝ, ีฝีฟีฅีฒีฎีธึ‚ีกีฎ {mastodon}-ีธีพึ‰\n", - "server_banner.learn_more": "ิปีดีกีถีกีฌ ีกึ‚ีฅีฌีซีถ", "server_banner.server_stats": "ีีฅึ€ีธึ‚ีฅึ€ีซ ีพีซีณีกีฏีจ", "sign_in_banner.create_account": "ีีฟีฅีฒีฎีฅีฌ ีฐีกีทีซึ‚", "sign_in_banner.sign_in": "ี„ีธึ‚ีฟึ„", @@ -471,7 +457,6 @@ "status.direct": "ี„ีกีฝีถีกึ‚ีธึ€ ีตีซีทีกีฟีกีฏีธึ‚ีด @{name}", "status.direct_indicator": "ี„ีกีฝีถีกึ‚ีธึ€ ีตีซีทีกีฟีกีฏีธึ‚ีด", "status.edit": "ิฝีดีขีกีฃึ€ีฅีฌ", - "status.edited": "ิฝีดีขีกีฃึ€ีธึ‚ีฅีฌ ีงี {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "ี†ีฅึ€ีคีถีฅีฌ", "status.favourite": "ี€ีกีพีกีถีฅีฌ", diff --git a/app/javascript/mastodon/locales/ia.json b/app/javascript/mastodon/locales/ia.json index 0796662851..53cc938592 100644 --- a/app/javascript/mastodon/locales/ia.json +++ b/app/javascript/mastodon/locales/ia.json @@ -3,56 +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 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 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.browse_more_on_origin_server": "Explorar 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": "Reportar @{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}", @@ -63,58 +73,93 @@ "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", + "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 sur {domain} non es actualmente 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", "column.direct": "Mentiones private", "column.directory": "Navigar profilos", "column.domain_blocks": "Dominios blocate", - "column.favourites": "Favoritos", - "column.firehose": "Fluxos in directe", + "column.favourites": "Favorites", + "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", @@ -123,24 +168,28 @@ "compose_form.spoiler.unmarked": "Adder advertimento de contento", "compose_form.spoiler_placeholder": "Advertimento de contento (optional)", "confirmation_modal.cancel": "Cancellar", - "confirmations.block.block_and_report": "Blocar e signalar", "confirmations.block.confirm": "Blocar", - "confirmations.block.message": "Es tu secur que tu vole blocar {name}?", "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.domain_block.confirm": "Blocar le dominio complete", + "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.mute.message": "Es tu secur que tu vole silentiar {name}?", + "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,8 +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.dismiss": "Dimitter", - "embed.preview": "Hic es como il parera:", + "dismissable_banner.community_timeline": "Ecce le messages public le plus recente del personas con contos sur {domain}.", + "dismissable_banner.dismiss": "Clauder", + "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": "Necuno de iste servitor pote sequer te.", + "domain_block_modal.they_wont_know": "Ille non sapera que ille ha essite blocate.", + "domain_block_modal.title": "Blocar dominio?", + "domain_block_modal.you_will_lose_followers": "Tote tu sequitores de iste servitor essera removite.", + "domain_block_modal.you_wont_see_posts": "Tu non videra messages e notificationes de usatores sur iste servitor.", + "domain_pill.activitypub_lets_connect": "Illo te permitte connecter e interager con personas non solmente sur Mastodon, ma tamben sur altere applicationes social.", + "domain_pill.activitypub_like_language": "ActivityPub es como le linguage commun que Mastodon parla con altere retes social.", + "domain_pill.server": "Servitor", + "domain_pill.their_handle": "Su pseudonymo:", + "domain_pill.their_server": "Su casa digital, ubi vive tote su messages.", + "domain_pill.their_username": "Su identificator unic sur su servitor. Es possibile trovar usatores con le mesme nomine de usator sur servitores differente.", + "domain_pill.username": "Nomine de usator", + "domain_pill.whats_in_a_handle": "Que significa un pseudonymo?", + "domain_pill.who_they_are": "Un pseudonymo indica qui un persona es e ubi se trova, de maniera que tu pote interager con personas sur tote le rete social de .", + "domain_pill.who_you_are": "Perque tu pseudonymo indica qui tu es e ubi tu te trova, le gente pote interager con te desde tote le rete social de .", + "domain_pill.your_handle": "Tu pseudonymo:", + "domain_pill.your_server": "Tu casa digital, ubi vive tote tu messages. Non te place? Cambia de servitor a omne momento e porta tu sequitores con te.", + "domain_pill.your_username": "Tu identificator unic sur iste servitor. Es possibile trovar usatores con le mesme nomine de usator sur servitores differente.", + "embed.instructions": "Incorpora iste message sur tu sito web con le codice sequente.", + "embed.preview": "Ecce como illlo parera:", "emoji_button.activity": "Activitate", "emoji_button.clear": "Rader", "emoji_button.custom": "Personalisate", @@ -163,48 +239,93 @@ "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.", - "errors.unexpected_crash.report_issue": "Signalar un defecto", + "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": "Reportar problema", "explore.search_results": "Resultatos de recerca", "explore.suggested_follows": "Personas", "explore.title": "Explorar", "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_suggestions.curated_suggestion": "Selection del editores", - "follow_suggestions.dismiss": "Non monstrar novemente", + "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 de novo", + "follow_suggestions.featured_longer": "Seligite con cura per le equipa de {domain}", + "follow_suggestions.friends_of_friends_longer": "Popular inter le gente que tu seque", + "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.popular_suggestion_longer": "Popular sur {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Similar al profilos que tu ha sequite recentemente", "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", "footer.source_code": "Vider le codice fonte", @@ -216,181 +337,477 @@ "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 autor", "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 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 ha essite celate per le moderatores de {domain}.", "link_preview.author": "Per {name}", + "link_preview.more_from_author": "Plus de {name}", + "link_preview.shares": "{count, plural, one {{counter} message} other {{counter} messages}}", "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}}", - "mute_modal.duration": "Duration", - "mute_modal.hide_notifications": "Celar notificationes de iste usator?", - "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 in 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": "Ille pote mentionar te e sequer te, ma tu non potera vider le.", + "mute_modal.they_wont_know": "Ille non sapera que ille 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", + "navigation_bar.compose": "Componer un nove message", "navigation_bar.direct": "Mentiones private", "navigation_bar.discover": "Discoperir", "navigation_bar.domain_blocks": "Dominios blocate", - "navigation_bar.favourites": "Favoritos", + "navigation_bar.explore": "Explorar", + "navigation_bar.favourites": "Favorites", "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.logout": "Clauder 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 reportate {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.moderation-warning.learn_more": "Apprender plus", + "notification.moderation_warning": "Tu ha recipite un advertimento de moderation", + "notification.moderation_warning.action_delete_statuses": "Alcunes de tu messages ha essite removite.", + "notification.moderation_warning.action_disable": "Tu conto ha essite disactivate.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Alcunes de tu messages ha essite marcate como sensibile.", + "notification.moderation_warning.action_none": "Tu conto ha recipite un advertimento de moderation.", + "notification.moderation_warning.action_sensitive": "Tu messages essera marcate como sensibile a partir de ora.", + "notification.moderation_warning.action_silence": "Tu conto ha essite limitate.", + "notification.moderation_warning.action_suspend": "Tu conto ha essite suspendite.", + "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": "Clauder", + "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 reportos:", + "notifications.column_settings.admin.sign_up": "Nove inscriptiones:", "notifications.column_settings.alert": "Notificationes de scriptorio", - "notifications.column_settings.favourite": "Favoritos:", + "notifications.column_settings.favourite": "Favorites:", "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.favourites": "Favoritos", + "notifications.filter.boosts": "Impulsos", + "notifications.filter.favourites": "Favorites", + "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": "Sondage", "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 reporto 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": "Reportage 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 reportar, 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 post aperir 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.learn_more": "Apprender plus", + "server_banner.administered_by": "Administrate per:", + "server_banner.is_one_of_many": "{domain} es un de multe servitores independente de Mastodon que tu pote usar pro participar in le fediverso.", "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.mastodon_is": "Mastodon es le melior maniera de sequer lo que passa.", + "sign_in_banner.sign_in": "Aperir session", + "sign_in_banner.sso_redirect": "Aperir session o crear conto", + "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": "Modificate le {date}", - "status.edited_x_times": "Modificate {count, plural, one {{count} tempore} other {{count} tempores}}", - "status.favourite": "Adder al favoritos", + "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 favorites", + "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": "Reportar @{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.translated_from_with": "Traducite de {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 multimedia", + "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 88e99a7086..d86b5854f4 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,15 +154,21 @@ "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.block_and_report": "Blokir & Laporkan", "confirmations.block.confirm": "Blokir", - "confirmations.block.message": "Apa Anda yakin ingin memblokir {name}?", "confirmations.cancel_follow_request.confirm": "Batalkan permintaan", "confirmations.cancel_follow_request.message": "Apakah Anda yakin ingin membatalkan permintaan Anda untuk mengikuti {name}?", "confirmations.delete.confirm": "Hapus", @@ -151,15 +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": "Sembunyikan keseluruhan domain", + "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.mute.explanation": "Ini akan menyembunyikan pos dari mereka dan pos yang menyebut mereka, tapi ini tetap mengizinkan mereka melihat posmu dan mengikutimu.", - "confirmations.mute.message": "Apa Anda yakin ingin membisukan {name}?", "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", @@ -168,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", @@ -179,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", @@ -248,6 +295,15 @@ "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.", + "follow_suggestions.personalized_suggestion": "Saran yang dipersonalisasi", + "follow_suggestions.popular_suggestion": "Saran populer", + "follow_suggestions.popular_suggestion_longer": "Populer di {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Serupa dengan profil yang baru Anda ikuti", + "follow_suggestions.view_all": "Lihat semua", "followed_tags": "Tagar yang diikuti", "footer.about": "Tentang", "footer.directory": "Direktori profil", @@ -270,10 +326,10 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "Ikuti tagar", "hashtag.unfollow": "Batalkan pengikutan tagar", - "home.column_settings.basic": "Dasar", "home.column_settings.show_reblogs": "Tampilkan boost", "home.column_settings.show_replies": "Tampilkan balasan", "home.hide_announcements": "Sembunyikan pengumuman", + "home.pending_critical_update.link": "Lihat pembaruan", "home.show_announcements": "Tampilkan pengumuman", "interaction_modal.description.follow": "Dengan sebuah akun di Mastodon, Anda bisa mengikuti {name} untuk menerima kirimannya di beranda Anda.", "interaction_modal.description.reblog": "Dengan sebuah akun di Mastodon, Anda bisa mem-boost kiriman ini untuk membagikannya ke pengikut Anda sendiri.", @@ -325,6 +381,7 @@ "lightbox.previous": "Sebelumnya", "limited_account_hint.action": "Tetap tampilkan profil", "limited_account_hint.title": "Profil ini telah disembunyikan oleh moderator {domain}.", + "link_preview.author": "Oleh {name}", "lists.account.add": "Tambah ke daftar", "lists.account.remove": "Hapus dari daftar", "lists.delete": "Hapus daftar", @@ -339,11 +396,11 @@ "lists.search": "Cari di antara orang yang Anda ikuti", "lists.subheading": "Daftar Anda", "load_pending": "{count, plural, other {# item baru}}", + "loading_indicator.label": "Memuatโ€ฆ", "media_gallery.toggle_visible": "Tampil/Sembunyikan", "moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.", - "mute_modal.duration": "Durasi", - "mute_modal.hide_notifications": "Sembunyikan notifikasi dari pengguna ini?", - "mute_modal.indefinite": "Tak terbatas", + "mute_modal.hide_options": "Sembunyikan opsi", + "mute_modal.title": "Bisukan pengguna?", "navigation_bar.about": "Tentang", "navigation_bar.blocks": "Pengguna diblokir", "navigation_bar.bookmarks": "Markah", @@ -381,9 +438,6 @@ "notifications.column_settings.admin.report": "Laporan baru:", "notifications.column_settings.admin.sign_up": "Pendaftaran baru:", "notifications.column_settings.alert": "Notifikasi desktop", - "notifications.column_settings.filter_bar.advanced": "Tampilkan semua kategori", - "notifications.column_settings.filter_bar.category": "Bilah penyaring cepat", - "notifications.column_settings.filter_bar.show_bar": "Tampilkan bilah filter", "notifications.column_settings.follow": "Pengikut baru:", "notifications.column_settings.follow_request": "Permintaan mengikuti baru:", "notifications.column_settings.mention": "Balasan:", @@ -511,8 +565,6 @@ "server_banner.about_active_users": "Orang menggunakan server ini selama 30 hari terakhir (Pengguna Aktif Bulanan)", "server_banner.active_users": "pengguna aktif", "server_banner.administered_by": "Dikelola oleh:", - "server_banner.introduction": "{domain} adalah bagian dari jaringan sosial terdesentralisasi yang diberdayakan oleh {mastodon}.", - "server_banner.learn_more": "Pelajari lebih lanjut", "server_banner.server_stats": "Statistik server:", "sign_in_banner.create_account": "Buat akun", "sign_in_banner.sign_in": "Masuk", @@ -527,7 +579,6 @@ "status.delete": "Hapus", "status.detailed_status": "Tampilan detail percakapan", "status.edit": "Edit", - "status.edited": "Diedit {date}", "status.edited_x_times": "Diedit {count, plural, other {{count} kali}}", "status.embed": "Tanam", "status.filter": "Saring kiriman ini", diff --git a/app/javascript/mastodon/locales/ie.json b/app/javascript/mastodon/locales/ie.json index 0c21832ed6..f15b982889 100644 --- a/app/javascript/mastodon/locales/ie.json +++ b/app/javascript/mastodon/locales/ie.json @@ -89,6 +89,14 @@ "announcement.announcement": "Proclamation", "attachments_list.unprocessed": "(รญntractat)", "audio.hide": "Celar audio", + "block_modal.remote_users_caveat": "Noi va petir que li servitor {domain} mey respecter tui decision. Tรกmen, obedientie ne es garantit pro que chascun servitor gere bloccas diferentmen. Possibilmen public postas va restar visibil a usatores de inloggat.", + "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", "bundle_column_error.copy_stacktrace": "Copiar erra-raporte", "bundle_column_error.error.body": "Li demandat pรกgine ne posset esser rendit. Fรณrsan it es un problema in nor code, o un problema de compatibilitรก con li navigator.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Adjunter avise pri li contenete", "compose_form.spoiler_placeholder": "Advertiment de contenete (optional)", "confirmation_modal.cancel": "Anullar", - "confirmations.block.block_and_report": "Bloccar & Raportar", "confirmations.block.confirm": "Bloccar", - "confirmations.block.message": "Esque tu vermen vole bloccar {name}?", "confirmations.cancel_follow_request.confirm": "Retraer petition", "confirmations.cancel_follow_request.message": "Esque tu vermen vole retraer tui petition sequer {name}?", "confirmations.delete.confirm": "Deleter", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Esque tu vermen vole permanentmen deleter ti-ci liste?", "confirmations.discard_edit_media.confirm": "Forjettar", "confirmations.discard_edit_media.message": "Tu have รญnconservat changes al descrition de medie o al previse, forjettar les sin egarda?", - "confirmations.domain_block.confirm": "Bloccar li tot dominia", + "confirmations.domain_block.confirm": "Bloccar servitor", "confirmations.domain_block.message": "Esque tu es certissim que tu vole bloccar li tot {domain}? In mult casus, bloccar o silentiar quelc specific contos es suficent e preferibil. Tu ne va vider contenete de ti dominia in quelcunc public tรฉmpor-linea o in tui notificationes. Tui sequitores de ti dominia va esser removet.", "confirmations.edit.confirm": "Redacter", "confirmations.edit.message": "Redacter nu va remplazzar li missage quel tu actualmen composi. Esque tu vermen vole proceder?", "confirmations.logout.confirm": "Exear", "confirmations.logout.message": "Esque tu vermen vole exear?", "confirmations.mute.confirm": "Silentiar", - "confirmations.mute.explanation": "To-ci va celar postas de ilu e postas mentionant ilu, ma it ancor va permisser ilu vider tui postas e sequer te.", - "confirmations.mute.message": "Esque tu vermen vole silentiar {name}?", "confirmations.redraft.confirm": "Deleter & redacter", "confirmations.redraft.message": "Esque tu vermen vole deleter ti-ci posta e redacter it? Favorites e boosts va esser perdit, e responses al posta original va esser orfanat.", "confirmations.reply.confirm": "Responder", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Tis-ci es postas del social retage queles es popular hodie. Nov postas con plu mult boosts e favorites es monstrat plu alt.", "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_block_modal.they_wont_know": "Ne va esser conscient pri li bloccada.", + "domain_block_modal.title": "Bloccar dominia?", + "domain_block_modal.you_will_lose_followers": "Omni tui sequitores de ti-ci servitor va esser efaciat.", + "domain_block_modal.you_wont_see_posts": "Tu ne va vider postas ni notificationes de usatores sur ti-ci servitor.", + "domain_pill.activitypub_lets_connect": "It possibilisa tui conexiones e interactiones con persones ne solmen sur Mastodon, ma anc tra diferent social aplis.", + "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.their_username": "Su unic identificator sur su servitor. It es possibil que altri servitores va haver usatores con li sam nรณmine.", + "domain_pill.username": "Usator-nรณmine", + "domain_pill.whats_in_a_handle": "Ex quo consiste un identificator?", + "domain_pill.who_they_are": "Pro que identificatores informa qui e u un person is, tu posse interacter con persones tra li rete social de .", + "domain_pill.who_you_are": "Pro que tui identificator informa qui e u tu es, persones posse interacter con te tra li rete social de .", + "domain_pill.your_handle": "Tui identificator:", + "domain_pill.your_server": "Tui digital hem, u trova se omni tui postas. Si it ne plese te, tu posse transferer ad un altri servitor quandecunc e tui sequitores con te.", + "domain_pill.your_username": "Tui unic identificator sur ti-ci servitor. It es possibil que altri servitores va haver usatores con li sam nรณmine.", "embed.instructions": "Inbedar ti-ci posta per copiar li code in infra.", "embed.preview": "Vi qualmen it va aspecter:", "emoji_button.activity": "Activitรก", @@ -241,6 +266,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.", @@ -271,16 +297,28 @@ "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.mentions": "{count, plural, one {mention} other {mentiones}}", + "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", "follow_request.authorize": "Autorisar", "follow_request.reject": "Rejecter", "follow_requests.unlocked_explanation": "Benque tu conto ne es cludet, li administratores de {domain} pensat que tu fรณrsan vell voler tractar seque-petitiones de tis-ci contos manualmen.", - "follow_suggestions.curated_suggestion": "Selection del Servitor", + "follow_suggestions.curated_suggestion": "Selection del employates", "follow_suggestions.dismiss": "Ne monstrar plu", + "follow_suggestions.featured_longer": "Selectet manualmen del equip de {domain}", + "follow_suggestions.friends_of_friends_longer": "Populari รญnter li persones queles tu seque", + "follow_suggestions.hints.featured": "Ti-ci profil ha esset selectet directmen del equip de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Ti-ci profil es populari รญnter tis qui tu seque.", + "follow_suggestions.hints.most_followed": "Ti-ci profil es un del max sequet sur {domain}.", + "follow_suggestions.hints.most_interactions": "Ti-ci profil ha recivet mult atention recentmen sur {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Ti-ci profil es simil al profiles queles tu ha recentmen sequet.", "follow_suggestions.personalized_suggestion": "Personalisat suggestion", "follow_suggestions.popular_suggestion": "Populari suggestion", + "follow_suggestions.popular_suggestion_longer": "Populari sur {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Simil a profiles queles tu sequet recentmen", "follow_suggestions.view_all": "Vider omnicos", "follow_suggestions.who_to_follow": "Persones a sequer", "followed_tags": "Sequet hashtags", @@ -309,7 +347,6 @@ "hashtag.follow": "Sequer hashtag", "hashtag.unfollow": "Dessequer hashtag", "hashtags.and_other": "โ€ฆe {count, plural, other {# in plu}}", - "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Monstrar boosts", "home.column_settings.show_replies": "Monstrar responses", "home.hide_announcements": "Celar proclamationes", @@ -395,9 +432,15 @@ "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.duration": "Duration", - "mute_modal.hide_notifications": "Celar notificationes de ti-ci usator?", - "mute_modal.indefinite": "รndefinit", + "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?", + "mute_modal.you_wont_see_mentions": "Tu ne va vider postas mentionant li usator.", + "mute_modal.you_wont_see_posts": "Ne posse vider tui postas e inversi.", "navigation_bar.about": "Information", "navigation_bar.advanced_interface": "Aperter in li web-interfacie avansat", "navigation_bar.blocks": "Bloccat usatores", @@ -430,11 +473,29 @@ "notification.follow": "{name} sequet te", "notification.follow_request": "{name} ha petit sequer te", "notification.mention": "{name} mentionat te", + "notification.moderation-warning.learn_more": "Aprender plu", + "notification.moderation_warning": "Tu ha recivet un moderatori advertiment", + "notification.moderation_warning.action_delete_statuses": "Alcun de tui postas ha esset efaciat.", + "notification.moderation_warning.action_disable": "Tui conto ha esset desactivisat.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Alcun de tui postas ha esset marcat quam sensitiv.", + "notification.moderation_warning.action_none": "Tui conto ha recivet un moderatori advertiment.", + "notification.moderation_warning.action_sensitive": "Desde nu tui postas va esser marcat quam sensitiv.", + "notification.moderation_warning.action_silence": "Tui conto ha esset limitat.", + "notification.moderation_warning.action_suspend": "Tui conto ha esset suspendet.", "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": "Perdit conexiones con {name}", + "notification.relationships_severance_event.account_suspension": "Un admin de {from} ha suspendet {target}, dunc con ti person tu ne plu posse reciver actualisationes ni far interactiones.", + "notification.relationships_severance_event.domain_block": "Un admin de {from} ha bloccat {target}, includente {followersCount} de tui sequitores e {followingCount, plural, one {# conto} other {# contos}} sequet de te.", + "notification.relationships_severance_event.learn_more": "Aprender plu", + "notification.relationships_severance_event.user_domain_block": "Tu ha bloccat {target}, efaciante {followersCount} de tui sequitores e {followingCount, plural, one {# conto} other {# contos}} sequet de te.", "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:", @@ -443,7 +504,6 @@ "notifications.column_settings.favourite": "Favorites:", "notifications.column_settings.filter_bar.advanced": "Monstrar omni categories", "notifications.column_settings.filter_bar.category": "Rapid filtre-barre", - "notifications.column_settings.filter_bar.show_bar": "Monstrar filtre-barre", "notifications.column_settings.follow": "Nov sequitores:", "notifications.column_settings.follow_request": "Nov petitiones de sequer:", "notifications.column_settings.mention": "Mentiones:", @@ -469,6 +529,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", @@ -625,13 +694,10 @@ "server_banner.about_active_users": "Gente usant ti-ci servitor durant li ultim 30 dies (Mensual Activ Usatores)", "server_banner.active_users": "activ usatores", "server_banner.administered_by": "Administrat de:", - "server_banner.introduction": "{domain} es un part del decentralisat social retage constructet sur {mastodon}.", - "server_banner.learn_more": "Aprender plu", "server_banner.server_stats": "Statisticas pri li servitor:", "sign_in_banner.create_account": "Crear un conto", "sign_in_banner.sign_in": "Intrar", "sign_in_banner.sso_redirect": "Intrar o registrar se", - "sign_in_banner.text": "Intrar por sequer profiles o hashtags, favoritisar, partir e responder a postas. Tu posse anc interacter per tui conto che un diferent servitor.", "status.admin_account": "Aperter interfacie de moderation por @{name}", "status.admin_domain": "Aperter interfacie de moderation por {domain}", "status.admin_status": "Aperter ti-ci posta in li interfacie de moderation", @@ -645,10 +711,11 @@ "status.direct": "Privatmen mentionar @{name}", "status.direct_indicator": "Privat mention", "status.edit": "Modificar", - "status.edited": "Modificat ye {date}", + "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", @@ -669,6 +736,7 @@ "status.reblog": "Boostar", "status.reblog_private": "Boostar con li original visibilitรก", "status.reblogged_by": "{name} boostat", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "Ancor nequi ha boostat ti-ci posta. Quande alqui fa it, ilu va aparir ci.", "status.redraft": "Deleter & redacter", "status.remove_bookmark": "Remover marcator", diff --git a/app/javascript/mastodon/locales/ig.json b/app/javascript/mastodon/locales/ig.json index a4f7268422..4e3e3997da 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", @@ -37,23 +38,33 @@ "confirmations.delete.confirm": "Hichapแปฅ", "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "Hichapแปฅ", - "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.edit.confirm": "Dezie", "confirmations.mute.confirm": "Mee ogbi", "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", @@ -121,7 +132,6 @@ "report_notification.categories.other": "แปŒzแป", "search.placeholder": "Chแปแป", "server_banner.active_users": "ojiarแปฅ dแป‹ รฌrรจ", - "server_banner.learn_more": "Mแปฅtakwuo", "sign_in_banner.sign_in": "Sign in", "status.admin_status": "Open this status in the moderation interface", "status.bookmark": "Kee ebenrแปฅtแปฅakฤ", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index c468f689ab..016a111c46 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -149,9 +149,7 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmation_modal.cancel": "Anulez", - "confirmations.block.block_and_report": "Restriktez e Raportizez", "confirmations.block.confirm": "Restriktez", - "confirmations.block.message": "Ka vu certe volas restrikar {name}?", "confirmations.cancel_follow_request.confirm": "Desendez demando", "confirmations.cancel_follow_request.message": "Ka vu certe volas desendar vua demando di sequar {name}?", "confirmations.delete.confirm": "Efacez", @@ -160,15 +158,12 @@ "confirmations.delete_list.message": "Ka vu certe volas netempale efacar ca listo?", "confirmations.discard_edit_media.confirm": "Efacez", "confirmations.discard_edit_media.message": "Vu havas nesparita chanji di mediodeskript o prevido, vu volas jus efacar?", - "confirmations.domain_block.confirm": "Hide entire domain", "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.", "confirmations.edit.confirm": "Modifikez", "confirmations.edit.message": "Modifikar nun remplasos la mesajo quon vu nune skribas. Ka vu certe volas procedar?", "confirmations.logout.confirm": "Ekirez", "confirmations.logout.message": "Ka tu certe volas ekirar?", "confirmations.mute.confirm": "Silencigez", - "confirmations.mute.explanation": "Co celigos posti de oli e posti quo mencionas oli, ma ol ankore permisas oli vidar vua posti e sequar vu.", - "confirmations.mute.message": "Ka vu certe volas silencigar {name}?", "confirmations.redraft.confirm": "Efacez e riskisez", "confirmations.redraft.message": "Ka vu certe volas efacar ca posto e riskisigar ol? Favoriziti e repeti esos perdita, e respondi al posto originala esos orfanigita.", "confirmations.reply.confirm": "Respondez", @@ -292,7 +287,6 @@ "hashtag.follow": "Sequez hashtago", "hashtag.unfollow": "Desequez hashtago", "hashtags.and_other": "โ€ฆe {count, plural, one {# plusa}other {# plusa}}", - "home.column_settings.basic": "Simpla", "home.column_settings.show_reblogs": "Montrar repeti", "home.column_settings.show_replies": "Montrar respondi", "home.hide_announcements": "Celez anunci", @@ -378,9 +372,6 @@ "loading_indicator.label": "Karganteโ€ฆ", "media_gallery.toggle_visible": "Chanjar videbleso", "moved_to_account_banner.text": "Vua konto {disabledAccount} es nune desaktiva pro ke vu movis a {movedToAccount}.", - "mute_modal.duration": "Durado", - "mute_modal.hide_notifications": "Celez avizi de ca uzanto?", - "mute_modal.indefinite": "Nedefinitiva", "navigation_bar.about": "Pri co", "navigation_bar.advanced_interface": "Apertez per retintervizajo", "navigation_bar.blocks": "Blokusita uzeri", @@ -424,9 +415,6 @@ "notifications.column_settings.admin.sign_up": "Nova registranti:", "notifications.column_settings.alert": "Desktopavizi", "notifications.column_settings.favourite": "Favoriziti:", - "notifications.column_settings.filter_bar.advanced": "Montrez omna kategorii", - "notifications.column_settings.filter_bar.category": "Rapidfiltrobaro", - "notifications.column_settings.filter_bar.show_bar": "Montrez filtrobaro", "notifications.column_settings.follow": "Nova sequanti:", "notifications.column_settings.follow_request": "Nova sequodemandi:", "notifications.column_settings.mention": "Mencioni:", @@ -594,13 +582,10 @@ "server_banner.about_active_users": "Personi quo uzas ca servilo dum antea 30 dii (monate aktiva uzanti)", "server_banner.active_users": "aktiva uzanti", "server_banner.administered_by": "Administresis da:", - "server_banner.introduction": "{domain} esas parto di necentraligita sociala ret quo povizesas da {mastodon}.", - "server_banner.learn_more": "Lernez plue", "server_banner.server_stats": "Servilstatistiko:", "sign_in_banner.create_account": "Kreez konto", "sign_in_banner.sign_in": "Enirez", "sign_in_banner.sso_redirect": "Enirar o krear konto", - "sign_in_banner.text": "Enirez por sequar profili o hashtagi, favorizar, partigar e respondizar posti. On povas anke interagar de vua konto kun diferanta servilo.", "status.admin_account": "Apertez jerintervizajo por @{name}", "status.admin_domain": "Apertez jerintervizajo por {domain}", "status.admin_status": "Open this status in the moderation interface", @@ -614,7 +599,6 @@ "status.direct": "Private mencionez @{name}", "status.direct_indicator": "Privata menciono", "status.edit": "Modifikez", - "status.edited": "Modifikesis ye {date}", "status.edited_x_times": "Modifikesis {count, plural, one {{count} foyo} other {{count} foyi}}", "status.embed": "Eninsertez", "status.favourite": "Favorizar", diff --git a/app/javascript/mastodon/locales/is.json b/app/javascript/mastodon/locales/is.json index 3c2337efd2..08605f5238 100644 --- a/app/javascript/mastodon/locales/is.json +++ b/app/javascript/mastodon/locales/is.json @@ -89,6 +89,14 @@ "announcement.announcement": "Auglรฝsing", "attachments_list.unprocessed": "(รณunniรฐ)", "audio.hide": "Fela hljรณรฐ", + "block_modal.remote_users_caveat": "Viรฐ munum biรฐja {domain} netรพjรณninn um aรฐ virรฐa รกkvรถrรฐun รพรญna. Hitt er svo annaรฐ mรกl hvort hann fari eftir รพessu, ekki er hรฆgt aรฐ tryggja eftirfylgni รพvรญ sumir netรพjรณnar meรฐhรถndla รบtilokanir รก sinn hรกtt. Opinberar fรฆrslur gรฆtu veriรฐ sรฝnilegar notendum sem ekki eru skrรกรฐir inn.", + "block_modal.show_less": "Sรฝna minna", + "block_modal.show_more": "Sรฝna meira", + "block_modal.they_cant_mention": "Viรฐkomandi geta ekki minnst รก รพig eรฐa fylgst meรฐ รพรฉr.", + "block_modal.they_cant_see_posts": "Viรฐkomandi geta ekki sรฉรฐ fรฆrslurnar รพรญnar og รพรบ ekki รพeirra.", + "block_modal.they_will_know": "Viรฐkomandi geta sรฉรฐ aรฐ รพeir eru รบtilokaรฐir.", + "block_modal.title": "รštiloka notanda?", + "block_modal.you_wont_see_mentions": "รžรบ munt ekki sjรก fรฆrslur sem minnast รก viรฐkomandi aรฐila.", "boost_modal.combo": "รžรบ getur รฝtt รก {combo} til aรฐ sleppa รพessu nรฆst", "bundle_column_error.copy_stacktrace": "Afrita villuskรฝrslu", "bundle_column_error.error.body": "Umbeรฐna sรญรฐau var ekki hรฆgt aรฐ myndgera. รžaรฐ gรฆti veriรฐ vegna villu รญ kรณรฐanum okkar eรฐa vandamรกls meรฐ samhรฆfni vafra.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Bรฆta viรฐ aรฐvรถrun vegna efnis", "compose_form.spoiler_placeholder": "Aรฐvรถrun vegna efnis (valkvรฆtt)", "confirmation_modal.cancel": "Hรฆtta viรฐ", - "confirmations.block.block_and_report": "รštiloka og kรฆra", "confirmations.block.confirm": "รštiloka", - "confirmations.block.message": "Ertu viss um aรฐ รพรบ viljir loka รก {name}?", "confirmations.cancel_follow_request.confirm": "Taka beiรฐni til baka", "confirmations.cancel_follow_request.message": "Ertu viss um aรฐ รพรบ viljir taka til baka beiรฐnina um aรฐ fylgjast meรฐ {name}?", "confirmations.delete.confirm": "Eyรฐa", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Ertu viss um aรฐ รพรบ viljir eyรฐa รพessum lista endanlega?", "confirmations.discard_edit_media.confirm": "Henda", "confirmations.discard_edit_media.message": "รžรบ ert meรฐ รณvistaรฐar breytingar รก lรฝsingu myndefnis eรฐa forskoรฐunar, henda รพeim samt?", - "confirmations.domain_block.confirm": "รštiloka allt lรฉniรฐ", + "confirmations.domain_block.confirm": "รštiloka netรพjรณn", "confirmations.domain_block.message": "Ertu alveg algjรถrlega viss um aรฐ รพรบ viljir loka รก allt {domain}? ร flestum tilfellum er vรฆnlegra aรฐ nota fรฆrri en markvissari รบtilokanir eรฐa aรฐ รพagga niรฐur tiltekna aรฐila. รžรบ munt ekki sjรก efni frรก รพessu lรฉni รญ neinum opinberum tรญmalรญnum eรฐa รญ tilkynningunum รพรญnum. Fylgjendur รพรญnir frรก รพessu lรฉni verรฐa fjarlรฆgรฐir.", "confirmations.edit.confirm": "Breyta", "confirmations.edit.message": "Ef รพรบ breytir nรบna verรฐur skrifaรฐ yfir skilaboรฐin sem รพรบ ert aรฐ semja nรบna. Ertu viss um aรฐ รพรบ viljir halda รกfram?", "confirmations.logout.confirm": "Skrรก รบt", "confirmations.logout.message": "Ertu viss um aรฐ รพรบ viljir skrรก รพig รบt?", "confirmations.mute.confirm": "รžagga", - "confirmations.mute.explanation": "รžetta mun fela fรฆrslur frรก รพeim og รพรฆr fรฆrslur รพar sem minnst er รก รพau, en รพaรฐ mun samt sem รกรฐur gera รพeim kleift aรฐ sjรก fรฆrslurnar รพรญnar og aรฐ fylgjast meรฐ รพรฉr.", - "confirmations.mute.message": "Ertu viss um aรฐ รพรบ viljir รพagga niรฐur รญ {name}?", "confirmations.redraft.confirm": "Eyรฐa og endurvinna drรถg", "confirmations.redraft.message": "Ertu viss um aรฐ รพรบ viljir eyรฐa รพessari fรฆrslu og enduvinna drรถgin? Eftirlรฆti og endurbirtingar munu glatast og svรถr viรฐ upprunalegu fรฆrslunni munu verรฐa munaรฐarlaus.", "confirmations.reply.confirm": "Svara", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "รžessar fรฆrslur frรก รพessum og รถรฐrum netรพjรณnum รก dreifhรฝsta netkerfinu eru aรฐ fรก aukna athygli รญ รพessu tรถluรฐum orรฐum.", "dismissable_banner.explore_tags": "รžetta eru myllumerki sem รญ augnablikinu eru aรฐ fรก aukna athygli hjรก fรณlki รก รพessum og รถรฐrum netรพjรณnum รก dreifhรฝsta netkerfinu.", "dismissable_banner.public_timeline": "รžetta eru nรฝjustu opinberu fรฆrslurnar frรก fรณlki รก samfรฉlagsnetinu sem fรณlk รก {domain} fylgjast meรฐ.", + "domain_block_modal.block": "รštiloka netรพjรณn", + "domain_block_modal.block_account_instead": "รštiloka {name} รญ staรฐinn", + "domain_block_modal.they_can_interact_with_old_posts": "Fรณlk frรก รพessum netรพjรณni getur sรฝslaรฐ meรฐ eldri fรฆrslur รพรญnar.", + "domain_block_modal.they_cant_follow": "Enginn frรก รพessum netรพjรณni getur fylgst meรฐ รพรฉr.", + "domain_block_modal.they_wont_know": "Viรฐkomandi mun ekki vita aรฐ hann hafi veriรฐ รบtilokaรฐur.", + "domain_block_modal.title": "รštiloka lรฉn?", + "domain_block_modal.you_will_lose_followers": "Allir fylgjendur รพรญnir af รพessum netรพjรณni verรฐa fjarlรฆgรฐir.", + "domain_block_modal.you_wont_see_posts": "รžรบ munt ekki sjรก neinar fรฆrslur eรฐa tilkynningar frรก notendum รก รพessum netรพjรณni.", + "domain_pill.activitypub_lets_connect": "รžaรฐ gerir รพรฉr kleift aรฐ tengjast og eiga รญ samskiptum viรฐ fรณlk, ekki bara รก Mastodon, heldur einnig รก mรถrgum รถรฐrum mismunandi samfรฉlagsmiรฐlum.", + "domain_pill.activitypub_like_language": "ActivityPub er eins og tungumรกl sem Mastodon notar til aรฐ tala viรฐ รถnnur samfรฉlagsnet.", + "domain_pill.server": "Netรพjรณnn", + "domain_pill.their_handle": "Kennislรณรฐin รพeirra:", + "domain_pill.their_server": "Stafrรฆnt heimili viรฐkomandi, รพar sem allar fรฆrslur hans eru hรฝstar.", + "domain_pill.their_username": "Sรฉrtรฆkt auรฐkenni viรฐkomandi รก netรพjรณni hans. รžaรฐ er mรถgulegt aรฐ finna notendur meรฐ sama notandanafn รก mismunandi netรพjรณnum.", + "domain_pill.username": "Notandanafn", + "domain_pill.whats_in_a_handle": "Hvaรฐ er รญ kennislรณรฐ (handle)?", + "domain_pill.who_they_are": "Vegna รพess aรฐ kennislรณรฐir segja hver einhver sรฉ og hvar hann sรฉ aรฐ finna, getur รพรบ รกtt รญ samskiptum viรฐ fรณlk รญ gegnum samfรฉlagsvef sem knรบinn er af .", + "domain_pill.who_you_are": "Vegna รพess aรฐ kennislรณรฐin รพรญn segir hver รพรบ sรฉrt og hvar รพig sรฉ aรฐ finna, getur fรณlk รกtt รญ samskiptum viรฐ รพig รญ gegnum samfรฉlagsvef sem knรบinn er af .", + "domain_pill.your_handle": "Kennislรณรฐin รพรญn:", + "domain_pill.your_server": "Stafrรฆnt heimili รพitt, รพar sem allar fรฆrslur รพรญnar eru hรฝstar. Kanntu ekki viรฐ รพennan netรพjรณn? รžรบ getur flutt รพig รก milli netรพjรณna hvenรฆr sem er og tekiรฐ meรฐ รพรฉr alla fylgjendurna รพรญna.", + "domain_pill.your_username": "Sรฉrtรฆkt auรฐkenni รพitt รก รพessum netรพjรณni. รžaรฐ er mรถgulegt aรฐ finna notendur meรฐ sama notandanafn รก mismunandi netรพjรณnum.", "embed.instructions": "Felldu รพessa fรฆrslu inn รญ vefsvรฆรฐiรฐ รพitt meรฐ รพvรญ aรฐ afrita kรณรฐann hรฉr fyrir neรฐan.", "embed.preview": "Svona mun รพetta lรญta รบt:", "emoji_button.activity": "Virkni", @@ -241,6 +266,7 @@ "empty_column.list": "รžaรฐ er ennรพรก ekki neitt รก รพessum lista. รžegar meรฐlimir รก listanum senda inn nรฝjar fรฆrslur, munu รพรฆr birtast hรฉr.", "empty_column.lists": "รžรบ ert ennรพรก ekki meรฐ neina lista. รžegar รพรบ bรฝrรฐ til einhvern lista, munu hann birtast hรฉr.", "empty_column.mutes": "รžรบ hefur ekki รพaggaรฐ niรฐur รญ neinum notendum ennรพรก.", + "empty_column.notification_requests": "Allt hreint! รžaรฐ er ekkert hรฉr. รžegar รพรบ fรฆrรฐ nรฝjar tilkynningar, munu รพรฆr birtast hรฉr รญ samrรฆmi viรฐ stillingarnar รพรญnar.", "empty_column.notifications": "รžรบ ert ekki ennรพรก meรฐ neinar tilkynningar. Vertu รญ samskiptum viรฐ aรฐra til aรฐ umrรฆรฐur fari af staรฐ.", "empty_column.public": "รžaรฐ er ekkert hรฉr! Skrifaรฐu eitthvaรฐ opinberlega, eรฐa fylgstu meรฐ notendum รก รถรฐrum netรพjรณnum til aรฐ fylla upp รญ รพetta", "error.unexpected_crash.explanation": "Vegna villu รญ kรณรฐanum okkar eรฐa samhรฆfnivandamรกla รญ vafra er ekki hรฆgt aรฐ birta รพessa sรญรฐu svo vel sรฉ.", @@ -271,16 +297,28 @@ "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", "firehose.local": "รพessum netรพjรณni", "firehose.remote": "รถรฐrum netรพjรณnum", "follow_request.authorize": "Heimila", "follow_request.reject": "Hafna", "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 umsjรณnarfรณlks", + "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}.", + "follow_suggestions.hints.most_interactions": "รžetta notandasniรฐ hefur vakiรฐ mikla athygli aรฐ undanfรถrnu รก {domain}.", + "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รฐ", @@ -309,7 +347,6 @@ "hashtag.follow": "Fylgjast meรฐ myllumerki", "hashtag.unfollow": "Hรฆtta aรฐ fylgjast meรฐ myllumerki", "hashtags.and_other": "โ€ฆog {count, plural, other {# til viรฐbรณtar}}", - "home.column_settings.basic": "Einfalt", "home.column_settings.show_reblogs": "Sรฝna endurbirtingar", "home.column_settings.show_replies": "Birta svรถr", "home.hide_announcements": "Fela auglรฝsingar", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Birta notandasniรฐiรฐ samt", "limited_account_hint.title": "รžetta notandasniรฐ hefur veriรฐ faliรฐ af umsjรณnarmรถnnum {domain}.", "link_preview.author": "Eftir {name}", + "link_preview.more_from_author": "Meira frรก {name}", + "link_preview.shares": "{count, plural, one {{counter} fรฆrsla} other {{counter} fรฆrslur}}", "lists.account.add": "Bรฆta รก lista", "lists.account.remove": "Fjarlรฆgja af lista", "lists.delete": "Eyรฐa lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "Hleรฐ innโ€ฆ", "media_gallery.toggle_visible": "Vรญxla sรฝnileika", "moved_to_account_banner.text": "Aรฐgangurinn รพinn {disabledAccount} er รณvirkur รญ augnablikinu vegna รพess aรฐ รพรบ fluttir รพig yfir รก {movedToAccount}.", - "mute_modal.duration": "Lengd", - "mute_modal.hide_notifications": "Fela tilkynningar frรก รพessum notanda?", - "mute_modal.indefinite": "ร“endanlegt", + "mute_modal.hide_from_notifications": "Fela รบr tilkynningum", + "mute_modal.hide_options": "Fela valkosti", + "mute_modal.indefinite": "รžar til รฉg hรฆtti aรฐ รพagga niรฐur รญ viรฐkomandi", + "mute_modal.show_options": "Birta valkosti", + "mute_modal.they_can_mention_and_follow": "Viรฐkomandi geta minnst รก รพig og fylgst meรฐ รพรฉr, en รพรบ munt ekki sjรก รพรก.", + "mute_modal.they_wont_know": "Viรฐkomandi aรฐilar munu ekki vita aรฐ รพaggaรฐ hefur veriรฐ niรฐur รญ รพeim.", + "mute_modal.title": "รžagga niรฐur รญ notanda?", + "mute_modal.you_wont_see_mentions": "รžรบ munt ekki sjรก fรฆrslur sem minnast รก viรฐkomandi aรฐila.", + "mute_modal.you_wont_see_posts": "Viรฐkomandi geta รกfram sรฉรฐ fรฆrslurnar รพรญnar en รพรบ munt ekki sjรก fรฆrslurnar รพeirra.", "navigation_bar.about": "Um hugbรบnaรฐinn", "navigation_bar.advanced_interface": "Opna รญ รญtarlegu vefviรฐmรณti", "navigation_bar.blocks": "รštilokaรฐir notendur", @@ -430,11 +475,29 @@ "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", + "notification_requests.dismiss": "Afgreiรฐa", + "notification_requests.notifications_from": "Tilkynningar frรก {name}", + "notification_requests.title": "Sรญaรฐar tilkynningar", "notifications.clear": "Hreinsa tilkynningar", "notifications.clear_confirmation": "Ertu viss um aรฐ รพรบ viljir endanlega eyรฐa รถllum tilkynningunum รพรญnum?", "notifications.column_settings.admin.report": "Nรฝjar kรฆrur:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Birta sรญustikuna", "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:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Tilkynningar รก skjรกborรฐi eru ekki aรฐgengilegar megna รกรฐur hafnaรฐra beiรฐna fyrir vafra", "notifications.permission_denied_alert": "Ekki var hรฆgt aรฐ virkja tilkynningar รก skjรกborรฐi, รพar sem heimildum fyrir vafra var รกรฐur hafnaรฐ", "notifications.permission_required": "Tilkynningar รก skjรกborรฐi eru ekki aรฐgengilegar รพar sem nauรฐsynlegar heimildir hafa ekki veriรฐ veittar.", + "notifications.policy.filter_new_accounts.hint": "รštbรบiรฐ {days, plural, one {sรญรฐasta daginn} other {sรญรฐustu # daga}}", + "notifications.policy.filter_new_accounts_title": "Nรฝir notendur", + "notifications.policy.filter_not_followers_hint": "รžar meรฐ taliรฐ fรณlk sem hefur fylgst meรฐ รพรฉr รญ minna en {days, plural, one {einn dag} other {# daga}}", + "notifications.policy.filter_not_followers_title": "Fรณlk sem fylgist ekki meรฐ รพรฉr", + "notifications.policy.filter_not_following_hint": "รžar til รพรบ samรพykkir viรฐkomandi handvirkt", + "notifications.policy.filter_not_following_title": "Fรณlk sem รพรบ fylgist ekki meรฐ", + "notifications.policy.filter_private_mentions_hint": "Sรญaรฐ nema รพaรฐ sรฉ รญ svari viรฐ einhverju รพar sem รพรบ minntist รก viรฐkomandi eรฐa ef รพรบ fylgist meรฐ sendandanum", + "notifications.policy.filter_private_mentions_title": "ร“umbeรฐiรฐ einkaspjall", + "notifications.policy.title": "Sรญa รบt tilkynningar frรกโ€ฆ", "notifications_permission_banner.enable": "Virkja tilkynningar รก skjรกborรฐi", "notifications_permission_banner.how_to_control": "Til aรฐ taka รก mรณti tilkynningum รพegar Mastodon er ekki opiรฐ, skaltu virkja tilkynningar รก skjรกborรฐi. รžegar รพรฆr eru orรฐnar virkar geturรฐu stรฝrt nรกkvรฆmlega hverskonar atvik framleiรฐa tilkynningar meรฐ รพvรญ aรฐ nota {icon}-hnappinn hรฉr fyrir ofan.", "notifications_permission_banner.title": "Aldrei missa af neinu", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Folk sem hefur notaรฐ รพennan netรพjรณn sรญรฐustu 30 daga (virkir notendur รญ mรกnuรฐinum)", "server_banner.active_users": "virkir notendur", "server_banner.administered_by": "Stรฝrt af:", - "server_banner.introduction": "{domain} er hluti af dreifhรฝsta samfรฉlagsnetinu sem keyrt er af {mastodon}.", - "server_banner.learn_more": "Kanna nรกnar", + "server_banner.is_one_of_many": "{domain} er einn af fjรถlmรถrgum รณhรกรฐum Mastodon-รพjรณnum sem รพรบ getur notaรฐ til aรฐ taka รพรกtt รญ fediverse-samfรฉlaginu.", "server_banner.server_stats": "Tรถlfrรฆรฐi รพjรณns:", "sign_in_banner.create_account": "Bรบa til notandaaรฐgang", + "sign_in_banner.follow_anyone": "Fylgstu meรฐ hverjum sem er รญ รพessum samtvinnaรฐa heimi og skoรฐaรฐu allt รญ tรญmarรถรฐ. Engin reiknirit, auglรฝsingar eรฐa smellbeitur.", + "sign_in_banner.mastodon_is": "Mastodon er besta leiรฐin til aรฐ fylgjast meรฐ hvaรฐ sรฉ รญ gangi.", "sign_in_banner.sign_in": "Skrรก inn", "sign_in_banner.sso_redirect": "Skrรก inn eรฐa nรฝskrรก", - "sign_in_banner.text": "Skrรกรฐu รพig inn til aรฐ fylgjast meรฐ notendum eรฐa myllumerkjum, svara fรฆrslum, deila รพeim eรฐa setja รญ eftirlรฆti. รžรบ getur einnig รกtt รญ samskiptum รก aรฐgangnum รพรญnum รก รถรฐrum netรพjรณnum.", "status.admin_account": "Opna umsjรณnarviรฐmรณt fyrir @{name}", "status.admin_domain": "Opna umsjรณnarviรฐmรณt fyrir @{domain}", "status.admin_status": "Opna รพessa fรฆrslu รญ umsjรณnarviรฐmรณtinu", @@ -645,10 +716,11 @@ "status.direct": "Einkaspjall viรฐ @{name}", "status.direct_indicator": "Einkaspjall", "status.edit": "Breyta", - "status.edited": "Breytt {date}", + "status.edited": "Sรญรฐast breytt {date}", "status.edited_x_times": "Breytt {count, plural, one {{count} sinni} other {{count} sinnum}}", "status.embed": "รvefja", "status.favourite": "Eftirlรฆti", + "status.favourites": "{count, plural, one {eftirlรฆti} other {eftirlรฆti}}", "status.filter": "Sรญa รพessa fรฆrslu", "status.filtered": "Sรญaรฐ", "status.hide": "Fela fรฆrslu", @@ -669,6 +741,7 @@ "status.reblog": "Endurbirting", "status.reblog_private": "Endurbirta til upphaflegra lesenda", "status.reblogged_by": "{name} endurbirti", + "status.reblogs": "{count, plural, one {endurbirting} other {endurbirtingar}}", "status.reblogs.empty": "Enginn hefur ennรพรก endurbirt รพessa fรฆrslu. รžegar einhver gerir รพaรฐ, mun รพaรฐ birtast hรฉr.", "status.redraft": "Eyรฐa og endurvinna drรถg", "status.remove_bookmark": "Fjarlรฆgja bรณkamerki", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index db8e88bd2a..3672b5fd7a 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -83,12 +83,20 @@ "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", "attachments_list.unprocessed": "(non elaborato)", "audio.hide": "Nascondi audio", + "block_modal.remote_users_caveat": "Chiederemo al server {domain} di rispettare la tua decisione. Tuttavia, la conformitร  non รจ garantita poichรฉ alcuni server potrebbero gestire i blocchi in modo diverso. I post pubblici potrebbero essere ancora visibili agli utenti che non hanno effettuato l'accesso.", + "block_modal.show_less": "Mostra meno", + "block_modal.show_more": "Mostra di piรน", + "block_modal.they_cant_mention": "Non possono menzionarti o seguirti.", + "block_modal.they_cant_see_posts": "Non possono vedere i tuoi post e tu non vedrai i loro.", + "block_modal.they_will_know": "Possono vedere che sono bloccati.", + "block_modal.title": "Bloccare l'utente?", + "block_modal.you_wont_see_mentions": "Non vedrai i post che li menzionano.", "boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio, la prossima volta", "bundle_column_error.copy_stacktrace": "Copia rapporto sull'errore", "bundle_column_error.error.body": "Impossibile rendedrizzare la pagina richiesta. Potrebbe dipendere da un bug nel nostro codice o da un problema di compatibilitร  di un browser.", @@ -160,26 +168,22 @@ "compose_form.spoiler.unmarked": "Aggiungi l'avviso del contenuto", "compose_form.spoiler_placeholder": "Contenuto sensibile (facoltativo)", "confirmation_modal.cancel": "Annulla", - "confirmations.block.block_and_report": "Blocca & Segnala", "confirmations.block.confirm": "Blocca", - "confirmations.block.message": "Sei sicuro di voler bloccare {name}?", "confirmations.cancel_follow_request.confirm": "Annulla la richiesta", "confirmations.cancel_follow_request.message": "Sei sicuro di voler annullare la tua richiesta per seguire {name}?", "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 l'intero dominio", + "confirmations.domain_block.confirm": "Blocca il server", "confirmations.domain_block.message": "Sei davvero sicuro di voler bloccare l'intero {domain}? In gran parte dei casi, รจ sufficiente e preferibile bloccare o silenziare alcuni profili. Non visualizzerai i contenuti da quel dominio in alcuna cronologia pubblica o tra le tue notifiche. I tuoi seguaci da quel dominio saranno rimossi.", "confirmations.edit.confirm": "Modifica", "confirmations.edit.message": "Modificare ora sovrascriverร  il messaggio che stai correntemente componendo. Sei sicuro di voler procedere?", "confirmations.logout.confirm": "Disconnettiti", "confirmations.logout.message": "Sei sicuro di volerti disconnettere?", "confirmations.mute.confirm": "Silenzia", - "confirmations.mute.explanation": "Questo nasconderร  i post da loro e i post che li menzionano, ma consentirร  comunque loro di visualizzare i tuoi post e di seguirti.", - "confirmations.mute.message": "Sei sicuro di voler silenziare {name}?", "confirmations.redraft.confirm": "Elimina e riscrivi", "confirmations.redraft.message": "Sei sicuro di voler eliminare questo post e riscriverlo? I preferiti e i boost andranno persi e le risposte al post originale non saranno piรน collegate.", "confirmations.reply.confirm": "Rispondi", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Questi sono post da tutto il social web che stanno guadagnando popolaritร  oggi. I post piรน recenti con piรน condivisioni e preferiti sono classificati piรน in alto.", "dismissable_banner.explore_tags": "Questi hashtag stanno ottenendo popolaritร  tra le persone su questo e altri server della rete decentralizzata, al momento.", "dismissable_banner.public_timeline": "Questi sono i post pubblici piรน recenti di persone sul social che le persone su {domain} seguono.", + "domain_block_modal.block": "Blocca il server", + "domain_block_modal.block_account_instead": "Blocca invece @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Le persone da questo server possono interagire con i tuoi vecchi post.", + "domain_block_modal.they_cant_follow": "Nessuno da questo server puรฒ seguirti.", + "domain_block_modal.they_wont_know": "Non sapranno di essere stati bloccati.", + "domain_block_modal.title": "Bloccare il dominio?", + "domain_block_modal.you_will_lose_followers": "Tutti i tuoi seguaci da questo server verranno rimossi.", + "domain_block_modal.you_wont_see_posts": "Non vedrai post o notifiche dagli utenti su questo server.", + "domain_pill.activitypub_lets_connect": "Ti consente di connetterti e interagire con le persone non solo su Mastodon, ma anche su diverse app social.", + "domain_pill.activitypub_like_language": "ActivityPub รจ come la lingua che Mastodon parla con altri social network.", + "domain_pill.server": "Server", + "domain_pill.their_handle": "Il loro nome univoco:", + "domain_pill.their_server": "La loro casa digitale, dove risiedono tutti i loro post.", + "domain_pill.their_username": "Il loro identificatore univoco sul loro server. รˆ possibile trovare utenti con lo stesso nome utente su server diversi.", + "domain_pill.username": "Nome utente", + "domain_pill.whats_in_a_handle": "Cosa c'รจ in un nome univoco?", + "domain_pill.who_they_are": "Poichรฉ i nomi univoci indicano chi sia qualcuno e dove si trovi, puoi interagire con le persone attraverso la rete sociale delle .", + "domain_pill.who_you_are": "Poichรฉ il tuo nome univoco indica chi tu sia e dove ti trovi, le persone possono interagire con te sulla rete sociale delle .", + "domain_pill.your_handle": "Il tuo nome univoco:", + "domain_pill.your_server": "La tua casa digitale, dove vivono tutti i tuoi post. Non ti piace questa? Cambia server in qualsiasi momento e porta con te anche i tuoi seguaci.", + "domain_pill.your_username": "Il tuo identificatore univoco su questo server. รˆ possibile trovare utenti con lo stesso nome utente su server diversi.", "embed.instructions": "Incorpora questo post sul tuo sito web, copiando il seguente codice.", "embed.preview": "Ecco come apparirร :", "emoji_button.activity": "Attivitร ", @@ -238,9 +263,10 @@ "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.", "empty_column.public": "Non c'รจ nulla qui! Scrivi qualcosa pubblicamente o segui manualmente gli utenti dagli altri server per riempire questo spazio", "error.unexpected_crash.explanation": "A causa di un bug nel nostro codice o di un problema di compatibilitร  del browser, non รจ stato possibile visualizzare correttamente questa pagina.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Questo server", "firehose.remote": "Altri server", "follow_request.authorize": "Autorizza", "follow_request.reject": "Rifiuta", "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 dell'editore", + "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}.", + "follow_suggestions.hints.most_interactions": "Recentemente, questo profilo ha ricevuto molta attenzione su {domain}.", + "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Segui l'hashtag", "hashtag.unfollow": "Smetti di seguire l'hashtag", "hashtags.and_other": "โ€ฆe {count, plural, other {# in piรน}}", - "home.column_settings.basic": "Base", "home.column_settings.show_reblogs": "Mostra reblog", "home.column_settings.show_replies": "Mostra risposte", "home.hide_announcements": "Nascondi annunci", @@ -321,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", @@ -377,27 +414,35 @@ "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", + "link_preview.more_from_author": "Altro da {name}", + "link_preview.shares": "{count, plural, one {{counter} post} other {{counter} post}}", + "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}}", "moved_to_account_banner.text": "Il tuo profilo {disabledAccount} รจ correntemente disabilitato perchรฉ ti sei spostato a {movedToAccount}.", - "mute_modal.duration": "Durata", - "mute_modal.hide_notifications": "Nascondere le notifiche da questo utente?", - "mute_modal.indefinite": "Per sempre", + "mute_modal.hide_from_notifications": "Nascondi dalle notifiche", + "mute_modal.hide_options": "Nascondi le opzioni", + "mute_modal.indefinite": "Finchรฉ io non le riattivo", + "mute_modal.show_options": "Mostre le opzioni", + "mute_modal.they_can_mention_and_follow": "Possono menzionarti e seguirti, ma non li vedrai.", + "mute_modal.they_wont_know": "Non sapranno di essere stati silenziati.", + "mute_modal.title": "Silenziare l'utente?", + "mute_modal.you_wont_see_mentions": "Non vedrai i post che li menzionano.", + "mute_modal.you_wont_see_posts": "Possono ancora vedere i tuoi post, ma tu non vedrai i loro.", "navigation_bar.about": "Info", "navigation_bar.advanced_interface": "Apri nell'interfaccia web avanzata", "navigation_bar.blocks": "Utenti bloccati", @@ -430,11 +475,29 @@ "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.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", + "notification_requests.dismiss": "Ignora", + "notification_requests.notifications_from": "Notifiche da {name}", + "notification_requests.title": "Notifiche filtrate", "notifications.clear": "Cancella le notifiche", "notifications.clear_confirmation": "Sei sicuro di voler cancellare permanentemente tutte le tue notifiche?", "notifications.column_settings.admin.report": "Nuove segnalazioni:", @@ -442,8 +505,7 @@ "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 rapida del filtro", - "notifications.column_settings.filter_bar.show_bar": "Mostra la barra del filtro", + "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:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Notifiche desktop non disponibili a causa della precedentemente negata richiesta di autorizzazioni del browser", "notifications.permission_denied_alert": "Impossibile abilitare le notifiche desktop, poichรฉ l'autorizzazione del browser รจ stata precedentemente negata", "notifications.permission_required": "Notifiche destkop non disponibili poichรฉ l'autorizzazione richiesta non รจ stata concessa.", + "notifications.policy.filter_new_accounts.hint": "Creato {days, plural, one {un giorno} other {# giorni}} fa", + "notifications.policy.filter_new_accounts_title": "Nuovi account", + "notifications.policy.filter_not_followers_hint": "Incluse le persone che ti seguono da meno di {days, plural, one {un giorno} other {# giorni}}", + "notifications.policy.filter_not_followers_title": "Persone che non ti seguono", + "notifications.policy.filter_not_following_hint": "Fino a quando non le approvi manualmente", + "notifications.policy.filter_not_following_title": "Persone che non segui", + "notifications.policy.filter_private_mentions_hint": "Filtrate, a meno che non sia in risposta alla tua menzione o se segui il mittente", + "notifications.policy.filter_private_mentions_title": "Menzioni private indesiderate", + "notifications.policy.title": "Filtra le notifiche daโ€ฆ", "notifications_permission_banner.enable": "Abilita le notifiche desktop", "notifications_permission_banner.how_to_control": "Per ricevere le notifiche quando Mastodon non รจ aperto, abilita le notifiche desktop. Puoi controllare precisamente quali tipi di interazioni generano le notifiche destkop, tramite il pulsante {icon} sopra, una volta abilitate.", "notifications_permission_banner.title": "Non perderti mai nulla", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Persone che hanno utilizzato questo server negli ultimi 30 giorni (Utenti Attivi Mensilmente)", "server_banner.active_users": "utenti attivi", "server_banner.administered_by": "Amministrato da:", - "server_banner.introduction": "{domain} รจ parte del social network decentralizzato, sviluppato da {mastodon}.", - "server_banner.learn_more": "Scopri di piรน", + "server_banner.is_one_of_many": "{domain} รจ uno dei tanti server Mastodon indipendenti che puoi usare per partecipare al fediverso.", "server_banner.server_stats": "Statistiche del server:", "sign_in_banner.create_account": "Crea un profilo", + "sign_in_banner.follow_anyone": "Segui chiunque nel fediverso e vedi tutto in ordine cronologico. Nessun algoritmo, annunci o clickbait in vista.", + "sign_in_banner.mastodon_is": "Mastodon รจ il modo migliore per tenere il passo con quello che sta accadendo.", "sign_in_banner.sign_in": "Accedi", "sign_in_banner.sso_redirect": "Accedi o Registrati", - "sign_in_banner.text": "Accedi per seguire profili o hashtag, condividere, rispondere e aggiungere post ai preferiti. Puoi anche interagire dal tuo account su un server diverso.", "status.admin_account": "Apri interfaccia di moderazione per @{name}", "status.admin_domain": "Apri l'interfaccia di moderazione per {domain}", "status.admin_status": "Apri questo post nell'interfaccia di moderazione", @@ -645,10 +716,11 @@ "status.direct": "Menziona privatamente @{name}", "status.direct_indicator": "Menzione privata", "status.edit": "Modifica", - "status.edited": "Modificato il {date}", + "status.edited": "Ultima modifica {date}", "status.edited_x_times": "Modificato {count, plural, one {{count} volta} other {{count} volte}}", "status.embed": "Incorpora", "status.favourite": "Preferito", + "status.favourites": "{count, plural, one {preferito} other {preferiti}}", "status.filter": "Filtra questo post", "status.filtered": "Filtrato", "status.hide": "Nascondi il post", @@ -669,6 +741,7 @@ "status.reblog": "Reblog", "status.reblog_private": "Reblog con visibilitร  originale", "status.reblogged_by": "Rebloggato da {name}", + "status.reblogs": "{count, plural, one {boost} other {boost}}", "status.reblogs.empty": "Ancora nessuno ha rebloggato questo post. Quando qualcuno lo farร , apparirร  qui.", "status.redraft": "Elimina e riscrivi", "status.remove_bookmark": "Rimuovi segnalibro", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 180963e9e6..90a46edd5b 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": "่ฆๆฑ‚ใ•ใ‚ŒใŸใƒšใƒผใ‚ธใ‚’ใƒฌใƒณใƒ€ใƒชใƒณใ‚ฐใงใใพใ›ใ‚“ใงใ—ใŸใ€‚ใ‚ณใƒผใƒ‰ใฎใƒใ‚ฐใ€ใพใŸใฏใƒ–ใƒฉใ‚ฆใ‚ถใฎไบ’ๆ›ๆ€งใฎๅ•้กŒใŒๅŽŸๅ› ใงใ‚ใ‚‹ๅฏ่ƒฝๆ€งใŒใ‚ใ‚Šใพใ™ใ€‚", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ๆœฌๆ–‡ใฏ้š ใ•ใ‚Œใฆใ„ใพใ›ใ‚“", "compose_form.spoiler_placeholder": "้–ฒ่ฆงๆณจๆ„ (ใ‚ชใƒ—ใ‚ทใƒงใƒณ)", "confirmation_modal.cancel": "ใ‚ญใƒฃใƒณใ‚ปใƒซ", - "confirmations.block.block_and_report": "ใƒ–ใƒญใƒƒใ‚ฏใ—้€šๅ ฑ", "confirmations.block.confirm": "ใƒ–ใƒญใƒƒใ‚ฏ", - "confirmations.block.message": "ๆœฌๅฝ“ใซ{name}ใ•ใ‚“ใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ—ใพใ™ใ‹๏ผŸ", "confirmations.cancel_follow_request.confirm": "ใƒ•ใ‚ฉใƒญใƒผใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅ–ใ‚Šๆถˆใ™", "confirmations.cancel_follow_request.message": "{name}ใซๅฏพใ™ใ‚‹ใƒ•ใ‚ฉใƒญใƒผใƒชใ‚ฏใ‚จใ‚นใƒˆใ‚’ๅ–ใ‚Šๆถˆใ—ใพใ™ใ‹?", "confirmations.delete.confirm": "ๅ‰Š้™ค", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ๆœฌๅฝ“ใซใ“ใฎใƒชใ‚นใƒˆใ‚’ๅฎŒๅ…จใซๅ‰Š้™คใ—ใพใ™ใ‹๏ผŸ", "confirmations.discard_edit_media.confirm": "็ ดๆฃ„", "confirmations.discard_edit_media.message": "ใƒกใƒ‡ใ‚ฃใ‚ขใฎ่ชฌๆ˜ŽใพใŸใฏใƒ—ใƒฌใƒ“ใƒฅใƒผใซไฟๅญ˜ใ•ใ‚Œใฆใ„ใชใ„ๅค‰ๆ›ดใŒใ‚ใ‚Šใพใ™ใ€‚ใใ‚Œใงใ‚‚็ ดๆฃ„ใ—ใพใ™ใ‹๏ผŸ", - "confirmations.domain_block.confirm": "ใƒ‰ใƒกใ‚คใƒณๅ…จไฝ“ใ‚’ใƒ–ใƒญใƒƒใ‚ฏ", + "confirmations.domain_block.confirm": "ใ‚ตใƒผใƒใƒผใ‚’ใƒ–ใƒญใƒƒใ‚ฏ", "confirmations.domain_block.message": "ๆœฌๅฝ“ใซ{domain}ๅ…จไฝ“ใ‚’้ž่กจ็คบใซใ—ใพใ™ใ‹๏ผŸ ๅคšใใฎๅ ดๅˆใฏๅ€‹ๅˆฅใซใƒ–ใƒญใƒƒใ‚ฏใ‚„ใƒŸใƒฅใƒผใƒˆใ™ใ‚‹ใ ใ‘ใงๅ……ๅˆ†ใงใ‚ใ‚Šใ€ใพใŸๅฅฝใพใ—ใ„ใงใ™ใ€‚ๅ…ฌ้–‹ใ‚ฟใ‚คใƒ ใƒฉใ‚คใƒณใซใใฎใƒ‰ใƒกใ‚คใƒณใฎใ‚ณใƒณใƒ†ใƒณใƒ„ใŒ่กจ็คบใ•ใ‚Œใชใใชใ‚Šใ€้€š็Ÿฅใ‚‚ๅฑŠใ‹ใชใใชใ‚Šใพใ™ใ€‚ใใฎใƒ‰ใƒกใ‚คใƒณใฎใƒ•ใ‚ฉใƒญใƒฏใƒผใฏใ‚ขใƒณใƒ•ใ‚ฉใƒญใƒผใ•ใ‚Œใพใ™ใ€‚", "confirmations.edit.confirm": "็ทจ้›†", "confirmations.edit.message": "ไปŠ็ทจ้›†ใ™ใ‚‹ใจ็พๅœจไฝœๆˆไธญใฎใƒกใƒƒใ‚ปใƒผใ‚ธใŒไธŠๆ›ธใใ•ใ‚Œใพใ™ใ€‚ๆœฌๅฝ“ใซๅฎŸ่กŒใ—ใพใ™ใ‹๏ผŸ", "confirmations.logout.confirm": "ใƒญใ‚ฐใ‚ขใ‚ฆใƒˆ", "confirmations.logout.message": "ๆœฌๅฝ“ใซใƒญใ‚ฐใ‚ขใ‚ฆใƒˆใ—ใพใ™ใ‹๏ผŸ", "confirmations.mute.confirm": "ใƒŸใƒฅใƒผใƒˆ", - "confirmations.mute.explanation": "ใ“ใ‚Œใซใ‚ˆใ‚Š็›ธๆ‰‹ใฎๆŠ•็จฟใจ่ฟ”ไฟกใฏ่ฆ‹ใˆใชใใชใ‚Šใพใ™ใŒใ€็›ธๆ‰‹ใฏใ‚ใชใŸใ‚’ใƒ•ใ‚ฉใƒญใƒผใ—็ถšใ‘ๆŠ•็จฟใ‚’่ฆ‹ใ‚‹ใ“ใจใŒใงใใพใ™ใ€‚", - "confirmations.mute.message": "ๆœฌๅฝ“ใซ{name}ใ•ใ‚“ใ‚’ใƒŸใƒฅใƒผใƒˆใ—ใพใ™ใ‹๏ผŸ", "confirmations.redraft.confirm": "ๅ‰Š้™คใ—ใฆไธ‹ๆ›ธใใซๆˆปใ™", "confirmations.redraft.message": "ๆŠ•็จฟใ‚’ๅ‰Š้™คใ—ใฆไธ‹ๆ›ธใใซๆˆปใ—ใพใ™ใ€‚ใ“ใฎๆŠ•็จฟใธใฎใŠๆฐ—ใซๅ…ฅใ‚Š็™ป้Œฒใ‚„ใƒ–ใƒผใ‚นใƒˆใฏๅคฑใ‚ใ‚Œใ€่ฟ”ไฟกใฏๅญค็ซ‹ใ™ใ‚‹ใ“ใจใซใชใ‚Šใพใ™ใ€‚ใ‚ˆใ‚ใ—ใ„ใงใ™ใ‹๏ผŸ", "confirmations.reply.confirm": "่ฟ”ไฟก", @@ -205,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": "ๆดปๅ‹•", @@ -241,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": "ไธๅ…ทๅˆใ‹ใƒ–ใƒฉใ‚ฆใ‚ถใฎไบ’ๆ›ๆ€งๅ•้กŒใฎใŸใ‚ใ€ใ“ใฎใƒšใƒผใ‚ธใ‚’ๆญฃใ—ใ่กจ็คบใงใใพใ›ใ‚“ใงใ—ใŸใ€‚", @@ -271,13 +297,30 @@ "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 {้€š็ŸฅใŒใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฏใ‚ใ‚Šใพใ›ใ‚“} 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.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} ใงใ‚‚ใฃใจใ‚‚ใƒ•ใ‚ฉใƒญใƒผใ•ใ‚Œใฆใ„ใ‚‹ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฎใฒใจใคใงใ™ใ€‚", + "follow_suggestions.hints.most_interactions": "{domain} ใงใ„ใพๅคงใใชๆณจ็›ฎใ‚’้›†ใ‚ใฆใ„ใพใ™ใ€‚", + "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": "ใƒ•ใ‚ฉใƒญใƒผไธญใฎใƒใƒƒใ‚ทใƒฅใ‚ฟใ‚ฐ", "footer.about": "ๆฆ‚่ฆ", "footer.directory": "ใƒ‡ใ‚ฃใƒฌใ‚ฏใƒˆใƒช", @@ -304,7 +347,6 @@ "hashtag.follow": "ใƒใƒƒใ‚ทใƒฅใ‚ฟใ‚ฐใ‚’ใƒ•ใ‚ฉใƒญใƒผใ™ใ‚‹", "hashtag.unfollow": "ใƒใƒƒใ‚ทใƒฅใ‚ฟใ‚ฐใฎใƒ•ใ‚ฉใƒญใƒผใ‚’่งฃ้™ค", "hashtags.and_other": "ใปใ‹{count, plural, other {#ๅ€‹}}", - "home.column_settings.basic": "ๅŸบๆœฌ่จญๅฎš", "home.column_settings.show_reblogs": "ใƒ–ใƒผใ‚นใƒˆ่กจ็คบ", "home.column_settings.show_replies": "่ฟ”ไฟก่กจ็คบ", "home.hide_announcements": "ใŠ็Ÿฅใ‚‰ใ›ใ‚’้š ใ™", @@ -390,9 +432,15 @@ "loading_indicator.label": "่ชญใฟ่พผใฟไธญโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {็”ปๅƒใ‚’้–‰ใ˜ใ‚‹} other {็”ปๅƒใ‚’้–‰ใ˜ใ‚‹}}", "moved_to_account_banner.text": "ใ‚ใชใŸใฎใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ€Ž{disabledAccount}ใ€ใฏใ€Ž{movedToAccount}ใ€ใซ็งปๅ‹•ใ—ใŸใŸใ‚็พๅœจ็„กๅŠนใซใชใฃใฆใ„ใพใ™ใ€‚", - "mute_modal.duration": "ใƒŸใƒฅใƒผใƒˆใ™ใ‚‹ๆœŸ้–“", - "mute_modal.hide_notifications": "ใ“ใฎใƒฆใƒผใ‚ถใƒผใ‹ใ‚‰ใฎ้€š็Ÿฅใ‚’้š ใ—ใพใ™ใ‹๏ผŸ", + "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": "ใƒ–ใƒญใƒƒใ‚ฏใ—ใŸใƒฆใƒผใ‚ถใƒผ", @@ -425,11 +473,29 @@ "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.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": "ๅ—ใ‘ๅ…ฅใ‚Œใ‚‹", + "notification_requests.dismiss": "็„ก่ฆ–", + "notification_requests.notifications_from": "{name}ใ‹ใ‚‰ใฎ้€š็Ÿฅ", + "notification_requests.title": "ไฟ็•™ไธญใฎ้€š็Ÿฅ", "notifications.clear": "้€š็Ÿฅใ‚’ๆถˆๅŽป", "notifications.clear_confirmation": "ๆœฌๅฝ“ใซ้€š็Ÿฅใ‚’ๆถˆๅŽปใ—ใพใ™ใ‹๏ผŸ", "notifications.column_settings.admin.report": "ๆ–ฐใ—ใ„้€šๅ ฑ:", @@ -438,7 +504,6 @@ "notifications.column_settings.favourite": "ใŠๆฐ—ใซๅ…ฅใ‚Š:", "notifications.column_settings.filter_bar.advanced": "ใ™ในใฆใฎใ‚ซใƒ†ใ‚ดใƒชใ‚’่กจ็คบ", "notifications.column_settings.filter_bar.category": "ใ‚ฏใ‚คใƒƒใ‚ฏใƒ•ใ‚ฃใƒซใ‚ฟใƒผใƒใƒผ:", - "notifications.column_settings.filter_bar.show_bar": "ใƒ•ใ‚ฃใƒซใ‚ฟใƒผใƒใƒผใ‚’่กจ็คบ", "notifications.column_settings.follow": "ๆ–ฐใ—ใ„ใƒ•ใ‚ฉใƒญใƒฏใƒผ:", "notifications.column_settings.follow_request": "ๆ–ฐใ—ใ„ใƒ•ใ‚ฉใƒญใƒผใƒชใ‚ฏใ‚จใ‚นใƒˆ:", "notifications.column_settings.mention": "่ฟ”ไฟก:", @@ -464,6 +529,15 @@ "notifications.permission_denied": "ใƒ–ใƒฉใ‚ฆใ‚ถใฎ้€š็ŸฅใŒๆ‹’ๅฆใ•ใ‚Œใฆใ„ใ‚‹ใŸใ‚ใƒ‡ใ‚นใ‚ฏใƒˆใƒƒใƒ—้€š็Ÿฅใฏๅˆฉ็”จใงใใพใ›ใ‚“", "notifications.permission_denied_alert": "ใƒ–ใƒฉใ‚ฆใ‚ถใฎ้€š็ŸฅใŒๆ‹’ๅฆใ•ใ‚Œใฆใ„ใ‚‹ใŸใ‚ใƒ‡ใ‚นใ‚ฏใƒˆใƒƒใƒ—้€š็Ÿฅใ‚’ๆœ‰ๅŠนใซใงใใพใ›ใ‚“", "notifications.permission_required": "ๅฟ…่ฆใชๆจฉ้™ใŒไป˜ไธŽใ•ใ‚Œใฆใ„ใชใ„ใŸใ‚ใ€ใƒ‡ใ‚นใ‚ฏใƒˆใƒƒใƒ—้€š็Ÿฅใฏๅˆฉ็”จใงใใพใ›ใ‚“ใ€‚", + "notifications.policy.filter_new_accounts.hint": "ไฝœๆˆใ‹ใ‚‰{days, plural, other {#ๆ—ฅ}}ไปฅๅ†…ใฎใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‹ใ‚‰ใฎ้€š็ŸฅใŒใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚Œใพใ™", + "notifications.policy.filter_new_accounts_title": "ๆ–ฐใ—ใ„ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‹ใ‚‰ใฎ้€š็Ÿฅใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ™ใ‚‹", + "notifications.policy.filter_not_followers_hint": "ใƒ•ใ‚ฉใƒญใƒผใ•ใ‚Œใฆใ„ใฆใ‚‚ใ€ใƒ•ใ‚ฉใƒญใƒผใ‹ใ‚‰{days, plural, other {#ๆ—ฅ}}็ตŒใฃใฆใ„ใชใ„ๅ ดๅˆใฏใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚Œใพใ™", + "notifications.policy.filter_not_followers_title": "ใƒ•ใ‚ฉใƒญใƒผใ•ใ‚Œใฆใ„ใชใ„ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‹ใ‚‰ใฎ้€š็Ÿฅใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ™ใ‚‹", + "notifications.policy.filter_not_following_hint": "ๆ‰‹ๅ‹•ใง้€š็Ÿฅใ‚’ๅ—ใ‘ๅ…ฅใ‚ŒใŸใ‚ขใ‚ซใ‚ฆใƒณใƒˆใฏใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚Œใพใ›ใ‚“", + "notifications.policy.filter_not_following_title": "ใƒ•ใ‚ฉใƒญใƒผใ—ใฆใ„ใชใ„ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‹ใ‚‰ใฎ้€š็Ÿฅใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ™ใ‚‹", + "notifications.policy.filter_private_mentions_hint": "ใ‚ใชใŸใŒใƒกใƒณใ‚ทใƒงใƒณใ—ใŸ็›ธๆ‰‹ใ‹ใ‚‰ใฎ่ฟ”ไฟกใ€ใŠใ‚ˆใณใƒ•ใ‚ฉใƒญใƒผใ—ใฆใ„ใ‚‹ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใ‹ใ‚‰ใฎ่ฟ”ไฟกไปฅๅค–ใŒใƒ–ใƒญใƒƒใ‚ฏใ•ใ‚Œใพใ™", + "notifications.policy.filter_private_mentions_title": "ๅค–้ƒจใ‹ใ‚‰ใฎ้žๅ…ฌ้–‹ใฎ่ฟ”ไฟกใ‚’ใƒ–ใƒญใƒƒใ‚ฏใ™ใ‚‹", + "notifications.policy.title": "้€š็Ÿฅใฎใƒ•ใ‚ฃใƒซใ‚ฟใƒชใƒณใ‚ฐ", "notifications_permission_banner.enable": "ใƒ‡ใ‚นใ‚ฏใƒˆใƒƒใƒ—้€š็Ÿฅใ‚’ๆœ‰ๅŠนใซใ™ใ‚‹", "notifications_permission_banner.how_to_control": "Mastodonใ‚’้–‰ใ˜ใฆใ„ใ‚‹้–“ใงใ‚‚้€š็Ÿฅใ‚’ๅ—ไฟกใ™ใ‚‹ใซใฏใƒ‡ใ‚นใ‚ฏใƒˆใƒƒใƒ—้€š็Ÿฅใ‚’ๆœ‰ๅŠนใซใ—ใฆใใ ใ•ใ„ใ€‚ๆœ‰ๅŠนใซใ™ใ‚‹ใจไธŠใฎ {icon} ใƒœใ‚ฟใƒณใ‹ใ‚‰้€š็Ÿฅใฎๅ†…ๅฎนใ‚’็ดฐใ‹ใใ‚ซใ‚นใ‚ฟใƒžใ‚คใ‚บใงใใพใ™ใ€‚", "notifications_permission_banner.title": "ใŠ่ฆ‹้€ƒใ—ใชใ", @@ -620,13 +694,10 @@ "server_banner.about_active_users": "้ŽๅŽป30ๆ—ฅ้–“ใซใ“ใฎใ‚ตใƒผใƒใƒผใ‚’ไฝฟ็”จใ—ใฆใ„ใ‚‹ไบบ (ๆœˆ้–“ใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ใƒฆใƒผใ‚ถใƒผ)", "server_banner.active_users": "ไบบใฎใ‚ขใ‚ฏใƒ†ใ‚ฃใƒ–ใƒฆใƒผใ‚ถใƒผ", "server_banner.administered_by": "็ฎก็†่€…", - "server_banner.introduction": "{domain}ใฏ{mastodon}ใ‚’ไฝฟใฃใŸๅˆ†ๆ•ฃๅž‹ใ‚ฝใƒผใ‚ทใƒฃใƒซใƒใƒƒใƒˆใƒฏใƒผใ‚ฏใฎไธ€้ƒจใงใ™ใ€‚", - "server_banner.learn_more": "ใ‚‚ใฃใจ่ฉณใ—ใ", "server_banner.server_stats": "ใ‚ตใƒผใƒใƒผใฎๆƒ…ๅ ฑ", "sign_in_banner.create_account": "ใ‚ขใ‚ซใ‚ฆใƒณใƒˆไฝœๆˆ", "sign_in_banner.sign_in": "ใƒญใ‚ฐใ‚คใƒณ", "sign_in_banner.sso_redirect": "ใƒญใ‚ฐใ‚คใƒณใพใŸใฏ็™ป้Œฒ", - "sign_in_banner.text": "ใ‚ขใ‚ซใ‚ฆใƒณใƒˆใŒใ‚ใ‚Œใฐใƒฆใƒผใ‚ถใƒผใ‚„ใƒใƒƒใ‚ทใƒฅใ‚ฟใ‚ฐใ‚’ใƒ•ใ‚ฉใƒญใƒผใ—ใŸใ‚Šใ€ๆŠ•็จฟใฎใŠๆฐ—ใซๅ…ฅใ‚Š็™ป้Œฒใ‚„ใƒ–ใƒผใ‚นใƒˆใ€ๆŠ•็จฟใธใฎ่ฟ”ไฟกใŒใงใใพใ™ใ€‚ๅˆฅใฎใ‚ตใƒผใƒใƒผใฎใƒฆใƒผใ‚ถใƒผใจใฎไบคๆตใ‚‚ๅฏ่ƒฝใงใ™ใ€‚", "status.admin_account": "@{name}ใ•ใ‚“ใฎใƒขใƒ‡ใƒฌใƒผใ‚ทใƒงใƒณ็”ป้ขใ‚’้–‹ใ", "status.admin_domain": "{domain}ใฎใƒขใƒ‡ใƒฌใƒผใ‚ทใƒงใƒณ็”ป้ขใ‚’้–‹ใ", "status.admin_status": "ใ“ใฎๆŠ•็จฟใ‚’ใƒขใƒ‡ใƒฌใƒผใ‚ทใƒงใƒณ็”ป้ขใง้–‹ใ", @@ -640,10 +711,11 @@ "status.direct": "@{name}ใ•ใ‚“ใซ้žๅ…ฌ้–‹ใงๆŠ•็จฟ", "status.direct_indicator": "้žๅ…ฌ้–‹ใฎ่ฟ”ไฟก", "status.edit": "็ทจ้›†", - "status.edited": "{date}ใซ็ทจ้›†", + "status.edited": "ๆœ€็ต‚ๆ›ดๆ–ฐๆ—ฅ {date}", "status.edited_x_times": "{count}ๅ›ž็ทจ้›†", "status.embed": "ๅŸ‹ใ‚่พผใฟ", "status.favourite": "ใŠๆฐ—ใซๅ…ฅใ‚Š", + "status.favourites": "{count, plural, one {ใŠๆฐ—ใซๅ…ฅใ‚Š} other {ใŠๆฐ—ใซๅ…ฅใ‚Š}}", "status.filter": "ใ“ใฎๆŠ•็จฟใ‚’ใƒ•ใ‚ฃใƒซใ‚ฟใƒผใ™ใ‚‹", "status.filtered": "ใƒ•ใ‚ฃใƒซใ‚ฟใƒผใ•ใ‚Œใพใ—ใŸ", "status.hide": "ๆŠ•็จฟใ‚’้ž่กจ็คบ", @@ -664,6 +736,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/ka.json b/app/javascript/mastodon/locales/ka.json index 8628cb38a2..7af4dccd86 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -71,15 +71,12 @@ "compose_form.spoiler.unmarked": "แƒขแƒ”แƒฅแƒกแƒขแƒ˜ แƒแƒ แƒแƒ แƒ“แƒแƒ›แƒแƒšแƒฃแƒšแƒ˜", "confirmation_modal.cancel": "แƒฃแƒแƒ แƒงแƒแƒคแƒ", "confirmations.block.confirm": "แƒ‘แƒšแƒแƒ™แƒ˜", - "confirmations.block.message": "แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒ’แƒกแƒฃแƒ แƒ— แƒ“แƒแƒ‘แƒšแƒแƒ™แƒแƒ— {name}?", "confirmations.delete.confirm": "แƒ’แƒแƒฃแƒฅแƒ›แƒ”แƒ‘แƒ", "confirmations.delete.message": "แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒ’แƒกแƒฃแƒ แƒ— แƒ’แƒแƒแƒฃแƒฅแƒ›แƒแƒ— แƒ”แƒก แƒกแƒขแƒแƒขแƒฃแƒกแƒ˜?", "confirmations.delete_list.confirm": "แƒ’แƒแƒฃแƒฅแƒ›แƒ”แƒ‘แƒ", "confirmations.delete_list.message": "แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒ’แƒกแƒฃแƒ แƒ— แƒกแƒแƒ›แƒฃแƒ“แƒแƒ›แƒแƒ“ แƒ’แƒแƒแƒฃแƒฅแƒ›แƒแƒ— แƒ”แƒก แƒกแƒ˜แƒ?", - "confirmations.domain_block.confirm": "แƒ›แƒ—แƒ”แƒšแƒ˜ แƒ“แƒแƒ›แƒ”แƒœแƒ˜แƒก แƒ“แƒแƒ›แƒแƒšแƒ•แƒ", "confirmations.domain_block.message": "แƒœแƒแƒฆแƒ“แƒแƒ“, แƒœแƒแƒฆแƒ“แƒแƒ“, แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒ’แƒกแƒฃแƒ แƒ— แƒ“แƒแƒ‘แƒšแƒแƒ™แƒแƒ— แƒ›แƒ—แƒ”แƒšแƒ˜ {domain}? แƒฃแƒ›แƒ”แƒขแƒ”แƒก แƒจแƒ”แƒ›แƒ—แƒฎแƒ•แƒ”แƒ•แƒแƒจแƒ˜ แƒ แƒแƒ›แƒ“แƒ”แƒœแƒ˜แƒ›แƒ” แƒ’แƒแƒ›แƒ˜แƒ–แƒœแƒฃแƒšแƒ˜ แƒ‘แƒšแƒแƒ™แƒ˜ แƒแƒœ แƒ’แƒแƒฉแƒฃแƒ›แƒ”แƒ‘แƒ แƒกแƒแƒ™แƒ›แƒแƒ แƒ˜แƒกแƒ˜ แƒ“แƒ แƒฃแƒ™แƒ”แƒ—แƒ”แƒกแƒ˜แƒ. แƒ™แƒแƒœแƒขแƒ”แƒœแƒขแƒก แƒแƒ› แƒ“แƒแƒ›แƒ”แƒœแƒ˜แƒ“แƒแƒœ แƒ•แƒ”แƒ  แƒ˜แƒฎแƒ˜แƒšแƒแƒ•แƒ— แƒ•แƒ”แƒ แƒช แƒ”แƒ แƒ— แƒฆแƒ˜แƒ แƒ—แƒแƒ˜แƒ›แƒšแƒแƒ˜แƒœแƒ–แƒ” แƒแƒœ แƒ—แƒฅแƒ•แƒ”แƒœแƒก แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒจแƒ˜. แƒแƒ› แƒ“แƒแƒ›แƒ”แƒœแƒ˜แƒ“แƒแƒœ แƒแƒ แƒกแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒ›แƒ˜แƒ›แƒ“แƒ”แƒ•แƒ แƒ”แƒ‘แƒ˜ แƒแƒ›แƒแƒ˜แƒจแƒšแƒ”แƒ‘แƒ.", "confirmations.mute.confirm": "แƒ’แƒแƒฉแƒฃแƒ›แƒ”แƒ‘แƒ", - "confirmations.mute.message": "แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒ’แƒกแƒฃแƒ แƒ— แƒ’แƒแƒแƒฉแƒฃแƒ›แƒแƒ— {name}?", "confirmations.redraft.confirm": "แƒ’แƒแƒฃแƒฅแƒ›แƒ”แƒ‘แƒ แƒ“แƒ แƒ’แƒแƒ“แƒแƒœแƒแƒฌแƒ˜แƒšแƒ”แƒ‘แƒ", "confirmations.unfollow.confirm": "แƒœแƒฃแƒฆแƒแƒ  แƒ›แƒ˜แƒฐแƒงแƒ•แƒ”แƒ‘แƒ˜", "confirmations.unfollow.message": "แƒ“แƒแƒ แƒฌแƒ›แƒฃแƒœแƒ”แƒ‘แƒฃแƒšแƒ˜ แƒฎแƒแƒ แƒ—, แƒแƒฆแƒแƒ  แƒ’แƒกแƒฃแƒ แƒ— แƒ›แƒ˜แƒฐแƒงแƒ•แƒ”แƒ‘แƒแƒ“แƒ”แƒ— {name}-แƒก?", @@ -114,7 +111,6 @@ "follow_request.reject": "แƒฃแƒแƒ แƒงแƒแƒคแƒ", "getting_started.heading": "แƒ“แƒแƒฌแƒงแƒ”แƒ‘แƒ", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", - "home.column_settings.basic": "แƒซแƒ˜แƒ แƒ˜แƒ—แƒแƒ“แƒ˜", "home.column_settings.show_reblogs": "แƒ‘แƒฃแƒกแƒขแƒ”แƒ‘แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ", "home.column_settings.show_replies": "แƒžแƒแƒกแƒฃแƒฎแƒ”แƒ‘แƒ˜แƒก แƒฉแƒ•แƒ”แƒœแƒ”แƒ‘แƒ", "keyboard_shortcuts.back": "แƒฃแƒ™แƒแƒœ แƒ’แƒแƒ“แƒแƒกแƒแƒกแƒ•แƒšแƒ”แƒšแƒแƒ“", @@ -161,7 +157,6 @@ "lists.search": "แƒซแƒ”แƒ‘แƒœแƒ แƒแƒ“แƒแƒ›แƒ˜แƒแƒœแƒ”แƒ‘แƒก แƒจแƒแƒ แƒ˜แƒก แƒ แƒแƒ›แƒ”แƒšแƒ—แƒแƒช แƒ›แƒ˜แƒฐแƒงแƒ•แƒ”แƒ‘แƒ˜แƒ—", "lists.subheading": "แƒ—แƒฅแƒ•แƒ”แƒœแƒ˜ แƒกแƒ˜แƒ”แƒ‘แƒ˜", "media_gallery.toggle_visible": "แƒฎแƒ˜แƒšแƒ•แƒแƒ“แƒแƒ‘แƒ˜แƒก แƒฉแƒแƒ แƒ—แƒ•แƒ", - "mute_modal.hide_notifications": "แƒ“แƒแƒ•แƒ›แƒแƒšแƒแƒ— แƒจแƒ”แƒขแƒงแƒแƒ‘แƒ˜แƒœแƒ”แƒ‘แƒ”แƒ‘แƒ˜ แƒแƒ› แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ˜แƒกแƒ’แƒแƒœ?", "navigation_bar.blocks": "แƒ“แƒแƒ‘แƒšแƒแƒ™แƒ˜แƒšแƒ˜ แƒ›แƒแƒ›แƒฎแƒ›แƒแƒ แƒ”แƒ‘แƒšแƒ”แƒ‘แƒ˜", "navigation_bar.community_timeline": "แƒšแƒแƒ™แƒแƒšแƒฃแƒ แƒ˜ แƒ—แƒแƒ˜แƒ›แƒšแƒแƒ˜แƒœแƒ˜", "navigation_bar.compose": "Compose new toot", diff --git a/app/javascript/mastodon/locales/kab.json b/app/javascript/mastodon/locales/kab.json index b69e93952b..5aa46bafde 100644 --- a/app/javascript/mastodon/locales/kab.json +++ b/app/javascript/mastodon/locales/kab.json @@ -1,5 +1,8 @@ { "about.contact": "Anermis:", + "about.disclaimer": "Mastodon d aseษฃแบ“an ilelli, d aseษฃแบ“an n uษฃbalu yeldin, d tnezzut n Mastodon gGmbH.", + "about.not_available": "Talษฃut-a ur tettwabder ara deg uqeddac-a.", + "about.powered_by": "Azeแนญแนญa inmetti yettwasษฃelsen sษฃur {mastodon}", "about.rules": "Ilugan n uqeddac", "account.account_note_header": "Tazmilt", "account.add_or_remove_from_list": "Rnu neษฃ kkes seg tebdarin", @@ -10,34 +13,42 @@ "account.block_short": "Sewแธฅel", "account.blocked": "Yettusewแธฅel", "account.browse_more_on_origin_server": "Snirem ugar deg umeษฃnu aneแบ“li", - "account.cancel_follow_request": "Withdraw follow request", + "account.cancel_follow_request": "Sefsex taแธfart", "account.copy": "Nษฃel assaษฃ ษฃer umaษฃnu", + "account.direct": "Bder-d @{name} weแธฅd-s", "account.disable_notifications": "แธคbes ur iyi-d-ttazen ara ilษฃa mi ara d-isuffeษฃ @{name}", "account.domain_blocked": "Taษฃult yeffren", "account.edit_profile": "แบ’reg amaษฃnu", "account.enable_notifications": "Azen-iyi-d ilษฃa mi ara d-isuffeษฃ @{name}", "account.endorse": "Welleh fell-as deg umaษฃnu-inek", + "account.featured_tags.last_status_at": "Tasuffeษฃt taneggarut ass n {date}", "account.featured_tags.last_status_never": "Ulac tisuffaษฃ", "account.follow": "แธŒfer", "account.followers": "Imeแธfaren", "account.followers.empty": "Ar tura, ulac yiwen i yeแนญแนญafaแน›en amseqdac-agi.", "account.followers_counter": "{count, plural, one {{count} n umeแธfar} other {{count} n imeแธfaren}}", + "account.following": "Yeแนญแนญafaแน›", "account.following_counter": "{count, plural, one {{counter} yettwaแธfaren} other {{counter} yettwaแธfaren}}", "account.follows.empty": "Ar tura, amseqdac-agi ur yeแนญแนญafaแน› yiwen.", "account.go_to_profile": "Ddu ษฃer umaษฃnu", "account.hide_reblogs": "Ffer ayen i ibeแนญแนญu @{name}", + "account.joined_short": "Izeddi da seg ass n", "account.link_verified_on": "Taษฃara n useษฃwen-a tettwasenqed ass n {date}", "account.locked_info": "Amiแธan-agi uslig isekweแน›. D bab-is kan i izemren ad yeวงวง, s ufus-is, win ara t-iแธefแน›en.", "account.media": "Timidyatin", "account.mention": "Bder-d @{name}", + "account.moved_to": "{name} yenna-d dakken amiแธan-is amaynut yuษฃal :", "account.mute": "Sgugem @{name}", + "account.mute_notifications_short": "Susem ilษฃa", "account.mute_short": "Sgugem", "account.muted": "Yettwasgugem", + "account.no_bio": "Ulac aglam i d-yettunefken.", "account.open_original_page": "Ldi asebter anasli", "account.posts": "Tisuffaษฃ", "account.posts_with_replies": "Tisuffaษฃ d tririyin", "account.report": "Cetki ษฃef @{name}", "account.requested": "Di laษ›แธil ad yettwaqbel. Ssit i wakken ad yefsex usuter n uแธfar", + "account.requested_follow": "{name} yessuter ad kยทm-yeแธfer", "account.share": "Bแธu amaษฃnu n @{name}", "account.show_reblogs": "Ssken-d inebแธa n @{name}", "account.statuses_counter": "{count, plural, one {{counter} n tsuffeษฃt} other {{counter} n tsuffaษฃ}}", @@ -56,7 +67,12 @@ "alert.unexpected.title": "Ayhuh!", "announcement.announcement": "Ulษฃu", "audio.hide": "Ffer amesli", - "boost_modal.combo": "Tzemreแธ ad tetekkiแธ ษฃef {combo} akken ad tessurfeแธ aya tikelt-nniแธen", + "block_modal.show_less": "Ssken-d drus", + "block_modal.show_more": "Ssken-d ugar", + "block_modal.they_cant_mention": "Ur zmiren ad kยทm-id-bedren, ur zmiren ad kยทm-แธefren.", + "block_modal.they_cant_see_posts": "Ur zmiren ad walin tisufaษฃ-nwen, ur tettwalim tid-nsen.", + "block_modal.title": "Sewแธฅel aseqdac ?", + "boost_modal.combo": "Tzemreแธ ad tsiteแธ ษฃef {combo} akken ad tzegleแธ aya tikelt i d-iteddun", "bundle_column_error.copy_stacktrace": "Nษฃel tuccแธa n uneqqis", "bundle_column_error.error.title": "Uh, ala !", "bundle_column_error.network.title": "Tuccแธa deg uแบ“eแนญแนญa", @@ -66,12 +82,15 @@ "bundle_modal_error.close": "Mdel", "bundle_modal_error.message": "Tella-d kra n tuccแธa mi d-yettali ugbur-agi.", "bundle_modal_error.retry": "ฦreแธ tikelt-nniแธen", + "closed_registrations_modal.description": "Asnulfu n umiแธan deg {domain} maฤฤi d ayen izemren ad yili, maca ttxil-kยทm, err deg lbal-ikยทim belli ur teแธฅwaวงeแธ ara amiแธan s wudem ibanen ษฃef {domain} akken ad tesqedceแธ Mastodon.", "closed_registrations_modal.find_another_server": "Aff-d aqeddac nniแธen", + "closed_registrations_modal.title": "Ajerred deg Masแนญudun", "column.about": "ฦ”ef", "column.blocks": "Imiแธanen yettusแธฅebsen", "column.bookmarks": "Ticraแธ", "column.community": "Tasuddemt tadigant", - "column.directory": "Inig deg imaษฃnuten", + "column.direct": "Tabdarin tusligin", + "column.directory": "Inig deg imeษฃna", "column.domain_blocks": "Taษฃulin yeffren", "column.favourites": "Imenyafen", "column.follow_requests": "Isuturen n teแธfeแน›t", @@ -94,7 +113,9 @@ "community.column_settings.remote_only": "Anmeggag kan", "compose.language.change": "Beddel tutlayt", "compose.language.search": "Nadi tutlayin โ€ฆ", + "compose.published.body": "Yeffeษฃ-d yizen-nni.", "compose.published.open": "Ldi", + "compose.saved.body": "Tettwasekles tsuffeษฃt.", "compose_form.direct_message_warning_learn_more": "Issin ugar", "compose_form.encryption_warning": "", "compose_form.hashtag_warning": "", @@ -102,29 +123,29 @@ "compose_form.lock_disclaimer.lock": "yettwacekkel", "compose_form.placeholder": "D acu i itezzin deg wallaษฃ?", "compose_form.poll.duration": "Tanzagt n tefrant", + "compose_form.poll.multiple": "Aแนญas n ufran", "compose_form.poll.option_placeholder": "Taxtiแน›t {number}", "compose_form.poll.single": "Fren yiwen", + "compose_form.poll.type": "Aษฃanib", + "compose_form.publish": "Suffeษฃ", "compose_form.publish_form": "Tasuffeษฃt tamaynut", "compose_form.reply": "Err", "compose_form.save_changes": "Leqqem", "compose_form.spoiler.marked": "Kkes aแธris yettwaffren deffir n walษฃu", "compose_form.spoiler.unmarked": "Rnu aแธris yettwaffren deffir n walษฃu", "confirmation_modal.cancel": "Sefsex", - "confirmations.block.block_and_report": "Sewแธฅel & sewษ›ed", "confirmations.block.confirm": "Sewแธฅel", - "confirmations.block.message": "Tebษฃiแธ s tidet ad tesแธฅebseแธ {name}?", "confirmations.delete.confirm": "Kkes", "confirmations.delete.message": "Tebษฃiแธ s tidet ad tekkseแธ tasuffeษฃt-agi?", "confirmations.delete_list.confirm": "Kkes", "confirmations.delete_list.message": "Tebษฃiแธ s tidet ad tekkseแธ umuษฃ-agi i lebda?", "confirmations.discard_edit_media.confirm": "Sefsex", - "confirmations.domain_block.confirm": "Ffer taษฃult meแน›แน›a", + "confirmations.domain_block.confirm": "Sewแธฅel aqeddac", "confirmations.edit.confirm": "แบ’reg", + "confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreแธ akka tura. Tetแธฅeqqeแธ tebษฃiแธ ad tkemmleแธ?", "confirmations.logout.confirm": "Ffeษฃ", "confirmations.logout.message": "D tidet tebษฃiแธ ad teffษฃeแธ?", "confirmations.mute.confirm": "Sgugem", - "confirmations.mute.explanation": "Aya ad yeffer iznan-is d wid i deg d-yettwabder neษฃ d-tettwabder, maca xas akka yezmer neษฃ tezmer awali n yiznan-inek d uแธfaแน›-ik.", - "confirmations.mute.message": "Tetแธฅeqqeแธ belli tebษฃiแธ ad ttegugmeแธ {name}?", "confirmations.redraft.confirm": "Sfeแธ & ฦiwed tira", "confirmations.reply.confirm": "Err", "confirmations.reply.message": "Tiririt akka tura ad k-degger izen-agi i tettaruแธ. Tebษฃiแธ ad tkemmleแธ?", @@ -134,14 +155,24 @@ "conversation.mark_as_read": "Creแธ yettwaษฃแน›a", "conversation.open": "Ssken adiwenni", "conversation.with": "Akked {names}", + "copy_icon_button.copied": "Yettwanษฃel ษฃer ufus", "copypaste.copied": "Yettwanษฃel", + "copypaste.copy_to_clipboard": "Nษฃel ษฃer afus", "directory.federated": "Deg fedivers yettwasnen", "directory.local": "Seg {domain} kan", "directory.new_arrivals": "Imaynuten id yewแธen", "directory.recently_active": "Yermed xas melmi kan", "disabled_account_banner.account_settings": "Iษฃewwaแน›en n umiแธan", - "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.", + "dismissable_banner.dismiss": "Agi", + "dismissable_banner.explore_links": "D tiqsiแธin n yisallen i yettwabแธan ass-a deg web inmetti. Tiqsiแธin n yisallen timaynutin i d-yettwassufษฃen s wugar n medden yemgaraden, d tid i d-yufraren ugar.", + "dismissable_banner.explore_statuses": "Ti d tisufaษฃ seg uzeแนญแนญa anmetti i d-yettawin tamyigawt ass-a. Tisufaษฃ timaynutin yesฮตan aแนญas n lวงehd d tid iแธฅemmlen s waแนญas, ttwaฮตlayit d timezwura.", + "dismissable_banner.explore_tags": "D wiyi i d ihacแนญagen i d-yettawin tamyigawt deg web anmetti ass-a. Ihacแนญagen i sseqdacen ugar n medden, ฮตlayit d imezwura.", + "domain_block_modal.block": "Sewแธฅel aqeddac", + "domain_block_modal.they_cant_follow": "Yiwen ur yezmir ad kยทm-id-yeแธfer seg uqeddac-a.", + "domain_pill.activitypub_like_language": "ActivityPub am tutlayt yettmeslay Mastodon d izeแธwan inmettiyen nniแธen.", + "domain_pill.server": "Aqeddac", + "domain_pill.username": "Isem n useqdac", + "domain_pill.your_server": "D axxam-inekยทinem umแธin, anda i zedษฃent akk tsuffaษฃ-ikยทim. Ur kยทm-yeฮตวงib ara wa? Ssenfel-d iqeddacen melmi i akยทm-yehwa, awi-d daษฃen ineแธfaren-ikยทim yid-kยทm.", "embed.instructions": "แบ’แบ“u addad-agi deg usmel-inek s wenฮณal n tangalt yellan sdaw-agi.", "embed.preview": "Akka ara d-iban:", "emoji_button.activity": "Aqeddic", @@ -163,16 +194,16 @@ "empty_column.account_timeline": "Ulac tisuffaษฃ da !", "empty_column.account_unavailable": "Ur nufi ara amaษฃnu-ayi", "empty_column.blocks": "Ur tesแธฅebseแธ ula yiwen n umseqdac ar tura.", - "empty_column.bookmarked_statuses": "Ulac tijewwaqin i terniแธ ษฃer yismenyifen-ik ar tura. Ticki terniแธ yiwet, ad d-tettwasken da.", + "empty_column.bookmarked_statuses": "Ulac kra n tsuffeษฃt i terniแธ ษฃer yismenyifen-ikยทim ar tura. Ticki terniแธ yiwet, ad d-tettwasken da.", "empty_column.community": "Tasuddemt tazayezt tadigant n yisallen d tilemt. Aru ihi kra akken ad tt-teฤฤareแธ!", "empty_column.domain_blocks": "Ulac kra n taษฃult yettwaffren ar tura.", - "empty_column.follow_requests": "Ulac ษฃur-k ula yiwen n usuter n teแธfeแน›t. Ticki teแนญแนญfeแธ-d yiwen ad d-yettwasken da.", + "empty_column.follow_requests": "Ulac ษฃur-kยทm ula yiwen n usuter n teแธfeแน›t. Ticki teแนญแนญfeแธ-d yiwen ad d-yettwasken da.", "empty_column.hashtag": "Ar tura ulac kra n ugbur yesษ›an assaษฃ ษฃer uhacแนญag-agi.", "empty_column.home": "Tasuddemt tagejdant n yisallen d tilemt! แบ’er {public} neษฃ nadi ad tafeแธ imseqdacen-nniแธen ad ten-แธefแน›eแธ.", "empty_column.list": "Ar tura ur yelli kra deg umuษฃ-a. Ad d-yettwasken da ticki iษ›eggalen n wumuษฃ-a suffษฃen-d kra.", - "empty_column.lists": "Ulac ษฃur-k kra n wumuษฃ yakan. Ad d-tettwasken da ticki tesluleแธ-d yiwet.", - "empty_column.mutes": "Ulac ษฃur-k imseqdacen i yettwasgugmen.", - "empty_column.notifications": "Ulac ษฃur-k tilษฃa. Sedmer akked yemdanen-nniแธen akken ad tebduแธ adiwenni.", + "empty_column.lists": "Ulac ษฃur-kยทm kra n wumuษฃ yakan. Ad d-tettwasken da ticki tesluleแธ-d yiwet.", + "empty_column.mutes": "Ulac ษฃur-kยทm imseqdacen i yettwasgugmen.", + "empty_column.notifications": "Ulac ษฃur-kยทm tilษฃa. Sedmer akked yemdanen-nniแธen akken ad tebduแธ adiwenni.", "empty_column.public": "Ulac kra da! Aru kra, neษฃ แธfeแน› imdanen i yellan deg yiqeddacen-nniแธen akken ad d-teฤฤar tsuddemt tazayezt", "error.unexpected_crash.next_steps": "Smiren asebter-a, ma ur yekkis ara wugur, แบ“er d akken tzemreแธ ad tesqedceแธ Maแนฃแนญudun deg yiminig-nniแธen neษฃ deg usnas anaแนฃli.", "errors.unexpected_crash.copy_stacktrace": "Nษฃel stacktrace ษฃef wafus", @@ -183,16 +214,25 @@ "explore.trending_links": "Isallen", "explore.trending_statuses": "Tisuffaษฃ", "explore.trending_tags": "Ihacแนญagen", + "filter_modal.added.review_and_configure_title": "Iษฃewwaแน›en n imzizdig", "filter_modal.added.settings_link": "asebter n yiษฃewwaแน›en", + "filter_modal.added.short_explanation": "Tasuffeษฃt-a tettwarna ษฃer taggayt-a n yimsizdegen: {title}.", + "filter_modal.select_filter.expired": "yemmut", "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", "follow_request.authorize": "Ssireg", "follow_request.reject": "Agi", + "follow_suggestions.dismiss": "Ur ttษ›awad ara ad t-id-sekneแนญ", + "follow_suggestions.view_all": "Wali-ten akk", + "follow_suggestions.who_to_follow": "Menhu ara แธefแน›eแธ", "followed_tags": "Ihacแนญagen yettwaแธfaren", "footer.about": "ฦ”ef", - "footer.directory": "Akaram n imaษฃnuten", + "footer.directory": "Akaram n imeษฃna", "footer.get_app": "Awi-d asnas", "footer.invite": "ฦreแธ-d kra n yimdanen", "footer.keyboard_shortcuts": "Inegzumen n unasiw", @@ -209,15 +249,30 @@ "hashtag.column_settings.tag_mode.any": "Yiwen seg-sen", "hashtag.column_settings.tag_mode.none": "Yiwen ala seg-sen", "hashtag.column_settings.tag_toggle": "Glu-d s yihacแนญagen imerna i ujgu-agi", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} imtekki} other {{counter} n imtekkiyen}}", + "hashtag.counter_by_uses": "{count, plural, one {{counter} n tsuffeษฃt} other {{counter} n tsuffaษฃ}}", + "hashtag.counter_by_uses_today": "{count, plural, one {{counter} n tsuffeษฃt} other {{counter} n tsuffaษฃ}} assa", "hashtag.follow": "แธŒfeแน› ahacแนญag", - "home.column_settings.basic": "Igejdanen", + "hashtags.and_other": "โ€ฆd {count, plural, one {}other {# nniแธen}}", "home.column_settings.show_reblogs": "Ssken-d beแนญแนญu", "home.column_settings.show_replies": "Ssken-d tiririyin", "home.hide_announcements": "Ffer ulษฃuyen", + "home.pending_critical_update.body": "Ma ulac aษฃilif, leqqem aqeddac-ik Mastodon akken kan tzemreแธ !", + "home.pending_critical_update.link": "Wali ileqman", "home.show_announcements": "Ssken-d ulษฃuyen", + "interaction_modal.description.favourite": "S umiแธan ษฃef Mastodon, tzemreแธ ad tesmenyifeแธ tasuffeษฃt-a akken ad teวงวงeแธ amaru ad iแบ“er belli tแธฅemmleแธ-tt u ad tt-id-tsellkeแธ i ticki.", + "interaction_modal.description.follow": "S umiแธan deg Mastodon, tzemreแธ ad tแธefreแธ {name} akken ad d-teแนญแนญfeแธ iznan-is deg lxiแธ-ikยทim agejdan.", + "interaction_modal.description.reblog": "S umiแธan deg Mastodon, tzemreแธ ad tesnerniแธ tasuffeษฃt-a akken ad tt-tebแธuแธ d yineแธfaren-ikยทim.", + "interaction_modal.description.reply": "S umiแธan deg Mastodon, tzemreแธ ad d-terreแธ ษฃef tsuffeษฃt-a.", + "interaction_modal.login.action": "Awi-yi ษฃer uqeddac-iw", + "interaction_modal.login.prompt": "Taษฃult n uqeddac-ikยทim agejdan, amedya mastodon.social", "interaction_modal.no_account_yet": "Ulac-ikยทikem deg Maแนฃแนญudun?", + "interaction_modal.on_another_server": "Deg uqeddac nniแธen", "interaction_modal.on_this_server": "Deg uqeddac-ayi", + "interaction_modal.sign_in": "Ur tekcimeแธ ara ษฃer uqeddac-a. Anda yella umiแธan-ikยทim ?", + "interaction_modal.sign_in_hint": "Ihi : Wa d asmel ideg tjerdeแธ. Ma ur tecfiแธ ara, nadi imayl n ummager deg tenkult-ikยทim. Tzemreแธ daษฃen ad d-tefkeแธ isem-ikยทim n useqdac ummid ! (amedya @Mastodon@mastodon.social)", "interaction_modal.title.follow": "แธŒfer {name}", + "interaction_modal.title.reply": "Tiririt i tsuffeษฃt n {name}", "intervals.full.days": "{number, plural, one {# n wass} other {# n wussan}}", "intervals.full.hours": "{number, plural, one {# n usarag} other {# n yesragen}}", "intervals.full.minutes": "{number, plural, one {# n tesdat} other {# n tesdatin}}", @@ -230,6 +285,7 @@ "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "i kennu ษฃer wadda n tebdart", "keyboard_shortcuts.enter": "i tildin n tsuffeษฃt", + "keyboard_shortcuts.favourites": "Ldi tabdert n yismenyifen", "keyboard_shortcuts.federated": "i tildin n tsuddemt tamatut n yisallen", "keyboard_shortcuts.heading": "Inegzumen n unasiw", "keyboard_shortcuts.home": "i tildin n tsuddemt tagejdant n yisallen", @@ -258,6 +314,7 @@ "lightbox.expand": "Simeษฃer tamnaแธt n uskan n tugna", "lightbox.next": "ฦ”er zdat", "lightbox.previous": "ฦ”er deffir", + "limited_account_hint.action": "Wali amaษฃnu akken yebษฃu yili", "link_preview.author": "S-ษฃur {name}", "lists.account.add": "Rnu ษฃer tebdart", "lists.account.remove": "Kkes seg tebdart", @@ -275,11 +332,12 @@ "load_pending": "{count, plural, one {# n uferdis amaynut} other {# n yiferdisen imaynuten}}", "loading_indicator.label": "Yessalay-d โ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Ffer tugna} other {Ffer tugniwin}}", - "mute_modal.duration": "Tanzagt", - "mute_modal.hide_notifications": "Tebษฃiแธ ad teffreแธ talษฃutin n umseqdac-a?", - "mute_modal.indefinite": "Ur yettwasbadu ara", + "mute_modal.hide_options": "Ffer tinefrunin", + "mute_modal.show_options": "Sken-d tinefrunin", + "mute_modal.title": "Sgugem aseqdac?", "navigation_bar.about": "ฦ”ef", - "navigation_bar.blocks": "Imseqdacen yettusแธฅebsen", + "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", "navigation_bar.compose": "Aru tajewwiqt tamaynut", @@ -289,10 +347,12 @@ "navigation_bar.favourites": "Imenyafen", "navigation_bar.filters": "Awalen i yettwasgugmen", "navigation_bar.follow_requests": "Isuturen n teแธfeแน›t", + "navigation_bar.followed_tags": "Ihacแนญagen yettwaแธfaren", "navigation_bar.follows_and_followers": "Imeแธfaแน›en akked wid i teแนญแนญafaแน›eแธ", "navigation_bar.lists": "Tibdarin", "navigation_bar.logout": "Ffeษฃ", "navigation_bar.mutes": "Iseqdacen yettwasusmen", + "navigation_bar.opened_in_classic_interface": "Tisuffaษฃ, imiแธanen akked isebtar-nniแธen igejdanen ldin-d s wudem amezwer deg ugrudem web aklasiki.", "navigation_bar.personal": "Udmawan", "navigation_bar.pins": "Tisuffaษฃ yettwasenแนญแธen", "navigation_bar.preferences": "Imenyafen", @@ -300,18 +360,22 @@ "navigation_bar.search": "Nadi", "navigation_bar.security": "Taษฃellist", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", - "notification.follow": "{name} yeแนญแนญafaแน›-ik", - "notification.follow_request": "{name} yessuter-d ad k-yeแธfeแน›", + "notification.follow": "iแนญแนญafar-ikยทem-id {name}", + "notification.follow_request": "{name} yessuter-d ad kยทm-yeแธfeแน›", "notification.mention": "{name} yebder-ik-id", "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", + "notification_requests.notifications_from": "Ilษฃa sษฃur {name}", "notifications.clear": "Sfeแธ tilษฃa", "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": "Ssken-d meแน›แน›a tiggayin", + "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:", @@ -322,6 +386,7 @@ "notifications.column_settings.show": "Ssken-d tilษฃa deg ujgu", "notifications.column_settings.sound": "Rmed imesli", "notifications.column_settings.status": "Tisuffaษฃ timaynutin :", + "notifications.column_settings.unread_notifications.category": "Ilษฃa ur nettwaษฃra", "notifications.filter.all": "Akk", "notifications.filter.boosts": "Seวงhed", "notifications.filter.favourites": "Imenyafen", @@ -333,6 +398,14 @@ "notifications.group": "{count} n tilษฃa", "notifications.mark_as_read": "Creแธ meแน›แน›a iilษฃa am wakken ttwaษฃran", "notifications.permission_denied": "D awezษฃi ad yili wermad n yilษฃa n tnarit axateแน› turagt tettwagdel.", + "notifications.policy.filter_new_accounts.hint": "Imiแธanen imaynuten i d-yennulfan deg {days, plural, one {yiwen n wass} other {# n wussan}} yezrin", + "notifications.policy.filter_new_accounts_title": "Imiแธan imaynuten", + "notifications.policy.filter_not_followers_hint": "Ula d wid akked tid i kยทm-id-iแธefren, ur wwiแธen ara {days, plural, one {yiwen n wass} other {# n wussan}}", + "notifications.policy.filter_not_followers_title": "Wid akked tid ur kยทm-id-yeแนญแนญafaren ara", + "notifications.policy.filter_not_following_hint": "Alamma tqebleแธ-ten s ufus", + "notifications.policy.filter_not_following_title": "Wid akked tid ur tettแธafareแธ ara", + "notifications.policy.filter_private_mentions_title": "Abdar uslig ur yettwasferken ara", + "notifications.policy.title": "Sizdeg ilษฃa sษฃur โ€ฆ", "notifications_permission_banner.enable": "Rmed talษฃutin n tnarit", "notifications_permission_banner.title": "Ur zeggel acemma", "onboarding.action.back": "Tuษฃalin ษฃer deffir", @@ -341,21 +414,32 @@ "onboarding.actions.go_to_home": "Go to your home feed", "onboarding.compose.template": "Azul a #Mastodon!", "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.title": "Popular on Mastodon", + "onboarding.follows.title": "Ttwassnen deg Mastodon", "onboarding.profile.display_name": "Isem ara d-yettwaskanen", + "onboarding.profile.note": "Tameddurt", + "onboarding.profile.note_hint": "Tzemreแธ ad d-@tbedreแธ imdanen niแธen neษฃ #ihacแนญagen โ€ฆ", + "onboarding.profile.save_and_continue": "Sekles, tkemmleแธ", + "onboarding.profile.title": "Asbadu n umaษฃnu", + "onboarding.profile.upload_avatar": "Sali tugna n umaษฃnu", + "onboarding.profile.upload_header": "Sali tacacit n umaษฃnu", + "onboarding.share.lead": "Ini-asen i medden amek ara kยทm-id-afen deg Mastodon!", + "onboarding.share.message": "Nekk d {username} deg #Mastodon! แธŒfer iyi-d sya {url}", "onboarding.share.title": "Bแธu amaษฃnu-inekยทinem", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.skip": "Want to skip right ahead?", - "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", + "onboarding.start.title": "Tseggmeแธ-tt !", + "onboarding.steps.follow_people.body": "Aแธfer n medden yelhan, d tikti n Mastodon.", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", - "onboarding.steps.publish_status.body": "Say hello to the world.", + "onboarding.steps.publish_status.body": "Ini-as azul i umaแธal s uแธris, s tiwlafin, s tividyutin neษฃ s tefranin {emoji}", + "onboarding.steps.publish_status.title": "Aru tasuffeษฃt-inekยทinem tamezwarutt", "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", "picture_in_picture.restore": "Err-it amkan-is", - "poll.closed": "Ifukk", + "poll.closed": "Tfukk", "poll.refresh": "Smiren", + "poll.reveal": "Wali igmaแธ", "poll.total_people": "{count, plural, one {# n wemdan} other {# n yemdanen}}", "poll.total_votes": "{count, plural, one {# n udษฃaแน›} other {# n yedษฃaแน›en}}", "poll.vote": "Dษฃeแน›", @@ -363,8 +447,16 @@ "poll_button.add_poll": "Rnu asenqed", "poll_button.remove_poll": "Kkes asenqed", "privacy.change": "Seggem tabaแธnit n yizen", + "privacy.direct.long": "Wid akk i d-yettwabdaren deg tsuffeษฃt", + "privacy.direct.short": "Imdanen yettwafernen", + "privacy.private.long": "Ala wid i kยทm-yeแนญแนญafaแน›en", + "privacy.private.short": "Imeแธfaren", + "privacy.public.long": "Kra n win yellan deg Masแนญudun neษฃ berra-s", "privacy.public.short": "Azayez", + "privacy.unlisted.long": "Kra kan n ilguritmen", + "privacy_policy.last_updated": "Aleqqem aneggaru {date}", "privacy_policy.title": "Tasertit tabaแธnit", + "recommended": "Yettuwelleh", "refresh": "Smiren", "regeneration_indicator.label": "Yessalay-dโ€ฆ", "regeneration_indicator.sublabel": "Tasuddemt tagejdant ara d-tettwaheggay!", @@ -387,23 +479,36 @@ "report.next": "Uแธfiแน›", "report.placeholder": "Iwenniten-nniแธen", "report.reasons.dislike": "Ur t-แธฅemmleษฃ ara", + "report.reasons.other": "D ayen nniแธen", "report.reasons.spam": "D aspam", "report.submit": "Azen", "report.target": "Mmel {target}", + "report.thanks.title": "Ur tebษฃiแธ ara ad twaliแธ aya?", "report.unfollow": "Seแธฅbes aแธfar n @{name}", "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", "report_notification.categories.other": "Ayen nniแธen", "report_notification.categories.spam": "Aspam", "report_notification.open": "Ldi aneqqis", + "search.no_recent_searches": "Ulac inadiyen ineggura", "search.placeholder": "Nadi", + "search.quick_action.account_search": "Imaษฃnuten mแนฃadan d {x}", + "search.quick_action.go_to_account": "Ddu ษฃer umaษฃnu {x}", + "search.quick_action.go_to_hashtag": "Ddu ษฃer uhacแนญag {x}", + "search.quick_action.open_url": "Ldi tansa URL deg Mastodon", + "search.quick_action.status_search": "Tisuffaษฃ mแนฃadan d {x}", "search.search_or_paste": "Nadi neษฃ senแนญeแธ URL", + "search_popout.full_text_search_disabled_message": "Ur yelli ara deg {domain}.", + "search_popout.language_code": "Tangalt ISO n tutlayt", + "search_popout.options": "Iwellihen n unadi", + "search_popout.recent": "Inadiyen ineggura", "search_popout.user": "amseqdac", + "search_results.accounts": "Imeษฃna", "search_results.all": "Akk", "search_results.hashtags": "Ihacแนญagen", + "search_results.see_all": "Wali-ten akk", "search_results.statuses": "Tisuffaษฃ", "search_results.title": "Anadi ษฃef {q}", "server_banner.administered_by": "Yettwadbel sษฃur :", - "server_banner.learn_more": "Issin ugar", "sign_in_banner.create_account": "Snulfu-d amiแธan", "sign_in_banner.sign_in": "Qqen", "sign_in_banner.sso_redirect": "Qqen neษฃ jerred", @@ -415,10 +520,11 @@ "status.copy": "Nษฃel assaษฃ ษฃer tasuffeษฃt", "status.delete": "Kkes", "status.edit": "แบ’reg", - "status.edited": "Tettwaแบ“reg deg {date}", "status.edited_x_times": "Tettwaแบ“reg {count, plural, one {{count} n tikkelt} other {{count} n tikkal}}", "status.embed": "Seddu", + "status.filter": "Sizdeg tassufeษฃt-a", "status.filtered": "Yettwasizdeg", + "status.hide": "Ffer tasuffeษฃt", "status.load_more": "Sali ugar", "status.media_hidden": "Amidya yettwaffer", "status.mention": "Bder-d @{name}", @@ -434,11 +540,13 @@ "status.reblogs.empty": "Ula yiwen ur yebแธi tajewwiqt-agi ar tura. Ticki yebแธa-tt yiwen, ad d-iban da.", "status.redraft": "Kkes tษ›iwdeแธ tira", "status.remove_bookmark": "Kkes tacreแธt", + "status.replied_to": "Yยทterra-yas i {name}", "status.reply": "Err", "status.replyAll": "Err i lxiแธ", "status.report": "Cetki ษฃef @{name}", "status.sensitive_warning": "Agbur amแธฅulfu", "status.share": "Bแธu", + "status.show_filter_reason": "Ssken-d akken yebษฃu yili", "status.show_less": "Ssken-d drus", "status.show_less_all": "Semแบ“i akk tisuffษฃin", "status.show_more": "Ssken-d ugar", @@ -460,7 +568,7 @@ "timeline_hint.resources.followers": "Imeแธfaแน›en", "timeline_hint.resources.follows": "TยทYeแนญafaแน›", "timeline_hint.resources.statuses": "Tisuffaษฃ tiqdimin", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} n wemdan} other {{counter} n medden}} deg {days, plural, one {ass} other {{days} n wussan}} iษ›eddan", "trends.trending_now": "Ayen mucaษ›en tura", "ui.beforeunload": "Arewway-ikยทim ad iruแธฅ ma yella tefeษฃ-d deg Maแนฃแนญudun.", "units.short.billion": "{count}B", @@ -484,6 +592,7 @@ "upload_modal.preparing_ocr": "Aheyyi n OCRโ€ฆ", "upload_modal.preview_label": "Taskant ({ratio})", "upload_progress.label": "Asali iteddu...", + "username.taken": "Yettwaแนญแนญef yisem-a n useqdac. ฦreแธ wayeแธ", "video.close": "Mdel tabidyutt", "video.download": "Sidered afaylu", "video.exit_fullscreen": "Ffeษฃ seg ugdil aฤuran", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 1f6cc78a57..bd0a806cdb 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -105,20 +105,15 @@ "compose_form.spoiler.marked": "ะœำ™ั‚ั–ะฝ ะตัะบะตั€ั‚ัƒะผะตะฝ ะถะฐัั‹ั€ั‹ะปา“ะฐะฝ", "compose_form.spoiler.unmarked": "ะœำ™ั‚ั–ะฝ ะถะฐัั‹ั€ั‹ะปะผะฐา“ะฐะฝ", "confirmation_modal.cancel": "าšะฐะนั‚ั‹ะฟ ะฐะปัƒ", - "confirmations.block.block_and_report": "ะ‘ะปะพะบ ะถำ™ะฝะต ะจะฐา“ั‹ะผ", "confirmations.block.confirm": "ะ‘าฑา“ะฐั‚ั‚ะฐัƒ", - "confirmations.block.message": "{name} ะฐั‚ั‚ั‹ า›ะพะปะดะฐะฝัƒัˆั‹ะฝั‹ ะฑาฑา“ะฐั‚ั‚ะฐะนั‚ั‹ะฝั‹าฃั‹ะทา“ะฐ ัะตะฝั–ะผะดั–ัั–ะท ะฑะต?", "confirmations.delete.confirm": "ำจัˆั–ั€ัƒ", "confirmations.delete.message": "ะ‘าฑะป ะถะฐะทะฑะฐะฝั‹ ำฉัˆั–ั€ะตัั–ะท ะฑะต?", "confirmations.delete_list.confirm": "ำจัˆั–ั€ัƒ", "confirmations.delete_list.message": "ะ‘าฑะป ั‚ั–ะทั–ะผะดั– ะถะพััั‹ะท ะฑะฐ ัˆั‹ะฝั‹ะผะตะฝ?", - "confirmations.domain_block.confirm": "ะ‘าฑะป ะดะพะผะตะฝะดั– ะฑาฑา“ะฐั‚ั‚ะฐ", "confirmations.domain_block.message": "ะ‘าฑะป ะดะพะผะตะฝะดะตะณั– {domain} ะถะฐะทะฑะฐะปะฐั€ะดั‹ ัˆั‹ะฝั‹ะผะตะฝ ะฑาฑา“ะฐั‚ั‚ะฐะนัั‹ะท ะฑะฐ? ะšะตะนะดะต าฏะฝัั–ะท า›ั‹ะปั‹ะฟ ั‚ะฐัั‚ะฐัƒ ะดะฐ ะถะตั‚ะบั–ะปั–ะบั‚ั–.", "confirmations.logout.confirm": "ะจั‹า“ัƒ", "confirmations.logout.message": "ะจั‹า“ะฐั‚ั‹ะฝั‹าฃั‹ะทา“ะฐ ัะตะฝั–ะผะดั–ัั–ะท ะฑะต?", "confirmations.mute.confirm": "าฎะฝัั–ะท า›ั‹ะปัƒ", - "confirmations.mute.explanation": "ะžะปะฐั€ะดั‹าฃ ะฟะพัั‚ั‚ะฐั€ั‹ ะถะต ะพะปะฐั€ ั‚ัƒั€ะฐะปั‹ ะผะตะฝัˆะฝะดะฐั€ ัั–ะทะณะต ะบำฉั€ั–ะฝะฑะตะนะดั–, ะฑั–ั€ะฐา› ะพะปะฐั€ ัั–ะทะดั–าฃ ะฟะพัั‚ั‚ะฐั€ะดั‹ ะบำฉั€ะต ะฐะปะฐะดั‹ ะถำ™ะฝะต ะถะฐะทั‹ะปะฐ ะฐะปะฐะดั‹.", - "confirmations.mute.message": "{name} ะฐั‚ั‚ั‹ า›ะพะปะดะฐะฝัƒัˆั‹ าฏะฝัั–ะท ะฑะพะปัั‹ะฝ ะฑะฐ?", "confirmations.redraft.confirm": "ำจัˆั–ั€ัƒะดั– า›าฑะฟั‚ะฐัƒ", "confirmations.reply.confirm": "ะ–ะฐัƒะฐะฟ", "confirmations.reply.message": "ะ–ะฐัƒะฐะฑั‹าฃั‹ะท ะถะฐะทั‹ะฟ ะถะฐั‚า›ะฐะฝ ะถะฐะทะฑะฐาฃั‹ะทะดั‹าฃ าฏัั‚ั–ะฝะต ะบะตั‚ะตะดั–. ะ–ะฐะปา“ะฐัั‚ั‹ั€ะฐะผั‹ะท ะฑะฐ?", @@ -181,7 +176,6 @@ "hashtag.column_settings.tag_mode.any": "ะžัั‹ะปะฐั€ะดั‹าฃ ะฑั–ั€ะตัƒั–ะฝ", "hashtag.column_settings.tag_mode.none": "ะ‘าฑะปะฐั€ะดั‹าฃ ะตัˆา›ะฐะนัั‹ัั‹ะฝ", "hashtag.column_settings.tag_toggle": "ะžัั‹ ะฑะฐา“ะฐะฝา“ะฐ า›ะพัั‹ะผัˆะฐ ั‚ะตะณั‚ะตั€ะดั– า›ะพัั‹าฃั‹ะท", - "home.column_settings.basic": "ะะตะณั–ะทะณั–", "home.column_settings.show_reblogs": "ะ‘ำฉะปั–ััƒะปะตั€ะดั– ะบำฉั€ัะตั‚ัƒ", "home.column_settings.show_replies": "ะ–ะฐัƒะฐะฟั‚ะฐั€ะดั‹ ะบำฉั€ัะตั‚ัƒ", "home.hide_announcements": "ะะฝะพะฝัั‚ะฐั€ะดั‹ ะถะฐัั‹ั€", @@ -235,7 +229,6 @@ "lists.subheading": "ะขั–ะทั–ะผะดะตั€ั–าฃั–ะท", "load_pending": "{count, plural, one {# ะถะฐาฃะฐ ะฝำ™ั€ัะต} other {# ะถะฐาฃะฐ ะฝำ™ั€ัะต}}", "media_gallery.toggle_visible": "ะšำฉั€ั–ะฝัƒะดั– า›ะพััƒ", - "mute_modal.hide_notifications": "ะ‘าฑะป า›ะพะปะดะฐะฝัƒัˆั‹ ะตัะบะตั€ั‚ะฟะตะปะตั€ั–ะฝ ะถะฐัั‹ั€ะฐะผั‹ะท ะฑะฐ?", "navigation_bar.blocks": "ะ‘าฑา“ะฐั‚ั‚ะฐะปา“ะฐะฝะดะฐั€", "navigation_bar.bookmarks": "ะ‘ะตั‚ะฑะตะปะณั–ะปะตั€", "navigation_bar.community_timeline": "ะ–ะตั€ะณั–ะปั–ะบั‚ั– ะถะตะปั–", @@ -263,8 +256,6 @@ "notifications.clear": "ะ•ัะบะตั€ั‚ะฟะตะปะตั€ะดั– ั‚ะฐะทะฐั€ั‚", "notifications.clear_confirmation": "ะจั‹ะฝั‹ะผะตะฝ ะฑะฐั€ะปั‹า› ะตัะบะตั€ั‚ะฟะตะปะตั€ะดั– ำฉัˆั–ั€ะตัั–ะท ะฑะต?", "notifications.column_settings.alert": "าฎัั‚ะตะป ะตัะบะตั€ั‚ะฟะตะปะตั€ั–", - "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/kn.json b/app/javascript/mastodon/locales/kn.json index 396aebbdf2..ceb0f8b9b6 100644 --- a/app/javascript/mastodon/locales/kn.json +++ b/app/javascript/mastodon/locales/kn.json @@ -31,7 +31,6 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmations.delete.message": "Are you sure you want to delete this status?", - "confirmations.domain_block.confirm": "Hide entire domain", "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.", "embed.instructions": "Embed this status on your website by copying the code below.", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 50d9959994..c4c084d98e 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "๊ฒŒ์‹œ๋ฌผ ์—†์Œ", "account.featured_tags.title": "{name} ๋‹˜์˜ ์ถ”์ฒœ ํ•ด์‹œํƒœ๊ทธ", "account.follow": "ํŒ”๋กœ์šฐ", - "account.follow_back": "๋งžํŒ”๋กœ์šฐ", + "account.follow_back": "๋งžํŒ”๋กœ์šฐ ํ•˜๊ธฐ", "account.followers": "ํŒ”๋กœ์›Œ", "account.followers.empty": "์•„์ง ์•„๋ฌด๋„ ์ด ์‚ฌ์šฉ์ž๋ฅผ ํŒ”๋กœ์šฐํ•˜๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", "account.followers_counter": "{counter} ํŒ”๋กœ์›Œ", @@ -53,7 +53,7 @@ "account.mute_notifications_short": "์•Œ๋ฆผ ๋ฎคํŠธ", "account.mute_short": "๋ฎคํŠธ", "account.muted": "๋ฎคํŠธ๋จ", - "account.mutual": "์ƒํ˜ธ ํŒ”๋กœ์šฐ", + "account.mutual": "๋งžํŒ”๋กœ์šฐ ์ค‘", "account.no_bio": "์ œ๊ณต๋œ ์„ค๋ช…์ด ์—†์Šต๋‹ˆ๋‹ค.", "account.open_original_page": "์›๋ณธ ํŽ˜์ด์ง€ ์—ด๊ธฐ", "account.posts": "๊ฒŒ์‹œ๋ฌผ", @@ -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": "์š”์ฒญํ•œ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋ง ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ €ํฌ์˜ ์ฝ”๋“œ์— ๋ฒ„๊ทธ๊ฐ€ ์žˆ๊ฑฐ๋‚˜, ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "์—ด๋žŒ ์ฃผ์˜ ๋ฌธ๊ตฌ ์ถ”๊ฐ€", "compose_form.spoiler_placeholder": "๋‚ด์šฉ ๊ฒฝ๊ณ  (์„ ํƒ์‚ฌํ•ญ)", "confirmation_modal.cancel": "์ทจ์†Œ", - "confirmations.block.block_and_report": "์ฐจ๋‹จํ•˜๊ณ  ์‹ ๊ณ ํ•˜๊ธฐ", "confirmations.block.confirm": "์ฐจ๋‹จ", - "confirmations.block.message": "์ •๋ง๋กœ {name}๋ฅผ ์ฐจ๋‹จํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "confirmations.cancel_follow_request.confirm": "์š”์ฒญ ์‚ญ์ œ", "confirmations.cancel_follow_request.message": "์ •๋ง {name}๋‹˜์— ๋Œ€ํ•œ ํŒ”๋กœ์šฐ ์š”์ฒญ์„ ์ทจ์†Œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "confirmations.delete.confirm": "์‚ญ์ œ", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "์ •๋ง๋กœ ์ด ๋ฆฌ์ŠคํŠธ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "confirmations.discard_edit_media.confirm": "์ €์žฅ ์•ˆํ•จ", "confirmations.discard_edit_media.message": "๋ฏธ๋””์–ด ์„ค๋ช…์ด๋‚˜ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์— ๋Œ€ํ•œ ์ €์žฅํ•˜์ง€ ์•Š์€ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„๋ฆฌ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", - "confirmations.domain_block.confirm": "๋„๋ฉ”์ธ ์ „์ฒด๋ฅผ ์ฐจ๋‹จ", + "confirmations.domain_block.confirm": "์„œ๋ฒ„ ์ฐจ๋‹จ", "confirmations.domain_block.message": "์ •๋ง๋กœ {domain} ์ „์ฒด๋ฅผ ์ฐจ๋‹จํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๊ฐœ๋ณ„ ์ฐจ๋‹จ์ด๋‚˜ ๋ฎคํŠธ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ณต๊ฐœ ํƒ€์ž„๋ผ์ธ๊ณผ ์•Œ๋ฆผ์—์„œ ํ•ด๋‹น ๋„๋ฉ”์ธ์—์„œ ์ž‘์„ฑ๋œ ์ฝ˜ํ…์ธ ๋ฅผ ๋ณด์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋„๋ฉ”์ธ์— ์†ํ•œ ํŒ”๋กœ์›Œ์™€์˜ ๊ด€๊ณ„๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.", "confirmations.edit.confirm": "์ˆ˜์ •", "confirmations.edit.message": "์ง€๊ธˆ ํŽธ์ง‘ํ•˜๋ฉด ์ž‘์„ฑ ์ค‘์ธ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฎ์–ด์”๋‹ˆ๋‹ค. ์ง„ํ–‰์ด ํ™•์‹คํ•œ๊ฐ€์š”?", "confirmations.logout.confirm": "๋กœ๊ทธ์•„์›ƒ", "confirmations.logout.message": "์ •๋ง๋กœ ๋กœ๊ทธ์•„์›ƒ ํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "confirmations.mute.confirm": "๋ฎคํŠธ", - "confirmations.mute.explanation": "์ด ๋™์ž‘์€ ํ•ด๋‹น ๊ณ„์ •์˜ ๊ฒŒ์‹œ๋ฌผ๊ณผ ํ•ด๋‹น ๊ณ„์ •์„ ๋ฉ˜์…˜ํ•˜๋Š” ๊ฒŒ์‹œ๋ฌผ์„ ์ˆจ๊น๋‹ˆ๋‹ค, ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ํ•ด๋‹น ๊ณ„์ •์ด ๋‹น์‹ ์˜ ๊ฒŒ์‹œ๋ฌผ์„ ๋ณด๊ณ  ํŒ”๋กœ์šฐ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.", - "confirmations.mute.message": "์ •๋ง๋กœ {name} ๋‹˜์„ ๋ฎคํŠธํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "confirmations.redraft.confirm": "์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์“ฐ๊ธฐ", "confirmations.redraft.message": "์ •๋ง๋กœ ์ด ๊ฒŒ์‹œ๋ฌผ์„ ์‚ญ์ œํ•˜๊ณ  ๋‹ค์‹œ ์“ฐ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ? ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ์— ๋Œ€ํ•œ ๋ถ€์ŠคํŠธ์™€ ์ข‹์•„์š”๋ฅผ ์žƒ๊ฒŒ ๋˜๊ณ  ์›๋ณธ์— ๋Œ€ํ•œ ๋‹ต์žฅ์€ ์—ฐ๊ฒฐ ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.", "confirmations.reply.confirm": "๋‹ต๊ธ€", @@ -205,14 +209,35 @@ "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": "์ด๊ฒƒ์€ ๋งˆ์Šคํ† ๋ˆ ๋ฟ๋งŒ์ด ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์†Œ์…œ ์•ฑ๋“ค์„ ๋„˜๋‚˜๋“ค๋ฉฐ ์‚ฌ๋žŒ๋“ค์„ ์—ฐ๊ฒฐํ•˜๊ณ  ์ƒํ˜ธ์ž‘์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.", + "domain_pill.activitypub_like_language": "์•กํ‹ฐ๋น„ํ‹ฐํŽ์€ ๋งˆ์Šคํ† ๋ˆ์ด ๋‹ค๋ฅธ ์†Œ์…œ ๋„คํŠธ์›Œํฌ์™€ ๋Œ€ํ™”ํ•  ๋•Œ ์“ฐ๋Š” ์–ธ์–ด ๊ฐ™์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค.", + "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": "ํ™œ๋™", "emoji_button.clear": "์ง€์šฐ๊ธฐ", - "emoji_button.custom": "์‚ฌ์šฉ์ž ์ง€์ •", + "emoji_button.custom": "์ปค์Šคํ…€", "emoji_button.flags": "๊นƒ๋ฐœ", "emoji_button.food": "์Œ์‹๊ณผ ๋งˆ์‹ค๊ฒƒ", - "emoji_button.label": "์—๋ชจ์ง€๋ฅผ ์ถ”๊ฐ€", + "emoji_button.label": "์—๋ชจ์ง€ ์ถ”๊ฐ€", "emoji_button.nature": "์ž์—ฐ", "emoji_button.not_found": "ํ•ด๋‹นํ•˜๋Š” ์—๋ชจ์ง€๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค", "emoji_button.objects": "๋ฌผ๊ฑด", @@ -241,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": "๋ฒ„๊ทธ ํ˜น์€ ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋กœ ์ด ํŽ˜์ด์ง€๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", @@ -271,16 +297,28 @@ "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": "๋ชจ๋‘", "firehose.local": "์ด ์„œ๋ฒ„", "firehose.remote": "๋‹ค๋ฅธ ์„œ๋ฒ„", - "follow_request.authorize": "ํ—ˆ๊ฐ€", + "follow_request.authorize": "์Šน์ธ", "follow_request.reject": "๊ฑฐ๋ถ€", "follow_requests.unlocked_explanation": "๊ท€ํ•˜์˜ ๊ณ„์ •์ด ์ž ๊ธด ๊ณ„์ •์ด ์•„๋‹์ง€๋ผ๋„, {domain} ์Šคํƒœํ”„๋Š” ์ด ๊ณ„์ •๋“ค์˜ ํŒ”๋กœ์šฐ ์š”์ฒญ์„ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด ์ฃผ์‹œ๋ฉด ์ข‹๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.", - "follow_suggestions.curated_suggestion": "์ค‘์žฌ์ž์˜ ์ถ”์ฒœ", + "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}์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ํŒ”๋กœ์šฐ ๋œ ์‚ฌ๋žŒ๋“ค ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.", + "follow_suggestions.hints.most_interactions": "์ด ํ”„๋กœํ•„์€ ์ตœ๊ทผ {domain}์—์„œ ๋งŽ์€ ๊ด€์‹ฌ์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.", + "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": "ํŒ”๋กœ์šฐ ์ค‘์ธ ํ•ด์‹œํƒœ๊ทธ", @@ -309,7 +347,6 @@ "hashtag.follow": "ํŒ”๋กœ์šฐ", "hashtag.unfollow": "ํŒ”๋กœ์šฐ ํ•ด์ œ", "hashtags.and_other": "โ€ฆ๊ทธ๋ฆฌ๊ณ  {count, plural,other {#๊ฐœ ๋”}}", - "home.column_settings.basic": "๊ธฐ๋ณธ", "home.column_settings.show_reblogs": "๋ถ€์ŠคํŠธ ํ‘œ์‹œ", "home.column_settings.show_replies": "๋‹ต๊ธ€ ํ‘œ์‹œ", "home.hide_announcements": "๊ณต์ง€์‚ฌํ•ญ ์ˆจ๊ธฐ๊ธฐ", @@ -377,6 +414,8 @@ "limited_account_hint.action": "๊ทธ๋ž˜๋„ ํ”„๋กœํ•„ ๋ณด๊ธฐ", "limited_account_hint.title": "์ด ํ”„๋กœํ•„์€ {domain}์˜ ์ค‘์žฌ์ž์— ์˜ํ•ด ์ˆจ๊ฒจ์ง„ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.", "link_preview.author": "{name}", + "link_preview.more_from_author": "{name} ํ”„๋กœํ•„ ๋ณด๊ธฐ", + "link_preview.shares": "{count, plural, other {{counter} ๊ฐœ์˜ ๊ฒŒ์‹œ๋ฌผ}}", "lists.account.add": "๋ฆฌ์ŠคํŠธ์— ์ถ”๊ฐ€", "lists.account.remove": "๋ฆฌ์ŠคํŠธ์—์„œ ์ œ๊ฑฐ", "lists.delete": "๋ฆฌ์ŠคํŠธ ์‚ญ์ œ", @@ -395,9 +434,15 @@ "loading_indicator.label": "๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘...", "media_gallery.toggle_visible": "์ด๋ฏธ์ง€ ์ˆจ๊ธฐ๊ธฐ", "moved_to_account_banner.text": "๋‹น์‹ ์˜ ๊ณ„์ • {disabledAccount}๋Š” {movedToAccount}๋กœ ์ด๋™ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ํ˜„์žฌ ๋น„ํ™œ์„ฑํ™” ์ƒํƒœ์ž…๋‹ˆ๋‹ค.", - "mute_modal.duration": "๊ธฐ๊ฐ„", - "mute_modal.hide_notifications": "์ด ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ์˜ ์•Œ๋ฆผ์„ ์ˆจ๊ธฐ์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", - "mute_modal.indefinite": "๋ฌด๊ธฐํ•œ", + "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": "์ฐจ๋‹จํ•œ ์‚ฌ์šฉ์ž", @@ -430,20 +475,37 @@ "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.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": "์ˆ˜๋ฝ", + "notification_requests.dismiss": "์ง€์šฐ๊ธฐ", + "notification_requests.notifications_from": "{name} ๋‹˜์œผ๋กœ๋ถ€ํ„ฐ์˜ ์•Œ๋ฆผ", + "notification_requests.title": "๊ฑธ๋Ÿฌ์ง„ ์•Œ๋ฆผ", "notifications.clear": "์•Œ๋ฆผ ๋น„์šฐ๊ธฐ", "notifications.clear_confirmation": "์ •๋ง๋กœ ์•Œ๋ฆผ์„ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?", "notifications.column_settings.admin.report": "์ƒˆ ์‹ ๊ณ :", "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.advanced": "๋ชจ๋“  ๋ฒ”์ฃผ ํ‘œ์‹œ", "notifications.column_settings.filter_bar.category": "๋น ๋ฅธ ํ•„ํ„ฐ ๋ง‰๋Œ€", - "notifications.column_settings.filter_bar.show_bar": "ํ•„ํ„ฐ ๋ง‰๋Œ€ ๋ณด์ด๊ธฐ", "notifications.column_settings.follow": "์ƒˆ ํŒ”๋กœ์›Œ:", "notifications.column_settings.follow_request": "์ƒˆ ํŒ”๋กœ์šฐ ์š”์ฒญ:", "notifications.column_settings.mention": "๋ฉ˜์…˜:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์„ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์—†์Œ", "notifications.permission_denied_alert": "์ด์ „์— ๋ธŒ๋ผ์šฐ์ € ๊ถŒํ•œ์ด ๊ฑฐ๋ถ€๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์ด ํ™œ์„ฑํ™” ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", "notifications.permission_required": "ํ•„์š”ํ•œ ๊ถŒํ•œ์ด ์Šน์ธ๋˜์ง€ ์•Š์•„ ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", + "notifications.policy.filter_new_accounts.hint": "{days, plural, one {ํ•˜๋ฃจ} other {#์ผ}} ์•ˆ์— ๋งŒ๋“ค์–ด์ง„", + "notifications.policy.filter_new_accounts_title": "์ƒˆ ๊ณ„์ •", + "notifications.policy.filter_not_followers_hint": "๋‚˜๋ฅผ ํŒ”๋กœ์šฐ ํ•œ ์ง€ {days, plural, other {# ์ผ}}์ด ๋˜์ง€ ์•Š์€ ์‚ฌ๋žŒ๋“ค์„ ํฌํ•จ", + "notifications.policy.filter_not_followers_title": "๋‚˜๋ฅผ ํŒ”๋กœ์šฐํ•˜์ง€ ์•Š๋Š” ์‚ฌ๋žŒ๋“ค", + "notifications.policy.filter_not_following_hint": "๋‚ด๊ฐ€ ์ˆ˜๋™์œผ๋กœ ์Šน์ธํ•˜์ง€ ์•Š๋Š” ํ•œ", + "notifications.policy.filter_not_following_title": "๋‚ด๊ฐ€ ํŒ”๋กœ์šฐํ•˜์ง€ ์•Š๋Š” ์‚ฌ๋žŒ๋“ค", + "notifications.policy.filter_private_mentions_hint": "๋‚ด๊ฐ€ ํ•œ ๋ฉ˜์…˜์— ๋‹จ ๋‹ต๊ธ€์ด๊ฑฐ๋‚˜ ๋‚ด๊ฐ€ ๋ฐœ์‹ ์ž๋ฅผ ํŒ”๋กœ์šฐ ํ•œ ๊ฒƒ์ด ์•„๋‹Œ ์ด์ƒ ๊ฑธ๋Ÿฌ์ง‘๋‹ˆ๋‹ค", + "notifications.policy.filter_private_mentions_title": "์ฒญํ•˜์ง€ ์•Š์€ ๊ฐœ์ธ์ ์ธ ๋ฉ˜์…˜", + "notifications.policy.title": "์•Œ๋ฆผ์„ ์ œ์™ธํ•  ์กฐ๊ฑด๋“คโ€ฆ", "notifications_permission_banner.enable": "๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ ํ™œ์„ฑํ™”", "notifications_permission_banner.how_to_control": "๋งˆ์Šคํ† ๋ˆ์ด ์—ด๋ ค ์žˆ์ง€ ์•Š์„ ๋•Œ์—๋„ ์•Œ๋ฆผ์„ ๋ฐ›์œผ๋ ค๋ฉด, ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์„ ํ™œ์„ฑํ™” ํ•˜์„ธ์š”. ๋‹น์‹ ์€ ์–ด๋–ค ์ข…๋ฅ˜์˜ ๋ฐ˜์‘์ด ๋ฐ์Šคํฌํƒ‘ ์•Œ๋ฆผ์„ ๋ฐœ์ƒํ•  ์ง€๋ฅผ {icon} ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์„ธ์„ธํ•˜๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.", "notifications_permission_banner.title": "์•„๋ฌด๊ฒƒ๋„ ๋†“์น˜์ง€ ๋งˆ์„ธ์š”", @@ -531,7 +602,7 @@ "privacy.public.long": "๋งˆ์Šคํ† ๋ˆ ๋‚ด์™ธ ๋ชจ๋‘", "privacy.public.short": "๊ณต๊ฐœ", "privacy.unlisted.additional": "๊ณต๊ฐœ์™€ ๋˜‘๊ฐ™์ง€๋งŒ ๊ฒŒ์‹œ๋ฌผ์ด ์‹ค์‹œ๊ฐ„ ํ”ผ๋“œ๋‚˜ ํ•ด์‹œํƒœ๊ทธ, ๋‘˜๋Ÿฌ๋ณด๊ธฐ, (๊ณ„์ • ์„ค์ •์—์„œ ํ—ˆ์šฉํ–ˆ๋”๋ผ๋„) ๋งˆ์Šคํ† ๋ˆ ๊ฒ€์ƒ‰์—์„œ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค.", - "privacy.unlisted.long": "๋” ์ ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŒกํŒŒ๋ ˆ", + "privacy.unlisted.long": "๋” ์ ์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํŒกํŒŒ๋ฅด", "privacy.unlisted.short": "์กฐ์šฉํ•œ ๊ณต๊ฐœ", "privacy_policy.last_updated": "{date}์— ๋งˆ์ง€๋ง‰์œผ๋กœ ์—…๋ฐ์ดํŠธ๋จ", "privacy_policy.title": "๊ฐœ์ธ์ •๋ณด์ฒ˜๋ฆฌ๋ฐฉ์นจ", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "30์ผ ๋™์•ˆ ์ด ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•œ ์‚ฌ๋žŒ๋“ค (์›”๊ฐ„ ํ™œ์„ฑ ์ด์šฉ์ž)", "server_banner.active_users": "ํ™œ์„ฑ ์‚ฌ์šฉ์ž", "server_banner.administered_by": "๊ด€๋ฆฌ์ž:", - "server_banner.introduction": "{domain}์€ ๋งˆ์Šคํ† ๋ˆ์œผ๋กœ ์šด์˜๋˜๋Š” ํƒˆ์ค‘์•™ํ™” ๋œ ์†Œ์…œ ๋„คํŠธ์›Œํฌ์˜ ์ผ๋ถ€์ž…๋‹ˆ๋‹ค.", - "server_banner.learn_more": "๋” ์•Œ์•„๋ณด๊ธฐ", + "server_banner.is_one_of_many": "{domain}์€ ํŽ˜๋””๋ฒ„์Šค๋ฅผ ํ†ตํ•ด ์ฐธ์—ฌํ•  ์ˆ˜ ์žˆ๋Š” ๋งŽ์€ ๋งˆ์Šคํ† ๋ˆ ์„œ๋ฒ„๋“ค ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค", "server_banner.server_stats": "์„œ๋ฒ„ ํ†ต๊ณ„:", "sign_in_banner.create_account": "๊ณ„์ • ์ƒ์„ฑ", + "sign_in_banner.follow_anyone": "ํŽ˜๋””๋ฒ„์Šค๋ฅผ ํ†ตํ•ด ๋ˆ„๊ตฌ๋“ ์ง€ ํŒ”๋กœ์šฐํ•˜๊ณ  ์‹œ๊ฐ„์ˆœ์œผ๋กœ ๊ฒŒ์‹œ๋ฌผ์„ ๋ฐ›์•„๋ณด์„ธ์š”. ์•Œ๊ณ ๋ฆฌ์ฆ˜๋„, ๊ด‘๊ณ ๋„, ํด๋ฆญ์„ ์œ ๋„ํ•˜๋Š” ๊ฒƒ๋“ค๋„ ์—†์Šต๋‹ˆ๋‹ค.", + "sign_in_banner.mastodon_is": "๋งˆ์Šคํ† ๋ˆ์€ ๋ฌด์—‡์ด ์ผ์–ด๋‚˜๋Š”์ง€ ๋ฐ›์•„๋ณด๋Š” ๊ฐ€์žฅ ์ข‹์€ ์ˆ˜๋‹จ์ž…๋‹ˆ๋‹ค.", "sign_in_banner.sign_in": "๋กœ๊ทธ์ธ", "sign_in_banner.sso_redirect": "๋กœ๊ทธ์ธ ๋˜๋Š” ๊ฐ€์ž…ํ•˜๊ธฐ", - "sign_in_banner.text": "๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ํ”„๋กœํ•„์ด๋‚˜ ํ•ด์‹œํƒœ๊ทธ๋ฅผ ํŒ”๋กœ์šฐํ•˜๊ฑฐ๋‚˜ ๋งˆ์Œ์— ๋“ค์–ดํ•˜๊ฑฐ๋‚˜ ๊ณต์œ ํ•˜๊ณ  ๋‹ต๊ธ€์„ ๋‹ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์„œ๋ฒ„์— ์žˆ๋Š” ๋ณธ์ธ์˜ ๊ณ„์ •์„ ํ†ตํ•ด ์ฐธ์—ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.", "status.admin_account": "@{name}์— ๋Œ€ํ•œ ์ค‘์žฌ ํ™”๋ฉด ์—ด๊ธฐ", "status.admin_domain": "{domain}์— ๋Œ€ํ•œ ์ค‘์žฌ ํ™”๋ฉด ์—ด๊ธฐ", "status.admin_status": "์ค‘์žฌ ํ™”๋ฉด์—์„œ ์ด ๊ฒŒ์‹œ๋ฌผ ์—ด๊ธฐ", @@ -645,10 +716,11 @@ "status.direct": "@{name} ๋‹˜์—๊ฒŒ ๊ฐœ์ธ์ ์œผ๋กœ ๋ฉ˜์…˜", "status.direct_indicator": "๊ฐœ์ธ์ ์ธ ๋ฉ˜์…˜", "status.edit": "์ˆ˜์ •", - "status.edited": "{date}์— ์ˆ˜์ •ํ•จ", + "status.edited": "{date}์— ๋งˆ์ง€๋ง‰์œผ๋กœ ํŽธ์ง‘๋จ", "status.edited_x_times": "{count}๋ฒˆ ์ˆ˜์ •๋จ", "status.embed": "์ž„๋ฒ ๋“œ", "status.favourite": "์ข‹์•„์š”", + "status.favourites": "{count, plural, other {์ข‹์•„์š”}}", "status.filter": "์ด ๊ฒŒ์‹œ๋ฌผ์„ ํ•„ํ„ฐ", "status.filtered": "ํ•„ํ„ฐ๋กœ ๊ฑธ๋Ÿฌ์ง", "status.hide": "๊ฒŒ์‹œ๋ฌผ ์ˆจ๊ธฐ๊ธฐ", @@ -669,6 +741,7 @@ "status.reblog": "๋ถ€์ŠคํŠธ", "status.reblog_private": "์›๋ž˜์˜ ์ˆ˜์‹ ์ž๋“ค์—๊ฒŒ ๋ถ€์ŠคํŠธ", "status.reblogged_by": "{name} ๋‹˜์ด ๋ถ€์ŠคํŠธํ–ˆ์Šต๋‹ˆ๋‹ค", + "status.reblogs": "{count, plural, other {๋ถ€์ŠคํŠธ}}", "status.reblogs.empty": "์•„์ง ์•„๋ฌด๋„ ์ด ๊ฒŒ์‹œ๋ฌผ์„ ๋ถ€์ŠคํŠธํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋ถ€์ŠคํŠธ ํ•œ ์‚ฌ๋žŒ๋“ค์ด ์—ฌ๊ธฐ์— ํ‘œ์‹œ ๋ฉ๋‹ˆ๋‹ค.", "status.redraft": "์ง€์šฐ๊ณ  ๋‹ค์‹œ ์“ฐ๊ธฐ", "status.remove_bookmark": "๋ถ๋งˆํฌ ์‚ญ์ œ", diff --git a/app/javascript/mastodon/locales/ku.json b/app/javascript/mastodon/locales/ku.json index 4a0fd671db..83fcef26fb 100644 --- a/app/javascript/mastodon/locales/ku.json +++ b/app/javascript/mastodon/locales/ku.json @@ -135,9 +135,7 @@ "compose_form.spoiler.marked": "HiลŸyariya naverokรช rake", "compose_form.spoiler.unmarked": "HiลŸyariya naverokรช tevlรฎ bike", "confirmation_modal.cancel": "Dev jรช berde", - "confirmations.block.block_and_report": "Asteng bike & ragihรฎne", "confirmations.block.confirm": "Asteng bike", - "confirmations.block.message": "Ma tu dixwazรฎ ku {name} asteng bikรฎ?", "confirmations.cancel_follow_request.confirm": "Daxwazรช vekiลŸรฎne", "confirmations.cancel_follow_request.message": "Tu dixwazรฎ โ€‹โ€‹daxwaza xwe ya ลŸopandina {name} vekลŸรฎnรฎ?", "confirmations.delete.confirm": "Jรช bibe", @@ -146,14 +144,11 @@ "confirmations.delete_list.message": "Tu ji dil dixwazรฎ vรช lรฎsteyรช bi awayekรฎ mayรฎnde jรช bibรฎ?", "confirmations.discard_edit_media.confirm": "Biavรชje", "confirmations.discard_edit_media.message": "Guhertinรชn neqedandรฎ di danasรฎna an pรชลŸdรฎtina medyayรช de hene, wan bi her awayรฎ bavรชje?", - "confirmations.domain_block.confirm": "Tevahiya navperรช asteng bike", "confirmations.domain_block.message": "Tu pรช bawerรฎ ku tu dixwazรฎ tevahiya {domain} asteng bikรฎ? Di gelek rewลŸan de astengkirin an jรฎ bรชdengkirin tรชrรช dike รป tรช hilbijartin. Tu nikarรฎ naveroka vรช navperรช di demnameyรช an jรฎ agahdariyรชn xwe de bibรฎnรฎ. ลžopรฎnerรชn te yรช di vรช navperรช wรช werin jรชbirin.", "confirmations.edit.confirm": "Serrast bike", "confirmations.logout.confirm": "Derkeve", "confirmations.logout.message": "Ma tu dixwazรฎ ku derkevรฎ?", "confirmations.mute.confirm": "Bรชdeng bike", - "confirmations.mute.explanation": "Ev รช ลŸandinรชn ji wan tรช รป ลŸandinรชn ku behsa wan dike veลŸรชre, lรช hรช jรฎ maf dide ku ew ลŸandinรชn te bibรฎnin รป te biลŸopรฎnin.", - "confirmations.mute.message": "Bi rastรฎ tu dixwazรฎ {name} bรชdeng bikรฎ?", "confirmations.redraft.confirm": "Jรช bibe & ji nรป ve serrast bike", "confirmations.reply.confirm": "Bersivรช bide", "confirmations.reply.message": "Bersiva niha li ser peyama ku tu niha berhev dikรฎ dรช binivsรฎne. Ma pรช bawer รฎ ku tu dixwazรฎ bidomรฎnรฎ?", @@ -258,7 +253,6 @@ "hashtag.column_settings.tag_toggle": "Ji bo vรช stรปnรช hin pรชvekan tevlรฎ bike", "hashtag.follow": "Hashtagรช biลŸopรฎne", "hashtag.unfollow": "Hashtagรช neลŸopรฎne", - "home.column_settings.basic": "Bingehรฎn", "home.column_settings.show_reblogs": "Bilindkirinan nรฎลŸan bike", "home.column_settings.show_replies": "Bersivan nรฎลŸan bide", "home.hide_announcements": "Reklaman veลŸรชre", @@ -329,9 +323,6 @@ "load_pending": "{count, plural, one {# hรชmaneke nรป} other {#hรชmaneke nรป}}", "media_gallery.toggle_visible": "{number, plural, one {Wรชneyรช veลŸรชre} other {Wรชneyan veลŸรชre}}", "moved_to_account_banner.text": "Ajimรชrรช te {disabledAccount} niha neรงalak e ji ber ku te bar kir bo {movedToAccount}.", - "mute_modal.duration": "Dem", - "mute_modal.hide_notifications": "Agahdariyan ji ev bikarhรชner veลŸรชre?", - "mute_modal.indefinite": "Nediyar", "navigation_bar.about": "Derbar", "navigation_bar.blocks": "Bikarhรชnerรชn astengkirรฎ", "navigation_bar.bookmarks": "ลžรปnpel", @@ -370,9 +361,6 @@ "notifications.column_settings.admin.report": "Ragihandinรชn nรป:", "notifications.column_settings.admin.sign_up": "Tomarkirinรชn nรป:", "notifications.column_settings.alert": "Agahdariyรชn sermaseyรช", - "notifications.column_settings.filter_bar.advanced": "Hemรป beลŸan nรฎลŸan bide", - "notifications.column_settings.filter_bar.category": "ลživika parzรปna bilรชz", - "notifications.column_settings.filter_bar.show_bar": "Darika parzรปnรช nรฎลŸan bide", "notifications.column_settings.follow": "ลžopรฎnerรชn nรป:", "notifications.column_settings.follow_request": "Daxwazรชn ลŸopandinรช nรป:", "notifications.column_settings.mention": "Qalkirin:", @@ -504,8 +492,6 @@ "server_banner.about_active_users": "Kesรชn ku di van 30 rojรชn dawรฎ de vรช rajekarรช bi kar tรฎnin (Bikarhรชnerรชn ร‡alak รชn Mehane)", "server_banner.active_users": "bikarhรชnerรชn รงalak", "server_banner.administered_by": "Tรช bi rรชvebirin ji aliyรช:", - "server_banner.introduction": "{domain} beลŸek ji tora civakรฎ ya nenavendรฎ ye bi hรชzdariya {mastodon}.", - "server_banner.learn_more": "Bรชtir fรชr bibe", "server_banner.server_stats": "Amarรชn rajekar:", "sign_in_banner.create_account": "Ajimรชr biafirรฎne", "sign_in_banner.sign_in": "Tรชkeve", @@ -522,7 +508,6 @@ "status.direct": "Bi taybetรฎ qale @{name} bike", "status.direct_indicator": "Qalkirinรช taybet", "status.edit": "Serrast bike", - "status.edited": "Di {date} de hate serrastkirin", "status.edited_x_times": "{count, plural, one {{count} car} other {{count} car}} hate serrastkirin", "status.embed": "Bi cih bike", "status.filter": "Vรช ลŸandiyรช parzรปn bike", diff --git a/app/javascript/mastodon/locales/kw.json b/app/javascript/mastodon/locales/kw.json index e42f50aeff..794cbd9ede 100644 --- a/app/javascript/mastodon/locales/kw.json +++ b/app/javascript/mastodon/locales/kw.json @@ -86,20 +86,15 @@ "compose_form.spoiler.marked": "Dilea gwarnyans dalgh", "compose_form.spoiler.unmarked": "Keworra gwarnyans dalgh", "confirmation_modal.cancel": "Hedhi", - "confirmations.block.block_and_report": "Lettya & Reportya", "confirmations.block.confirm": "Lettya", - "confirmations.block.message": "Owgh hwi sur a vynnes lettya {name}?", "confirmations.delete.confirm": "Dilea", "confirmations.delete.message": "Owgh hwi sur a vynnes dilea'n post ma?", "confirmations.delete_list.confirm": "Dilea", "confirmations.delete_list.message": "Owgh hwi sur a vynnes dilea'n rol ma yn fast?", - "confirmations.domain_block.confirm": "Lettya gorfarth dhien", "confirmations.domain_block.message": "Owgh hwi wir, wir sur a vynnes lettya'n {domain} dhien? Y'n brassa rann a gasow, boghes lettyansow medrys po tawheansow yw lowr ha gwell. Ny wrewgh hwi gweles dalgh a'n worfarth na yn py amserlin boblek pynag po yn agas gwarnyansow. Agas holyoryon an worfarth na a vydh diles.", "confirmations.logout.confirm": "Digelmi", "confirmations.logout.message": "Owgh hwi sur a vynnes digelmi?", "confirmations.mute.confirm": "Tawhe", - "confirmations.mute.explanation": "Hemm a wra kudha postow anedha ha postow orth aga meneges, mes hwath aga gasa dhe weles agas postow ha'gas holya.", - "confirmations.mute.message": "Owgh hwi sur a vynnes tawhe {name}?", "confirmations.redraft.confirm": "Dilea & daskynskrifa", "confirmations.reply.confirm": "Gorthebi", "confirmations.reply.message": "Gorthebi lemmyn a wra ughskrifa'n messach esowgh hwi orth y skrifa lemmyn. Owgh hwi sur a vynnes pesya?", @@ -166,7 +161,6 @@ "hashtag.column_settings.tag_mode.any": "Pynag a'n re ma", "hashtag.column_settings.tag_mode.none": "Travyth a'n re ma", "hashtag.column_settings.tag_toggle": "Yssynsi taggys ynwedhek rag an goloven ma", - "home.column_settings.basic": "Selyek", "home.column_settings.show_reblogs": "Diskwedhes kenerthow", "home.column_settings.show_replies": "Diskwedhes gorthebow", "home.hide_announcements": "Kudha deklaryansow", @@ -226,9 +220,6 @@ "lists.subheading": "Agas rolyow", "load_pending": "{count, plural, one {# daklennowydh} other {# a daklennow nowydh}}", "media_gallery.toggle_visible": "Hide {number, plural, one {aven} other {aven}}", - "mute_modal.duration": "Duryans", - "mute_modal.hide_notifications": "Kudha gwarnyansow a'n devnydhyer ma?", - "mute_modal.indefinite": "Andhevri", "navigation_bar.blocks": "Devnydhyoryon lettys", "navigation_bar.bookmarks": "Folennosow", "navigation_bar.community_timeline": "Amserlin leel", @@ -257,8 +248,6 @@ "notifications.clear": "Dilea gwarnyansow", "notifications.clear_confirmation": "Owgh hwi sur a vynnes dilea agas gwarnyansow oll yn fast?", "notifications.column_settings.alert": "Gwarnyansow pennskrin", - "notifications.column_settings.filter_bar.advanced": "Displetya rummow oll", - "notifications.column_settings.filter_bar.category": "Barr sidhla skav", "notifications.column_settings.follow": "Holyoryon nowydh:", "notifications.column_settings.follow_request": "Govynnow holya nowydh:", "notifications.column_settings.mention": "Menegow:", diff --git a/app/javascript/mastodon/locales/la.json b/app/javascript/mastodon/locales/la.json index 698b3da4c3..d867034f01 100644 --- a/app/javascript/mastodon/locales/la.json +++ b/app/javascript/mastodon/locales/la.json @@ -1,7 +1,9 @@ { "about.contact": "Ratio:", "about.domain_blocks.no_reason_available": "Ratio abdere est", + "about.domain_blocks.silenced.explanation": "Tua profilia atque tuum contentum ab hac serve praecipue non videbis, nisi explลrฤ“s expresse aut subsequeris et optฤ“s.", "account.account_note_header": "Annotatio", + "account.add_or_remove_from_list": "Adde aut ฤ“ripe ex tabellฤซs", "account.badges.bot": "Robotum", "account.badges.group": "Congregatio", "account.block": "Impedire @{name}", @@ -11,11 +13,21 @@ "account.domain_blocked": "Dominium impeditum", "account.edit_profile": "Recolere notionem", "account.featured_tags.last_status_never": "Nulla contributa", + "account.featured_tags.title": "Hashtag notฤtฤซ {name}", + "account.followers_counter": "{count, plural, one {{counter} Sectator} other {{counter} Sectatores}}", + "account.following_counter": "{count, plural, one {{counter} Sequens} other {{counter} Sequentes}}", + "account.moved_to": "{name} significavit eum suam rationem novam nunc esse:", "account.muted": "Confutatus", + "account.requested_follow": "{name} postulavit ut te sequeretur", + "account.statuses_counter": "{count, plural, one {{counter} Nuntius} other {{counter} Nuntii}}", "account.unblock_short": "Solvere impedimentum", "account_note.placeholder": "Click to add a note", "admin.dashboard.retention.average": "Mediocritas", + "admin.impact_report.instance_accounts": "Rationes perfiles hoc deleret", + "alert.unexpected.message": "Error inopinatus occurrit.", "announcement.announcement": "Proclamatio", + "attachments_list.unprocessed": "(immลซtฤtus)", + "block_modal.you_wont_see_mentions": "Nuntios quibus eos commemorant non videbis.", "bundle_column_error.error.title": "Eheu!", "bundle_column_error.retry": "Retemptare", "bundle_column_error.routing.title": "CCCCIIII", @@ -32,31 +44,60 @@ "compose_form.direct_message_warning_learn_more": "Discere plura", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", + "compose_form.lock_disclaimer": "Tua ratio non est {clausa}. Quisquis te sequi potest ut visum accipiat nuntios tuos tantum pro sectatoribus.", "compose_form.lock_disclaimer.lock": "clausum", "compose_form.placeholder": "What is on your mind?", "compose_form.publish_form": "Barrire", "compose_form.spoiler.marked": "Text is hidden behind warning", - "compose_form.spoiler.unmarked": "Text is not hidden", + "compose_form.spoiler.unmarked": "Adde praeconium contentลซs", "confirmations.block.confirm": "Impedire", "confirmations.delete.confirm": "Oblitterare", "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "Oblitterare", - "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.discard_edit_media.message": "Habฤ“s mutationฤ“s in descriptionem vel prลspectum medii quae nลn sunt servฤtae; eas dฤ“mittam?", "confirmations.mute.confirm": "Confutare", "confirmations.reply.confirm": "Respondere", + "disabled_account_banner.account_settings": "Praeferentiae ratiลnis", + "disabled_account_banner.text": "Ratio tua {disabledAccount} debilitata est.", "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_block_modal.you_will_lose_followers": "Omnes sectatores tuฤซ ex hoc servล removฤ“buntur.", + "domain_block_modal.you_wont_see_posts": "Nuntios aut notificฤtiลnฤ“s ab usoribus in hลc servล nลn vidฤ“bis.", + "domain_pill.activitypub_like_language": "ActivityPub est velut lingua quam Mastodon cum aliฤซs sociฤlibus rฤ“tibus loquitur.", + "domain_pill.your_handle": "Tuus nominulus:", + "domain_pill.your_server": "Tua domus digitalis, ubi omnia tua nuntia habitant. Hanc non amas? Servฤ“s trฤnsferฤre potes quลcumque tempore et sectฤtลrฤ“s tuลs simul addลซcere.", + "domain_pill.your_username": "Tuล singulฤre id indicium in hลc servล est. Est possibile invenฤซre usลrฤ“s cum eลdem nลmine in servฤซs aliฤซs.", "embed.instructions": "Embed this status on your website by copying the code below.", + "emoji_button.activity": "Actiล", "emoji_button.food": "Cibus et potus", "emoji_button.people": "Homines", "emoji_button.search": "Quaerere...", + "empty_column.account_suspended": "Rฤtiล suspฤ“nsa", "empty_column.account_timeline": "Hic nulla contributa!", "empty_column.account_unavailable": "Notio non impetrabilis", - "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", + "empty_column.blocks": "Nondum quemquam usorem obsฤ“cฤvisti.", + "empty_column.direct": "Nลn habฤ“s adhลซc ullo mentionฤ“s prฤซvฤtฤs. Cum ลซnam mฤซseris aut accipis, hฤซc apparฤ“bit.", + "empty_column.followed_tags": "Nลn adhลซc aliquem hastฤginem secลซtus es. Cum id fฤ“ceris, hic ostendฤ“tur.", + "empty_column.home": "Tua linea temporum domesticus vacua est! Sequere plures personas ut eam compleas.", "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": "Nลn adhลซc habฤ“s ullo tabellฤs. Cum creฤs, hฤซc apparฤ“bunt.", + "empty_column.mutes": "Nondum quemquam usorem tacuisti.", + "empty_column.notification_requests": "Omnia clara sunt! Nihil hic est. Cum novฤs notificฤtiลnฤ“s accipฤซs, hic secundum tua praecepta apparebunt.", + "empty_column.notifications": "Nลn adhลซc habฤ“s ullo notificฤtiลnฤ“s. Cum aliฤซ tฤ“ interagunt, hฤซc videbis.", "explore.trending_statuses": "Contributa", + "filtered_notifications_banner.mentions": "{count, plural, one {mentiล} other {mentiลnฤ“s}}", + "firehose.all": "Omnis", + "footer.about": "De", "generic.saved": "Servavit", + "hashtag.column_settings.tag_mode.all": "Haec omnia", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} particeps} other {{counter} participฤ“s}}", + "hashtag.counter_by_uses": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}}", + "hashtag.counter_by_uses_today": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}} hodie", + "hashtags.and_other": "โ€ฆet {count, plural, other {# plus}}", + "intervals.full.days": "{number, plural, one {# die} other {# dies}}", + "intervals.full.hours": "{number, plural, one {# hora} other {# horae}}", + "intervals.full.minutes": "{number, plural, one {# minutum} other {# minuta}}", "keyboard_shortcuts.back": "Re navigare", "keyboard_shortcuts.blocked": "Aperire listam usorum obstructorum", "keyboard_shortcuts.boost": "Inlustrare publicatio", @@ -90,17 +131,47 @@ "keyboard_shortcuts.up": "to move up in the list", "lightbox.close": "Claudere", "lightbox.next": "Secundum", + "lists.account.add": "Adde ad tabellฤs", + "lists.new.create": "Addere tabella", + "load_pending": "{count, plural, one {# novum item} other {# nova itema}}", + "media_gallery.toggle_visible": "{number, plural, one {Cฤ“la imaginem} other {Cฤ“la imagines}}", + "moved_to_account_banner.text": "Tua ratione {disabledAccount} interdum reposita est, quod ad {movedToAccount} migrฤvisti.", + "mute_modal.you_wont_see_mentions": "Non videbis nuntios quฤซ eลs commemorant.", + "navigation_bar.about": "De", "navigation_bar.domain_blocks": "Hidden domains", - "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", - "notification.reblog": "{name} boosted your status", + "not_signed_in_indicator.not_signed_in": "Ad hunc locum pervenire oportet ut inฤซre facias.", + "notification.admin.report": "{name} nuntiavit {target}", + "notification.admin.sign_up": "{name} subscripsit", + "notification.favourite": "{name} nuntium tuum favit", + "notification.follow": "{name} te secutus est", + "notification.follow_request": "{name} postulavit ut te sequeretur", + "notification.mention": "{name} memoravi", + "notification.moderation_warning": "Accepistฤซ monitionem moderationis.", + "notification.moderation_warning.action_disable": "Ratio tua debilitata est.", + "notification.moderation_warning.action_none": "Tua ratiล monitum moderฤtiลnis accฤ“pit.", + "notification.moderation_warning.action_sensitive": "Tua nuntia hinc sensibiliter notabuntur.", + "notification.moderation_warning.action_silence": "Ratio tua est limitata.", + "notification.moderation_warning.action_suspend": "Ratio tua suspensus est.", + "notification.own_poll": "Suffragium tuum terminatum est.", + "notification.poll": "Electione in quam suffragium dedisti finita est.", + "notification.reblog": "{name} tuum nuntium amplificavit.", + "notification.relationships_severance_event.account_suspension": "Admin ab {from} {target} suspendit, quod significat nลn iam posse tฤ“ novitฤtฤ“s ab eฤซs accipere aut cum eฤซs interagere.", + "notification.relationships_severance_event.domain_block": "Admin ab {from} {target} obsฤ“cฤvit, includฤ“ns {followersCount} ex tuฤซs sectฤtลribus et {followingCount, plural, one {# ratione} other {# rationibus}} quฤs sequeris.", + "notification.relationships_severance_event.user_domain_block": "Bloqueฤstฤซ {target}, removฤ“ns {followersCount} ex sectฤtลribus tuฤซs et {followingCount, plural, one {# rationem} other {# rationฤ“s}} quลs sequeris.", + "notification.status": "{name} nuper publicavit", + "notification.update": "{name} nuntium correxit", + "notification_requests.accept": "Accipe", "notifications.filter.all": "Omnia", "notifications.filter.polls": "Eventus electionis", + "notifications.group": "Notificฤtiลnฤ“s", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", - "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": "Tua domus feed est principalis via Mastodon experฤซrฤซ. Quล plลซrฤ“s persลnas sequeris, eล actฤซvior et interessantior erit. Ad tฤ“ incipiendum, ecce quaedam suฤsiones:", "onboarding.follows.title": "Popular on Mastodon", - "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", + "onboarding.profile.display_name_hint": "Tuum nomen completum aut tuum nomen ludens...", + "onboarding.start.lead": "Nunc pars es Mastodonis, singularis, socialis medii platformae decentralis ubiโ€”non algorismusโ€”tuam ipsius experientiam curas. Incipiฤmus in nova hac socialis regione:", "onboarding.start.skip": "Want to skip right ahead?", + "onboarding.start.title": "Perfecisti eam!", "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", "onboarding.steps.publish_status.body": "Say hello to the world.", @@ -108,30 +179,47 @@ "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", + "onboarding.tips.2fa": "Scisne? Tลซam ratiลnem sฤ“cลซrฤre potes duลrum elementลrum authentฤซcฤtiลnem in ratiลnis tuฤซ praeferentiฤซs statuendล. Cum ลซllฤ app TOTP ex tuฤ ฤ“lฤ“ctiลne operฤtur, numerus tฤ“lephลnicus necessฤrius nลn est!", + "onboarding.tips.accounts_from_other_servers": "Scisne? Quoniam Mastodon dฤ“centrฤlis est, nลnnulla profฤซlia quae invenฤซs in servฤซs aliฤซs quam tuลrum erunt hospitฤta. Tamen cum eฤซs sine impedฤซmentล interฤgere potes! Servus eลrum in alterฤ parte nลminis eลrum est!", + "onboarding.tips.migration": "Scisne? Sฤซ sentฤซs {domain} tibi in futลซrล nลn esse optimam servฤซ ฤ“lฤ“ctiลnem, ad alium servum Mastodon sine amittendล sectฤtลribus tuฤซs migrฤre potes. Etiam tuum servum hospitฤrฤซ potes!", + "onboarding.tips.verification": "Scisne? Tลซam ratiลnem verificฤre potes iungendล nexum ad prลfฤซlium Mastodon tuum in propriฤ pฤginฤ interrฤ“tiฤ et addendล pฤginam ad prลfฤซlium tuum. Nullae pecลซniae aut documenta necessฤria sunt!", "poll.closed": "Clausum", + "poll.total_people": "{count, plural, one {# persona} other {# personae}}", + "poll.total_votes": "{count, plural, one {# suffragium} other {# suffragia}}", "poll.vote": "Eligere", "poll.voted": "Elegisti hoc responsum", + "poll.votes": "{votes, plural, one {# sufragium} other {# sufragia}}", "poll_button.add_poll": "Addere electionem", "poll_button.remove_poll": "Auferre electionem", "privacy.change": "Adjust status privacy", "privacy.public.short": "Coram publico", + "regeneration_indicator.sublabel": "Tua domus feed praeparฤtur!", + "relative_time.full.days": "{number, plural, one {# ante die} other {# ante dies}}", + "relative_time.full.hours": "{number, plural, one {# ante horam} other {# ante horas}}", "relative_time.full.just_now": "nunc", + "relative_time.full.minutes": "{number, plural, one {# ante minutum} other {# ante minuta}}", + "relative_time.full.seconds": "{number, plural, one {# ante secundum} other {# ante secunda}}", "relative_time.just_now": "nunc", "relative_time.today": "hodie", + "reply_indicator.attachments": "{count, plural, one {# annexus} other {# annexลซs}}", "report.block": "Impedimentum", + "report.block_explanation": "Non videbis eorum nuntios. Non poterunt vidฤ“re tuลs nuntios aut tฤ“ sequฤซ. Intelligere poterunt sฤ“ obstrลซctลs esse.", "report.categories.other": "Altera", "report.category.title_account": "notio", "report.category.title_status": "contributum", "report.close": "Confectum", "report.mute": "Confutare", + "report.mute_explanation": "Non videbis eลrum nuntiลs. Possunt adhuc tฤ“ sequฤซ et tuลs nuntiลs vidฤ“re, nec sciฤ“bunt sฤ“ tacitลs esse.", "report.next": "Secundum", - "report.placeholder": "Type or paste additional comments", + "report.placeholder": "Commentฤriฤซ adiลซnctฤซ", "report.submit": "Mittere", "report.target": "Report {target}", - "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", + "report_notification.attached_statuses": "{count, plural, one {{count} nuntius} other {{count} nuntii}} attachiatus", "report_notification.categories.other": "Altera", "search.placeholder": "Quaerere", - "server_banner.learn_more": "Discere plura", + "search_results.all": "Omnis", + "server_banner.active_users": "Usลซrฤriฤซ ฤctฤซvฤซ", + "server_banner.administered_by": "Administratur:", "sign_in_banner.sign_in": "Sign in", "status.admin_status": "Open this status in the moderation interface", "status.block": "Impedire @{name}", @@ -139,15 +227,30 @@ "status.copy": "Copy link to status", "status.delete": "Oblitterare", "status.edit": "Recolere", - "status.edited": "Recultum {date}", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", + "status.favourites": "{count, plural, one {favoritum} other {favorita}}", + "status.history.created": "{name} creatum {date}", + "status.history.edited": "{name} correxit {date}", "status.open": "Expand this status", - "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", + "status.reblogged_by": "{name} adiuvavit", + "status.reblogs": "{count, plural, one {auctus} other {auctลซs}}", + "status.title.with_attachments": "{user} publicavit {attachmentCount, plural, one {unum annexum} other {{attachmentCount} annexa}}", "tabs_bar.home": "Domi", + "time_remaining.days": "{number, plural, one {# die} other {# dies}} restant", + "time_remaining.hours": "{number, plural, one {# hora} other {# horae}} restant", + "time_remaining.minutes": "{number, plural, one {# minutum} other {# minuta}} restant", + "time_remaining.seconds": "{number, plural, one {# secundum} other {# secunda}} restant", + "timeline_hint.remote_resource_not_displayed": "{resource} ab aliฤซs servฤซs nลn ostenduntur.", "timeline_hint.resources.statuses": "Contributa pristina", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} persลna} other {{counter} persลnae}} in {days, plural, one {diฤ“ prฤซdiฤ“} other {diฤ“bus praeteritฤซs {days}}}", + "ui.beforeunload": "Si Mastodon discesseris, tua epitome peribit.", + "units.short.billion": "{count} millia milionum", + "units.short.million": "{count} milionum", + "units.short.thousand": "{count} millia", + "upload_button.label": "Imaginฤ“s, vฤซdeล aut fฤซle audฤซtลซs adde", "upload_form.audio_description": "Describe for people who are hard of hearing", "upload_form.edit": "Recolere", + "upload_modal.description_placeholder": "A velox brunneis vulpes salit super piger canis", "upload_progress.label": "Uploadingโ€ฆ", "video.mute": "Confutare soni" } diff --git a/app/javascript/mastodon/locales/lad.json b/app/javascript/mastodon/locales/lad.json index 3ec3b6af1b..bf676a6020 100644 --- a/app/javascript/mastodon/locales/lad.json +++ b/app/javascript/mastodon/locales/lad.json @@ -89,6 +89,12 @@ "announcement.announcement": "Pregon", "attachments_list.unprocessed": "(no prosesado)", "audio.hide": "Eskonde audio", + "block_modal.show_less": "Amostra manko", + "block_modal.show_more": "Amostra mas", + "block_modal.they_cant_mention": "No te puede enmentar ni segir.", + "block_modal.they_will_know": "Puede ver ke esta blokado.", + "block_modal.title": "Bloka utilizador?", + "block_modal.you_wont_see_mentions": "No veras publikasyones ke lo enmentan.", "boost_modal.combo": "Puedes klikar {combo} para ometer esto la proksima vez", "bundle_column_error.copy_stacktrace": "Kopia el raporto de yerro", "bundle_column_error.error.body": "La pajina solisitada no pudo ser renderada. Podria ser por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador.", @@ -160,9 +166,7 @@ "compose_form.spoiler.unmarked": "Adjusta avertensya de kontenido", "compose_form.spoiler_placeholder": "Avertensya de kontenido (opsyonal)", "confirmation_modal.cancel": "Anula", - "confirmations.block.block_and_report": "Bloka i raporta", "confirmations.block.confirm": "Bloka", - "confirmations.block.message": "Estas siguro ke keres blokar a {name}?", "confirmations.cancel_follow_request.confirm": "Anula solisitud", "confirmations.cancel_follow_request.message": "Estas siguro ke keres anular tu solisitud de segir a {name}?", "confirmations.delete.confirm": "Efasa", @@ -171,15 +175,13 @@ "confirmations.delete_list.message": "Estas siguro ke keres permanentemente efasar esta lista?", "confirmations.discard_edit_media.confirm": "Anula", "confirmations.discard_edit_media.message": "Tienes trokamientos no guadrados en la deskripsion o vista previa. Keres efasarlos entanto?", - "confirmations.domain_block.confirm": "Bloka domeno entero", + "confirmations.domain_block.confirm": "Bloka sirvidor", "confirmations.domain_block.message": "Estas totalmente siguro ke keres blokar todo el domeno {domain}? En djeneral unos kuantos blokos o silensiamientos son sufisientes i preferavles. No veras kontenido de akel domeno en dinguna linya de tiempo publika ni ent tus avizos. Tus suivantes de akel domeno seran kitados.", "confirmations.edit.confirm": "Edita", "confirmations.edit.message": "Si edites agora, kitaras el mesaj kualo estas eskriviendo aktualmente. Estas siguro ke keres fazerlo?", "confirmations.logout.confirm": "Sal", "confirmations.logout.message": "Estas siguro ke keres salir de tu kuento?", "confirmations.mute.confirm": "Silensia", - "confirmations.mute.explanation": "Esto eskondera las publikasyones de este kuento i publikasyones ke lo enmentan, pero ainda les permetera segirte.", - "confirmations.mute.message": "Estas siguro ke keres silensiar a {name}?", "confirmations.redraft.confirm": "Efasa i reeskrive", "confirmations.redraft.message": "Estas siguro ke keres efasar esta publikasyon i reeskrivirla? Pedreras todos los favoritos i repartajasyones asosiados kon esta publikasyon i repuestas a eya seran guerfanadas.", "confirmations.reply.confirm": "Arisponde", @@ -205,6 +207,18 @@ "dismissable_banner.explore_statuses": "Estas publikasyones de este sirvidor i otros de la red desentralizada estan agora popularas. Publikasyones mas muevas, kon mas repartajasiones i favoritadas por mas djente aparesen primero.", "dismissable_banner.explore_tags": "Estas etiketas estan agora popularas en la red sosyala. Etiketas uzadas por mas djente aparesen primero.", "dismissable_banner.public_timeline": "Estas son las publikasyones publikas mas resientes de personas en la red sosyala a las kualas la djente de {domain} sige.", + "domain_block_modal.block": "Bloka sirvidor", + "domain_block_modal.block_account_instead": "Bloka @{name} en su lugar", + "domain_block_modal.they_cant_follow": "Dingun de este sirvidor puede segirte.", + "domain_block_modal.they_wont_know": "No savra ke tiene sido blokado.", + "domain_block_modal.title": "Bloka el domeno?", + "domain_block_modal.you_will_lose_followers": "Se efasaran todos tus suivantes de este sirvidor.", + "domain_block_modal.you_wont_see_posts": "No veras publikasyones ni avizos de utilizadores en este sirvidor.", + "domain_pill.server": "Sirvidor", + "domain_pill.their_handle": "Su alias:", + "domain_pill.username": "Nombre de utilizador", + "domain_pill.whats_in_a_handle": "En ke konsiste el alias?", + "domain_pill.your_handle": "Tu alias:", "embed.instructions": "Enkrusta esta publikasyon en tu sitio internetiko kopiando este kodiche.", "embed.preview": "Paresera ansina:", "emoji_button.activity": "Aktivita", @@ -271,14 +285,22 @@ "filter_modal.select_filter.subtitle": "Kulanea una kategoria egzistente o kriya mueva", "filter_modal.select_filter.title": "Filtra esta publikasyon", "filter_modal.title.status": "Filtra una publikasyon", + "filtered_notifications_banner.pending_requests": "Avizos de {count, plural, =0 {dingun} one {una persona} other {# personas}} ke puedes koneser", + "filtered_notifications_banner.title": "Avizos filtrados", "firehose.all": "Todo", "firehose.local": "Este sirvidor", "firehose.remote": "Otros sirvidores", "follow_request.authorize": "Autoriza", "follow_request.reject": "Refuza", "follow_requests.unlocked_explanation": "Aunke tu kuento no esta serrado, la taifa de {domain} kreye ke talvez keres revizar manualmente las solisitudes de segimento de estos kuentos.", - "follow_suggestions.curated_suggestion": "Sujestion del sirvidor", + "follow_suggestions.curated_suggestion": "Seleksyon de la taifa", "follow_suggestions.dismiss": "No amostra mas", + "follow_suggestions.friends_of_friends_longer": "Popular entre personas a las kualas siges", + "follow_suggestions.hints.featured": "Este profil tiene sido eskojido por la taifa de {domain}.", + "follow_suggestions.hints.friends_of_friends": "Este profil es popular entre las personas ke siges.", + "follow_suggestions.hints.most_followed": "Este profil es uno de los mas segidos en {domain}.", + "follow_suggestions.hints.most_interactions": "Este profil tiene resivido muncha atansion resientemente en {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Este profil es similar a otros ke tienes segido resientemente.", "follow_suggestions.personalized_suggestion": "Sujestion personalizada", "follow_suggestions.popular_suggestion": "Sujestion populara", "follow_suggestions.view_all": "Ve todos", @@ -309,7 +331,6 @@ "hashtag.follow": "Sige etiketa", "hashtag.unfollow": "Desige etiketa", "hashtags.and_other": "โ€ฆi {count, plural, one {}other {# mas}}", - "home.column_settings.basic": "Opsyones bazikas", "home.column_settings.show_reblogs": "Amostra repartajasyones", "home.column_settings.show_replies": "Amostra repuestas", "home.hide_announcements": "Eskonde pregones", @@ -377,6 +398,7 @@ "limited_account_hint.action": "Amostra el profil entanto", "limited_account_hint.title": "Este profil fue eskondido por los moderadores de {domain}.", "link_preview.author": "Publikasyon de {name}", + "link_preview.more_from_author": "Mas de {name}", "lists.account.add": "Adjusta a lista", "lists.account.remove": "Kita de lista", "lists.delete": "Efasa lista", @@ -395,9 +417,13 @@ "loading_indicator.label": "Eskargandoโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Eskonde imaje} other {Eskonde imajes}}", "moved_to_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado porke transferates a {movedToAccount}.", - "mute_modal.duration": "Durasyon", - "mute_modal.hide_notifications": "Eskonder avizos de este utilizador?", - "mute_modal.indefinite": "Indefinida", + "mute_modal.hide_from_notifications": "Eskonde de avizos", + "mute_modal.hide_options": "Eskonde opsyones", + "mute_modal.indefinite": "Asta ke desho de silensyarlo", + "mute_modal.show_options": "Amostra opsyones", + "mute_modal.they_wont_know": "No savra ke tiene sido silensyado.", + "mute_modal.title": "Silensiar utilizador?", + "mute_modal.you_wont_see_mentions": "No veras publikasyones ke lo enmentan.", "navigation_bar.about": "Sovre mozotros", "navigation_bar.advanced_interface": "Avre en la enterfaz avanzada", "navigation_bar.blocks": "Utilizadores blokados", @@ -430,11 +456,20 @@ "notification.follow": "{name} te ampeso a segir", "notification.follow_request": "{name} tiene solisitado segirte", "notification.mention": "{name} te enmento", + "notification.moderation-warning.learn_more": "Ambezate mas", + "notification.moderation_warning.action_silence": "Tu kuento tiene sido limitado.", + "notification.moderation_warning.action_suspend": "Tu kuento tiene sido suspendido.", "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", + "notification_requests.dismiss": "Kita", + "notification_requests.notifications_from": "Avizos de {name}", + "notification_requests.title": "Avizos filtrados", "notifications.clear": "Efasa avizos", "notifications.clear_confirmation": "Estas siguro ke keres permanentemente efasar todos tus avizos?", "notifications.column_settings.admin.report": "Muveos raportos:", @@ -443,7 +478,6 @@ "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.filter_bar.show_bar": "Amostra vara de filtros", "notifications.column_settings.follow": "Muevos suivantes:", "notifications.column_settings.follow_request": "Muevas solisitudes de segimiento:", "notifications.column_settings.mention": "Enmentaduras:", @@ -469,6 +503,13 @@ "notifications.permission_denied": "Avizos de ensimameza no estan desponivles porke ya se tiene refuzado el permiso", "notifications.permission_denied_alert": "\"No se pueden kapasitar los avizos de ensimameza, porke ya se tiene refuzado el permiso de navigador", "notifications.permission_required": "Avizos de ensimameza no estan desponivles porke los nesesarios permisos no tienen sido risividos.", + "notifications.policy.filter_new_accounts.hint": "Kriyadas durante {days, plural, one {el ultimo diya} other {los ultimos # diyas}}", + "notifications.policy.filter_new_accounts_title": "Muevos kuentos", + "notifications.policy.filter_not_followers_title": "Personas ke te no sigen", + "notifications.policy.filter_not_following_hint": "Asta ke las aproves manualmente", + "notifications.policy.filter_not_following_title": "Personas ke no siges", + "notifications.policy.filter_private_mentions_title": "Enmentaduras privadas no solisitadas", + "notifications.policy.title": "Filtra avizos deโ€ฆ", "notifications_permission_banner.enable": "Kapasita avizos de ensimameza", "notifications_permission_banner.how_to_control": "Para risivir avizos kuando Mastodon no esta avierto, kapasita avizos de ensimameza. Puedes kontrolar presizamente kualos tipos de enteraksiones djeneren avizos de ensimameza kon el boton {icon} arriva kuando esten kapasitadas.", "notifications_permission_banner.title": "Nunkua te piedres niente", @@ -625,13 +666,10 @@ "server_banner.about_active_users": "Utilizadores aktivos en este sirvidor durante los ultimos 30 diyas (utilizadores aktivos mensuales)", "server_banner.active_users": "utilizadores aktivos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} es parte de la red sosyala desentralizada liderada por {mastodon}.", - "server_banner.learn_more": "Ambezate mas", "server_banner.server_stats": "Estatistikas del sirvidor:", "sign_in_banner.create_account": "Kriya kuento", "sign_in_banner.sign_in": "Konektate", "sign_in_banner.sso_redirect": "Konektate o enrejistrate", - "sign_in_banner.text": "Konektate para segir prefiles o etiketas, partajar publikasyones, arispondir a eyas i markar ke te plazen. Puedes tambyen enteraktuar dizde tu kuento en un sirvidor desferente.", "status.admin_account": "Avre la enterfaz de moderasyon para @{name}", "status.admin_domain": "Avre la enterfaz de moderasyon para @{domain}", "status.admin_status": "Avre esto en la enterfaz de moderasyon", @@ -645,7 +683,7 @@ "status.direct": "Enmenta a @{name} en privado", "status.direct_indicator": "Enmentadura privada", "status.edit": "Edita", - "status.edited": "Editado {date}", + "status.edited": "Ultima edisyon: {date}", "status.edited_x_times": "Editado {count, plural, one {{count} vez} other {{count} vezes}}", "status.embed": "Inkrusta", "status.favourite": "Te plaze", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index 0923a10065..b365d64589 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -1,7 +1,7 @@ { "about.blocks": "Priลพiลซrimi serveriai", - "about.contact": "Kontaktuoti:", - "about.disclaimer": "Mastodon โ€“ nemokama atvirojo kodo programa ir Mastodon gGmbH prekฤ—s ลพenklas.", + "about.contact": "Kontaktai:", + "about.disclaimer": "Mastodon โ€“ tai nemokama atvirojo kodo programinฤ— ฤฏranga ir Mastodon gGmbH prekฤ—s ลพenklas.", "about.domain_blocks.no_reason_available": "Prieลพastis nepateikta", "about.domain_blocks.preamble": "Mastodon paprastai leidลพia perลพiลซrฤ—ti turinฤฏ ir bendrauti su naudotojais iลก bet kurio kito fediverse esanฤio serverio. ล ios yra iลกimtys, kurios buvo padarytos ลกiame konkreฤiame serveryje.", "about.domain_blocks.silenced.explanation": "Paprastai nematysi profiliลณ ir turinio iลก ลกio serverio, nebent jฤฏ aiลกkiai ieลกkosi arba pasirinksi jฤฏ sekdamas (-a).", @@ -27,10 +27,10 @@ "account.domain_blocked": "Uลพblokuotas domenas", "account.edit_profile": "Redaguoti profilฤฏ", "account.enable_notifications": "Praneลกti man, kai @{name} paskelbia", - "account.endorse": "Rekomenduoti profilyje", - "account.featured_tags.last_status_at": "Paskutinฤฏ kartฤ… paskelbta {date}", + "account.endorse": "Rodyti profilyje", + "account.featured_tags.last_status_at": "Paskutinis ฤฏraลกas {date}", "account.featured_tags.last_status_never": "Nฤ—ra ฤฏraลกลณ", - "account.featured_tags.title": "{name} rekomenduojami saitaลพodลพiai", + "account.featured_tags.title": "{name} rodomi saitaลพodลพiai", "account.follow": "Sekti", "account.follow_back": "Sekti atgal", "account.followers": "Sekฤ—jai", @@ -38,13 +38,13 @@ "account.followers_counter": "{count, plural, one {{counter} sekฤ—jas} few {{counter} sekฤ—jai} many {{counter} sekฤ—jo} other {{counter} sekฤ—jลณ}}", "account.following": "Sekama", "account.following_counter": "{count, plural, one {{counter} sekimas} few {{counter} sekimai} many {{counter} sekimo} other {{counter} sekimลณ}}", - "account.follows.empty": "ล is (-i) naudotojas (-a) dar nieko neseka.", + "account.follows.empty": "ล is naudotojas dar nieko neseka.", "account.go_to_profile": "Eiti ฤฏ profilฤฏ", "account.hide_reblogs": "Slฤ—pti pakฤ—limus iลก @{name}", "account.in_memoriam": "Atminimui.", "account.joined_short": "Prisijungฤ—", "account.languages": "Keisti prenumeruojamas kalbas", - "account.link_verified_on": "ล ios nuorodos nuosavybฤ— buvo patikrinta {date}.", + "account.link_verified_on": "ล ios nuorodos nuosavybฤ— buvo patikrinta {date}", "account.locked_info": "ล ios paskyros privatumo bลซsena nustatyta kaip uลพrakinta. Savininkas (-ฤ—) rankiniu bลซdu perลพiลซri, kas gali sekti.", "account.media": "Medija", "account.mention": "Paminฤ—ti @{name}", @@ -53,13 +53,13 @@ "account.mute_notifications_short": "Nutildyti praneลกimus", "account.mute_short": "Nutildyti", "account.muted": "Nutildytas", - "account.mutual": "Abipusis", + "account.mutual": "Bendri", "account.no_bio": "Nฤ—ra pateikto apraลกymo.", "account.open_original_page": "Atidaryti originalinฤฏ puslapฤฏ", "account.posts": "ฤฎraลกai", "account.posts_with_replies": "ฤฎraลกai ir atsakymai", "account.report": "Praneลกti apie @{name}", - "account.requested": "Laukiama patvirtinimo. Spustelฤ—k, jei nori atลกaukti sekimo praลกymฤ….", + "account.requested": "Laukiama patvirtinimo. Spustelฤ—k, jei nori atลกaukti sekimo praลกymฤ…", "account.requested_follow": "{name} papraลกฤ— tave sekti", "account.share": "Bendrinti @{name} profilฤฏ", "account.show_reblogs": "Rodyti pakฤ—limus iลก @{name}", @@ -72,7 +72,7 @@ "account.unmute": "Atลกaukti nutildymฤ… @{name}", "account.unmute_notifications_short": "Atลกaukti nutildymฤ… praneลกimams", "account.unmute_short": "Atลกaukti nutildymฤ…", - "account_note.placeholder": "Spustelฤ—k norฤ—damas (-a) pridฤ—ti pastabฤ…", + "account_note.placeholder": "Spustelฤ—k norint pridฤ—ti pastabฤ….", "admin.dashboard.daily_retention": "Naudotojลณ pasilikimo rodiklis pagal dienฤ… po registracijos", "admin.dashboard.monthly_retention": "Naudotojลณ pasilikimo rodiklis pagal mฤ—nesฤฏ po registracijos", "admin.dashboard.retention.average": "Vidurkis", @@ -82,28 +82,36 @@ "admin.impact_report.instance_followers": "Sekฤ—jai, kuriuos prarastลณ mลซsลณ naudotojai", "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.message": "Bandyk vฤ—liau po {retry_time, time, medium}.", + "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ฤ…", - "boost_modal.combo": "Gali paspausti {combo}, kad praleisti kitฤ… kartฤ…", + "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", + "block_modal.they_cant_mention": "Jie negali tave paminฤ—ti ar sekti.", + "block_modal.they_cant_see_posts": "Jie negali matyti tavo ฤฏraลกus, o tu nematysi jลณ.", + "block_modal.they_will_know": "Jie mato, kad yra uลพblokuoti.", + "block_modal.title": "Blokuoti naudotojฤ…?", + "block_modal.you_wont_see_mentions": "Nematysi ฤฏraลกus, kuriuose jie paminimi.", + "boost_modal.combo": "Galima paspausti {combo}, kad praleisti tai kitฤ… kartฤ…", "bundle_column_error.copy_stacktrace": "Kopijuoti klaidos ataskaitฤ…", - "bundle_column_error.error.body": "Uลพklausos puslapio nepavyko atvaizduoti. Tai gali bลซti dฤ—l mลซsลณ kodo klaidos arba narลกyklฤ—s suderinamumo problemos.", + "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.", "bundle_column_error.error.title": "O, ne!", "bundle_column_error.network.body": "Bandant uลพkrauti ลกฤฏ puslapฤฏ ฤฏvyko klaida. Tai galฤ—jo atsitikti dฤ—l laikinos tavo interneto ryลกio arba ลกio serverio problemos.", "bundle_column_error.network.title": "Tinklo klaida", "bundle_column_error.retry": "Bandyti dar kartฤ…", - "bundle_column_error.return": "Grฤฏลพti ฤฏ pradลพiฤ…", + "bundle_column_error.return": "Grฤฏลพti ฤฏ pagrindinฤฏ", "bundle_column_error.routing.body": "Praลกyto puslapio nepavyko rasti. Ar esi tikras (-a), kad adreso juostoje nurodytas URL adresas yra teisingas?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Uลพdaryti", "bundle_modal_error.message": "Kraunant ลกฤฏ komponentฤ… kaลพkas nepavyko.", "bundle_modal_error.retry": "Bandyti dar kartฤ…", "closed_registrations.other_server_instructions": "Kadangi Mastodon yra decentralizuotas, gali susikurti paskyrฤ… kitame serveryje ir vis tiek bendrauti su ลกiuo serveriu.", - "closed_registrations_modal.description": "Sukurti paskyrฤ… {domain} ลกiuo metu neฤฏmanoma, taฤiau nepamirลกk, kad norint naudotis Mastodon nebลซtina turฤ—ti paskyrฤ… domene {domain}.", + "closed_registrations_modal.description": "Sukurti paskyrฤ… {domain} ลกiuo metu neฤฏmanoma, bet nepamirลกk, kad norint naudotis Mastodon nebลซtina turฤ—ti paskyrฤ… domene {domain}.", "closed_registrations_modal.find_another_server": "Rasti kitฤ… serverฤฏ", "closed_registrations_modal.preamble": "Mastodon yra decentralizuotas, todฤ—l nesvarbu, kur susikursi paskyrฤ…, galฤ—si sekti ir bendrauti su bet kuriuo ลกiame serveryje esanฤiu asmeniu. Jฤฏ gali net savarankiลกkai talpinti!", "closed_registrations_modal.title": "Uลพsiregistruoti Mastodon", @@ -114,9 +122,9 @@ "column.direct": "Privatลซs paminฤ—jimai", "column.directory": "Narลกyti profilius", "column.domain_blocks": "Uลพblokuoti domenai", - "column.favourites": "Mฤ—gstamiausi", + "column.favourites": "Mฤ—gstami", "column.firehose": "Tiesioginiai srautai", - "column.follow_requests": "Sekimo praลกymus", + "column.follow_requests": "Sekimo praลกymai", "column.home": "Pagrindinis", "column.lists": "Sฤ…raลกai", "column.mutes": "Nutildyti naudotojai", @@ -131,7 +139,7 @@ "column_header.show_settings": "Rodyti nustatymus", "column_header.unpin": "Atsegti", "column_subheading.settings": "Nustatymai", - "community.column_settings.local_only": "Tik vietinis", + "community.column_settings.local_only": "Tik vietinฤ—", "community.column_settings.media_only": "Tik medija", "community.column_settings.remote_only": "Tik nuotolinis", "compose.language.change": "Keisti kalbฤ…", @@ -140,17 +148,17 @@ "compose.published.open": "Atidaryti", "compose.saved.body": "ฤฎraลกas iลกsaugotas.", "compose_form.direct_message_warning_learn_more": "Suลพinoti daugiau", - "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", - "compose_form.hashtag_warning": "ล is ฤฏraลกas nebus ฤฏtraukta ฤฏ jokฤฏ saitaลพodฤฏ, nes ji nฤ—ra vieลกa. Tik vieลกลณ ฤฏraลกลณ galima ieลกkoti pagal saitaลพodฤฏ.", + "compose_form.encryption_warning": "Mastodon ฤฏraลกai nฤ—ra visapusiลกkai ลกifruojami. Per Mastodon nesidalyk jokia slapta informacija.", + "compose_form.hashtag_warning": "ล is ฤฏraลกas nebus ฤฏtrauktas ฤฏ jokฤฏ saitaลพodฤฏ, nes ji nฤ—ra vieลกa. Tik vieลกลณ ฤฏraลกลณ galima ieลกkoti pagal saitaลพodฤฏ.", "compose_form.lock_disclaimer": "Tavo paskyra nฤ—ra {locked}. Bet kas gali sekti tave ir perลพiลซrฤ—ti tik sekฤ—jams skirtus ฤฏraลกus.", "compose_form.lock_disclaimer.lock": "uลพrakinta", "compose_form.placeholder": "Kas tavo mintyse?", "compose_form.poll.duration": "Apklausos trukmฤ—", "compose_form.poll.multiple": "Keli pasirinkimai", - "compose_form.poll.option_placeholder": "{number} pasirinkimas", + "compose_form.poll.option_placeholder": "{number} parinktis", "compose_form.poll.single": "Pasirinkti vienฤ…", "compose_form.poll.switch_to_multiple": "Keisti apklausฤ…, kad bลซtลณ galima pasirinkti kelis pasirinkimus", - "compose_form.poll.switch_to_single": "Pakeisti apklausฤ…, kad bลซtลณ galima pasirinkti vienฤ… variantฤ…", + "compose_form.poll.switch_to_single": "Keisti apklausฤ…, kad bลซtลณ galima pasirinkti vienฤ… pasirinkimฤ…", "compose_form.poll.type": "Stilius", "compose_form.publish": "Skelbti", "compose_form.publish_form": "Naujas ฤฏraลกas", @@ -160,30 +168,28 @@ "compose_form.spoiler.unmarked": "Pridฤ—ti turinio ฤฏspฤ—jimฤ…", "compose_form.spoiler_placeholder": "Turinio ฤฏspฤ—jimas (pasirinktinis)", "confirmation_modal.cancel": "Atลกaukti", - "confirmations.block.block_and_report": "Blokuoti ir praneลกti", "confirmations.block.confirm": "Blokuoti", - "confirmations.block.message": "Ar tikrai nori uลพblokuoti {name}?", "confirmations.cancel_follow_request.confirm": "Atลกaukti praลกymฤ…", "confirmations.cancel_follow_request.message": "Ar tikrai nori atลกaukti savo praลกymฤ… sekti {name}?", "confirmations.delete.confirm": "Iลกtrinti", - "confirmations.delete.message": "Are you sure you want to delete this status?", + "confirmations.delete.message": "Ar tikrai nori iลกtrinti ลกฤฏ ฤฏraลกฤ…?", "confirmations.delete_list.confirm": "Iลกtrinti", "confirmations.delete_list.message": "Ar tikrai nori visam laikui iลกtrinti ลกฤฏ sฤ…raลกฤ…?", "confirmations.discard_edit_media.confirm": "Atmesti", "confirmations.discard_edit_media.message": "Turi neiลกsaugotลณ medijos apraลกymo ar perลพiลซros pakeitimลณ, vis tiek juos atmesti?", - "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.domain_block.confirm": "Blokuoti serverฤฏ", + "confirmations.domain_block.message": "Ar tikrai, tikrai nori uลพblokuoti visฤ… {domain}? Daugeliu atvejลณ uลพtenka keliลณ tiksliniลณ blokavimลณ arba nutildymลณ. ล io domeno turinio nematysi jokiose vieลกose laiko skalฤ—se ar praneลกimuose. Tavo sekฤ—jai iลก to domeno bus paลกalinti.", "confirmations.edit.confirm": "Redaguoti", "confirmations.edit.message": "Redaguojant dabar, bus perraลกyta ลกiuo metu kuriama ลพinutฤ—. Ar tikrai nori tฤ™sti?", "confirmations.logout.confirm": "Atsijungti", "confirmations.logout.message": "Ar tikrai nori atsijungti?", "confirmations.mute.confirm": "Nutildyti", - "confirmations.mute.explanation": "Tai paslฤ—ps jลณ ฤฏraลกus ir ฤฏraลกus, kuriuose jie menฤ—mi, taฤiau jie vis tiek galฤ—s matyti tavo ฤฏraลกus ir sekti.", - "confirmations.mute.message": "Ar tikrai norite nutildyti {name}?", "confirmations.redraft.confirm": "Iลกtrinti ir perraลกyti", + "confirmations.redraft.message": "Ar tikrai nori iลกtrinti ลกฤฏ ฤฏraลกฤ… ir paraลกyti jฤฏ iลก naujo? Bus prarastos mฤ—gstamai ir pakฤ—limai, o atsakymai ฤฏ originalinฤฏ ฤฏraลกฤ… taps liekamojais.", "confirmations.reply.confirm": "Atsakyti", - "confirmations.reply.message": "Atsakant dabar, bus perraลกyta metu kuriama ลพinutฤ—. Ar tikrai nori tฤ™sti?", + "confirmations.reply.message": "Atsakant dabar, bus perraลกyta ลกiuo metu kuriama ลพinutฤ—. Ar tikrai nori tฤ™sti?", "confirmations.unfollow.confirm": "Nebesekti", - "confirmations.unfollow.message": "Ar tikrai norite atsisakyti sekimo {name}?", + "confirmations.unfollow.message": "Ar tikrai nori nebesekti {name}?", "conversation.delete": "Iลกtrinti pokalbฤฏ", "conversation.mark_as_read": "ลฝymฤ—ti kaip skaitytฤ…", "conversation.open": "Perลพiลซrฤ—ti pokalbฤฏ", @@ -191,91 +197,131 @@ "copy_icon_button.copied": "Nukopijuota ฤฏ iลกkarpinฤ™", "copypaste.copied": "Nukopijuota", "copypaste.copy_to_clipboard": "Kopijuoti ฤฏ iลกkarpinฤ™", - "directory.local": "Iลก {domain} tik", - "directory.new_arrivals": "Naujos prekฤ—s", - "directory.recently_active": "Neseniai aktyvus", + "directory.federated": "Iลก ลพinomลณ fediversลณ", + "directory.local": "Tik iลก {domain}", + "directory.new_arrivals": "Nauji atvykฤ—liai", + "directory.recently_active": "Neseniai aktyvus (-i)", "disabled_account_banner.account_settings": "Paskyros nustatymai", - "disabled_account_banner.text": "Jลซsลณ paskyra {disabledAccount} ลกiuo metu yra iลกjungta.", + "disabled_account_banner.text": "Tavo paskyra {disabledAccount} ลกiuo metu yra iลกjungta.", + "dismissable_banner.community_timeline": "Tai โ€“ naujausi vieลกi ฤฏraลกai iลก ลพmoniลณ, kuriลณ paskyros talpinamos {domain}.", "dismissable_banner.dismiss": "Atmesti", - "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_statuses": "Tai ฤฏraลกai iลก viso socialinio tinklo, kurie ลกiandien sulaukia vis daugiau dฤ—mesio. Naujesni ฤฏraลกai, turintys daugiau boosts ir mฤ—gstamiausiลณ ฤฏraลกลณ, yra vertinami aukลกฤiau.", - "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", - "embed.instructions": "Embed this status on your website by copying the code below.", + "dismissable_banner.explore_links": "Tai โ€“ naujienos, kuriomis ลกiandien daugiausiai bendrinamasi socialiniame ลพiniatinklyje. Naujesnฤ—s naujienลณ istorijos, kurias paskelbฤ— daugiau skirtingลณ ลพmoniลณ, vertinamos aukลกฤiau.", + "dismissable_banner.explore_statuses": "Tai โ€“ ฤฏraลกai iลก viso socialinio ลพiniatinklio, kurie ลกiandien sulaukia daug dฤ—mesio. Naujesni ฤฏraลกai, turintys daugiau pakฤ—limลณ ir mฤ—gstamลณ, vertinami aukลกฤiau.", + "dismissable_banner.explore_tags": "Tai โ€“ saitaลพodลพiai, kurie ลกiandien sulaukia daug dฤ—mesio socialiniame ลพiniatinklyje. Saitaลพodลพiai, kuriuos naudoja daugiau skirtingลณ ลพmoniลณ, vertinami aukลกฤiau.", + "dismissable_banner.public_timeline": "Tai โ€“ naujausi vieลกi ฤฏraลกai iลก ลพmoniลณ socialiniame ลพiniatinklyje, kuriuos seka {domain} ลพmonฤ—s.", + "domain_block_modal.block": "Blokuoti serverฤฏ", + "domain_block_modal.block_account_instead": "Blokuoti {name} vietoj to", + "domain_block_modal.they_can_interact_with_old_posts": "ลฝmonฤ—s iลก ลกio serverio gali sฤ…veikauti su tavo senomis ฤฏraลกomis.", + "domain_block_modal.they_cant_follow": "Niekas iลก ลกio serverio negali tavฤ™s sekti.", + "domain_block_modal.they_wont_know": "Jie neลพinos, kad buvo uลพblokuoti.", + "domain_block_modal.title": "Blokuoti domenฤ…?", + "domain_block_modal.you_will_lose_followers": "Visi tavo sekฤ—jai iลก ลกio serverio bus paลกalinti.", + "domain_block_modal.you_wont_see_posts": "Nematysi naudotojลณ ฤฏraลกลณ ar praneลกimลณ ลกiame serveryje.", + "domain_pill.activitypub_lets_connect": "Tai leidลพia tau prisijungti ir bendrauti su ลพmonฤ—mis ne tik Mastodon, bet ir ฤฏvairiose socialinฤ—se programฤ—lฤ—se.", + "domain_pill.activitypub_like_language": "ActivityPub โ€“ tai tarsi kalba, kuria Mastodon kalba su kitais socialiniais tinklais.", + "domain_pill.server": "Serveris", + "domain_pill.their_handle": "Jลณ socialinis medijos vardas:", + "domain_pill.their_server": "Jลณ skaitmeniniai namai, kuriuose saugomi visi jลณ ฤฏraลกai.", + "domain_pill.their_username": "Jลณ unikalus identifikatorius jลณ serveryje. Skirtinguose serveriuose galima rasti naudotojลณ, turinฤiลณ tฤ… patฤฏ naudotojo vardฤ….", + "domain_pill.username": "Naudotojo vardas", + "domain_pill.whats_in_a_handle": "Kas yra socialiniame medijos varde?", + "domain_pill.who_they_are": "Kadangi socialines medijos vardai nurodo, kas ลพmogus yra ir kur jie yra, gali sฤ…veikauti su ลพmonฤ—mis visame socialiniame ลพiniatinklyje, kurฤฏ sudaro .", + "domain_pill.who_you_are": "Kadangi tavo socialinis medijos vardas nurodo, kas esi ir kur esi, ลพmonฤ—s gali sฤ…veikauti su tavimi visame socialiniame tinkle, kurฤฏ sudaro .", + "domain_pill.your_handle": "Tavo socialinis medijos vardas:", + "domain_pill.your_server": "Tavo skaitmeniniai namai, kuriuose saugomi visi tavo ฤฏraลกai. Nepatinka ลกis? Bet kada perkelk serverius ir atsivesk ir savo sekฤ—jus.", + "domain_pill.your_username": "Tavo unikalus identifikatorius ลกiame serveryje. Skirtinguose serveriuose galima rasti naudotojลณ su tuo paฤiu naudotojo vardu.", + "embed.instructions": "ฤฎterpk ลกฤฏ ฤฏraลกฤ… ฤฏ savo svetainฤ™ nukopijavus (-usi) toliau pateiktฤ… kodฤ….", "embed.preview": "ล tai kaip tai atrodys:", "emoji_button.activity": "Veikla", "emoji_button.clear": "Iลกvalyti", "emoji_button.custom": "Pasirinktinis", "emoji_button.flags": "Vฤ—liavos", - "emoji_button.food": "Maistas ir Gฤ—rimai", - "emoji_button.label": "ฤฎterpti veidelius", + "emoji_button.food": "Maistas ir gฤ—rimai", + "emoji_button.label": "ฤฎterpti jaustukฤ…", "emoji_button.nature": "Gamta", - "emoji_button.not_found": "Nerasta jokiลณ tinkamลณ jaustukลณ", + "emoji_button.not_found": "Nerasta jokiลณ tinkamลณ jaustukลณ.", "emoji_button.objects": "Objektai", "emoji_button.people": "ลฝmonฤ—s", - "emoji_button.recent": "Daลพniausiai naudojama", - "emoji_button.search": "Paieลกka...", + "emoji_button.recent": "Daลพniausiai naudojami", + "emoji_button.search": "Ieลกkoti...", "emoji_button.search_results": "Paieลกkos rezultatai", "emoji_button.symbols": "Simboliai", - "emoji_button.travel": "Kelionฤ—s ir Vietos", - "empty_column.account_hides_collections": "ล is naudotojas (-a) pasirinko nepadaryti ลกiฤ… informacijฤ… prieinamฤ…", - "empty_column.account_suspended": "Paskyra sustabdyta", - "empty_column.account_timeline": "No toots here!", - "empty_column.account_unavailable": "Profilis neprieinamas", - "empty_column.blocks": "Dar neuลพblokavote nฤ— vieno naudotojo.", - "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", - "empty_column.community": "Vietinฤ— laiko juosta yra tuลกฤia. Paraลกykite kฤ… nors vieลกai, kad pradฤ—tumฤ—te veikti!", - "empty_column.direct": "Dar neturite jokiลณ privaฤiลณ paminฤ—jimลณ. Kai iลกsiลณsite arba gausite tokฤฏ praneลกimฤ…, jis bus rodomas ฤia.", - "empty_column.domain_blocks": "There are no hidden domains yet.", - "empty_column.favourited_statuses": "Dar neturite mฤ—gstamiausiลณ ฤฏraลกลณ. Kai vienฤ… iลก jลณ pamฤ—gsite, jis bus rodomas ฤia.", - "empty_column.follow_requests": "Dar neturite jokiลณ sekimo uลพklausลณ. Kai gausite tokฤฏ praลกymฤ…, jis bus rodomas ฤia.", - "empty_column.followed_tags": "Dar nesekฤ—te jokiลณ grotaลพymiลณ. Kai tai padarysite, jie bus rodomi ฤia.", + "emoji_button.travel": "Kelionฤ—s ir vietos", + "empty_column.account_hides_collections": "ล is (-i) naudotojas (-a) pasirinko nepadaryti ลกiฤ… informacijฤ… prieinamฤ….", + "empty_column.account_suspended": "Paskyra pristabdyta.", + "empty_column.account_timeline": "Nฤ—ra ฤia ฤฏraลกลณ.", + "empty_column.account_unavailable": "Profilis neprieinamas.", + "empty_column.blocks": "Dar neuลพblokavai nฤ— vieno naudotojo.", + "empty_column.bookmarked_statuses": "Dar neturi nฤ— vienos ฤฏraลกo pridฤ—tos ลพymฤ—s. Kai vienฤ… iลก jลณ pridฤ—si ฤฏ ลพymes, jis bus rodomas ฤia.", + "empty_column.community": "Vietinฤ— laiko skalฤ— yra tuลกฤia. Paraลกyk kฤ… nors vieลกai, kad pradฤ—tum sฤ…veikauti.", + "empty_column.direct": "Dar neturi jokiลณ privaฤiลณ paminฤ—jimลณ. Kai iลกsiลณsi arba gausi vienฤ… iลก jลณ, jis bus rodomas ฤia.", + "empty_column.domain_blocks": "Dar nฤ—ra uลพblokuotลณ domenลณ.", + "empty_column.explore_statuses": "ล iuo metu niekas nฤ—ra tendencinga. Patikrink vฤ—liau!", + "empty_column.favourited_statuses": "Dar neturi mฤ—gstamลณ ฤฏraลกลณ. Kai vienฤ… iลก jลณ pamฤ—gsi, jis bus rodomas ฤia.", + "empty_column.favourites": "ล io ฤฏraลกo dar niekas nepamฤ—go. Kai kas nors tai padarys, jie bus rodomi ฤia.", + "empty_column.follow_requests": "Dar neturi jokiลณ sekimo praลกymลณ. Kai gausi tokฤฏ praลกymฤ…, jis bus rodomas ฤia.", + "empty_column.followed_tags": "Dar neseki jokiลณ saitaลพodลพiลณ. Kai tai padarysi, jie bus rodomi ฤia.", "empty_column.hashtag": "Nฤ—ra nieko ลกiame saitaลพodyje kol kas.", - "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.", - "empty_column.lists": "Dar neturite jokiลณ sฤ…raลกลณ. Kai jฤฏ sukursite, jis bus rodomas ฤia.", - "empty_column.mutes": "Dar nesate nutildฤ™ nฤ— vieno naudotojo.", - "empty_column.notifications": "Dar neturite jokiลณ praneลกimลณ. Kai kiti ลพmonฤ—s su jumis bendraus, matysite tai ฤia.", - "empty_column.public": "ฤŒia nieko nฤ—ra! Paraลกykite kฤ… nors vieลกai arba rankiniu bลซdu sekite naudotojus iลก kitลณ serveriลณ, kad jฤฏ uลพpildytumฤ—te", - "error.unexpected_crash.explanation": "Dฤ—l mลซsลณ kodo klaidos arba narลกyklฤ—s suderinamumo problemos ลกis puslapis negalฤ—jo bลซti rodomas teisingai.", - "error.unexpected_crash.explanation_addons": "ล ฤฏ puslapฤฏ nepavyko teisingai parodyti. ล iฤ… klaidฤ… greiฤiausiai sukฤ—lฤ— narลกyklฤ—s priedas arba automatinio vertimo ฤฏrankiai.", - "error.unexpected_crash.next_steps": "Pabandykite atnaujinti puslapฤฏ. Jei tai nepadeda, galbลซt vis dar galฤ—site naudotis \"Mastodon\" naudodami kitฤ… narลกyklฤ™ arba vietinฤ™ programฤ—lฤ™.", - "error.unexpected_crash.next_steps_addons": "Pabandykite juos iลกjungti ir atnaujinti puslapฤฏ. Jei tai nepadeda, galbลซt vis dar galฤ—site naudotis \"Mastodon\" naudodami kitฤ… narลกyklฤ™ arba vietinฤ™ programฤ—lฤ™.", - "errors.unexpected_crash.report_issue": "Praneลกti apie triktฤฏ", + "empty_column.home": "Tavo pagrindinio laiko skalฤ— tuลกฤia. Sek daugiau ลพmoniลณ, kad jฤ… uลพpildytum.", + "empty_column.list": "Nฤ—ra nieko ลกiame sฤ…raลกe kol kas. Kai ลกio sฤ…raลกo nariai paskelbs naujลณ ฤฏraลกลณ, jie bus rodomi ฤia.", + "empty_column.lists": "Dar neturi jokiลณ sฤ…raลกลณ. Kai jฤฏ sukursi, jis bus rodomas ฤia.", + "empty_column.mutes": "Dar nesi nutildฤ™s (-usi) nฤ— vieno naudotojo.", + "empty_column.notification_requests": "Viskas ลกvaru! ฤŒia nieko nฤ—ra. Kai gausi naujลณ praneลกimลณ, jie bus rodomi ฤia pagal tavo nustatymus.", + "empty_column.notifications": "Dar neturi jokiลณ praneลกimลณ. Kai kiti ลพmonฤ—s su tavimi sฤ…veikaus, matysi tai ฤia.", + "empty_column.public": "ฤŒia nieko nฤ—ra. Paraลกyk kฤ… nors vieลกai arba rankiniu bลซdu sek naudotojus iลก kitลณ serveriลณ, kad jฤฏ uลพpildytum.", + "error.unexpected_crash.explanation": "Dฤ—l mลซsลณ kodo riktos arba narลกyklฤ—s suderinamumo problemos ลกis puslapis negalฤ—jo bลซti rodomas teisingai.", + "error.unexpected_crash.explanation_addons": "ล ฤฏ puslapฤฏ nepavyko parodyti teisingai. ล iฤ… klaidฤ… greiฤiausiai sukฤ—lฤ— narลกyklฤ—s priedas arba automatinio vertimo ฤฏrankiai.", + "error.unexpected_crash.next_steps": "Pabandyk atnaujinti puslapฤฏ. Jei tai nepadeda, galbลซt vis dar galฤ—si naudotis Mastodon per kitฤ… narลกyklฤ™ arba savฤ…jฤ… programฤ—lฤ™.", + "error.unexpected_crash.next_steps_addons": "Pabandyk juos iลกjungti ir atnaujinti puslapฤฏ. Jei tai nepadeda, galbลซt vis dar galฤ—si naudotis Mastodon per kitฤ… narลกyklฤ™ arba savฤ…jฤ… programฤ—lฤ™.", + "errors.unexpected_crash.copy_stacktrace": "Kopijuoti dฤ—klo eigฤ… ฤฏ iลกkarpinฤ™", + "errors.unexpected_crash.report_issue": "Praneลกti apie problemฤ…", "explore.search_results": "Paieลกkos rezultatai", "explore.suggested_follows": "ลฝmonฤ—s", "explore.title": "Narลกyti", "explore.trending_links": "Naujienos", "explore.trending_statuses": "ฤฎraลกai", "explore.trending_tags": "Saitaลพodลพiai", - "filter_modal.added.context_mismatch_explanation": "ล i filtro kategorija netaikoma kontekste, kuriame perลพiลซrฤ—jote ลกฤฏ praneลกimฤ…. Jei norite, kad praneลกimas bลซtลณ filtruojamas ir ลกiame kontekste, turฤ—site redaguoti filtrฤ….", - "filter_modal.added.context_mismatch_title": "Konteksto neatitikimas!", - "filter_modal.added.expired_explanation": "ล i filtro kategorija nustojo galioti, kad ji bลซtลณ taikoma, turฤ—site pakeisti galiojimo datฤ….", - "filter_modal.added.expired_title": "Pasibaigฤ— filtro galiojimo laikas!", - "filter_modal.added.review_and_configure": "Norฤ—dami perลพiลซrฤ—ti ir toliau konfigลซruoti ลกiฤ… filtro kategorijฤ…, eikite ฤฏ {settings_link}.", - "filter_modal.added.review_and_configure_title": "Filtro nuostatos", - "filter_modal.added.settings_link": "nustatymลณ puslapis", - "filter_modal.added.short_explanation": "ล is praneลกimas buvo ฤฏtrauktas ฤฏ ลกiฤ… filtro kategorijฤ…: {title}.", - "filter_modal.added.title": "Pridฤ—tas filtras!", - "filter_modal.select_filter.context_mismatch": "netaikoma ลกiame kontekste", - "filter_modal.select_filter.expired": "nebegalioja", + "filter_modal.added.context_mismatch_explanation": "ล i filtro kategorija netaikoma kontekstui, kuriame perลพiลซrฤ—jai ลกฤฏ ฤฏraลกฤ…. Jei nori, kad ฤฏraลกas bลซtลณ filtruojamas ir ลกiame kontekste, turฤ—si redaguoti filtrฤ….", + "filter_modal.added.context_mismatch_title": "Konteksto neatitikimas.", + "filter_modal.added.expired_explanation": "ล i filtro kategorija nustojo galioti. Kad ji bลซtลณ taikoma, turฤ—si pakeisti galiojimo datฤ….", + "filter_modal.added.expired_title": "Baigฤ—si filtro galiojimas.", + "filter_modal.added.review_and_configure": "Norint perลพiลซrฤ—ti ir toliau konfigลซruoti ลกiฤ… filtro kategorijฤ…, eik ฤฏ {settings_link}.", + "filter_modal.added.review_and_configure_title": "Filtro nustatymai", + "filter_modal.added.settings_link": "nustatymลณ puslapฤฏ", + "filter_modal.added.short_explanation": "ล is ฤฏraลกas buvo pridฤ—tas ฤฏ ลกiฤ… filtro kategorijฤ…: {title}.", + "filter_modal.added.title": "Pridฤ—tas filtras.", + "filter_modal.select_filter.context_mismatch": "netaikoma ลกiame kontekste.", + "filter_modal.select_filter.expired": "nebegalioja.", "filter_modal.select_filter.prompt_new": "Nauja kategorija: {name}", "filter_modal.select_filter.search": "Ieลกkoti arba sukurti", - "filter_modal.select_filter.subtitle": "Naudoti esamฤ… kategorijฤ… arba sukurti naujฤ…", + "filter_modal.select_filter.subtitle": "Naudok esamฤ… kategorijฤ… arba sukurk naujฤ….", "filter_modal.select_filter.title": "Filtruoti ลกฤฏ ฤฏraลกฤ…", - "filter_modal.title.status": "Filtruoti ลกฤฏ ฤฏraลกฤ…", + "filter_modal.title.status": "Filtruoti ฤฏraลกฤ…", + "filtered_notifications_banner.mentions": "{count, plural, one {paminฤ—jimas} few {paminฤ—jimai} many {paminฤ—jimo} other {paminฤ—jimลณ}}", + "filtered_notifications_banner.pending_requests": "Praneลกimai iลก {count, plural, =0 {nฤ— vieno} one {vienos ลพmogaus} few {# ลพmoniลณ} many {# ลพmoniลณ} other {# ลพmoniลณ}}, kuriuos galbลซt paลพฤฏsti", + "filtered_notifications_banner.title": "Filtruojami praneลกimai", "firehose.all": "Visi", "firehose.local": "ล is serveris", "firehose.remote": "Kiti serveriai", - "follow_request.authorize": "Autorizuoti", + "follow_request.authorize": "Leisti", "follow_request.reject": "Atmesti", - "follow_requests.unlocked_explanation": "Nors tavo paskyra neuลพrakinta, {domain} personalas mano, kad galbลซt norฤ—si rankiniu bลซdu patikrinti ลกiลณ paskyrลณ sekimo uลพklausas.", - "follow_suggestions.curated_suggestion": "Redaktoriลณ pasirinkimas", + "follow_requests.unlocked_explanation": "Nors tavo paskyra neuลพrakinta, {domain} personalas mano, kad galbลซt norฤ—si rankiniu bลซdu patikrinti ลกiลณ paskyrลณ sekimo praลกymus.", + "follow_suggestions.curated_suggestion": "Personalo pasirinkimai", "follow_suggestions.dismiss": "Daugiau nerodyti", + "follow_suggestions.featured_longer": "Rankomis atrinkta {domain} komanda", + "follow_suggestions.friends_of_friends_longer": "Populiarus tarp ลพmoniลณ, kuriลณ seki", + "follow_suggestions.hints.featured": "ล ฤฏ profilฤฏ atrinko {domain} komanda.", + "follow_suggestions.hints.friends_of_friends": "ล is profilis yra populiarus tarp ลพmoniลณ, kuriuos seki.", + "follow_suggestions.hints.most_followed": "ล is profilis yra vienas iลก labiausiai sekamลณ domene {domain}.", + "follow_suggestions.hints.most_interactions": "Pastaruoju metu ลกis profilis sulaukia daug dฤ—mesio domane {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "ล is profilis panaลกus ฤฏ profilius, kuriuos neseniai sekei.", "follow_suggestions.personalized_suggestion": "Suasmenintas pasiลซlymas", "follow_suggestions.popular_suggestion": "Populiarus pasiลซlymas", + "follow_suggestions.popular_suggestion_longer": "Populiarus domene {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Panaลกลซs ฤฏ profilius, kuriuos neseniai seki", "follow_suggestions.view_all": "Perลพiลซrฤ—ti viskฤ…", "follow_suggestions.who_to_follow": "Kฤ… sekti", - "followed_tags": "Sekamos saitaลพodลพiai", + "followed_tags": "Sekami saitaลพodลพiai", "footer.about": "Apie", "footer.directory": "Profiliลณ katalogas", "footer.get_app": "Gauti programฤ—lฤ™", @@ -283,216 +329,273 @@ "footer.keyboard_shortcuts": "Spartieji klaviลกai", "footer.privacy_policy": "Privatumo politika", "footer.source_code": "Perลพiลซrฤ—ti ลกaltinio kodฤ…", - "footer.status": "Bลซsena", - "generic.saved": "Iลกsaugoti", - "getting_started.heading": "Pradedant", + "footer.status": "Statusas", + "generic.saved": "Iลกsaugota", + "getting_started.heading": "Kaip pradฤ—ti", "hashtag.column_header.tag_mode.all": "ir {additional}", "hashtag.column_header.tag_mode.any": "ar {additional}", "hashtag.column_header.tag_mode.none": "be {additional}", - "hashtag.column_settings.select.no_options_message": "Pasiลซlymลณ nerasta", - "hashtag.column_settings.select.placeholder": "ฤฎvesti grotaลพymesโ€ฆ", + "hashtag.column_settings.select.no_options_message": "Pasiลซlymลณ nerasta.", + "hashtag.column_settings.select.placeholder": "ฤฎvesti saitaลพodลพiusโ€ฆ", "hashtag.column_settings.tag_mode.all": "Visi ลกie", - "hashtag.column_settings.tag_mode.any": "Bet kuris ลกiลณ", + "hashtag.column_settings.tag_mode.any": "Bet kuris iลก ลกiลณ", "hashtag.column_settings.tag_mode.none": "Nฤ— vienas iลก ลกiลณ", - "hashtag.column_settings.tag_toggle": "Include additional tags in this column", - "hashtag.counter_by_accounts": "{count, plural,one {{counter} dalyvis}other {{counter} dalyviai}}", - "hashtag.counter_by_uses": "{count, plural, one {{counter} ฤฏraลกas} other {{counter} ฤฏraลกลณ}}", - "hashtag.counter_by_uses_today": "{count, plural, one {{counter} ฤฏraลกas} other {{counter} ฤฏraลกลณ}} ลกiandien", - "hashtag.follow": "Sekti grotaลพymฤ™", - "hashtag.unfollow": "Nesekti grotaลพymฤ—s", - "hashtags.and_other": "โ€ฆir{count, plural,other {#daugiau}}", - "home.column_settings.basic": "Pagrindinis", - "home.column_settings.show_reblogs": "Rodyti \"boosts\"", + "hashtag.column_settings.tag_toggle": "ฤฎtraukti papildomas ลกio stulpelio ลพymes", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} dalyvis} few {{counter} dalyviai} many {{counter} dalyvio} other {{counter} dalyviลณ}}", + "hashtag.counter_by_uses": "{count, plural, one {{counter} ฤฏraลกas} few {{counter} ฤฏraลกai} many {{counter} ฤฏraลกo} other {{counter} ฤฏraลกลณ}}", + "hashtag.counter_by_uses_today": "{count, plural, one {{counter} ฤฏraลกas} few {{counter} ฤฏraลกai} many {{counter} ฤฏraลกo} other {{counter} ฤฏraลกลณ}} ลกiandien", + "hashtag.follow": "Sekti saitaลพodฤฏ", + "hashtag.unfollow": "Nebesekti saitaลพodฤฏ", + "hashtags.and_other": "โ€ฆir {count, plural, one {# daugiau} few {# daugiau} many {# daugiau}other {# daugiau}}", + "home.column_settings.show_reblogs": "Rodyti pakฤ—limus", "home.column_settings.show_replies": "Rodyti atsakymus", "home.hide_announcements": "Slฤ—pti skelbimus", - "home.pending_critical_update.link": "ลฝiลซrฤ—ti atnaujinimus", - "home.pending_critical_update.title": "Galimas kritinis saugumo atnaujinimas!", + "home.pending_critical_update.body": "Kuo greiฤiau atnaujink savo Mastodon serverฤฏ.", + "home.pending_critical_update.link": "ลฝiลซrฤ—ti naujinimus", + "home.pending_critical_update.title": "Galimas kritinis saugumo naujinimas.", + "home.show_announcements": "Rodyti skelbimus", + "interaction_modal.description.favourite": "Su Mastodon paskyra gali pamฤ—gti ลกฤฏ ฤฏraลกฤ…, kad autorius (-ฤ—) ลพinotลณ, jog vertinti tai ir iลกsaugoti jฤฏ vฤ—liau.", + "interaction_modal.description.follow": "Su Mastodon paskyra gali sekti {name}, kad gautum jลณ ฤฏraลกus ฤฏ pagrindinฤฏ srautฤ….", + "interaction_modal.description.reblog": "Su Mastodon paskyra gali pakelti ลกiฤ… ฤฏraลกฤ… ir pasidalyti juo su savo sekฤ—jais.", + "interaction_modal.description.reply": "Su Mastodon paskyra gali atsakyti ฤฏ ลกฤฏ ฤฏraลกฤ….", + "interaction_modal.login.action": "ฤฎ pagrindinฤฏ puslapฤฏ", + "interaction_modal.login.prompt": "Tavo pagrindinio serverio domenas, pvz., mastodon.social.", "interaction_modal.no_account_yet": "Nesi Mastodon?", "interaction_modal.on_another_server": "Kitame serveryje", "interaction_modal.on_this_server": "ล iame serveryje", - "interaction_modal.sign_in": "Nesi prisijungฤ™s (-usi) prie ลกio serverio. Kur yra laikoma tavo paskyra?", + "interaction_modal.sign_in": "Nesi prisijungฤ™s (-usi) prie ลกio serverio. Kur yra talpinama tavo paskyra?", "interaction_modal.sign_in_hint": "Patarimas: tai svetainฤ—, kurioje uลพsiregistravai. Jei neprisimeni, ieลกkok sveikinimo el. laiลกko savo paลกto dฤ—ลพutฤ—je. Taip pat gali ฤฏvesti visฤ… savo naudotojo vardฤ… (pvz., @Mastodon@mastodon.social).", - "interaction_modal.title.favourite": "Mฤ—gstamiausias {name} ฤฏraลกas", + "interaction_modal.title.favourite": "Pamฤ—gti {name} ฤฏraลกฤ…", "interaction_modal.title.follow": "Sekti {name}", - "keyboard_shortcuts.back": "to navigate back", - "keyboard_shortcuts.blocked": "to open blocked users list", - "keyboard_shortcuts.boost": "to boost", - "keyboard_shortcuts.column": "to focus a status in one of the columns", - "keyboard_shortcuts.compose": "to focus the compose textarea", - "keyboard_shortcuts.direct": "to open direct messages column", - "keyboard_shortcuts.down": "to move down in the list", - "keyboard_shortcuts.enter": "to open status", - "keyboard_shortcuts.federated": "to open federated timeline", - "keyboard_shortcuts.heading": "Keyboard Shortcuts", - "keyboard_shortcuts.home": "to open home timeline", + "interaction_modal.title.reblog": "Pakelti {name} ฤฏraลกฤ…", + "interaction_modal.title.reply": "Atsakyti ฤฏ {name} ฤฏraลกฤ…", + "intervals.full.days": "{number, plural, one {# diena} few {# dienos} many {# dienos} other {# dienลณ}}", + "intervals.full.hours": "{number, plural, one {# valanda} few {# valandos} many {# valandos} other {# valandลณ}}", + "intervals.full.minutes": "{number, plural, one {# minutฤ—} few {# minutes} many {# minutฤ—s} other {# minuฤiลณ}}", + "keyboard_shortcuts.back": "Narลกyti atgal", + "keyboard_shortcuts.blocked": "Atidaryti uลพblokuotลณ naudotojลณ sฤ…raลกฤ…", + "keyboard_shortcuts.boost": "Pakelti ฤฏraลกฤ…", + "keyboard_shortcuts.column": "Fokusuoti stulpelฤฏ", + "keyboard_shortcuts.compose": "Fokusuoti rengykles teksto sritฤฏ", + "keyboard_shortcuts.description": "Apraลกymas", + "keyboard_shortcuts.direct": "atidaryti privaฤiลณ paminฤ—jimลณ stulpelฤฏ", + "keyboard_shortcuts.down": "Perkelti ลพemyn sฤ…raลกe", + "keyboard_shortcuts.enter": "Atidaryti ฤฏraลกฤ…", + "keyboard_shortcuts.favourite": "Pamฤ—gti ฤฏraลกฤ…", + "keyboard_shortcuts.favourites": "Atidaryti mฤ—gstamลณjลณ sฤ…raลกฤ…", + "keyboard_shortcuts.federated": "Atidaryti federacinฤ™ laiko skalฤ™", + "keyboard_shortcuts.heading": "Spartieji klaviลกai", + "keyboard_shortcuts.home": "Atidaryti pagrindinฤฏ laiko skalฤ™", "keyboard_shortcuts.hotkey": "Spartusis klaviลกas", - "keyboard_shortcuts.legend": "to display this legend", - "keyboard_shortcuts.local": "to open local timeline", - "keyboard_shortcuts.mention": "to mention author", - "keyboard_shortcuts.muted": "to open muted users list", - "keyboard_shortcuts.my_profile": "to open your profile", - "keyboard_shortcuts.notifications": "to open notifications column", + "keyboard_shortcuts.legend": "Rodyti ลกiฤ… legendฤ…", + "keyboard_shortcuts.local": "Atidaryti vietinฤ™ laiko skalฤ™", + "keyboard_shortcuts.mention": "Paminฤ—ti autoriลณ (-ฤ™)", + "keyboard_shortcuts.muted": "Atidaryti nutildytลณ naudotojลณ sฤ…raลกฤ…", + "keyboard_shortcuts.my_profile": "Atidaryti savo profilฤฏ", + "keyboard_shortcuts.notifications": "Atidaryti praneลกimลณ stulpelฤฏ", "keyboard_shortcuts.open_media": "Atidaryti medijฤ…", - "keyboard_shortcuts.pinned": "to open pinned toots list", - "keyboard_shortcuts.profile": "to open author's profile", - "keyboard_shortcuts.reply": "to reply", - "keyboard_shortcuts.requests": "to open follow requests list", - "keyboard_shortcuts.search": "to focus search", - "keyboard_shortcuts.spoilers": "to show/hide CW field", - "keyboard_shortcuts.start": "to open \"get started\" column", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.pinned": "Atidaryti prisegtลณ ฤฏraลกลณ sฤ…raลกฤ…", + "keyboard_shortcuts.profile": "Atidaryti autoriaus (-ฤ—s) profilฤฏ", + "keyboard_shortcuts.reply": "Atsakyti ฤฏ ฤฏraลกฤ…", + "keyboard_shortcuts.requests": "Atidaryti sekimo praลกymลณ sฤ…raลกฤ…", + "keyboard_shortcuts.search": "Fokusuoti paieลกkos juostฤ…", + "keyboard_shortcuts.spoilers": "Rodyti / slฤ—pti Tฤฎ laukฤ…", + "keyboard_shortcuts.start": "Atidarykite stulpelฤฏ Kaip pradฤ—ti", + "keyboard_shortcuts.toggle_hidden": "Rodyti / slฤ—pti tekstฤ… po Tฤฎ", "keyboard_shortcuts.toggle_sensitivity": "Rodyti / slฤ—pti medijฤ…", - "keyboard_shortcuts.toot": "to start a brand new toot", - "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", - "keyboard_shortcuts.up": "to move up in the list", + "keyboard_shortcuts.toot": "Pradฤ—ti naujฤ… ฤฏraลกฤ…", + "keyboard_shortcuts.unfocus": "Nebefokusuoti rengykles teksto sritฤฏ / paieลกkฤ…", + "keyboard_shortcuts.up": "Perkelti ฤฏ virลกลณ sฤ…raลกe", "lightbox.close": "Uลพdaryti", + "lightbox.compress": "Suspausti vaizdo perลพiลซros langelฤฏ", + "lightbox.expand": "Iลกplฤ—sti vaizdo perลพiลซros langelฤฏ", "lightbox.next": "Kitas", "lightbox.previous": "Ankstesnis", "limited_account_hint.action": "Vis tiek rodyti profilฤฏ", - "limited_account_hint.title": "ล ฤฏ profilฤฏ paslฤ—pฤ— {domain} moderatoriai.", + "limited_account_hint.title": "ล ฤฏ profilฤฏ paslฤ—pฤ— {domain} priลพiลซrฤ—tojai.", "link_preview.author": "Sukลซrฤ— {name}", + "link_preview.more_from_author": "Daugiau iลก {name}", + "link_preview.shares": "{count, plural, one {{counter} ฤฏraลกas} few {{counter} ฤฏraลกai} many {{counter} ฤฏraลกo} other {{counter} ฤฏraลกลณ}}", "lists.account.add": "Pridฤ—ti ฤฏ sฤ…raลกฤ…", "lists.account.remove": "Paลกalinti iลก sฤ…raลกo", "lists.delete": "Iลกtrinti sฤ…raลกฤ…", "lists.edit": "Redaguoti sฤ…raลกฤ…", - "lists.edit.submit": "Prieraลกo pakeitimas", + "lists.edit.submit": "Keisti pavadinimฤ…", + "lists.exclusive": "Slฤ—pti ลกiuos ฤฏraลกus iลก pagrindinio", "lists.new.create": "Pridฤ—ti sฤ…raลกฤ…", "lists.new.title_placeholder": "Naujas sฤ…raลกo pavadinimas", - "lists.replies_policy.followed": "Bet kuris sekamas naudotojas", - "lists.replies_policy.list": "Sฤ…raลกo nariai", - "lists.replies_policy.none": "Nei vienas", + "lists.replies_policy.followed": "Bet kuriam sekamam naudotojui", + "lists.replies_policy.list": "Sฤ…raลกo nariams", + "lists.replies_policy.none": "Nei vienam", "lists.replies_policy.title": "Rodyti atsakymus:", "lists.search": "Ieลกkoti tarp sekamลณ ลพmoniลณ", - "lists.subheading": "Jลซsลณ sฤ…raลกai", + "lists.subheading": "Tavo sฤ…raลกai", + "load_pending": "{count, plural, one {# naujas elementas} few {# nauji elementai} many {# naujo elemento} other {# naujลณ elementลณ}}", "loading_indicator.label": "Kraunamaโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Slฤ—pti vaizdฤ…} few {Slฤ—pti vaizdus} many {Slฤ—pti vaizdo} other {Slฤ—pti vaizdลณ}}", - "moved_to_account_banner.text": "Tavo paskyra {disabledAccount} ลกiuo metu yra iลกjungta, nes persikฤ—lei ฤฏ {movedToAccount}.", - "mute_modal.duration": "Trukmฤ—", - "mute_modal.hide_notifications": "Slฤ—pti ลกio naudotojo praneลกimus?", - "mute_modal.indefinite": "Neribotas", + "moved_to_account_banner.text": "Tavo paskyra {disabledAccount} ลกiuo metu iลกjungta, nes persikฤ—lei ฤฏ {movedToAccount}.", + "mute_modal.hide_from_notifications": "Slฤ—pti nuo praneลกimลณ", + "mute_modal.hide_options": "Slฤ—pti parinktis", + "mute_modal.indefinite": "Kol atลกauksiu jลณ nutildymฤ…", + "mute_modal.show_options": "Rodyti parinktis", + "mute_modal.they_can_mention_and_follow": "Jie gali tave paminฤ—ti ir sekti, bet tu jลณ nematysi.", + "mute_modal.they_wont_know": "Jie neลพinos, kad buvo nutildyti.", + "mute_modal.title": "Nutildyti naudotojฤ…?", + "mute_modal.you_wont_see_mentions": "Nematysi ฤฏraลกus, kuriuose jie paminimi.", + "mute_modal.you_wont_see_posts": "Jie vis tiek gali matyti tavo ฤฏraลกus, bet tu nematysi jลณ.", "navigation_bar.about": "Apie", - "navigation_bar.advanced_interface": "Atidarykite iลกplฤ—stinฤ™ ลพiniatinklio sฤ…sajฤ…", + "navigation_bar.advanced_interface": "Atidaryti iลกplฤ—stinฤ™ ลพiniatinklio sฤ…sajฤ…", "navigation_bar.blocks": "Uลพblokuoti naudotojai", "navigation_bar.bookmarks": "ลฝymฤ—s", - "navigation_bar.compose": "Compose new toot", + "navigation_bar.community_timeline": "Vietinฤ— laiko skalฤ—", + "navigation_bar.compose": "Sukurti naujฤ… ฤฏraลกฤ…", "navigation_bar.direct": "Privatลซs paminฤ—jimai", "navigation_bar.discover": "Atrasti", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.domain_blocks": "Uลพblokuoti domenai", "navigation_bar.explore": "Narลกyti", - "navigation_bar.favourites": "Mฤ—gstamiausi", - "navigation_bar.filters": "Nutylฤ—ti ลพodลพiai", - "navigation_bar.follow_requests": "Sekti praลกymus", - "navigation_bar.followed_tags": "Sekti grotaลพymฤ™", + "navigation_bar.favourites": "Mฤ—gstami", + "navigation_bar.filters": "Nutildyti ลพodลพiai", + "navigation_bar.follow_requests": "Sekimo praลกymai", + "navigation_bar.followed_tags": "Sekami saitaลพodลพiai", "navigation_bar.follows_and_followers": "Sekimai ir sekฤ—jai", "navigation_bar.lists": "Sฤ…raลกai", "navigation_bar.logout": "Atsijungti", - "navigation_bar.mutes": "Uลพtildyti naudotojai", + "navigation_bar.mutes": "Nutildyti naudotojai", "navigation_bar.opened_in_classic_interface": "ฤฎraลกai, paskyros ir kiti konkretลซs puslapiai pagal numatytuosius nustatymus atidaromi klasikinฤ—je ลพiniatinklio sฤ…sajoje.", "navigation_bar.personal": "Asmeninis", - "navigation_bar.pins": "Pinned toots", + "navigation_bar.pins": "Prisegti ฤฏraลกai", "navigation_bar.preferences": "Nuostatos", - "navigation_bar.public_timeline": "Federuota laiko juosta", + "navigation_bar.public_timeline": "Federacinฤ— laiko skalฤ—", "navigation_bar.search": "Ieลกkoti", "navigation_bar.security": "Apsauga", - "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", - "notification.admin.report": "{name} praneลกฤ—.{target}", + "not_signed_in_indicator.not_signed_in": "Norint pasiekti ลกฤฏ iลกteklฤฏ, reikia prisijungti.", + "notification.admin.report": "{name} praneลกฤ— {target}", "notification.admin.sign_up": "{name} uลพsiregistravo", - "notification.favourite": "{name} pamฤ—go jลซsลณ ฤฏraลกฤ…", - "notification.follow": "{name} pradฤ—jo jus sekti", - "notification.follow_request": "{name} nori tapti jลซsลณ sekฤ—ju", - "notification.mention": "{name} paminฤ—jo jus", + "notification.favourite": "{name} pamฤ—go tavo ฤฏraลกฤ…", + "notification.follow": "{name} seka tave", + "notification.follow_request": "{name} papraลกฤ— tave sekti", + "notification.mention": "{name} paminฤ—jo tave", + "notification.moderation-warning.learn_more": "Suลพinoti daugiau", + "notification.moderation_warning": "Gavai priลพiลซrฤ—jimo ฤฏspฤ—jimฤ…", + "notification.moderation_warning.action_delete_statuses": "Kai kurie tavo ฤฏraลกai buvo paลกalintos.", + "notification.moderation_warning.action_disable": "Tavo paskyra buvo iลกjungta.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo ฤฏraลกai buvo paลพymฤ—tos kaip jautrios.", + "notification.moderation_warning.action_none": "Tavo paskyra gavo priลพiลซrฤ—jimo ฤฏspฤ—jimฤ….", + "notification.moderation_warning.action_sensitive": "Nuo ลกiol tavo ฤฏraลกai bus paลพymฤ—ti kaip jautrลซs.", + "notification.moderation_warning.action_silence": "Tavo paskyra buvo apribota.", + "notification.moderation_warning.action_suspend": "Tavo paskyra buvo sustabdyta.", "notification.own_poll": "Tavo apklausa baigฤ—si", "notification.poll": "Apklausa, kurioje balsavai, pasibaigฤ—", - "notification.reblog": "{name} boosted your status", + "notification.reblog": "{name} pakฤ—lฤ— tavo ฤฏraลกฤ…", + "notification.relationships_severance_event": "Prarasti sฤ…ryลกiai su {name}", + "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", + "notification_requests.dismiss": "Atmesti", + "notification_requests.notifications_from": "Praneลกimai iลก {name}", + "notification_requests.title": "Filtruojami praneลกimai", "notifications.clear": "Iลกvalyti praneลกimus", "notifications.clear_confirmation": "Ar tikrai nori visam laikui iลกvalyti visus praneลกimus?", - "notifications.column_settings.admin.report": "Nauji ataskaitos:", - "notifications.column_settings.admin.sign_up": "Nauji prisiregistravimai:", + "notifications.column_settings.admin.report": "Naujos ataskaitos:", + "notifications.column_settings.admin.sign_up": "Naujos registracijos:", "notifications.column_settings.alert": "Darbalaukio praneลกimai", - "notifications.column_settings.favourite": "Mฤ—gstamiausi:", + "notifications.column_settings.favourite": "Mฤ—gstami:", "notifications.column_settings.filter_bar.advanced": "Rodyti visas kategorijas", - "notifications.column_settings.filter_bar.category": "Greito filtro juosta", - "notifications.column_settings.filter_bar.show_bar": "Rodyti filtro juostฤ…", + "notifications.column_settings.filter_bar.category": "Spartaus filtro juosta", "notifications.column_settings.follow": "Nauji sekฤ—jai:", - "notifications.column_settings.follow_request": "Nauji praลกymai sekti:", + "notifications.column_settings.follow_request": "Nauji sekimo praลกymai:", "notifications.column_settings.mention": "Paminฤ—jimai:", "notifications.column_settings.poll": "Balsavimo rezultatai:", - "notifications.column_settings.push": "\"Push\" praneลกimai", - "notifications.column_settings.reblog": "\"Boost\" kiekis:", + "notifications.column_settings.push": "Tiesioginiai praneลกimai", + "notifications.column_settings.reblog": "Pakฤ—limai:", "notifications.column_settings.show": "Rodyti stulpelyje", "notifications.column_settings.sound": "Paleisti garsฤ…", - "notifications.column_settings.status": "New toots:", + "notifications.column_settings.status": "Nauji ฤฏraลกai:", "notifications.column_settings.unread_notifications.category": "Neperskaityti praneลกimai", "notifications.column_settings.unread_notifications.highlight": "Paryลกkinti neperskaitytus praneลกimus", "notifications.column_settings.update": "Redagavimai:", "notifications.filter.all": "Visi", - "notifications.filter.boosts": "\"Boost\" kiekis", - "notifications.filter.favourites": "Mฤ—gstamiausi", + "notifications.filter.boosts": "Pakฤ—limai", + "notifications.filter.favourites": "Mฤ—gstami", "notifications.filter.follows": "Sekimai", "notifications.filter.mentions": "Paminฤ—jimai", "notifications.filter.polls": "Balsavimo rezultatai", - "notifications.filter.statuses": "Atnaujinimai iลก ลพmoniลณ kuriuos sekate", + "notifications.filter.statuses": "Naujinimai iลก ลพmoniลณ, kuriuos seki", "notifications.grant_permission": "Suteikti leidimฤ….", "notifications.group": "{count} praneลกimai", "notifications.mark_as_read": "Paลพymฤ—ti kiekvienฤ… praneลกimฤ… kaip perskaitytฤ…", - "notifications.permission_denied": "Darbalaukio praneลกimai nepasiekiami dฤ—l anksฤiau atmestos narลกyklฤ—s leidimลณ uลพklausos", - "notifications.permission_denied_alert": "Negalima ฤฏjungti darbalaukio praneลกimลณ, nes prieลก tai narลกyklฤ—s leidimas buvo atmestas", - "notifications.permission_required": "Darbalaukio praneลกimai nepasiekiami, nes nesuteiktas reikiamas leidimas.", + "notifications.permission_denied": "Darbalaukio praneลกimai nepasiekiami dฤ—l anksฤiau atmestos narลกyklฤ—s leidimลณ uลพklausos.", + "notifications.permission_denied_alert": "Negalima ฤฏjungti darbalaukio praneลกimลณ, nes prieลก tai narลกyklฤ—s leidimas buvo atmestas.", + "notifications.permission_required": "Darbalaukio praneลกimai nepasiekiami, nes nebuvo suteiktas reikiamas leidimas.", + "notifications.policy.filter_new_accounts.hint": "Sukurta per {days, plural, one {vienฤ… dienฤ…} few {# dienas} many {# dienos} other {# dienลณ}}", + "notifications.policy.filter_new_accounts_title": "Naujos paskyros", + "notifications.policy.filter_not_following_hint": "Kol jลณ nepatvirtinsi rankiniu bลซdu", + "notifications.policy.filter_not_following_title": "ลฝmoniลณ, kuriuos neseki", + "notifications.policy.filter_private_mentions_title": "Nepageidaujami privatลซs paminฤ—jimai", + "notifications.policy.title": "Filtruoti praneลกimus iลกโ€ฆ", "notifications_permission_banner.enable": "ฤฎjungti darbalaukio praneลกimus", - "notifications_permission_banner.how_to_control": "Jei norite gauti praneลกimus, kai \"Mastodon\" nฤ—ra atidarytas, ฤฏjunkite darbalaukio praneลกimus. ฤฎjungฤ™ darbalaukio praneลกimus, galite tiksliai valdyti, kokiลณ tipลณ sฤ…veikos generuoja darbalaukio praneลกimus, naudodamiesi pirmiau esanฤiu mygtuku {icon}.", - "notifications_permission_banner.title": "Niekada nieko nepraleiskite", - "onboarding.action.back": "Graลพinkite mane atgal", - "onboarding.actions.back": "Graลพinkite mane atgal", - "onboarding.actions.go_to_explore": "See what's trending", - "onboarding.actions.go_to_home": "Go to your home feed", + "notifications_permission_banner.how_to_control": "Jei nori gauti praneลกimus, kai Mastodon nฤ—ra atidarytas, ฤฏjunk darbalaukio praneลกimus. ฤฎjungฤ™s (-usi) darbalaukio praneลกimus, gali tiksliai valdyti, kokiลณ tipลณ sฤ…veikos generuoja darbalaukio praneลกimus, naudojant pirmiau esanฤiu mygtuku {icon}.", + "notifications_permission_banner.title": "Niekada nieko nepraleisk", + "onboarding.action.back": "Grฤ…ลพinti mane atgal", + "onboarding.actions.back": "Grฤ…ลพinti mane atgal", + "onboarding.actions.go_to_explore": "ฤฎ tendencijลณ puslapฤฏ", + "onboarding.actions.go_to_home": "ฤฎ mano pagrindinฤฏ srautลณ puslapฤฏ", "onboarding.compose.template": "Sveiki #Mastodon!", - "onboarding.follows.empty": "Deja, ลกiuo metu jokiลณ rezultatลณ parodyti negalima. Galite pabandyti naudoti paieลกkฤ… arba narลกyti atradimo puslapyje, kad surastumฤ—te ลพmoniลณ, kuriuos norite sekti, arba pabandyti vฤ—liau.", - "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.title": "Popular on Mastodon", + "onboarding.follows.empty": "Deja, ลกiuo metu jokiลณ rezultatลณ parodyti negalima. Gali pabandyti naudoti paieลกkฤ… arba narลกyti atradimo puslapฤฏ, kad surastum ลพmoniลณ, kuriuos nori sekti, arba bandyti vฤ—liau.", + "onboarding.follows.lead": "Tavo pagrindinis srautas โ€“ pagrindinis bลซdas patirti Mastodon. Kuo daugiau ลพmoniลณ seksi, tuo jis bus aktyvesnis ir ฤฏdomesnis. Norint pradฤ—ti, pateikiame keletฤ… pasiลซlymลณ:", + "onboarding.follows.title": "Suasmenink savo pagrindinฤฏ srautฤ…", "onboarding.profile.discoverable": "Padaryti mano profilฤฏ atrandamฤ…", - "onboarding.profile.discoverable_hint": "Kai pasirenki Mastodon atrandamumฤ…, tavo ฤฏraลกai gali bลซti rodomi paieลกkos rezultatuose ir trendose, o profilis gali bลซti siลซlomas panaลกiลณ interesลณ turintiems ลพmonฤ—ms.", + "onboarding.profile.discoverable_hint": "Kai sutinki su Mastodon atrandamumu, tavo ฤฏraลกai gali bลซti rodomi paieลกkos rezultatuose ir tendencijose, o profilis gali bลซti siลซlomas panaลกiลณ pomฤ—giลณ turintiems ลพmonฤ—ms.", "onboarding.profile.display_name": "Rodomas vardas", "onboarding.profile.display_name_hint": "Tavo pilnas vardas arba linksmas vardasโ€ฆ", "onboarding.profile.lead": "Gali visada tai uลพbaigti vฤ—liau nustatymuose, kur yra dar daugiau pritaikymo parinkฤiลณ.", "onboarding.profile.note": "Biografija", "onboarding.profile.note_hint": "Gali @paminฤ—ti kitus ลพmones arba #saitaลพodลพiusโ€ฆ", "onboarding.profile.save_and_continue": "Iลกsaugoti ir tฤ™sti", - "onboarding.profile.title": "Profilio konfigลซravimas", + "onboarding.profile.title": "Profilio sฤ…ranka", "onboarding.profile.upload_avatar": "ฤฎkelti profilio nuotraukฤ…", "onboarding.profile.upload_header": "ฤฎkelti profilio antraลกtฤ™", - "onboarding.share.lead": "Praneลกkite ลพmonฤ—ms, kaip jus rasti \"Mastodon\"!", - "onboarding.share.message": "Aลก {username} #Mastodon! Ateik sekti manฤ™s adresu {url}", + "onboarding.share.lead": "Leisk ลพmonฤ—ms suลพinoti, kaip tave rasti Mastodon!", + "onboarding.share.message": "Aลก {username}, esant #Mastodon! Ateik sekti manฤ™s adresu {url}.", "onboarding.share.next_steps": "Galimi kiti ลพingsniai:", - "onboarding.share.title": "Bendrinkite savo profilฤฏ", - "onboarding.start.lead": "Dabar esi Mastodon dalis โ€“ unikalios decentralizuotos socialinฤ—s ลพiniasklaidos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtฤฏ. Pradฤ—kime tavo kelionฤ™ ลกioje naujoje socialinฤ—je erdvฤ—je:", - "onboarding.start.skip": "Want to skip right ahead?", - "onboarding.start.title": "Jums pavyko!", - "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", - "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", - "onboarding.steps.publish_status.body": "Say hello to the world.", - "onboarding.steps.publish_status.title": "Susikลซrk savo pirmฤ…jฤฏ ฤฏraลกฤ…", - "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", - "onboarding.steps.setup_profile.title": "Customize your profile", - "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", - "onboarding.steps.share_profile.title": "Share your profile", - "picture_in_picture.restore": "Padฤ—kite jฤฏ atgal", - "poll.closed": "Uลพdaryti", + "onboarding.share.title": "Bendrink savo profilฤฏ", + "onboarding.start.lead": "Dabar esi Mastodon dalis โ€“ unikalios decentralizuotos socialinฤ—s medijos platformos, kurioje tu, o ne algoritmas, pats nustatai savo patirtฤฏ. Pradฤ—kime tavo kelionฤ™ ลกioje naujoje socialinฤ—je erdvฤ—je:", + "onboarding.start.skip": "Nereikia pagalbos pradฤ—ti?", + "onboarding.start.title": "Tau pavyko!", + "onboarding.steps.follow_people.body": "Sekti ฤฏdomius ลพmones โ€“ tai, kas yra Mastodon.", + "onboarding.steps.follow_people.title": "Suasmenink savo pagrindinฤฏ srautฤ…", + "onboarding.steps.publish_status.body": "Sakyk labas pasauliui tekstu, nuotraukomis, vaizdo ฤฏraลกais arba apklausomis {emoji}.", + "onboarding.steps.publish_status.title": "Sukลซrk savo pirmฤ…jฤฏ ฤฏraลกฤ…", + "onboarding.steps.setup_profile.body": "Padidink savo sฤ…veikฤ… turint iลกsamลณ profilฤฏ.", + "onboarding.steps.setup_profile.title": "Suasmenink savo profilฤฏ", + "onboarding.steps.share_profile.body": "Leisk draugams suลพinoti, kaip tave rasti Mastodon.", + "onboarding.steps.share_profile.title": "Bendrink savo Mastodon profilฤฏ", + "onboarding.tips.2fa": "Ar ลพinojai? Savo paskyrฤ… gali apsaugoti nustatant dviejลณ veiksniลณ tapatybฤ—s nustatymฤ… paskyros nustatymuose. Jis veikia su bet kuria pasirinkta TOTP programฤ—le, telefono numeris nebลซtinas.", + "onboarding.tips.accounts_from_other_servers": "Ar ลพinojai? Kadangi Mastodon decentralizuotas, kai kurie profiliai, su kuriais susidursi, bus talpinami ne tavo, o kituose serveriuose. Ir vis tiek galฤ—si su jais sklandลพiai bendrauti! Jลณ serveris yra antroje naudotojo vardo pusฤ—je.", + "onboarding.tips.migration": "Ar ลพinojai? Jei manai, kad {domain} serveris ateityje tau netiks, gali persikelti ฤฏ kitฤ… Mastodon serverฤฏ neprarandant savo sekฤ—jลณ. Gali net talpinti savo paties serverฤฏ.", + "onboarding.tips.verification": "Ar ลพinojai? Savo paskyrฤ… gali patvirtinti pateikฤ™s (-usi) nuorodฤ… ฤฏ Mastodon profilฤฏ savo interneto svetainฤ—je ir pridฤ—jฤ™s (-usi) svetainฤ™ prie savo profilio. Nereikia jokiลณ mokesฤiลณ ar dokumentลณ.", + "password_confirmation.exceeds_maxlength": "Slaptaลพodลพio patvirtinimas virลกija maksimalลณ slaptaลพodลพio ilgฤฏ.", + "password_confirmation.mismatching": "Slaptaลพodลพio patvirtinimas nesutampa.", + "picture_in_picture.restore": "Padฤ—ti jฤฏ atgal", + "poll.closed": "Uลพdaryta", "poll.refresh": "Atnaujinti", "poll.reveal": "Perลพiลซrฤ—ti rezultatus", + "poll.total_people": "{count, plural, one {# ลพmogus} few {# ลพmonฤ—s} many {# ลพmogus} other {# ลพmoniลณ}}", + "poll.total_votes": "{count, plural, one {# balsas} few {# balsai} many {# balso} other {# balsลณ}}", "poll.vote": "Balsuoti", "poll.voted": "Tu balsavai uลพ ลกฤฏ atsakymฤ…", "poll.votes": "{votes, plural, one {# balsas} few {# balsai} many {# balso} other {# balsลณ}}", "poll_button.add_poll": "Pridฤ—ti apklausฤ…", - "poll_button.remove_poll": "ล alinti apklausฤ…", - "privacy.change": "Adjust status privacy", + "poll_button.remove_poll": "Paลกalinti apklausฤ…", + "privacy.change": "Keisti ฤฏraลกo privatumฤ…", "privacy.direct.long": "Visus, paminฤ—tus ฤฏraลกe", "privacy.direct.short": "Konkretลซs ลพmonฤ—s", "privacy.private.long": "Tik sekฤ—jams", "privacy.private.short": "Sekฤ—jai", "privacy.public.long": "Bet kas iลก Mastodon ir ne Mastodon", - "privacy.public.short": "Vieลกas", + "privacy.public.short": "Vieลกa", "privacy.unlisted.additional": "Tai veikia lygiai taip pat, kaip ir vieลกa, tik ฤฏraลกas nebus rodomas tiesioginiuose srautuose, saitaลพodลพiose, narลกyme ar Mastodon paieลกkoje, net jei esi ฤฏtraukฤ™s (-usi) visฤ… paskyrฤ….", "privacy.unlisted.long": "Maลพiau algoritminiลณ fanfarลณ", "privacy.unlisted.short": "Tyliai vieลกa", @@ -500,8 +603,14 @@ "privacy_policy.title": "Privatumo politika", "recommended": "Rekomenduojama", "refresh": "Atnaujinti", - "regeneration_indicator.label": "Kraunasiโ€ฆ", + "regeneration_indicator.label": "Kraunamaโ€ฆ", + "regeneration_indicator.sublabel": "Ruoลกiamas tavo pagrindinis srautas!", + "relative_time.days": "{number} d.", + "relative_time.full.days": "prieลก {number, plural, one {# dienฤ…} few {# dienas} many {# dienos} other {# dienลณ}}", + "relative_time.full.hours": "prieลก {number, plural, one {# valandฤ…} few {# valandas} many {# valandos} other {# valandลณ}}", "relative_time.full.just_now": "kฤ… tik", + "relative_time.full.minutes": "prieลก {number, plural, one {# minutฤ™} few {# minutes} many {# minutฤ—s} other {# minuฤiลณ}}", + "relative_time.full.seconds": "prieลก {number, plural, one {# sekundฤ™} few {# sekundes} many {# sekundฤ—s} other {# sekundลพiลณ}}", "relative_time.hours": "{number} val.", "relative_time.just_now": "dabar", "relative_time.minutes": "{number} min.", @@ -511,15 +620,20 @@ "reply_indicator.cancel": "Atลกaukti", "reply_indicator.poll": "Apklausa", "report.block": "Blokuoti", - "report.categories.legal": "Legalus", + "report.block_explanation": "Jลณ ฤฏraลกลณ nematysi. Jie negalฤ—s matyti tavo ฤฏraลกลณ ar sekti tavฤ™s. Jie galฤ—s pamatyti, kad yra uลพblokuoti.", + "report.categories.legal": "Teisinฤ—s", "report.categories.other": "Kita", "report.categories.spam": "ล lamลกtas", "report.categories.violation": "Turinys paลพeidลพia vienฤ… ar daugiau serverio taisykliลณ", - "report.category.subtitle": "Pasirinkite tinkamiausiฤ… variantฤ…", + "report.category.subtitle": "Pasirink geriausiฤ… atitikmenฤฏ.", + "report.category.title": "Papasakok mums, kas vyksta su ลกiuo {type}", "report.category.title_account": "profilis", "report.category.title_status": "ฤฏraลกas", "report.close": "Atlikta", - "report.comment.title": "Ar yra dar kas nors, kฤ…, jลซsลณ manymu, turฤ—tume ลพinoti?", + "report.comment.title": "Ar yra dar kas nors, kฤ…, tavo manymu, turฤ—tume ลพinoti?", + "report.forward": "Persiลณsti ฤฏ {target}", + "report.forward_hint": "Paskyra yra iลก kito serverio. Siลณsti anoniminฤ™ ลกios ataskaitos kopijฤ… ir ten?", + "report.mute": "Nutildyti", "report.mute_explanation": "Jลณ ฤฏraลกลณ nematysi. Jie vis tiek gali tave sekti ir matyti ฤฏraลกus, bet neลพinos, kad jie nutildyti.", "report.next": "Tฤ™sti", "report.placeholder": "Papildomi komentarai", @@ -528,41 +642,42 @@ "report.reasons.legal": "Tai nelegalu", "report.reasons.legal_description": "Manai, kad tai paลพeidลพia tavo arba serverio ลกalies ฤฏstatymus", "report.reasons.other": "Tai kaลพkas kita", - "report.reasons.other_description": "ล is klausimas neatitinka kitลณ kategorijลณ", - "report.reasons.spam": "Tai ลกlamลกtas", + "report.reasons.other_description": "Problema netinka kitoms kategorijoms", + "report.reasons.spam": "Tai โ€“ ลกlamลกtas", "report.reasons.spam_description": "Kenkฤ—jiลกkos nuorodos, netikras ฤฏsitraukimas arba pasikartojantys atsakymai", "report.reasons.violation": "Tai paลพeidลพia serverio taisykles", "report.reasons.violation_description": "ลฝinai, kad tai paลพeidลพia konkreฤias taisykles", - "report.rules.subtitle": "Pasirink viskฤ…, kas tinka", + "report.rules.subtitle": "Pasirink viskฤ…, kas tinka.", "report.rules.title": "Kokios taisyklฤ—s paลพeidลพiamos?", - "report.statuses.subtitle": "Pasirinkti viskฤ…, kas tinka", - "report.statuses.title": "Ar yra kokiลณ nors ฤฏraลกลณ, patvirtinanฤiลณ ลกฤฏ praneลกimฤ…?", + "report.statuses.subtitle": "Pasirink viskฤ…, kas tinka.", + "report.statuses.title": "Ar yra kokiลณ nors ฤฏraลกลณ, patvirtinanฤiลณ ลกฤฏ ataskaitฤ…?", "report.submit": "Pateikti", - "report.target": "Report {target}", - "report.thanks.take_action": "ฤŒia pateikiamos galimybฤ—s kontroliuoti, kฤ… matote \"Mastodon\":", - "report.thanks.take_action_actionable": "Kol tai perลพiลซrฤ—sime, galite imtis veiksmลณ prieลก @{name}:", - "report.thanks.title": "Nenorite to matyti?", - "report.thanks.title_actionable": "Aฤiลซ, kad praneลกฤ—te, mes tai iลกnagrinฤ—sime.", + "report.target": "Praneลกama apie {target}", + "report.thanks.take_action": "ล tai parinktys, kaip kontroliuoti, kฤ… matai Mastodon:", + "report.thanks.take_action_actionable": "Kol perลพiลซrฤ—sime, gali imtis veiksmลณ prieลก {name}:", + "report.thanks.title": "Nenori to matyti?", + "report.thanks.title_actionable": "Aฤiลซ, kad praneลกei, mes tai iลกnagrinฤ—sime.", "report.unfollow": "Nebesekti @{name}", - "report.unfollow_explanation": "Jลซs sekate ลกiฤ… paskyrฤ…. Norฤ—dami nebematyti jลณ ฤฏraลกลณ savo pagrindiniame kanale, panaikinkite jลณ sekimฤ….", - "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", - "report_notification.categories.legal": "Legalus", + "report.unfollow_explanation": "Tu seki ลกiฤ… paskyrฤ…. Jei nori nebematyti jลณ ฤฏraลกลณ savo pagrindiniame sraute, nebesek jลณ.", + "report_notification.attached_statuses": "Pridฤ—ti {count, plural, one {{count} ฤฏraลกas} few {{count} ฤฏraลกai} many {{count} ฤฏraลกo} other {{count} ฤฏraลกลณ}}", + "report_notification.categories.legal": "Teisinฤ—s", "report_notification.categories.other": "Kita", "report_notification.categories.spam": "ล lamลกtas", "report_notification.categories.violation": "Taisyklฤ—s paลพeidimas", - "search.no_recent_searches": "Paieลกkos ฤฏraลกลณ nฤ—ra", + "report_notification.open": "Atidaryti ataskaitฤ…", + "search.no_recent_searches": "Nฤ—ra naujausiลณ paieลกkลณ.", "search.placeholder": "Paieลกka", "search.quick_action.account_search": "Profiliai, atitinkantys {x}", "search.quick_action.go_to_account": "Eiti ฤฏ profilฤฏ {x}", - "search.quick_action.go_to_hashtag": "Eiti ฤฏ hashtag {x}", + "search.quick_action.go_to_hashtag": "Eiti ฤฏ saitaลพodฤฏ {x}", "search.quick_action.open_url": "Atidaryti URL adresฤ… Mastodon", "search.quick_action.status_search": "Praneลกimai, atitinkantys {x}", - "search.search_or_paste": "Ieลกkok arba ฤฏklijuok URL", + "search.search_or_paste": "Ieลกkoti arba ฤฏklijuoti URL", "search_popout.full_text_search_disabled_message": "Nepasiekima {domain}.", "search_popout.full_text_search_logged_out_message": "Pasiekiama tik prisijungus.", "search_popout.language_code": "ISO kalbos kodas", "search_popout.options": "Paieลกkos nustatymai", - "search_popout.quick_actions": "Greiti veiksmai", + "search_popout.quick_actions": "Spartลซs veiksmai", "search_popout.recent": "Naujausios paieลกkos", "search_popout.specific_date": "konkreti data", "search_popout.user": "naudotojas", @@ -571,39 +686,42 @@ "search_results.hashtags": "Saitaลพodลพiai", "search_results.nothing_found": "Nepavyko rasti nieko pagal ลกiuos paieลกkos terminus.", "search_results.see_all": "ลฝiลซrฤ—ti viskฤ…", - "search_results.statuses": "Toots", + "search_results.statuses": "ฤฎraลกai", "search_results.title": "Ieลกkoti {q}", "server_banner.about_active_users": "ลฝmonฤ—s, kurie naudojosi ลกiuo serveriu per pastarฤ…sias 30 dienลณ (mฤ—nesio aktyvลซs naudotojai)", "server_banner.active_users": "aktyvลซs naudotojai", "server_banner.administered_by": "Administruoja:", - "server_banner.introduction": "{domain} yra decentralizuoto socialinio tinklo, kurฤฏ valdo {mastodon}, dalis.", - "server_banner.learn_more": "Suลพinoti daugiau", + "server_banner.is_one_of_many": "{domain} โ€“ tai vienas iลก daugelio nepriklausomลณ โ€žMastodonโ€œ serveriลณ, kuriuos gali naudoti fediverse.", "server_banner.server_stats": "Serverio statistika:", "sign_in_banner.create_account": "Sukurti paskyrฤ…", + "sign_in_banner.follow_anyone": "Sek bet kurฤฏ asmenฤฏ visoje fediverse ir ลพiลซrฤ—k viskฤ… chronologine tvarka. Jokiลณ algoritmลณ, reklamลณ ar paspaudimลณ.", + "sign_in_banner.mastodon_is": "โ€žMastodonโ€œ โ€“ tai geriausias bลซdas sekti, kas vyksta.", "sign_in_banner.sign_in": "Prisijungimas", - "sign_in_banner.sso_redirect": "Prisijungti arba Registruotis", - "sign_in_banner.text": "Prisijunk, kad galฤ—tum sekti profilius arba saitaลพodลพius, mฤ—gsti, bendrinti ir atsakyti ฤฏ ฤฏraลกus. Taip pat gali bendrauti iลก savo paskyros kitame serveryje.", - "status.admin_account": "Atvira moderavimo sฤ…saja @{name}", - "status.admin_domain": "Atvira moderavimo sฤ…saja {domain}", - "status.admin_status": "Open this status in the moderation interface", + "sign_in_banner.sso_redirect": "Prisijungti arba uลพsiregistruoti", + "status.admin_account": "Atidaryti priลพiลซrฤ—jimo sฤ…sajฤ… @{name}", + "status.admin_domain": "Atidaryti priลพiลซrฤ—jimo sฤ…sajฤ… {domain}", + "status.admin_status": "Atidaryti ลกฤฏ ฤฏraลกฤ… priลพiลซrฤ—jimo sฤ…sajoje", "status.block": "Blokuoti @{name}", - "status.bookmark": "ลฝymฤ—", + "status.bookmark": "Pridฤ—ti ฤฏ ลพymฤ—s", + "status.cancel_reblog_private": "Nebepakelti", + "status.cannot_reblog": "ล is ฤฏraลกas negali bลซti pakeltas.", "status.copy": "Kopijuoti nuorodฤ… ฤฏ ฤฏraลกฤ…", "status.delete": "Iลกtrinti", "status.detailed_status": "Iลกsami pokalbio perลพiลซra", "status.direct": "Privaฤiai paminฤ—ti @{name}", "status.direct_indicator": "Privatus paminฤ—jimas", "status.edit": "Redaguoti", - "status.edited": "Redaguota {date}", - "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", - "status.embed": "ฤฎterptas", - "status.favourite": "Mฤ—gstamiausias", + "status.edited": "Paskutinฤฏ kartฤ… redaguota {date}", + "status.edited_x_times": "Redaguota {count, plural, one {{count} kartฤ…} few {{count} kartus} many {{count} karto} other {{count} kartลณ}}", + "status.embed": "ฤฎterpti", + "status.favourite": "Pamฤ—gti", + "status.favourites": "{count, plural, one {mฤ—gstamas} few {mฤ—gstamai} many {mฤ—gstamลณ} other {mฤ—gstamลณ}}", "status.filter": "Filtruoti ลกฤฏ ฤฏraลกฤ…", "status.filtered": "Filtruota", "status.hide": "Slฤ—pti ฤฏraลกฤ…", - "status.history.created": "{name} sukurtas {date}", - "status.history.edited": "{name} redaguotas {date}", - "status.load_more": "Pakrauti daugiau", + "status.history.created": "{name} sukurta {date}", + "status.history.edited": "{name} redaguota {date}", + "status.load_more": "Krauti daugiau", "status.media.open": "Spausk, kad atidaryti", "status.media.show": "Spausk, kad matyti", "status.media_hidden": "Paslฤ—pta medija", @@ -611,15 +729,20 @@ "status.more": "Daugiau", "status.mute": "Nutildyti @{name}", "status.mute_conversation": "Nutildyti pokalbฤฏ", - "status.open": "Expand this status", + "status.open": "Iลกplฤ—sti ลกฤฏ ฤฏraลกฤ…", "status.pin": "Prisegti prie profilio", "status.pinned": "Prisegtas ฤฏraลกas", "status.read_more": "Skaityti daugiau", - "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", - "status.redraft": "Iลกtrinti ir iลก naujo parengti juodraลกtฤฏ", + "status.reblog": "Pakelti", + "status.reblog_private": "Pakelti su originaliu matomumu", + "status.reblogged_by": "{name} pakฤ—lฤ—", + "status.reblogs.empty": "ล io ฤฏraลกo dar niekas nepakฤ—lฤ—. Kai kas nors tai padarys, jie bus rodomi ฤia.", + "status.redraft": "Iลกtrinti ir parengti iลก naujo", + "status.remove_bookmark": "Paลกalinti ลพymฤ™", + "status.replied_to": "Atsakyta ฤฏ {name}", "status.reply": "Atsakyti", "status.replyAll": "Atsakyti ฤฏ gijฤ…", - "status.report": "Praneลกti @{name}", + "status.report": "Praneลกti apie @{name}", "status.sensitive_warning": "Jautrus turinys", "status.share": "Bendrinti", "status.show_filter_reason": "Rodyti vis tiek", @@ -628,36 +751,62 @@ "status.show_more": "Rodyti daugiau", "status.show_more_all": "Rodyti daugiau visiems", "status.show_original": "Rodyti originalฤ…", - "status.title.with_attachments": "{user}{attachmentCount, plural, one {priedas} few {{attachmentCount} priedai} many {{attachmentCount} priedo} other {{attachmentCount} priedลณ}}", + "status.title.with_attachments": "{user} paskelbฤ— {attachmentCount, plural, one {priedฤ…} few {{attachmentCount} priedus} many {{attachmentCount} priedo} other {{attachmentCount} priedลณ}}", "status.translate": "Versti", - "status.translated_from_with": "Iลกversta iลก {lang} naudojant {provider}", - "status.uncached_media_warning": "Perลพiลซra nepasiekiama", - "tabs_bar.home": "Pradลพia", + "status.translated_from_with": "Iลกversta iลก {lang} naudojant {provider}.", + "status.uncached_media_warning": "Perลพiลซra nepasiekiama.", + "status.unmute_conversation": "Atลกaukti pokalbio nutildymฤ…", + "status.unpin": "Atsegti iลก profilio", + "subscribed_languages.lead": "Po pakeitimo tavo pagrindinฤ—je ir sฤ…raลกo laiko skalฤ—je bus rodomi tik ฤฏraลกai pasirinktomis kalbomis. Jei nori gauti ฤฏraลกus visomis kalbomis, pasirink nฤ— vieno.", + "subscribed_languages.save": "Iลกsaugoti pakeitimus", + "subscribed_languages.target": "Keisti prenumeruojamas kalbas {target}", + "tabs_bar.home": "Pagrindinis", "tabs_bar.notifications": "Praneลกimai", - "time_remaining.days": "Liko {number, plural, one {# diena} few {# dienos} many {# dieno} other {# dienลณ}}", - "timeline_hint.remote_resource_not_displayed": "{resource} iลก kitลณ serveriลณ nerodomas.", + "time_remaining.days": "liko {number, plural, one {# diena} few {# dienos} many {# dienos} other {# dienลณ}}", + "time_remaining.hours": "liko {number, plural, one {# valanda} few {# valandos} many {# valandos} other {# valandลณ}}", + "time_remaining.minutes": "liko {number, plural, one {# minutฤ—} few {# minutฤ—s} many {# minutฤ—s} other {# minuฤiลณ}}", + "time_remaining.moments": "liko akimirkos", + "time_remaining.seconds": "liko {number, plural, one {# sekundฤ—} few {# sekundฤ—s} many {# sekundฤ—s} other {# sekundลพiลณ}}", + "timeline_hint.remote_resource_not_displayed": "{resource} iลก kitลณ serveriลณ nerodomi.", "timeline_hint.resources.followers": "Sekฤ—jai", "timeline_hint.resources.follows": "Seka", "timeline_hint.resources.statuses": "Senesni ฤฏraลกai", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} ลพmogus} few {{counter} ลพmonฤ—s} many {{counter} ลพmogus} other {{counter} ลพmoniลณ}} per {days, plural, one {dienฤ…} few {{days} dienas} many {{days} dienas} other {{days} dienลณ}}", + "trends.trending_now": "Tendencinga dabar", "ui.beforeunload": "Jei paliksi Mastodon, tavo juodraลกtis bus prarastas.", + "units.short.billion": "{count} mlrd.", + "units.short.million": "{count} mln.", "units.short.thousand": "{count} tลซkst.", - "upload_form.audio_description": "Describe for people with hearing loss", - "upload_form.description": "Describe for the visually impaired", + "upload_area.title": "Nuvilk, kad ฤฏkeltum", + "upload_button.label": "Pridฤ—ti vaizdลณ, vaizdo ฤฏraลกฤ… arba garso failฤ…", + "upload_error.limit": "Virลกyta failo ฤฏkฤ—limo riba.", + "upload_error.poll": "Failลณ ฤฏkฤ—limas neleidลพiamas su apklausomis.", + "upload_form.audio_description": "Apraลกyk ลพmonฤ—ms, kurie yra kurtieji ar neprigirdintys.", + "upload_form.description": "Apraลกyk ลพmonฤ—ms, kurie yra aklieji arba silpnaregiai.", "upload_form.edit": "Redaguoti", - "upload_form.video_description": "Describe for people with hearing loss or visual impairment", + "upload_form.thumbnail": "Keisti miniatiลซrฤ…", + "upload_form.video_description": "Apraลกyk ลพmonฤ—ms, kurie yra kurtieji, neprigirdintys, aklieji ar silpnaregiai.", + "upload_modal.analyzing_picture": "Analizuojamas vaizdasโ€ฆ", + "upload_modal.apply": "Taikyti", + "upload_modal.applying": "Pritaikomaโ€ฆ", "upload_modal.choose_image": "Pasirinkti vaizdฤ…", "upload_modal.description_placeholder": "Greita rudoji lapฤ— perลกoka tinginฤฏ ลกunฤฏ", + "upload_modal.detect_text": "Aptikti tekstฤ… iลก nuotraukos", "upload_modal.edit_media": "Redaguoti medijฤ…", + "upload_modal.hint": "Spustelฤ—k arba nuvilk apskritimฤ… perลพiลซroje, kad pasirinktum centrinฤฏ taลกkฤ…, kuris visada bus matomas visose miniatiลซrose.", + "upload_modal.preparing_ocr": "Rengimas OCRโ€ฆ", + "upload_modal.preview_label": "Perลพiลซra ({ratio})", "upload_progress.label": "ฤฎkeliama...", "upload_progress.processing": "Apdorojamaโ€ฆ", "username.taken": "ล is naudotojo vardas uลพimtas. Pabandyk kitฤ….", "video.close": "Uลพdaryti vaizdo ฤฏraลกฤ…", "video.download": "Atsisiลณsti failฤ…", "video.exit_fullscreen": "Iลกeiti iลก viso ekrano", + "video.expand": "Iลกplฤ—sti vaizdo ฤฏraลกฤ…", "video.fullscreen": "Visas ekranas", "video.hide": "Slฤ—pti vaizdo ฤฏraลกฤ…", - "video.mute": "Nutildyti garsฤ…", + "video.mute": "Iลกjungti garsฤ…", + "video.pause": "Pristabdyti", "video.play": "Leisti", - "video.unmute": "Atitildyti garsฤ…" + "video.unmute": "ฤฎjungti garsฤ…" } diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 07a7b25a79..13ceec21c8 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -8,7 +8,7 @@ "about.domain_blocks.silenced.title": "Ierobeลพotie", "about.domain_blocks.suspended.explanation": "Nekฤdi dati no ลกฤซ servera netiks apstrฤdฤti, uzglabฤti vai apmainฤซti, padarot neiespฤ“jamu mijiedarbฤซbu vai saziล†u ar lietotฤjiem no ลกฤซ servera.", "about.domain_blocks.suspended.title": "Apturฤ“tie", - "about.not_available": "ล ฤซ informฤcija ลกajฤ serverฤซ nav bijusi pieejama.", + "about.not_available": "ล ฤซ informฤcija nav padarฤซta pieejama ลกajฤ serverฤซ.", "about.powered_by": "Decentralizฤ“tu sociฤlo tฤซklu nodroลกina {mastodon}", "about.rules": "Servera noteikumi", "account.account_note_header": "Piezฤซme", @@ -21,24 +21,26 @@ "account.blocked": "Bloฤทฤ“ts", "account.browse_more_on_origin_server": "Pฤrlลซkot vairฤk sฤkotnฤ“jฤ profilฤ", "account.cancel_follow_request": "Atsaukt sekoลกanas pieprasฤซjumu", + "account.copy": "Ievietot saiti uz profilu starpliktuvฤ“", "account.direct": "Pieminฤ“t @{name} privฤti", "account.disable_notifications": "Pฤrtraukt man paziล†ot, kad @{name} publicฤ“ ierakstu", "account.domain_blocked": "Domฤ“ns ir bloฤทฤ“ts", - "account.edit_profile": "Rediฤฃฤ“t profilu", + "account.edit_profile": "Labot profilu", "account.enable_notifications": "Paziล†ot man, kad @{name} publicฤ“ ierakstu", "account.endorse": "Izcelts profilฤ", "account.featured_tags.last_status_at": "Beidzamฤ ziล†a {date}", "account.featured_tags.last_status_never": "Ierakstu nav", "account.featured_tags.title": "{name} izceltie tฤ“mturi", "account.follow": "Sekot", + "account.follow_back": "Sekot atpakaฤผ", "account.followers": "Sekotฤji", "account.followers.empty": "ล im lietotฤjam vฤ“l nav sekotฤju.", - "account.followers_counter": "{count, plural, one {{counter} Sekotฤjs} other {{counter} Sekotฤji}}", + "account.followers_counter": "{count, plural, zero {{counter} sekotฤju} one {{counter} sekotฤjs} other {{counter} sekotฤji}}", "account.following": "Seko", - "account.following_counter": "{count, plural, one {{counter} sekojamais} other {{counter} sekojamie}}", + "account.following_counter": "{count, plural, zero{{counter} sekojamo} one {{counter} sekojamais} other {{counter} sekojamie}}", "account.follows.empty": "ล is lietotฤjs pagaidฤm nevienam neseko.", "account.go_to_profile": "Doties uz profilu", - "account.hide_reblogs": "Slฤ“pt @{name} izceltas ziล†as", + "account.hide_reblogs": "Paslฤ“pt @{name} pastiprinฤtos ierakstus", "account.in_memoriam": "Piemiล†ai.", "account.joined_short": "Pievienojฤs", "account.languages": "Mainฤซt abonฤ“tฤs valodas", @@ -51,13 +53,14 @@ "account.mute_notifications_short": "Izslฤ“gt paziล†ojumu skaล†u", "account.mute_short": "Apklusinฤt", "account.muted": "Apklusinฤts", + "account.mutual": "Savstarpฤ“js", "account.no_bio": "Apraksts nav sniegts.", "account.open_original_page": "Atvฤ“rt oriฤฃinฤlo lapu", "account.posts": "Ieraksti", "account.posts_with_replies": "Ieraksti un atbildes", "account.report": "Sลซdzฤ“ties par @{name}", "account.requested": "Gaida apstiprinฤjumu. Nospied, lai atceltu sekoลกanas pieparasฤซjumu", - "account.requested_follow": "{name} nosลซtฤซja tev sekoลกanas pieprasฤซjumu", + "account.requested_follow": "{name} nosลซtฤซja Tev sekoลกanas pieprasฤซjumu", "account.share": "Dalฤซties ar @{name} profilu", "account.show_reblogs": "Parฤdฤซt @{name} pastiprinฤtos ierakstus", "account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}", @@ -86,6 +89,11 @@ "announcement.announcement": "Paziล†ojums", "attachments_list.unprocessed": "(neapstrฤdฤti)", "audio.hide": "Slฤ“pt audio", + "block_modal.remote_users_caveat": "Mฤ“s vaicฤsim serverim {domain} ล†emt vฤ“rฤ Tavu lฤ“mumu. Tomฤ“r atbilstฤซba nav nodroลกinฤta, jo atseviลกฤทi serveri var apstrฤdฤt bloฤทฤ“ลกanu citฤdi. Publiski ieraksti joprojฤm var bลซt redzami lietotฤjiem, kuri nav pieteikuลกies.", + "block_modal.show_less": "Rฤdฤซt mazฤk", + "block_modal.show_more": "Parฤdฤซt mazฤk", + "block_modal.they_cant_mention": "Nevar Tevi pieminฤ“t vai sekot Tev.", + "block_modal.they_cant_see_posts": "Nevar redzฤ“t Tavus ierakstus, un Tu neredzฤ“si lietotฤja.", "boost_modal.combo": "Nospied {combo}, lai nฤkamreiz ลกo izlaistu", "bundle_column_error.copy_stacktrace": "Kopฤ“t kฤผลซdu ziล†ojumu", "bundle_column_error.error.body": "Pieprasฤซto lapu nevarฤ“ja atveidot. Tas varฤ“tu bลซt saistฤซts ar kฤผลซdu mลซsu kodฤ, vai tฤ ir pฤrlลซkprogrammas saderฤซbas problฤ“ma.", @@ -97,18 +105,18 @@ "bundle_column_error.routing.body": "Pieprasฤซto lapu nevarฤ“ja atrast. Vai esi pฤrliecinฤts, ka URL adreses joslฤ ir pareizs?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Aizvฤ“rt", - "bundle_modal_error.message": "Kaut kas nogฤja greizi, ielฤdฤ“jot ลกo komponenti.", + "bundle_modal_error.message": "Kaut kas nogฤja greizi ลกฤซs sastฤvdaฤผas ielฤdฤ“ลกanas laikฤ.", "bundle_modal_error.retry": "Mฤ“ฤฃinฤt vฤ“lreiz", "closed_registrations.other_server_instructions": "Tฤ kฤ Mastodon ir decentralizฤ“ts, tu vari izveidot kontu citฤ serverฤซ un joprojฤm mijiedarboties ar ลกo.", - "closed_registrations_modal.description": "Paลกlaik nav iespฤ“jams izveidot kontu domฤ“nฤ {domain}, taฤu ล†em vฤ“rฤ, ka tev nav nepiecieลกams konts tieลกi {domain}, lai lietotu Mastodon.", + "closed_registrations_modal.description": "Paลกlaik nav iespฤ“jams izveidot kontu {domain}, bet, lลซdzu, ล†em vฤ“rฤ, ka Tev nav nepiecieลกams tieลกi {domain} konts, lai lietotu Mastodon!", "closed_registrations_modal.find_another_server": "Atrast citu serveri", - "closed_registrations_modal.preamble": "Mastodon ir decentralizฤ“ts, tฤpฤ“c neatkarฤซgi no tฤ, kur tu izveido savu kontu, varฤ“si sekot lฤซdzi un sazinฤties ar ikvienu ลกajฤ serverฤซ. Tu pat vari vadฤซt to pats!", + "closed_registrations_modal.preamble": "Mastodon ir decentralizฤ“ts, tฤpฤ“c neatkarฤซgi no tฤ, kur Tu izveido savu kontu, varฤ“si sekot un mijiedarboties ar ikvienu ลกajฤ serverฤซ. Tu pat vari to paลกizvietot!", "closed_registrations_modal.title": "Reฤฃistrฤ“ลกanฤs Mastodon", "column.about": "Par", "column.blocks": "Bloฤทฤ“tie lietotฤji", "column.bookmarks": "Grฤmatzฤซmes", "column.community": "Vietฤ“jฤ laika lฤซnija", - "column.direct": "Privฤti pieminฤ“ti", + "column.direct": "Privฤtas pieminฤ“ลกanas", "column.directory": "Pฤrlลซkot profilus", "column.domain_blocks": "Bloฤทฤ“tie domฤ“ni", "column.favourites": "Iecienฤซtie", @@ -133,66 +141,72 @@ "community.column_settings.remote_only": "Tikai attฤlinฤtie", "compose.language.change": "Mainฤซt valodu", "compose.language.search": "Meklฤ“t valodas...", - "compose.published.body": "Ziล†a publicฤ“ta.", + "compose.published.body": "Ieraksts publicฤ“ta.", "compose.published.open": "Atvฤ“rt", "compose.saved.body": "Ziล†a saglabฤta.", "compose_form.direct_message_warning_learn_more": "Uzzinฤt vairฤk", - "compose_form.encryption_warning": "Ziล†as vietnฤ“ Mastodon nav pilnฤซbฤ ลกifrฤ“tas. Nedalies ar sensitฤซvu informฤciju caur Mastodon.", + "compose_form.encryption_warning": "Mastodon ieraksti nav pilnฤซbฤ ลกifrฤ“ti. Nedalies ar jebkฤdu jutฤซgu informฤciju caur Mastodon!", "compose_form.hashtag_warning": "ล ฤซ ziล†a netiks norฤdฤซta zem nevienas atsauces, jo tฤ nav publiska. Tikai publiskฤs ziล†ฤs var meklฤ“t pฤ“c atsauces.", - "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var tev piesekot un redzฤ“t tikai sekotฤjiem paredzฤ“tos ziล†ojumus.", + "compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot, lai redzฤ“tu tikai sekotฤjiem paredzฤ“tos ierakstus.", "compose_form.lock_disclaimer.lock": "slฤ“gts", - "compose_form.placeholder": "Kas tev padomฤ?", + "compose_form.placeholder": "Kas Tev padomฤ?", "compose_form.poll.duration": "Aptaujas ilgums", + "compose_form.poll.multiple": "Vairฤkas izvฤ“les iespฤ“jas", + "compose_form.poll.option_placeholder": "Izvฤ“le {number}", + "compose_form.poll.single": "Jฤizvฤ“las viens", "compose_form.poll.switch_to_multiple": "Mainฤซt aptaujas veidu, lai atฤผautu vairฤkas izvฤ“les", "compose_form.poll.switch_to_single": "Mainฤซt aptaujas veidu, lai atฤผautu vienu izvฤ“li", + "compose_form.publish": "Iesลซtฤซt", "compose_form.publish_form": "Jauns ieraksts", + "compose_form.reply": "Atbildฤ“t", + "compose_form.save_changes": "Atjauninฤt", "compose_form.spoiler.marked": "Noล†emt satura brฤซdinฤjumu", "compose_form.spoiler.unmarked": "Pievienot satura brฤซdinฤjumu", + "compose_form.spoiler_placeholder": "Satura brฤซdinฤjums (pฤ“c izvฤ“les)", "confirmation_modal.cancel": "Atcelt", - "confirmations.block.block_and_report": "Bloฤทฤ“t un ziล†ot", "confirmations.block.confirm": "Bloฤทฤ“t", - "confirmations.block.message": "Vai tieลกฤm vฤ“lies bloฤทฤ“t {name}?", "confirmations.cancel_follow_request.confirm": "Atsaukt pieprasฤซjumu", "confirmations.cancel_follow_request.message": "Vai tieลกฤm vฤ“lies atsaukt pieprasฤซjumu sekot {name}?", "confirmations.delete.confirm": "Dzฤ“st", "confirmations.delete.message": "Vai tieลกฤm vฤ“lies dzฤ“st ลกo ierakstu?", "confirmations.delete_list.confirm": "Dzฤ“st", - "confirmations.delete_list.message": "Vai tieลกam vฤ“lies neatgriezeniski dzฤ“st ลกo sarakstu?", + "confirmations.delete_list.message": "Vai tieลกฤm neatgriezeniski izdzฤ“st ลกo sarakstu?", "confirmations.discard_edit_media.confirm": "Atmest", - "confirmations.discard_edit_media.message": "Tev ir nesaglabฤtas izmaiล†as multivides aprakstฤ vai priekลกskatฤซjumฤ. Vฤ“lies tฤs atmest?", - "confirmations.domain_block.confirm": "Bloฤทฤ“t visu domฤ“nu", + "confirmations.discard_edit_media.message": "Ir nesaglabฤtas izmaiล†as informฤcijas nesฤ“ja aprakstฤ vai priekลกskatฤซjumฤ. Vฤ“lies tฤs atmest tik un tฤ?", "confirmations.domain_block.message": "Vai tu tieลกฤm vฤ“lies bloฤทฤ“t visu domฤ“nu {domain}? Parasti pietiek, ja nobloฤทฤ“ vai apklusini kฤdu. Tu neredzฤ“si saturu vai paziล†ojumus no ลกฤซ domฤ“na nevienฤ laika lฤซnijฤ. Tavi sekotฤji no ลกฤซ domฤ“na tiks noล†emti.", - "confirmations.edit.confirm": "Rediฤฃฤ“t", - "confirmations.edit.message": "Rediฤฃฤ“jot, tiks pฤrrakstฤซts ziล†ojums, kuru tu ลกobrฤซd raksti. Vai tieลกฤm vฤ“lies turpinฤt?", + "confirmations.edit.confirm": "Labot", + "confirmations.edit.message": "Laboลกana pฤrrakstฤซs ziล†ojumu, kas ลกobrฤซd tiek sastฤdฤซts. Vai tieลกฤm turpinฤt?", "confirmations.logout.confirm": "Iziet", "confirmations.logout.message": "Vai tieลกฤm vฤ“lies izrakstฤซties?", "confirmations.mute.confirm": "Apklusinฤt", - "confirmations.mute.explanation": "ล ฤdi no viล†iem tiks slฤ“ptas ziล†as un ziล†as, kurฤs viล†i tiek pieminฤ“ti, taฤu viล†i joprojฤm varฤ“s redzฤ“t tavas ziล†as un sekot tev.", - "confirmations.mute.message": "Vai tieลกฤm vฤ“lies apklusinฤt {name}?", "confirmations.redraft.confirm": "Dzฤ“st un pฤrrakstฤซt", "confirmations.redraft.message": "Vai tieลกฤm vฤ“lies dzฤ“st ลกo ziล†u un no jauna noformฤ“t to? Izlase un pastiprinฤjumi tiks zaudฤ“ti, un atbildes uz sฤkotnฤ“jo ziล†u tiks atstฤtas bez autoratlฤซdzฤซbas.", "confirmations.reply.confirm": "Atbildฤ“t", - "confirmations.reply.message": "Ja tagad atbildฤ“si, tavs ziล†as uzmetums tiks dzฤ“sts. Vai tieลกฤm vฤ“lies turpinฤt?", + "confirmations.reply.message": "Tลซlฤซtฤ“ja atbildฤ“ลกana pฤrrakstฤซs paลกlaik sastฤdฤซto ziล†u. Vai tieลกฤm turpinฤt?", "confirmations.unfollow.confirm": "Pฤrstฤt sekot", "confirmations.unfollow.message": "Vai tieลกam vairs nevฤ“lies sekot lietotฤjam {name}?", "conversation.delete": "Dzฤ“st sarunu", "conversation.mark_as_read": "Atzฤซmฤ“t kฤ izlasฤซtu", "conversation.open": "Skatฤซt sarunu", "conversation.with": "Ar {names}", + "copy_icon_button.copied": "Ievietots starpliktuvฤ“", "copypaste.copied": "Nokopฤ“ts", "copypaste.copy_to_clipboard": "Kopฤ“t uz starpliktuvi", "directory.federated": "No pazฤซstamas federฤcijas", "directory.local": "Tikai no {domain}", "directory.new_arrivals": "Jaunpienฤcฤ“ji", - "directory.recently_active": "Nesen aktฤซvie", + "directory.recently_active": "Nesen aktฤซvi", "disabled_account_banner.account_settings": "Konta iestatฤซjumi", "disabled_account_banner.text": "Tavs konts {disabledAccount} paลกlaik ir atspฤ“jots.", - "dismissable_banner.community_timeline": "ล ฤซs ir jaunฤkฤs publiskฤs ziล†as no personฤm, kuru kontus mitina {domain}.", + "dismissable_banner.community_timeline": "ล ie ir jaunฤkie publiskie ieraksti no cilvฤ“kiem, kuru konti ir mitinฤti {domain}.", "dismissable_banner.dismiss": "Atcelt", "dismissable_banner.explore_links": "Par ลกiem jaunumiem ลกobrฤซd runฤ cilvฤ“ki ลกajฤ un citos decentralizฤ“tฤ tฤซkla serveros.", - "dismissable_banner.explore_statuses": "Ieraksti, kas ลกobrฤซd gลซst arvien lielฤku ievฤ“rฤซbu visฤ sociฤlajฤ tฤซklฤ. Augstฤk tiek kฤrtoti neseni ieraksti, kas pastiprinฤti un pievienoti izlasฤ“m.", + "dismissable_banner.explore_statuses": "ล ie ir ieraksti, kas ลกodien gลซst arvien lielฤku ievฤ“rฤซbu visฤ sociฤlajฤ tฤซklฤ. Augstฤk tiek kฤrtoti jaunฤki ieraksti, kuri tiek vairฤk pastiprinฤti un ievietoti izlasฤ“s.", "dismissable_banner.explore_tags": "ล ie tฤ“mturi ลกobrฤซd kฤผลซst arvien populฤrฤki cilvฤ“ku vidลซ ลกajฤ un citos decentralizฤ“tฤ tฤซkla serveros.", - "dismissable_banner.public_timeline": "ล ฤซs ir jaunฤkฤs publiskฤs ziล†as no lietotฤjiem sociฤlajฤ tฤซmeklฤซ, kurฤm seko lietotฤji domฤ“nฤ {domain}.", + "dismissable_banner.public_timeline": "ล ie ir jaunฤkie publiskie ieraksti no lietotฤjiem sociฤlajฤ tฤซmeklฤซ, kuriem {domain} seko cilvฤ“ki.", + "domain_block_modal.they_cant_follow": "Neviens ลกajฤ serverฤซ nevar Tev sekot.", + "domain_pill.server": "Serveris", + "domain_pill.username": "Lietotฤjvฤrds", "embed.instructions": "Iestrฤdฤ ลกo ziล†u savฤ mฤjaslapฤ, kopฤ“jot zemฤk redzamo kodu.", "embed.preview": "Tas izskatฤซsies ลกฤdi:", "emoji_button.activity": "Aktivitฤte", @@ -215,22 +229,22 @@ "empty_column.account_timeline": "ล eit ziล†ojumu nav!", "empty_column.account_unavailable": "Profils nav pieejams", "empty_column.blocks": "Paลกreiz tu neesi nevienu bloฤทฤ“jis.", - "empty_column.bookmarked_statuses": "Paลกreiz tev nav neviena grฤmatzฤซmฤ“m pievienota ieraksta. Kad tฤdu pievienosi, tas parฤdฤซsies ลกeit.", + "empty_column.bookmarked_statuses": "Paลกlaik Tev nav neviena grฤmatzฤซmฤ“s pievienota ieraksta. Kad tฤdu pievienosi, tas parฤdฤซsies ลกeit.", "empty_column.community": "Vietฤ“jฤ laika lฤซnija ir tukลกa. Uzraksti kaut ko publiski, lai viss notiktu!", - "empty_column.direct": "Jums vฤ“l nav nevienas privฤtas pieminฤ“ลกanas. Nosลซtot vai saล†emot to, tas tiks parฤdฤซts ลกeit.", + "empty_column.direct": "Tev vฤ“l nav privฤtu pieminฤ“ลกanu. Kad Tu nosลซtฤซsi vai saล†emsi kฤdu, tฤ pฤrฤdฤซsies ลกeit.", "empty_column.domain_blocks": "Vฤ“l nav neviena bloฤทฤ“ta domฤ“na.", - "empty_column.explore_statuses": "Paลกlaik nekฤ aktuฤla nav. Pฤrbaudi vฤ“lฤk!", - "empty_column.favourited_statuses": "Tev vฤ“l nav nevienas iecienฤซtฤkฤs ziล†as. Kad iecienฤซsi kฤdu, tas tiks parฤdฤซts ลกeit.", + "empty_column.explore_statuses": "Paลกlaik nav nekฤ aktuฤla. Ieskaties ลกeit vฤ“lฤk!", + "empty_column.favourited_statuses": "Tev vฤ“l nav iecienฤซtฤko ierakstu. Kad pievienosi kฤdu izlasei, tas tiks parฤdฤซts ลกeit.", "empty_column.favourites": "ล o ziล†u neviens vฤ“l nav pievienojis izlasei. Kad kฤds to izdarฤซs, tas parฤdฤซsies ลกeit.", - "empty_column.follow_requests": "ล obrฤซd tev nav sekoลกanas pieprasฤซjumu. Kad kฤds pieteiksies tev sekot, pieprasฤซjums parฤdฤซsies ลกeit.", + "empty_column.follow_requests": "ล obrฤซd Tev nav sekoลกanas pieprasฤซjumu. Kad saล†emsi kฤdu, tas parฤdฤซsies ลกeit.", "empty_column.followed_tags": "Tu vฤ“l neesi sekojis nevienam tฤ“mturim. Kad to izdarฤซsi, tie tiks parฤdฤซti ลกeit.", "empty_column.hashtag": "Ar ลกo tฤ“mturi nekas nav atrodams.", - "empty_column.home": "Tava mฤjas laikrinda ir tukลกa! Lai to aizpildฤซtu, pieseko vairฤk cilvฤ“kiem.", - "empty_column.list": "ล is saraksts paลกreiz ir tukลกs. Kad ลกฤซ saraksta dalฤซbnieki publicฤ“s jaunas ziล†as, tฤs parฤdฤซsies ลกeit.", - "empty_column.lists": "Paลกreiz tev nav neviena saraksta. Kad tฤdu izveidosi, tas parฤdฤซsies ลกeit.", + "empty_column.home": "Tava mฤjas laikjosla ir tukลกa. Seko vairฤk cilvฤ“kiem, lai to piepildฤซtu!", + "empty_column.list": "Pagaidฤm ลกajฤ sarakstฤ nekฤ nav. Kad ลกฤซ saraksta dalฤซbnieki ievietos jaunus ierakstus, tie parฤdฤซsies ลกeit.", + "empty_column.lists": "Paลกlaik Tev nav neviena saraksta. Kad tฤdu izveidosi, tas parฤdฤซsies ลกeit.", "empty_column.mutes": "Neviens lietotฤjs vฤ“l nav apklusinฤts.", - "empty_column.notifications": "Tev vฤ“l nav paziล†ojumu. Kad citi cilvฤ“ki ar tevi mijiedarbosies, tu to redzฤ“si ลกeit.", - "empty_column.public": "ล eit vฤ“l nekฤ nav! Ieraksti ko publiski vai pieseko lietotฤjiem no citiem serveriem", + "empty_column.notifications": "Tev vฤ“l nav paziล†ojumu. Kad citi cilvฤ“ki ar Tevi mijiedarbosies, Tu to redzฤ“si ลกeit.", + "empty_column.public": "ล eit nekฤ nav. Ieraksti kaut ko publiski vai seko lietotฤjiem no citiem serveriem, lai iegลซtu saturu", "error.unexpected_crash.explanation": "Koda kฤผลซdas vai pฤrlลซkprogrammas saderฤซbas problฤ“mas dฤ“ฤผ ลกo lapu nevarฤ“ja parฤdฤซt pareizi.", "error.unexpected_crash.explanation_addons": "ล o lapu nevarฤ“ja parฤdฤซt pareizi. ล o kฤผลซdu, iespฤ“jams, izraisฤซja pฤrlลซkprogrammas papildinฤjums vai automฤtiskฤs tulkoลกanas rฤซki.", "error.unexpected_crash.next_steps": "Mฤ“ฤฃini atsvaidzinฤt lapu. Ja tas nepalฤซdz, iespฤ“jams, varฤ“si lietot Mastodon, izmantojot citu pฤrlลซkprogrammu vai lietotni.", @@ -239,13 +253,13 @@ "errors.unexpected_crash.report_issue": "Ziล†ot par problฤ“mu", "explore.search_results": "Meklฤ“ลกanas rezultฤti", "explore.suggested_follows": "Cilvฤ“ki", - "explore.title": "Pฤrlลซkot", + "explore.title": "Izpฤ“tฤซt", "explore.trending_links": "Jaunumi", - "explore.trending_statuses": "Ziล†as", + "explore.trending_statuses": "Ieraksti", "explore.trending_tags": "Tฤ“mturi", - "filter_modal.added.context_mismatch_explanation": "ล ฤซ filtra kategorija neattiecas uz kontekstu, kurฤ esi piekฤผuvis ลกai ziล†ai. Ja vฤ“lies, lai ziล†a tiktu filtrฤ“ta arฤซ ลกajฤ kontekstฤ, tev bลซs jฤrediฤฃฤ“ filtrs.", + "filter_modal.added.context_mismatch_explanation": "ล ฤซ atlases kategorija neattiecas uz kontekstu, kurฤ esi piekฤผuvis ลกim ierakstam. Ja vฤ“lies, lai ieraksts tiktu atlasฤซts arฤซ ลกajฤ kontekstฤ, Tev bลซs jฤlabo atlase.", "filter_modal.added.context_mismatch_title": "Konteksta neatbilstฤซba!", - "filter_modal.added.expired_explanation": "ล ai filtra kategorijai ir beidzies derฤซguma termiล†ลก. Lai to lietotu, tev bลซs jฤmaina derฤซguma termiล†ลก.", + "filter_modal.added.expired_explanation": "ล ai atlases kategorijai ir beidzies derฤซguma termiล†ลก. Lai to lietotu, Tev bลซs jฤmaina derฤซguma termiล†ลก.", "filter_modal.added.expired_title": "Filtra termiล†ลก beidzies!", "filter_modal.added.review_and_configure": "Lai pฤrskatฤซtu un tฤlฤk konfigurฤ“tu ลกo filtru kategoriju, dodies uz {settings_link}.", "filter_modal.added.review_and_configure_title": "Filtra iestatฤซjumi", @@ -255,16 +269,23 @@ "filter_modal.select_filter.context_mismatch": "neattiecas uz ลกo kontekstu", "filter_modal.select_filter.expired": "beidzies", "filter_modal.select_filter.prompt_new": "Jauna kategorija: {name}", - "filter_modal.select_filter.search": "Meklฤ“ vai izveido", + "filter_modal.select_filter.search": "Meklฤ“t vai izveidot", "filter_modal.select_filter.subtitle": "Izmanto esoลกu kategoriju vai izveido jaunu", "filter_modal.select_filter.title": "Filtrฤ“t ลกo ziล†u", "filter_modal.title.status": "Filtrฤ“t ziล†u", + "filtered_notifications_banner.pending_requests": "Paziล†ojumi no {count, plural, =0 {neviena} one {viena cilvฤ“ka} other {# cilvฤ“kiem}}, ko Tu varฤ“tu zinฤt", "firehose.all": "Visi", "firehose.local": "ล is serveris", "firehose.remote": "Citi serveri", "follow_request.authorize": "Autorizฤ“t", "follow_request.reject": "Noraidฤซt", - "follow_requests.unlocked_explanation": "Lai gan tavs konts nav bloฤทฤ“ts, {domain} darbinieki iedomฤjฤs, ka, iespฤ“jams, vฤ“lฤ“sies pฤrskatฤซt pieprasฤซjumus no ลกiem kontiem.", + "follow_requests.unlocked_explanation": "Lai gan Tavs konts nav slฤ“gts, {domain} darbinieki iedomฤjฤs, ka Tu varฤ“tu vฤ“lฤ“ties paลกrocฤซgi pฤrskatฤซt sekoลกanas pieprasฤซjumus no ลกiem kontiem.", + "follow_suggestions.curated_suggestion": "Darbinieku izvฤ“le", + "follow_suggestions.dismiss": "Vairs nerฤdฤซt", + "follow_suggestions.personalized_suggestion": "Pielฤgots ieteikums", + "follow_suggestions.similar_to_recently_followed_longer": "Lฤซdzฤซgi profieliem, kuriem nesen sฤki sekot", + "follow_suggestions.view_all": "Skatฤซt visu", + "follow_suggestions.who_to_follow": "Kam sekot", "followed_tags": "Sekojamie tฤ“mturi", "footer.about": "Par", "footer.directory": "Profilu direktorija", @@ -286,12 +307,11 @@ "hashtag.column_settings.tag_mode.none": "Neviens no ลกiem", "hashtag.column_settings.tag_toggle": "Pievienot kolonnai papildu tฤ“mturus", "hashtag.counter_by_accounts": "{count, plural, one {{counter} dalฤซbnieks} other {{counter} dalฤซbnieki}}", - "hashtag.counter_by_uses": "{count, plural, zero {{counter} ziล†a} one {{counter} ieraksts} other {{counter} ziล†as}}", - "hashtag.counter_by_uses_today": "{count, plural, one {{counter} ziล†a} other {{counter} ziล†as}} ลกodien", + "hashtag.counter_by_uses": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}", + "hashtag.counter_by_uses_today": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}} ลกodien", "hashtag.follow": "Sekot tฤ“mturim", "hashtag.unfollow": "Pฤrstฤt sekot tฤ“mturim", - "hashtags.and_other": "..un {count, plural, other {# vairฤk}}", - "home.column_settings.basic": "Pamata", + "hashtags.and_other": "โ€ฆ un {count, plural, other {vฤ“l #}}", "home.column_settings.show_reblogs": "Rฤdฤซt pastiprinฤtos ierakstus", "home.column_settings.show_replies": "Rฤdฤซt atbildes", "home.hide_announcements": "Slฤ“pt paziล†ojumus", @@ -300,16 +320,16 @@ "home.pending_critical_update.title": "Pieejams kritisks droลกฤซbas jauninฤjums!", "home.show_announcements": "Rฤdฤซt paziล†ojumus", "interaction_modal.description.favourite": "Ar Mastodon kontu tu vari pievienot ลกo ziล†u izlasei, lai informฤ“tu autoru, ka to novฤ“rtฤ“, un saglabฤtu to vฤ“lฤkai lasฤซลกanai.", - "interaction_modal.description.follow": "Ar Mastodon kontu tu vari sekot {name}, lai saล†emtu viล†u ziล†as savฤ mฤjas plลซsmฤ.", - "interaction_modal.description.reblog": "Izmantojot kontu Mastodon, tu vari izcelt ลกo ziล†u, lai kopฤซgotu to ar saviem sekotฤjiem.", + "interaction_modal.description.follow": "Ar Mastodon kontu Tu vari sekot {name}, lai saล†emtu lietotฤja ierakstus savฤ mฤjas plลซsmฤ.", + "interaction_modal.description.reblog": "Ar Mastodon kontu Tu vari izvirzฤซt ลกo ierakstu, lai kopฤซgotu to ar saviem sekotฤjiem.", "interaction_modal.description.reply": "Ar Mastodon kontu tu vari atbildฤ“t uz ลกo ziล†u.", - "interaction_modal.login.action": "Nogฤdฤ mani mฤjฤs", + "interaction_modal.login.action": "Nogฤdฤt mani mฤjฤs", "interaction_modal.login.prompt": "Tavas mฤjvietas servera domฤ“ns, piem., mastodon.social", "interaction_modal.no_account_yet": "Neesi Mastodon?", "interaction_modal.on_another_server": "Citฤ serverฤซ", "interaction_modal.on_this_server": "ล ajฤ serverฤซ", - "interaction_modal.sign_in": "Tu neesi pieteicies ลกajฤ serverฤซ. Kur tiek mitinฤts tavs konts?", - "interaction_modal.sign_in_hint": "Padoms: ล ฤซ ir vietne, kurฤ tu piereฤฃistrฤ“jies. Ja neatceries, meklฤ“ sveiciena e-pastu savฤ iesลซtnฤ“. Vari arฤซ ievadฤซt pilnu lietotฤjvฤrdu! (piem., @Mastodon@mastodon.social)", + "interaction_modal.sign_in": "Tu neesi pieteicies ลกajฤ serverฤซ. Kur tiek mitinฤts Tavs konts?", + "interaction_modal.sign_in_hint": "Padoms: tฤ ir tฤซmekฤผvietne, kurฤ Tu reฤฃistrฤ“jies. Ja neatceries, jฤmeklฤ“ sveiciena e-pasts savฤ iesลซtnฤ“. Vari arฤซ ievadฤซt pilnu lietotฤjvฤrdu (piem., @Mastodon@mastodon.social).", "interaction_modal.title.favourite": "Pievienot {name} ziล†u izlasei", "interaction_modal.title.follow": "Sekot {name}", "interaction_modal.title.reblog": "Pastiprinฤt {name} ierakstu", @@ -359,14 +379,15 @@ "limited_account_hint.action": "Tik un tฤ rฤdฤซt profilu", "limited_account_hint.title": "{domain} moderatori ir paslฤ“puลกi ลกo profilu.", "link_preview.author": "Pฤ“c {name}", + "link_preview.more_from_author": "Vairฤk no {name}", "lists.account.add": "Pievienot sarakstam", "lists.account.remove": "Noล†emt no saraksta", - "lists.delete": "Dzฤ“st sarakstu", - "lists.edit": "Rediฤฃฤ“t sarakstu", + "lists.delete": "Izdzฤ“st sarakstu", + "lists.edit": "Labot sarakstu", "lists.edit.submit": "Mainฤซt virsrakstu", - "lists.exclusive": "Paslฤ“pt ลกฤซs ziล†as no mฤjvietas", + "lists.exclusive": "Nerฤdฤซt ลกos ierakstus sฤkumฤ", "lists.new.create": "Pievienot sarakstu", - "lists.new.title_placeholder": "Jaunais saraksta nosaukums", + "lists.new.title_placeholder": "Jaunฤ saraksta nosaukums", "lists.replies_policy.followed": "Jebkuram sekotajam lietotฤjam", "lists.replies_policy.list": "Saraksta dalฤซbniekiem", "lists.replies_policy.none": "Nevienam", @@ -374,21 +395,23 @@ "lists.search": "Meklฤ“t starp cilvฤ“kiem, kuriem tu seko", "lists.subheading": "Tavi saraksti", "load_pending": "{count, plural, one {# jauna lieta} other {# jaunas lietas}}", + "loading_indicator.label": "Ielฤdฤ“โ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Slฤ“pt attฤ“lu} other {Slฤ“pt attฤ“lus}}", - "moved_to_account_banner.text": "Tavs konts {disabledAccount} paลกlaik ir atspฤ“jots, jo pฤrcฤ“lies uz kontu {movedToAccount}.", - "mute_modal.duration": "Ilgums", - "mute_modal.hide_notifications": "Slฤ“pt paziล†ojumus no ลกฤซ lietotฤja?", - "mute_modal.indefinite": "Beztermiล†a", + "moved_to_account_banner.text": "Tavs konts {disabledAccount} paลกlaik ir atspฤ“jots, jo Tu pฤrcฤ“lies uz kontu {movedToAccount}.", + "mute_modal.hide_from_notifications": "Paslฤ“pt paziล†ojumos", + "mute_modal.hide_options": "Paslฤ“pt iespฤ“jas", + "mute_modal.show_options": "Parฤdฤซt iespฤ“jas", + "mute_modal.title": "Apklusinฤt lietotฤju?", "navigation_bar.about": "Par", "navigation_bar.advanced_interface": "Atvฤ“rt paplaลกinฤtฤ tฤซmekฤผa saskarnฤ“", "navigation_bar.blocks": "Bloฤทฤ“tie lietotฤji", "navigation_bar.bookmarks": "Grฤmatzฤซmes", "navigation_bar.community_timeline": "Vietฤ“jฤ laika lฤซnija", "navigation_bar.compose": "Veidot jaunu ziล†u", - "navigation_bar.direct": "Privฤti pieminฤ“ti", + "navigation_bar.direct": "Privฤtas pieminฤ“ลกanas", "navigation_bar.discover": "Atklฤt", "navigation_bar.domain_blocks": "Bloฤทฤ“tie domฤ“ni", - "navigation_bar.explore": "Pฤrlลซkot", + "navigation_bar.explore": "Izpฤ“tฤซt", "navigation_bar.favourites": "Izlase", "navigation_bar.filters": "Apklusinฤtie vฤrdi", "navigation_bar.follow_requests": "Sekoลกanas pieprasฤซjumi", @@ -397,37 +420,49 @@ "navigation_bar.lists": "Saraksti", "navigation_bar.logout": "Iziet", "navigation_bar.mutes": "Apklusinฤtie lietotฤji", - "navigation_bar.opened_in_classic_interface": "Ziล†as, konti un citas noteiktas lapas pฤ“c noklusฤ“juma tiek atvฤ“rtas klasiskajฤ tฤซmekฤผa saskarnฤ“.", + "navigation_bar.opened_in_classic_interface": "Ieraksti, konti un citas noteiktas lapas pฤ“c noklusฤ“juma tiek atvฤ“rtas klasiskajฤ tฤซmekฤผa saskarnฤ“.", "navigation_bar.personal": "Personฤซgie", "navigation_bar.pins": "Piespraustฤs ziล†as", "navigation_bar.preferences": "Iestatฤซjumi", "navigation_bar.public_timeline": "Apvienotฤ laika lฤซnija", "navigation_bar.search": "Meklฤ“t", "navigation_bar.security": "Droลกฤซba", - "not_signed_in_indicator.not_signed_in": "Lai piekฤผลซtu ลกim resursam, tev ir jฤpierakstฤs.", + "not_signed_in_indicator.not_signed_in": "Ir jฤpiesakฤs, lai piekฤผลซtu ลกim resursam.", "notification.admin.report": "{name} ziล†oja par {target}", - "notification.admin.sign_up": "{name} ir pierakstฤซjies", + "notification.admin.sign_up": "{name} pierakstฤซjฤs", "notification.favourite": "{name} pievienoja tavu ziล†u izlasei", - "notification.follow": "{name} uzsฤka tev sekot", - "notification.follow_request": "{name} nosลซtฤซja tev sekoลกanas pieprasฤซjumu", - "notification.mention": "{name} pieminฤ“ja tevi", + "notification.follow": "{name} uzsฤka Tev sekot", + "notification.follow_request": "{name} nosลซtฤซja Tev sekoลกanas pieprasฤซjumu", + "notification.mention": "{name} pieminฤ“ja Tevi", + "notification.moderation-warning.learn_more": "Uzzinฤt vairฤk", + "notification.moderation_warning.action_delete_statuses": "Daลพi no Taviem ierakstiem tika noล†emti.", + "notification.moderation_warning.action_disable": "Tavs konts tika atspฤ“jots.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Daลพi no Taviem ierakstiem tika atzฤซmฤ“ti kฤ jutฤซgi.", + "notification.moderation_warning.action_sensitive": "Tavi ieraksti turpmฤk tiks atzฤซmฤ“ti kฤ jutฤซgi.", + "notification.moderation_warning.action_silence": "Tavs konts tika ierobeลพots.", + "notification.moderation_warning.action_suspend": "Tava konta darbฤซba tika apturฤ“ta.", "notification.own_poll": "Tava aptauja ir noslฤ“gusies", "notification.poll": "Aptauja, kurฤ tu piedalฤซjies, ir noslฤ“gusies", - "notification.reblog": "{name} pastiprinฤja tavu ierakstu", + "notification.reblog": "{name} pastiprinฤja Tavu ierakstu", + "notification.relationships_severance_event": "Zaudฤ“ti savienojumi ar {name}", + "notification.relationships_severance_event.learn_more": "Uzzinฤt vairฤk", "notification.status": "{name} tikko publicฤ“ja", - "notification.update": "{name} rediฤฃฤ“ja ierakstu", + "notification.update": "{name} laboja ierakstu", + "notification_requests.accept": "Pieล†emt", + "notification_requests.dismiss": "Noraidฤซt", + "notification_requests.notifications_from": "Paziล†ojumi no {name}", + "notification_requests.title": "Atlasฤซtie paziล†ojumi", "notifications.clear": "Notฤซrฤซt paziล†ojumus", "notifications.clear_confirmation": "Vai tieลกฤm vฤ“lies neatgriezeniski notฤซrฤซt visus savus paziล†ojumus?", "notifications.column_settings.admin.report": "Jauni ziล†ojumi:", "notifications.column_settings.admin.sign_up": "Jaunas pierakstฤซลกanฤs:", "notifications.column_settings.alert": "Darbvirsmas paziล†ojumi", "notifications.column_settings.favourite": "Izlase:", - "notifications.column_settings.filter_bar.advanced": "Rฤdฤซt visas kategorijas", - "notifications.column_settings.filter_bar.category": "ฤ€tro filtru josla", - "notifications.column_settings.filter_bar.show_bar": "Rฤdฤซt filtru joslu", + "notifications.column_settings.filter_bar.advanced": "Attฤ“lot visas kategorijas", + "notifications.column_settings.filter_bar.category": "Atrฤs atlasฤซลกanas josla", "notifications.column_settings.follow": "Jauni sekotฤji:", "notifications.column_settings.follow_request": "Jauni sekoลกanas pieprasฤซjumi:", - "notifications.column_settings.mention": "Pieminฤ“jumi:", + "notifications.column_settings.mention": "Pieminฤ“ลกanas:", "notifications.column_settings.poll": "Aptaujas rezultฤti:", "notifications.column_settings.push": "Uznirstoลกie paziล†ojumi", "notifications.column_settings.reblog": "Pastiprinฤtie ieraksti:", @@ -441,7 +476,7 @@ "notifications.filter.boosts": "Pastiprinฤtie ieraksti", "notifications.filter.favourites": "Izlases", "notifications.filter.follows": "Seko", - "notifications.filter.mentions": "Pieminฤ“jumi", + "notifications.filter.mentions": "Pieminฤ“ลกanas", "notifications.filter.polls": "Aptaujas rezultฤti", "notifications.filter.statuses": "Jaunumi no cilvฤ“kiem, kuriem tu seko", "notifications.grant_permission": "Pieลกฤทirt atฤผauju.", @@ -450,6 +485,11 @@ "notifications.permission_denied": "Darbvirsmas paziล†ojumi nav pieejami, jo iepriekลก tika noraidฤซts pฤrlลซka atฤผauju pieprasฤซjums", "notifications.permission_denied_alert": "Darbvirsmas paziล†ojumus nevar iespฤ“jot, jo pฤrlลซkprogrammai atฤผauja tika iepriekลก atteikta", "notifications.permission_required": "Darbvirsmas paziล†ojumi nav pieejami, jo nav pieลกฤทirta nepiecieลกamฤ atฤผauja.", + "notifications.policy.filter_new_accounts_title": "Jauni konti", + "notifications.policy.filter_not_followers_title": "Cilvฤ“ki, kuri Tev neseko", + "notifications.policy.filter_not_following_hint": "Lฤซdz tos paลกrocฤซgi apstiprinฤsi", + "notifications.policy.filter_not_following_title": "Cilvฤ“ki, kuriem Tu neseko", + "notifications.policy.title": "Atlasฤซt paziล†ojumus noโ€ฆ", "notifications_permission_banner.enable": "Iespฤ“jot darbvirsmas paziล†ojumus", "notifications_permission_banner.how_to_control": "Lai saล†emtu paziล†ojumus, kad Mastodon nav atvฤ“rts, iespฤ“jo darbvirsmas paziล†ojumus. Vari precฤซzi kontrolฤ“t, kฤda veida mijiedarbฤซbas rada darbvirsmas paziล†ojumus, izmantojot augstฤk redzamo pogu {icon}, kad tie bลซs iespฤ“joti.", "notifications_permission_banner.title": "Nekad nepalaid neko garฤm", @@ -458,35 +498,44 @@ "onboarding.actions.go_to_explore": "Skatฤซt tendences", "onboarding.actions.go_to_home": "Dodieties uz manu mฤjas plลซsmu", "onboarding.compose.template": "Sveiki, #Mastodon!", - "onboarding.follows.empty": "Diemลพฤ“l paลกlaik nevar parฤdฤซt rezultฤtus. Vari mฤ“ฤฃinฤt izmantot meklฤ“ลกanu vai pฤrlลซkot izpฤ“tes lapu, lai atrastu personas, kurฤm sekot, vai mฤ“ฤฃinฤt vฤ“lreiz vฤ“lฤk.", - "onboarding.follows.lead": "Tava mฤjas plลซsma ir galvenais veids, kฤ izbaudฤซt Mastodon. Jo vairฤk cilvฤ“ku sekosi, jo aktฤซvฤk un interesantฤk tas bลซs. Lai sฤktu, ลกeit ir daลพi ieteikumi:", - "onboarding.follows.title": "Populฤrs Mastodon", - "onboarding.share.lead": "Paziล†o citiem, kฤ viล†i tevi var atrast Mastodon!", + "onboarding.follows.empty": "Diemลพฤ“l paลกlaik nevar parฤdฤซt rezultฤtus. Vari mฤ“ฤฃinฤt izmantot meklฤ“ลกanu vai pฤrlลซkot izpฤ“tes lapu, lai atrastu cilvฤ“kus, kuriem sekot, vai vฤ“lฤk mฤ“ฤฃinฤt vฤ“lreiz.", + "onboarding.follows.lead": "Tava mฤjas plลซsma ir galvenais veids, kฤ pieredzฤ“t Mastodon. Jo vairฤk cilvฤ“kiem sekosi, jo dzฤซvฤซgฤka un aizraujoลกฤka tฤ bลซs. Lai sฤktu, ลกeit ir daลพi ieteikumi:", + "onboarding.follows.title": "Pielฤgo savu mฤjas barotni", + "onboarding.profile.discoverable": "Padarฤซt manu profilu atklฤjamu", + "onboarding.profile.display_name": "Attฤ“lojamais vฤrds", + "onboarding.profile.display_name_hint": "Tavs pilnais vฤrds vai Tavs joku vฤrdsโ€ฆ", + "onboarding.profile.note": "Apraksts", + "onboarding.profile.note_hint": "Tu vari @pieminฤ“t citus cilvฤ“kus vai #tฤ“mturusโ€ฆ", + "onboarding.profile.save_and_continue": "Saglabฤt un turpinฤt", + "onboarding.profile.title": "Profila iestatฤซลกana", + "onboarding.profile.upload_avatar": "Augลกupielฤdฤ“t profila attฤ“lu", + "onboarding.profile.upload_header": "Augลกupielฤdฤ“t profila galveni", + "onboarding.share.lead": "Dari cilvฤ“kiem zinฤmu, ka viล†i var Tevi atrast Mastodon!", "onboarding.share.message": "Es esmu {username} #Mastodon! Nฤc sekot man uz {url}", "onboarding.share.next_steps": "Iespฤ“jamie nฤkamie soฤผi:", "onboarding.share.title": "Kopฤซgo savu profilu", - "onboarding.start.lead": "Tagad tu esat daฤผa no Mastodonย โ€” unikฤlas, decentralizฤ“tas sociฤlo mediju platformas, kurฤ tu, nevis algoritms, veido savu pieredzi. Sฤksim darbu ลกajฤ jaunajฤ sociฤlajฤ jomฤ:", + "onboarding.start.lead": "Tagad Tu esi daฤผa no Mastodonย โ€” vienreizฤ“jas, decentralizฤ“tas sociฤlฤs mediju platformas, kurฤ Tu, nevis algoritms, veido Tavu pieredzi. Sฤksim darbu ลกajฤ jaunajฤ sociฤlajฤ jomฤ:", "onboarding.start.skip": "Nav nepiecieลกama palฤซdzฤซba darba sฤkลกanai?", "onboarding.start.title": "Tev tas izdevฤs!", "onboarding.steps.follow_people.body": "Tu pats veido savu plลซsmu. Piepildฤซsim to ar interesantiem cilvฤ“kiem.", - "onboarding.steps.follow_people.title": "Sekot {count, plural, one {one person} other {# cilvฤ“kiem}}", - "onboarding.steps.publish_status.body": "Sveicini pasauli ar tekstu, fotoattฤ“liem, video, vai aptaujฤm {emoji}", + "onboarding.steps.follow_people.title": "Pielฤgo savu mฤjas barotni", + "onboarding.steps.publish_status.body": "Pasveicini pasauli ar tekstu, attฤ“liem, video vai aptaujฤm {emoji}", "onboarding.steps.publish_status.title": "Izveido savu pirmo ziล†u", - "onboarding.steps.setup_profile.body": "Citi, visticamฤk, sazinฤsies ar tevi, izmantojot aizpildฤซtu profilu.", + "onboarding.steps.setup_profile.body": "Palielini mijiedarbฤซbu ar aptveroลกu profilu!", "onboarding.steps.setup_profile.title": "Pielฤgo savu profilu", - "onboarding.steps.share_profile.body": "Paziล†o saviem draugiem, kฤ tevi atrast Mastodon!", + "onboarding.steps.share_profile.body": "Dari saviem draugiem zinฤmu, kฤ Tevi atrast Mastodon!", "onboarding.steps.share_profile.title": "Kopฤซgo savu Mastodon profilu", - "onboarding.tips.2fa": "Vai zinฤji? Tu vari aizsargฤt savu kontu, konta iestatฤซjumos iestatot divu faktoru autentifikฤciju. Tas darbojas ar jebkuru tevis izvฤ“lฤ“tu TOTP lietotni, nav nepiecieลกams tฤlruล†a numurs!", + "onboarding.tips.2fa": "Vai zinฤji? Tu vari aizsargฤt savu kontu, konta iestatฤซjumos iestatot divpakฤpju autentifikฤciju. Tas darbojas ar jebkuru Tevis izvฤ“lฤ“tu TOTP lietotni, nav nepiecieลกams tฤlruล†a numurs!", "onboarding.tips.accounts_from_other_servers": "Vai zinฤji? Tฤ kฤ Mastodon ir decentralizฤ“ts, daลพi profili, ar kuriem saskaraties, tiks mitinฤti citos, nevis tavos serveros. Un tomฤ“r tu varat sazinฤties ar viล†iem nevainojami! Viล†u serveris atrodas viล†u lietotฤjvฤrda otrajฤ pusฤ“!", - "onboarding.tips.migration": "Vai zinฤji? Ja uzskati, ka {domain} nฤkotnฤ“ nav lieliska servera izvฤ“le, vari pฤriet uz citu Mastodon serveri, nezaudฤ“jot savus sekotฤjus. Tu pat vari mitinฤt savu personฤซgo serveri!", - "onboarding.tips.verification": "Vai zinฤji? Tu vari verificฤ“t savu kontu, ievietojot saiti uz savu Mastodon profilu savฤ vietnฤ“ un pievienojot vietni savam profilam. Nav nepiecieลกami nekฤdi maksฤjumi vai dokumenti!", + "onboarding.tips.migration": "Vai zinฤji? Ja uzskati, ka {domain} nฤkotnฤ“ nav lieliska servera izvฤ“le, vari pฤriet uz citu Mastodon serveri, nezaudฤ“jot savus sekotฤjus. Tu pat vari mitinฤt savu serveri!", + "onboarding.tips.verification": "Vai zinฤji? Tu vari apliecinฤt savu kontu, ievietojot savฤ tฤซmekฤผvietnฤ“ saiti uz savu Mastodon profilu un pievienojot tฤซmekฤผvietni savam profilam. Nav nepiecieลกami nekฤdi maksฤjumi vai dokumenti.", "password_confirmation.exceeds_maxlength": "Paroles apstiprinฤลกana pฤrsniedz maksimฤlo paroles garumu", "password_confirmation.mismatching": "Paroles apstiprinฤjums neatbilst", "picture_in_picture.restore": "Novietot atpakaฤผ", "poll.closed": "Pabeigta", "poll.refresh": "Atsvaidzinฤt", "poll.reveal": "Skatฤซt rezultฤtus", - "poll.total_people": "{count, plural, zero {# cilvฤ“ku} one {# persona} other {# cilvฤ“ki}}", + "poll.total_people": "{count, plural, zero {# cilvฤ“ku} one {# cilvฤ“ks} other {# cilvฤ“ki}}", "poll.total_votes": "{count, plural, zero {# balsojumu} one {# balsojums} other {# balsojumi}}", "poll.vote": "Balsot", "poll.voted": "Tu balsoji par ลกo atbildi", @@ -494,9 +543,16 @@ "poll_button.add_poll": "Pievienot aptauju", "poll_button.remove_poll": "Noล†emt aptauju", "privacy.change": "Mainฤซt ieraksta privฤtumu", + "privacy.direct.long": "Visi ierakstฤ pieminฤ“tie", + "privacy.direct.short": "Noteikti cilvฤ“ki", + "privacy.private.long": "Tikai Tavi sekotฤji", + "privacy.private.short": "Sekotฤji", + "privacy.public.long": "Jebkurลก Mastodon un ฤrpus tฤ", "privacy.public.short": "Publiska", + "privacy.unlisted.long": "Mazฤk algoritmisku fanfaru", "privacy_policy.last_updated": "Pฤ“dฤ“jo reizi atjauninฤta {date}", "privacy_policy.title": "Privฤtuma politika", + "recommended": "Ieteicams", "refresh": "Atsvaidzinฤt", "regeneration_indicator.label": "Ielฤdฤ“โ€ฆ", "regeneration_indicator.sublabel": "Tiek gatavota tava plลซsma!", @@ -511,9 +567,11 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "ลกodien", + "reply_indicator.attachments": "{count, plural, zero{# pielikumu} one {# pielikums} other {# pielikumi}}", "reply_indicator.cancel": "Atcelt", + "reply_indicator.poll": "Aptauja", "report.block": "Bloฤทฤ“t", - "report.block_explanation": "Tu neredzฤ“si viล†u ziล†as. Viล†i nevarฤ“s redzฤ“t tavas ziล†as vai sekot tev. Viล†i varฤ“s saprast, ka ir bloฤทฤ“ti.", + "report.block_explanation": "Tu neredzฤ“si viล†u ierakstus. Viล†i nevarฤ“s redzฤ“t Tavus ierakstus vai sekot tev. Viล†i varฤ“s saprast, ka ir bloฤทฤ“ti.", "report.categories.legal": "Tiesisks", "report.categories.other": "Citi", "report.categories.spam": "Spams", @@ -527,7 +585,7 @@ "report.forward": "Pฤrsลซtฤซt {target}", "report.forward_hint": "Konts ir no cita servera. Vai nosลซtฤซt anonimizฤ“tu sลซdzฤซbas kopiju arฤซ tam?", "report.mute": "Apklusinฤt", - "report.mute_explanation": "Tu neredzฤ“si viล†u ziล†as. Viล†i joprojฤm var tev sekot un redzฤ“t tavas ziล†as un nezinฤs, ka viล†i ir apklusinฤti.", + "report.mute_explanation": "Tu neredzฤ“si viล†u ierakstus. Viล†i joprojฤm var Tev sekot un redzฤ“t Tavus ierakstus un nezinฤs, ka viล†i ir apklusinฤti.", "report.next": "Tฤlฤk", "report.placeholder": "Papildu komentฤri", "report.reasons.dislike": "Man tas nepatฤซk", @@ -543,15 +601,15 @@ "report.rules.subtitle": "Atlasi visus atbilstoลกos", "report.rules.title": "Kuri noteikumi tiek pฤrkฤpti?", "report.statuses.subtitle": "Atlasi visus atbilstoลกos", - "report.statuses.title": "Vai ir kฤdi ieraksti, kas atbalsta ลกo sลซdzฤซbu?", + "report.statuses.title": "Vai ir kฤdi ieraksti, kas apstiprina ลกo ziล†ojumu?", "report.submit": "Iesniegt", "report.target": "Ziล†oลกana par: {target}", - "report.thanks.take_action": "Tฤlฤk ir norฤdฤซtas iespฤ“jas, kฤ kontrolฤ“t Mastodon redzamo saturu:", + "report.thanks.take_action": "ล eit ir iespฤ“jas, lai pฤrvaldฤซtu Mastodon redzamo saturu:", "report.thanks.take_action_actionable": "Kamฤ“r mฤ“s to izskatฤm, tu vari veikt darbฤซbas pret @{name}:", "report.thanks.title": "Vai nevฤ“lies to redzฤ“t?", "report.thanks.title_actionable": "Paldies, ka ziล†oji, mฤ“s to izskatฤซsim.", "report.unfollow": "Pฤrtraukt sekot @{name}", - "report.unfollow_explanation": "Tu seko ลกim kontam. Lai vairs neredzฤ“tu viล†u ziล†as savฤ mฤjas plลซsmฤ, pฤrtrauc viล†iem sekot.", + "report.unfollow_explanation": "Tu seko ลกim kontam. Lai vairs neredzฤ“tu tฤ ierakstus savฤ mฤjas plลซsmฤ, pฤrtrauc sekot tam!", "report_notification.attached_statuses": "Pievienoti {count, plural,one {{count} sลซtฤซjums} other {{count} sลซtฤซjumi}}", "report_notification.categories.legal": "Tiesisks", "report_notification.categories.other": "Cita", @@ -564,56 +622,55 @@ "search.quick_action.go_to_account": "Doties uz profilu {x}", "search.quick_action.go_to_hashtag": "Doties uz tฤ“mturi {x}", "search.quick_action.open_url": "Atvฤ“rt URL Mastodonฤ", - "search.quick_action.status_search": "Ziล†as atbilst {x}", - "search.search_or_paste": "Meklฤ“ vai iekopฤ“ URL", + "search.quick_action.status_search": "Ieraksti, kas atbilst {x}", + "search.search_or_paste": "Meklฤ“t vai ielฤซmฤ“t URL", "search_popout.full_text_search_disabled_message": "Nav pieejams {domain}.", + "search_popout.full_text_search_logged_out_message": "Pieejams tikai pฤ“c pieteikลกanฤs.", "search_popout.language_code": "ISO valodas kods", "search_popout.options": "Meklฤ“ลกanas iespฤ“jas", "search_popout.quick_actions": "ฤ€trฤs darbฤซbas", "search_popout.recent": "Nesen meklฤ“tais", - "search_popout.specific_date": "konkrฤ“ts datums", + "search_popout.specific_date": "noteikts datums", "search_popout.user": "lietotฤjs", "search_results.accounts": "Profili", "search_results.all": "Visi", "search_results.hashtags": "Tฤ“mturi", - "search_results.nothing_found": "Nevarฤ“ja atrast neko ลกiem meklฤ“ลกanas vienumiem", + "search_results.nothing_found": "Nevarฤ“ja atrast neko, kas atbilstu ลกim meklฤ“ลกanas vaicฤjumam", "search_results.see_all": "Skatฤซt visus", "search_results.statuses": "Ieraksti", "search_results.title": "Meklฤ“t {q}", "server_banner.about_active_users": "Cilvฤ“ki, kas izmantojuลกi ลกo serveri pฤ“dฤ“jo 30ย dienu laikฤ (aktฤซvie lietotฤji mฤ“nesฤซ)", - "server_banner.active_users": "aktฤซvie lietotฤji", - "server_banner.administered_by": "Administrฤ“:", - "server_banner.introduction": "{domain} ir daฤผa no decentralizฤ“tฤ sociฤlฤ tฤซkla, ko nodroลกina {mastodon}.", - "server_banner.learn_more": "Uzzinฤt vairฤk", + "server_banner.active_users": "aktฤซvi lietotฤji", + "server_banner.administered_by": "Pฤrvalda:", "server_banner.server_stats": "Servera statistika:", "sign_in_banner.create_account": "Izveidot kontu", - "sign_in_banner.sign_in": "Pierakstฤซties", + "sign_in_banner.sign_in": "Pieteikties", "sign_in_banner.sso_redirect": "Piesakies vai Reฤฃistrฤ“jies", - "sign_in_banner.text": "Pieraksties, lai sekotu profiliem vai atsaucฤ“m, pievienotu izlasei, kopฤซgotu ziล†as un atbildฤ“tu uz tฤm. Vari arฤซ mijiedarboties no sava konta citฤ serverฤซ.", "status.admin_account": "Atvฤ“rt @{name} moderฤ“ลกanas saskarni", "status.admin_domain": "Atvฤ“rt {domain} moderฤ“ลกanas saskarni", "status.admin_status": "Atvฤ“rt ลกo ziล†u moderฤcijas saskarnฤ“", "status.block": "Bloฤทฤ“t @{name}", "status.bookmark": "Grฤmatzฤซme", - "status.cancel_reblog_private": "Neizcelt", + "status.cancel_reblog_private": "Nepastiprinฤt", "status.cannot_reblog": "ล o ziล†u nevar izcelt", - "status.copy": "Kopฤ“t saiti uz ziล†u", + "status.copy": "Ievietot ieraksta saiti starpliktuvฤ“", "status.delete": "Dzฤ“st", "status.detailed_status": "Detalizฤ“ts sarunas skats", "status.direct": "Pieminฤ“t @{name} privฤti", "status.direct_indicator": "Pieminฤ“ts privฤti", - "status.edit": "Rediฤฃฤ“t", - "status.edited": "Rediฤฃฤ“ts {date}", - "status.edited_x_times": "Rediฤฃฤ“ts {count, plural, one {{count} reize} other {{count} reizes}}", - "status.embed": "Iestrฤdฤt", - "status.favourite": "Iecienฤซts", + "status.edit": "Labot", + "status.edited": "Pฤ“dฤ“joreiz labots {date}", + "status.edited_x_times": "Labots {count, plural, zero {{count} reiลพu} one {{count} reizi} other {{count} reizes}}", + "status.embed": "Iegult", + "status.favourite": "Izlasฤ“", + "status.favourites": "{count, plural, zero {izlasฤ“s} one {izlasฤ“} other {izlasฤ“s}}", "status.filter": "Filtrฤ“ ลกo ziล†u", "status.filtered": "Filtrฤ“ts", "status.hide": "Slฤ“pt ierakstu", "status.history.created": "{name} izveidoja {date}", - "status.history.edited": "{name} rediฤฃฤ“ja {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}", @@ -627,6 +684,7 @@ "status.reblog": "Pastiprinฤt", "status.reblog_private": "Pastiprinฤt, nemainot redzamฤซbu", "status.reblogged_by": "{name} pastiprinฤja", + "status.reblogs": "{count, plural, zero {pastiprinฤjumu} one {pastiprinฤjums} other {pastiprinฤjumi}}", "status.reblogs.empty": "Neviens ลกo ierakstu vฤ“l nav pastiprinฤjis. Kad bลซs, tie parฤdฤซsies ลกeit.", "status.redraft": "Dzฤ“st un pฤrrakstฤซt", "status.remove_bookmark": "Noล†emt grฤmatzฤซmi", @@ -648,7 +706,7 @@ "status.uncached_media_warning": "Priekลกskatฤซjums nav pieejams", "status.unmute_conversation": "Noล†emt sarunas apklusinฤjumu", "status.unpin": "Noล†emt profila piespraudumu", - "subscribed_languages.lead": "Pฤ“c izmaiล†u veikลกanas tavฤ mฤjas un sarakstu laika lฤซnijฤ tiks rฤdฤซtas tikai ziล†as atlasฤซtajฤs valodฤs. Neatlasi nevienu, lai saล†emtu ziล†as visฤs valodฤs.", + "subscribed_languages.lead": "Pฤ“c izmaiล†u veikลกanas Tavฤ mฤjas un sarakstu laika lฤซnijฤ tiks rฤdฤซti tikai tie ieraksti atlasฤซtajฤs valodฤs. Neatlasฤซt nevienu, lai saล†emtu ierakstus visฤs valodฤs.", "subscribed_languages.save": "Saglabฤt izmaiล†as", "subscribed_languages.target": "Mainฤซt abonฤ“tฤs valodas priekลก {target}", "tabs_bar.home": "Sฤkums", @@ -662,8 +720,8 @@ "timeline_hint.resources.followers": "Sekotฤji", "timeline_hint.resources.follows": "Seko", "timeline_hint.resources.statuses": "Vecฤki ieraksti", - "trends.counter_by_accounts": "{count, plural, one {{counter} persona} other {{counter} cilvฤ“ki}} par {days, plural, one {# dienu} other {{days} dienฤm}}", - "trends.trending_now": "Aktuฤlฤs tendences", + "trends.counter_by_accounts": "{count, plural, zero {{counter} cilvฤ“ku} one {{counter} cilvฤ“ks} other {{counter} cilvฤ“ki}} {days, plural, one {{day} dienฤ} other {{days} dienฤs}}", + "trends.trending_now": "Paลกlaik populฤri", "ui.beforeunload": "Ja pametฤซsit Mastodonu, jลซsu melnraksts tiks zaudฤ“ts.", "units.short.billion": "{count}Mjd", "units.short.million": "{count}M", @@ -674,7 +732,7 @@ "upload_error.poll": "Datล†u augลกupielฤdes aptaujฤs nav atฤผautas.", "upload_form.audio_description": "Pievieno aprakstu cilvฤ“kiem ar dzirdes zudumu", "upload_form.description": "Pievieno aprakstu vฤjredzฤซgajiem", - "upload_form.edit": "Rediฤฃฤ“t", + "upload_form.edit": "Labot", "upload_form.thumbnail": "Nomainฤซt sฤซktฤ“lu", "upload_form.video_description": "Pievieno aprakstu cilvฤ“kiem ar dzirdes vai redzes traucฤ“jumiem", "upload_modal.analyzing_picture": "Analizฤ“ attฤ“luโ€ฆ", @@ -683,7 +741,7 @@ "upload_modal.choose_image": "Izvฤ“lฤ“ties attฤ“lu", "upload_modal.description_placeholder": "Raibais runcis rฤซgฤ ratu rumbฤ rลซc", "upload_modal.detect_text": "Noteikt tekstu no attฤ“la", - "upload_modal.edit_media": "Rediฤฃฤ“t multividi", + "upload_modal.edit_media": "Labot informฤcijas nesฤ“ju", "upload_modal.hint": "Noklikลกฤทini vai velc apli priekลกskatฤซjumฤ, lai izvฤ“lฤ“tos fokusa punktu, kas vienmฤ“r bลซs redzams visos sฤซktฤ“los.", "upload_modal.preparing_ocr": "Sagatavo OCRโ€ฆ", "upload_modal.preview_label": "Priekลกskatฤซt ({ratio})", diff --git a/app/javascript/mastodon/locales/mk.json b/app/javascript/mastodon/locales/mk.json index f7080842b7..d8a470ed47 100644 --- a/app/javascript/mastodon/locales/mk.json +++ b/app/javascript/mastodon/locales/mk.json @@ -80,20 +80,15 @@ "compose_form.spoiler.marked": "ะขะตะบัั‚ะพั‚ ะต ัะพะบั€ะธะตะฝ ะทะฐะด ะฟั€ะตะดัƒะฟั€ะตะดัƒะฒะฐัšะต", "compose_form.spoiler.unmarked": "ะขะตะบัั‚ะพั‚ ะฝะต ะต ัะพะบั€ะธะตะฝ", "confirmation_modal.cancel": "ะžั‚ะบะฐะถะธ", - "confirmations.block.block_and_report": "ะ‘ะปะพะบะธั€ะฐั˜ ะธ ะŸั€ะธั˜ะฐะฒะธ", "confirmations.block.confirm": "ะ‘ะปะพะบะธั€ะฐั˜", - "confirmations.block.message": "ะกะธะณัƒั€ะฝะธ ัั‚ะต ะดะตะบะฐ ะดะตะบะฐ ะณะพ ะฑะปะพะบะธั€ะฐั‚ะต {name}?", "confirmations.delete.confirm": "ะ˜ะทะฑั€ะธัˆะธ", "confirmations.delete.message": "ะกะธะณัƒั€ะฝะธ ัั‚ะต ะดะตะบะฐ ะณะพ ะฑั€ะธัˆะธั‚ะต ัั‚ะฐั‚ัƒัะพั‚?", "confirmations.delete_list.confirm": "ะ˜ะทะฑั€ะธัˆะธ", "confirmations.delete_list.message": "ะ”ะฐะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะตะบะฐ ัะฐะบะฐั‚ะต ะดะฐ ะณะพ ะธะทะฑั€ะธัˆะตั‚ะต ัะฟะธัะพะบะพะฒ?", - "confirmations.domain_block.confirm": "ะกะพะบั€ะธั˜ ั†ะตะป ะดะพะผะตะธะฝ", "confirmations.domain_block.message": "ะ”ะฐะปะธ ัะบั€ะพะท ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะตะบะฐ ัœะต ะฑะปะพะบะธั€ะฐั‚ะต ัั ะพะด {domain}? ะ’ะพ ะฟะพะฒะตัœะตั‚ะพ ัะปัƒั‡ะฐะตะฒะธ ะฝะตะบะพะปะบัƒ ั‚ะฐั€ะณะตั‚ะธั€ะฐะฝะธ ะฑะปะพะบะธั€ะฐัšะฐ ะธะปะธ ะทะฐัœัƒั‚ัƒะฒะฐัšะฐ ัะต ะดะพะฒะพะปะฝะธ ะธ ะฟั€ะตะดะปะพะถะตะฝะธ. ะะตะผะฐ ะดะฐ ั˜ะฐ ะฒะธะดะธั‚ะต ัะพะดั€ะถะธะฝะฐั‚ะฐ ะพะด ั‚ะพั˜ ะดะพะผะตะธะฝ ะฒะพ ะฝะธะบะพั˜ ั˜ะฐะฒะตะฝ ะฒั€ะตะผะตะฟะปะพะฒ ะธะปะธ ะฒะฐัˆะธั‚ะต ะฝะพั‚ะธั„ะธะบะฐั†ะธะธ. ะ’ะฐัˆะธั‚ะต ัะปะตะดะฑะตะฝะธั†ะธ ะพะด ั‚ะพั˜ ะดะพะผะตะธะฝ ัœะต ะฑะธะดะฐั‚ ะพัั‚ั€ะฐะฝะตั‚ะธ.", "confirmations.logout.confirm": "ะžะดั˜ะฐะฒะธ ัะต", "confirmations.logout.message": "ะ”ะฐะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะตะบะฐ ัะฐะบะฐั‚ะต ะดะฐ ัะต ะพะดั˜ะฐะฒะธั‚ะต?", "confirmations.mute.confirm": "ะ—ะฐัœัƒั‚ะธ", - "confirmations.mute.explanation": "ะŒะต ัะพะบั€ะธะต ะพะฑั˜ะฐะฒะธ ะพะด ะฝะธะฒ ะธ ะพะฑั˜ะฐะฒะธ ะบะพะธ ะณะธ ัะฟะพะผะฝัƒะฒะฐะฐั‚ ะฝะธะฒ, ะฝะพ ัะตัƒัˆั‚ะต ัœะต ะธะผ ะดะพะทะฒะพะปะธ ะดะฐ ะณะธ ะฒะธะดะฐั‚ ะฒะฐัˆะธั‚ะต ะฟะพัั‚ะพะฒะธ ะธ ะฒะต ัะปะตะดะฐั‚.", - "confirmations.mute.message": "ะ”ะฐะปะธ ัœะต ะณะพ ะทะฐัœัƒั‚ะธั‚ะต {name}?", "confirmations.reply.confirm": "ะžะดะณะพะฒะพั€ะธ", "confirmations.unfollow.confirm": "ะžะดัะปะตะดะธ", "confirmations.unfollow.message": "ะกะธะณัƒั€ะฝะธ ัั‚ะต ะดะตะบะฐ ัœะต ะณะพ ะพั‚ัะปะตะดะธั‚ะต {name}?", @@ -137,7 +132,6 @@ "hashtag.column_settings.tag_mode.any": "ะ‘ะธะปะพ ะบะพะธ", "hashtag.column_settings.tag_mode.none": "ะะธะบะพะธ", "hashtag.column_settings.tag_toggle": "ะกั‚ะฐะฒะธ ะดะพะดะฐั‚ะฝะธ ั‚ะฐะณะพะฒะธ ะทะฐ ะพะฒะฐะฐ ะบะพะปะพะฝะฐ", - "home.column_settings.basic": "ะžัะฝะพะฒะฝะพ", "home.column_settings.show_reblogs": "ะŸั€ะธะบะฐะถะธ ะฑัƒัั‚ะธั€ะฐัšะฐ", "home.column_settings.show_replies": "ะŸั€ะธะบะฐะถะธ ะพะดะณะพะฒะพั€ะธ", "intervals.full.days": "{number, plural, one {# ะดะตะฝ} other {# ะดะตะฝะฐ}}", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 0059dd333b..8fb4e818db 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -108,14 +108,11 @@ "compose_form.spoiler.marked": "เดŽเดดเตเดคเตเดคเต เดฎเตเดจเตเดจเดฑเดฟเดฏเดฟเดชเตเดชเดฟเดจเดพเตฝ เดฎเดฑเดšเตเดšเดฟเดฐเดฟเด•เตเด•เตเดจเตเดจเต", "compose_form.spoiler.unmarked": "เดŽเดดเตเดคเตเดคเต เดฎเดฑเดฏเตเด•เตเด•เดชเตเดชเต†เดŸเตเดŸเดฟเดŸเตเดŸเดฟเดฒเตเดฒ", "confirmation_modal.cancel": "เดฑเดฆเตเดฆเดพเด•เตเด•เตเด•", - "confirmations.block.block_and_report": "เดคเดŸเดฏเตเด•เดฏเตเด‚ เดฑเดฟเดชเตเดชเต‹เตผเดŸเตเดŸเตเด‚ เดšเต†เดฏเตเดฏเตเด•", "confirmations.block.confirm": "เดคเดŸเดฏเตเด•", - "confirmations.block.message": "{name} เดคเดŸเดฏเดพเตป เดจเดฟเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเตเดฃเตเดŸเต‹?", "confirmations.delete.confirm": "เดฎเดพเดฏเตเด•เตเด•เตเด•", "confirmations.delete.message": "เดˆ เดŸเต‚เดŸเตเดŸเต เด‡เดฒเตเดฒเดพเดคเดพเด•เตเด•เดฃเด‚ เดŽเดจเตเดจเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‰เดฑเดชเตเดชเดพเดฃเต‹?", "confirmations.delete_list.confirm": "เดฎเดพเดฏเตเด•เตเด•เตเด•", "confirmations.delete_list.message": "เดˆ เดชเดŸเตเดŸเดฟเด• เดŽเดจเตเดจเต†เดจเตเดจเต‡เด•เตเด•เตเดฎเดพเดฏเดฟ เดจเต€เด•เตเด•เด‚ เดšเต†เดฏเตเดฏเดพเตป เดจเดฟเด™เตเด™เตพ เด†เด—เตเดฐเดนเดฟเด•เตเด•เตเดจเตเดจเตเดฃเตเดŸเต‹?", - "confirmations.domain_block.confirm": "เดฎเตเดดเตเดตเตป เดกเตŠเดฎเต†เดฏเตโ€Œเดจเตเด‚ เดคเดŸเดฏเตเด•", "confirmations.logout.confirm": "เดชเตเดฑเดคเตเดคเตเด•เดŸเด•เตเด•เตเด•", "confirmations.logout.message": "เดจเดฟเด™เตเด™เตพเด•เตเด•เต เดฒเต‹เด—เต เด”เดŸเตเดŸเต เดšเต†เดฏเตเดฏเดฃเดฎเต†เดจเตเดจเต เด‰เดฑเดชเตเดชเดพเดฃเต‹?", "confirmations.mute.confirm": "เดจเดฟเดถเตเดถเดฌเตเดฆเดฎเดพเด•เตเด•เตเด•", @@ -181,7 +178,6 @@ "hashtag.column_settings.tag_mode.any": "เด‡เดตเดฏเดฟเดฒเต‡เดคเต†เด™เตเด•เดฟเดฒเตเด‚", "hashtag.column_settings.tag_mode.none": "เด‡เดคเดฟเดฒเตŠเดจเตเดจเตเดฎเดฒเตเดฒ", "hashtag.column_settings.tag_toggle": "เดˆ เดŽเดดเตเดคเตเดคเตเดชเด‚เด•เตเดคเดฟเด•เตเด•เต เด•เต‚เดŸเตเดคเตฝ เด‰เดชเดจเดพเดฎเด™เตเด™เตพ เดšเต‡เตผเด•เตเด•เตเด•", - "home.column_settings.basic": "เด…เดŸเดฟเดธเตเดฅเดพเดจเด‚", "home.column_settings.show_reblogs": "เดฌเต‚เดธเตเดฑเตเดฑเตเด•เตพ เด•เดพเดฃเดฟเด•เตเด•เตเด•", "home.column_settings.show_replies": "เดฎเดฑเตเดชเดŸเดฟเด•เตพ เด•เดพเดฃเดฟเด•เตเด•เตเด•", "home.hide_announcements": "เดชเตเดฐเด–เตเดฏเดพเดชเดจเด™เตเด™เตพ เดฎเดฑเดฏเตโ€Œเด•เตเด•เตเด•", @@ -230,8 +226,6 @@ "lists.replies_policy.none": "เด†เดฐเตเดฎเดฟเดฒเตเดฒ", "lists.replies_policy.title": "เด‡เดคเดฟเดจเตเดณเตเดณ เดฎเดฑเตเดชเดŸเดฟเด•เตพ เด•เดพเดฃเดฟเด•เตเด•เตเด•:", "lists.subheading": "เดŽเดจเตเดฑเต† เดชเดŸเตเดŸเดฟเด•เด•เตพ", - "mute_modal.duration": "เด•เดพเดฒเดพเดตเดงเดฟ", - "mute_modal.indefinite": "เด…เดจเดฟเดถเตเดšเดฟเดคเด•เดพเดฒ", "navigation_bar.blocks": "เดคเดŸเดฏเดชเตเดชเต†เดŸเตเดŸ เด‰เดชเดฏเต‹เด•เตเดคเดพเด•เตเด•เตพ", "navigation_bar.bookmarks": "เดฌเตเด•เตเด•เตเดฎเดพเตผเด•เตเด•เตเด•เตพ", "navigation_bar.community_timeline": "เดชเตเดฐเดพเดฆเต‡เดถเดฟเด• เดธเดฎเดฏเดฐเต‡เด–", @@ -255,7 +249,6 @@ "notifications.clear": "เด…เดฑเดฟเดฏเดฟเดชเตเดชเต เดฎเดพเดฏเตเด•เตเด•เตเด•", "notifications.clear_confirmation": "เดจเดฟเด™เตเด™เดณเตเดŸเต† เดŽเดฒเตเดฒเดพ เด…เดฑเดฟเดฏเดฟเดชเตเดชเตเด•เดณเตเด‚ เดถเดพเดถเตเดตเดคเดฎเดพเดฏเดฟ เดฎเดพเดฏเตโ€Œเด•เตเด•เดฃเดฎเต†เดจเตเดจเต เดจเดฟเด™เตเด™เตพเด•เตเด•เต เด‰เดฑเดชเตเดชเดพเดฃเต‹?", "notifications.column_settings.alert": "เดกเต†เดธเตเด•เตเดŸเต‹เดชเตเดชเต เด…เดฑเดฟเดฏเดฟเดชเตเดชเตเด•เตพ", - "notifications.column_settings.filter_bar.advanced": "เดŽเดฒเตเดฒเดพ เดตเดฟเดญเดพเด—เด™เตเด™เดณเตเด‚ เดชเตเดฐเดฆเตผเดถเดฟเดชเตเดชเดฟเด•เตเด•เตเด•", "notifications.column_settings.follow": "เดชเตเดคเดฟเดฏ เดชเดฟเดจเตเดคเตเดŸเดฐเตเดจเตเดจเดตเตผ:", "notifications.column_settings.follow_request": "เดชเตเดคเดฟเดฏ เดชเดฟเดจเตเดคเตเดŸเดฐเตฝ เด…เดญเตเดฏเตผเดคเตเดฅเดจเด•เตพ:", "notifications.column_settings.mention": "เดธเต‚เดšเดจเด•เตพ:", diff --git a/app/javascript/mastodon/locales/mr.json b/app/javascript/mastodon/locales/mr.json index 20231f0bbf..c07294d90a 100644 --- a/app/javascript/mastodon/locales/mr.json +++ b/app/javascript/mastodon/locales/mr.json @@ -17,9 +17,12 @@ "account.badges.group": "เค—เคŸ", "account.block": "@{name} เคฏเคพเค‚เคจเคพ เคฌเฅเคฒเฅ‰เค• เค•เคฐเคพ", "account.block_domain": "{domain} เคชเคพเคธเฅ‚เคจ เคธเคฐเฅเคต เคฒเคชเคตเคพ", + "account.block_short": "เค…เคตเคฐเฅ‹เคง", "account.blocked": "เคฌเฅเคฒเฅ‰เค• เค•เฅ‡เคฒเฅ‡ เค†เคนเฅ‡", "account.browse_more_on_origin_server": "เคฎเฅ‚เคณ เคชเฅเคฐเฅ‹เคซเคพเค‡เคฒเคตเคฐ เค…เคงเคฟเค• เคฌเฅเคฐเคพเค‰เค เค•เคฐเคพ", "account.cancel_follow_request": "เคซเฅ‰เคฒเฅ‹ เคตเคฟเคจเค‚เคคเฅ€ เคฎเคพเค—เฅ‡ เค˜เฅเคฏเคพ", + "account.copy": "เคฆเฅเคตเคพ เค•เฅ‰เคชเฅ€ เค•เคฐเคพ", + "account.direct": "เค–เคพเคœเค—เฅ€เคฐเคฟเคคเฅเคฏเคพ เค‰เคฒเฅเคฒเฅ‡เค–เฅ€เคค @{name}", "account.disable_notifications": "เคœเฅ‡เคตเฅเคนเคพ @{name} เคชเฅ‹เคธเฅเคŸ เค•เคฐเคคเคพเคค เคคเฅ‡เคตเฅเคนเคพ เคฎเคฒเคพ เคธเฅ‚เคšเคฟเคค เค•เคฐเคฃเฅ‡ เคฅเคพเค‚เคฌเคตเคพ", "account.domain_blocked": "Domain hidden", "account.edit_profile": "เคชเฅเคฐเฅ‹เคซเคพเค‡เคฒ เคเคกเคฟเคŸ เค•เคฐเคพ", @@ -29,6 +32,7 @@ "account.featured_tags.last_status_never": "เคชเฅ‹เคธเฅเคŸ เคจเคพเคนเฅ€เคค", "account.featured_tags.title": "{name} เคšเฅ‡ เคตเฅˆเคถเคฟเคทเฅเคŸเฅเคฏเฅ€เค•เฅƒเคค เคนเฅ…เคถเคŸเฅ…เค—", "account.follow": "เค…เคจเฅเคฏเคพเคฏเฅ€ เคตเฅเคนเคพ", + "account.follow_back": "เค†เคชเคฃเคนเฅ€ เค…เคจเฅเคธเคฐเคฃ เค•เคฐเคพ", "account.followers": "เค…เคจเฅเคฏเคพเคฏเฅ€", "account.followers.empty": "เคนเฅเคฏเคพ เคตเคพเคชเคฐเค•เคฐเฅเคคเฅเคฏเคพเคšเคพ เค†เคคเคพเคชเคฐเฅเคฏเค‚เคค เค•เฅ‹เคฃเฅ€ เค…เคจเฅเคฏเคพเคฏเฅ€ เคจเคพเคนเฅ€.", "account.followers_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", @@ -45,6 +49,7 @@ "account.mention": "@{name} เคšเคพ เค‰เคฒเฅเคฒเฅ‡เค– เค•เคฐเคพ", "account.moved_to": "{name} เคจเฅ‡ เคธเฅ‚เคšเคฟเคค เค•เฅ‡เคฒเฅ‡ เค†เคนเฅ‡ เค•เฅ€ เคคเฅเคฏเคพเค‚เคšเฅ‡ เคจเคตเฅ€เคจ เค–เคพเคคเฅ‡ เค†เคคเคพ เค†เคนเฅ‡:", "account.mute": "@{name} เคฒเคพ เคฎเฅ‚เค• เค•เคพเคฐเคพ", + "account.mute_short": "เคจเคฟ:เคถเคฌเฅเคฆ", "account.muted": "เคฎเฅŒเคจ", "account.open_original_page": "เคฎเฅ‚เคณ เคชเฅƒเคทเฅเค  เค‰เค˜เคกเคพ", "account.posts": "Toots", @@ -105,7 +110,6 @@ "confirmations.delete.message": "เคนเฅ‡ เคธเฅเคŸเฅ‡เคŸเคธ เคคเฅเคฎเฅเคนเคพเคฒเคพ เคจเค•เฅเค•เฅ€ เคนเคŸเคตเคพเคฏเคšเค‚เคฏ?", "confirmations.delete_list.confirm": "เคนเคŸเคตเคพ", "confirmations.delete_list.message": "เคนเฅ€ เคฏเคพเคฆเฅ€ เคคเฅเคฎเฅเคนเคพเคฒเคพ เคจเค•เฅเค•เฅ€ เค•เคพเคฏเคฎเคšเฅ€ เคนเคŸเคตเคพเคฏเคšเฅ€เคฏ?", - "confirmations.domain_block.confirm": "เคธเค‚เคชเฅ‚เคฐเฅเคฃ เคกเฅ‹เคฎเฅ‡เคจ เคฒเคชเคตเคพ", "confirmations.logout.message": "เคคเฅเคฎเคšเฅ€ เค–เคพเคคเฅเคฐเฅ€ เค†เคนเฅ‡ เค•เฅ€ เคคเฅเคฎเฅเคนเฅ€ เคฒเฅ‰เค— เค†เค‰เคŸ เค•เคฐเฅ‚ เค‡เคšเฅเค›เคฟเคคเคพ?", "confirmations.mute.confirm": "เค†เคตเคพเคœ เคฌเค‚เคฆ เค•เคฐเคพ", "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", @@ -122,7 +126,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "เคนเฅ…เคถเคŸเฅ…เค— เคซเฅ‰เคฒเฅ‹ เค•เคฐเคพ", "hashtag.unfollow": "เคนเฅ…เคถเคŸเฅ…เค— เค…เคจเคซเฅ‰เคฒเฅ‹ เค•เคฐเคพ", - "home.column_settings.basic": "เคฎเฅ‚เคณ", "home.column_settings.show_reblogs": "เคฌเฅ‚เคธเฅเคŸ เคฆเคพเค–เคตเคพ", "home.column_settings.show_replies": "เค‰เคคเฅเคคเคฐเฅ‡ เคฆเคพเค–เคตเคพ", "home.hide_announcements": "เค˜เฅ‹เคทเคฃเคพ เคฒเคชเคตเคพ", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 2c3221cfdd..3d7992faf7 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -21,6 +21,7 @@ "account.blocked": "Disekat", "account.browse_more_on_origin_server": "Layari selebihnya di profil asal", "account.cancel_follow_request": "Menarik balik permintaan mengikut", + "account.copy": "Salin pautan ke profil", "account.direct": "Sebut secara persendirian @{name}", "account.disable_notifications": "Berhenti maklumkan saya apabila @{name} mengirim hantaran", "account.domain_blocked": "Domain disekat", @@ -31,6 +32,7 @@ "account.featured_tags.last_status_never": "Tiada hantaran", "account.featured_tags.title": "Tanda pagar pilihan {name}", "account.follow": "Ikuti", + "account.follow_back": "Ikut balik", "account.followers": "Pengikut", "account.followers.empty": "Belum ada yang mengikuti pengguna ini.", "account.followers_counter": "{count, plural, one {{counter} Pengikut} other {{counter} Pengikut}}", @@ -51,6 +53,7 @@ "account.mute_notifications_short": "Redam pemberitahuan", "account.mute_short": "Redam", "account.muted": "Dibisukan", + "account.mutual": "Rakan kongsi", "account.no_bio": "Tiada penerangan diberikan.", "account.open_original_page": "Buka halaman asal", "account.posts": "Hantaran", @@ -143,15 +146,21 @@ "compose_form.lock_disclaimer.lock": "dikunci", "compose_form.placeholder": "Apakah yang sedang anda fikirkan?", "compose_form.poll.duration": "Tempoh undian", + "compose_form.poll.multiple": "Pelbagai pilihan", + "compose_form.poll.option_placeholder": "Pilihan {number}", + "compose_form.poll.single": "Pilih satu", "compose_form.poll.switch_to_multiple": "Ubah kepada membenarkan aneka undian", "compose_form.poll.switch_to_single": "Ubah kepada undian pilihan tunggal", + "compose_form.poll.type": "Gaya", + "compose_form.publish": "Siaran", "compose_form.publish_form": "Terbit", + "compose_form.reply": "Balas", + "compose_form.save_changes": "Kemas kini", "compose_form.spoiler.marked": "Buang amaran kandungan", "compose_form.spoiler.unmarked": "Tambah amaran kandungan", + "compose_form.spoiler_placeholder": "Amaran kandungan (pilihan)", "confirmation_modal.cancel": "Batal", - "confirmations.block.block_and_report": "Sekat & Lapor", "confirmations.block.confirm": "Sekat", - "confirmations.block.message": "Adakah anda pasti anda ingin menyekat {name}?", "confirmations.cancel_follow_request.confirm": "Tarik balik permintaan", "confirmations.cancel_follow_request.message": "Adakah anda pasti ingin menarik balik permintaan anda untuk mengikut {name}?", "confirmations.delete.confirm": "Padam", @@ -160,15 +169,12 @@ "confirmations.delete_list.message": "Adakah anda pasti anda ingin memadam senarai ini secara kekal?", "confirmations.discard_edit_media.confirm": "Singkir", "confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan pada penerangan atau pratonton media. Anda ingin membuangnya?", - "confirmations.domain_block.confirm": "Sekat keseluruhan domain", "confirmations.domain_block.message": "Adakah anda betul-betul, sungguh-sungguh pasti anda ingin menyekat keseluruhan {domain}? Selalunya, beberapa sekatan atau pembisuan tersasar sudah memadai dan lebih diutamakan. Anda tidak akan nampak kandungan daripada domain tersebut di mana-mana garis masa awam mahupun pemberitahuan anda. Pengikut anda daripada domain tersebut juga akan dibuang.", "confirmations.edit.confirm": "Sunting", "confirmations.edit.message": "Mengedit sekarang akan menimpa mesej yang sedang anda karang. Adakah anda pasti mahu meneruskan?", "confirmations.logout.confirm": "Log keluar", "confirmations.logout.message": "Adakah anda pasti anda ingin log keluar?", "confirmations.mute.confirm": "Bisukan", - "confirmations.mute.explanation": "Ini akan menyembunyikan hantaran daripada mereka dan juga hantaran yang menyebut mereka, tetapi ia masih membenarkan mereka melihat hantaran anda dan mengikuti anda.", - "confirmations.mute.message": "Adakah anda pasti anda ingin membisukan {name}?", "confirmations.redraft.confirm": "Padam & rangka semula", "confirmations.redraft.message": "Adakah anda pasti anda ingin memadam pos ini dan merangkanya semula? Kegemaran dan galakan akan hilang, dan balasan ke pos asal akan menjadi yatim.", "confirmations.reply.confirm": "Balas", @@ -179,6 +185,7 @@ "conversation.mark_as_read": "Tanda sudah dibaca", "conversation.open": "Lihat perbualan", "conversation.with": "Dengan {names}", + "copy_icon_button.copied": "Disalin ke papan klip", "copypaste.copied": "Disalin", "copypaste.copy_to_clipboard": "Salin ke papan klip", "directory.federated": "Dari fediverse yang diketahui", @@ -210,6 +217,7 @@ "emoji_button.search_results": "Hasil carian", "emoji_button.symbols": "Simbol", "emoji_button.travel": "Kembara & Tempat", + "empty_column.account_hides_collections": "Pengguna ini telah memilih untuk tidak menyediakan informasi tersebut", "empty_column.account_suspended": "Akaun digantung", "empty_column.account_timeline": "Tiada hantaran di sini!", "empty_column.account_unavailable": "Profil tidak tersedia", @@ -264,6 +272,14 @@ "follow_request.authorize": "Benarkan", "follow_request.reject": "Tolak", "follow_requests.unlocked_explanation": "Walaupun akaun anda tidak dikunci, kakitangan {domain} merasakan anda mungkin ingin menyemak permintaan ikutan daripada akaun ini secara manual.", + "follow_suggestions.curated_suggestion": "", + "follow_suggestions.dismiss": "Jangan papar lagi", + "follow_suggestions.hints.featured": "Profil{domain.", + "follow_suggestions.hints.friends_of_friends": "This profile is popular among the people you follow.", + "follow_suggestions.hints.most_followed": ".", + "follow_suggestions.personalized_suggestion": "Cadangan peribadi", + "follow_suggestions.popular_suggestion": "Cadangan terkenal", + "follow_suggestions.view_all": "Lihat semua", "followed_tags": "Topik terpilih", "footer.about": "Perihal", "footer.directory": "Direktori profil", @@ -284,10 +300,12 @@ "hashtag.column_settings.tag_mode.any": "Mana-mana daripada yang ini", "hashtag.column_settings.tag_mode.none": "Tiada apa pun daripada yang ini", "hashtag.column_settings.tag_toggle": "Sertakan tag tambahan untuk lajur ini", + "hashtag.counter_by_accounts": "{count, plural, other {{counter} peserta}}", + "hashtag.counter_by_uses": "{count, plural, other {{counter} siaran}}", + "hashtag.counter_by_uses_today": "{count, plural, other {{counter} siaran}} hari ini", "hashtag.follow": "Ikuti hashtag", "hashtag.unfollow": "Nyahikut tanda pagar", "hashtags.and_other": "โ€ฆdan {count, plural, other {# more}}", - "home.column_settings.basic": "Asas", "home.column_settings.show_reblogs": "Tunjukkan galakan", "home.column_settings.show_replies": "Tunjukkan balasan", "home.hide_announcements": "Sembunyikan pengumuman", @@ -370,11 +388,9 @@ "lists.search": "Cari dalam kalangan orang yang anda ikuti", "lists.subheading": "Senarai anda", "load_pending": "{count, plural, one {# item baharu} other {# item baharu}}", + "loading_indicator.label": "Memuatkanโ€ฆ", "media_gallery.toggle_visible": "{number, plural, other {Sembunyikan imej}}", "moved_to_account_banner.text": "Akaun anda {disabledAccount} kini dinyahdayakan kerana anda berpindah ke {movedToAccount}.", - "mute_modal.duration": "Tempoh", - "mute_modal.hide_notifications": "Sembunyikan pemberitahuan daripada pengguna ini?", - "mute_modal.indefinite": "Tidak tentu", "navigation_bar.about": "Perihal", "navigation_bar.advanced_interface": "Buka dalam antara muka web lanjutan", "navigation_bar.blocks": "Pengguna yang disekat", @@ -418,9 +434,6 @@ "notifications.column_settings.admin.sign_up": "Pendaftaran baru:", "notifications.column_settings.alert": "Pemberitahuan atas meja", "notifications.column_settings.favourite": "Kegemaran:", - "notifications.column_settings.filter_bar.advanced": "Papar semua kategori", - "notifications.column_settings.filter_bar.category": "Bar penapis pantas", - "notifications.column_settings.filter_bar.show_bar": "Paparkan bar penapis", "notifications.column_settings.follow": "Pengikut baharu:", "notifications.column_settings.follow_request": "Permintaan ikutan baharu:", "notifications.column_settings.mention": "Sebutan:", @@ -457,6 +470,11 @@ "onboarding.follows.empty": "Malangnya, tiada hasil dapat ditunjukkan sekarang. Anda boleh cuba menggunakan carian atau menyemak imbas halaman teroka untuk mencari orang untuk diikuti atau cuba lagi kemudian.", "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.title": "Popular on Mastodon", + "onboarding.profile.display_name": "Nama paparan", + "onboarding.profile.display_name_hint": "Nama penuh anda atau nama anda yang menyeronokkanโ€ฆ", + "onboarding.profile.note_hint": "Anda boleh @menyebut orang lain atau #hashtagsโ€ฆ", + "onboarding.profile.save_and_continue": "Simpan dan teruskan", + "onboarding.profile.upload_avatar": "Muat naik gambar profil", "onboarding.share.lead": "Beritahu orang ramai bagaimana mereka boleh menemui anda di Mastodon!", "onboarding.share.message": "Saya {username} di #Mastodon! Jom ikut saya di {url}", "onboarding.share.next_steps": "Langkah seterusnya yang mungkin:", @@ -490,9 +508,14 @@ "poll_button.add_poll": "Tambah undian", "poll_button.remove_poll": "Buang undian", "privacy.change": "Ubah privasi hantaran", + "privacy.direct.long": "Semua orang yang disebutkan dalam siaran", + "privacy.direct.short": "Orang tertentu", + "privacy.private.long": "Pengikut anda sahaja", + "privacy.private.short": "Pengikut", "privacy.public.short": "Awam", "privacy_policy.last_updated": "Dikemaskini {date}", "privacy_policy.title": "Dasar Privasi", + "recommended": "Disyorkan", "refresh": "Muat semula", "regeneration_indicator.label": "Memuatkanโ€ฆ", "regeneration_indicator.sublabel": "Suapan rumah anda sedang disediakan!", @@ -507,7 +530,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "relative_time.today": "hari ini", + "reply_indicator.attachments": "{count, plural, other {# lampiran}}", "reply_indicator.cancel": "Batal", + "reply_indicator.poll": "Undian", "report.block": "Sekat", "report.block_explanation": "Anda tidak akan melihat hantaran mereka. Mereka tidak dapat melihat hantaran anda atau mengikuti anda. Mereka akan sedar bahawa mereka disekat.", "report.categories.legal": "Sah", @@ -579,13 +604,10 @@ "server_banner.about_active_users": "Pengguna pelayan ini sepanjang 30 hari yang lalu (Pengguna Aktif Bulanan)", "server_banner.active_users": "pengguna aktif", "server_banner.administered_by": "Ditadbir oleh:", - "server_banner.introduction": "{domain} ialah sebahagian daripada rangkaian sosial terpencar dikuasakan oleh {mastodon}.", - "server_banner.learn_more": "Maklumat lanjut", "server_banner.server_stats": "Statistik pelayan:", "sign_in_banner.create_account": "Cipta akaun", "sign_in_banner.sign_in": "Daftar masuk", "sign_in_banner.sso_redirect": "Log masuk atau mendaftar", - "sign_in_banner.text": "Log masuk untuk mengikuti profil atau hashtag, kegemaran, kongsi dan balas pos. Anda juga boleh berinteraksi daripada akaun anda pada server lain.", "status.admin_account": "Buka antara muka penyederhanaan untuk @{name}", "status.admin_domain": "antara muka penyederhanaan", "status.admin_status": "Buka hantaran ini dalam antara muka penyederhanaan", @@ -599,7 +621,6 @@ "status.direct": "Sebut secara peribadi @{name}", "status.direct_indicator": "Sebutan peribadi", "status.edit": "Sunting", - "status.edited": "Disunting {date}", "status.edited_x_times": "Disunting {count, plural, other {{count} kali}}", "status.embed": "Benaman", "status.favourite": "Kegemaran", diff --git a/app/javascript/mastodon/locales/my.json b/app/javascript/mastodon/locales/my.json index 0d5985b1ce..e3287f3f32 100644 --- a/app/javascript/mastodon/locales/my.json +++ b/app/javascript/mastodon/locales/my.json @@ -150,9 +150,7 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmation_modal.cancel": "แ€•แ€šแ€บแ€–แ€ปแ€€แ€บแ€™แ€Šแ€บ", - "confirmations.block.block_and_report": "แ€˜แ€œแ€ฑแ€ฌแ€ทแ€•แ€ผแ€ฎแ€ธ แ€แ€ญแ€ฏแ€„แ€บแ€€แ€ผแ€ฌแ€ธแ€™แ€Šแ€บ", "confirmations.block.confirm": "แ€˜แ€œแ€ฑแ€ฌแ€ทแ€™แ€Šแ€บ", - "confirmations.block.message": "แ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€พ แ€‘แ€ฝแ€€แ€บแ€›แ€”แ€บ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธ?", "confirmations.cancel_follow_request.confirm": "แ€•แ€”แ€บแ€€แ€ผแ€ฌแ€ธแ€แ€ปแ€€แ€บแ€€แ€ญแ€ฏ แ€•แ€šแ€บแ€–แ€ปแ€€แ€บแ€™แ€Šแ€บ", "confirmations.cancel_follow_request.message": "{name} แ€€แ€ญแ€ฏ แ€…แ€ฑแ€ฌแ€„แ€ทแ€บแ€€แ€ผแ€Šแ€ทแ€บแ€แ€ผแ€„แ€บแ€ธแ€กแ€ฌแ€ธแ€•แ€šแ€บแ€–แ€ปแ€€แ€บแ€›แ€”แ€บ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธแ‹", "confirmations.delete.confirm": "แ€–แ€ปแ€€แ€บแ€™แ€Šแ€บ", @@ -161,15 +159,12 @@ "confirmations.delete_list.message": "แ€–แ€ปแ€€แ€บแ€›แ€”แ€บ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธ?", "confirmations.discard_edit_media.confirm": "แ€–แ€šแ€บแ€‘แ€ฏแ€แ€บแ€•แ€ซ", "confirmations.discard_edit_media.message": "แ€žแ€„แ€บแ€žแ€Šแ€บ แ€™แ€ฎแ€’แ€ฎแ€šแ€ฌแ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€แ€ปแ€€แ€บ แ€žแ€ญแ€ฏแ€ทแ€™แ€Ÿแ€ฏแ€แ€บ แ€กแ€…แ€™แ€บแ€ธแ€€แ€ผแ€Šแ€ทแ€บแ€›แ€พแ€ฏแ€แ€ผแ€„แ€บแ€ธแ€แ€ฝแ€„แ€บ แ€™แ€žแ€ญแ€™แ€บแ€ธแ€†แ€Šแ€บแ€ธแ€›แ€žแ€ฑแ€ธแ€žแ€ฑแ€ฌ แ€กแ€•แ€ผแ€ฑแ€ฌแ€„แ€บแ€ธแ€กแ€œแ€ฒแ€™แ€ปแ€ฌแ€ธแ€›แ€พแ€ญแ€žแ€Šแ€บแ‹ แ€™แ€Šแ€บแ€žแ€ญแ€ฏแ€ทแ€•แ€„แ€บแ€–แ€ผแ€…แ€บแ€…แ€ฑ แ€–แ€ปแ€€แ€บแ€•แ€…แ€บแ€™แ€Šแ€บแ€œแ€ฌแ€ธแ‹", - "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.message": "{domain} แ€แ€…แ€บแ€แ€ฏแ€œแ€ฏแ€ถแ€ธแ€€แ€ญแ€ฏ แ€˜แ€œแ€ฑแ€ฌแ€ทแ€œแ€ฏแ€•แ€บแ€›แ€”แ€บ แ€แ€€แ€šแ€บ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธ? แ€™แ€ปแ€ฌแ€ธแ€žแ€ฑแ€ฌแ€กแ€ฌแ€ธแ€–แ€ผแ€„แ€บแ€ท แ€กแ€”แ€Šแ€บแ€ธแ€…แ€ฏแ€€แ€ญแ€ฏ แ€•แ€…แ€บแ€™แ€พแ€แ€บแ€‘แ€ฌแ€ธ แ€˜แ€œแ€ฑแ€ฌแ€ทแ€œแ€ฏแ€•แ€บแ€แ€ผแ€„แ€บแ€ธแ€žแ€Šแ€บ แ€œแ€ฏแ€ถแ€œแ€ฑแ€ฌแ€€แ€บแ€•แ€ซแ€žแ€Šแ€บแ‹ แ€‘แ€ญแ€ฏ แ€’แ€ญแ€ฏแ€™แ€ญแ€”แ€บแ€ธแ€™แ€พ แ€กแ€€แ€ผแ€ฑแ€ฌแ€„แ€บแ€ธแ€กแ€›แ€ฌ แ€แ€…แ€บแ€แ€ฏแ€™แ€พ แ€™แ€ผแ€„แ€บแ€›แ€™แ€Šแ€บแ€™แ€Ÿแ€ฏแ€แ€บแ€žแ€Šแ€บแ€ทแ€กแ€•แ€ผแ€„แ€บ แ€‘แ€ญแ€ฏ แ€’แ€ญแ€ฏแ€™แ€ญแ€”แ€บแ€ธแ€แ€ฝแ€„แ€บแ€›แ€พแ€ญแ€žแ€ฑแ€ฌ แ€žแ€„แ€บแ แ€…แ€ฑแ€ฌแ€„แ€บแ€ทแ€€แ€ผแ€Šแ€บแ€ทแ€žแ€ฐแ€™แ€ปแ€ฌแ€ธแ€•แ€ซ แ€–แ€šแ€บแ€›แ€พแ€ฌแ€ธแ€•แ€…แ€บแ€™แ€Šแ€บแ€–แ€ผแ€…แ€บแ€žแ€Šแ€บแ‹", "confirmations.edit.confirm": "แ€•แ€ผแ€„แ€บแ€›แ€”แ€บ", "confirmations.edit.message": "แ€šแ€แ€ฏแ€•แ€ผแ€„แ€บแ€†แ€„แ€บแ€แ€ผแ€„แ€บแ€ธแ€แ€ฝแ€„แ€บ แ€žแ€„แ€บแ€œแ€€แ€บแ€›แ€พแ€ญแ€™แ€€แ€บแ€†แ€ฑแ€ทแ€แ€ปแ€บแ€€แ€ญแ€ฏ แ€–แ€ปแ€€แ€บแ€•แ€…แ€บแ€•แ€ผแ€ฎแ€ธ แ€กแ€žแ€…แ€บแ€›แ€ฑแ€ธแ€•แ€ซแ€™แ€Šแ€บแ‹ แ€›แ€พแ€ฑแ€ทแ€†แ€€แ€บแ€œแ€ญแ€ฏแ€žแ€Šแ€บแ€™แ€พแ€ฌ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธแ‹", "confirmations.logout.confirm": "แ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€พแ€‘แ€ฝแ€€แ€บแ€™แ€Šแ€บ", "confirmations.logout.message": "แ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€พ แ€‘แ€ฝแ€€แ€บแ€›แ€”แ€บ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธ?", "confirmations.mute.confirm": "แ€•แ€ญแ€แ€บแ€‘แ€ฌแ€ธแ€›แ€”แ€บ", - "confirmations.mute.explanation": "แŽแ€„แ€บแ€ธแ€žแ€Šแ€บ แŽแ€„แ€บแ€ธแ€แ€ญแ€ฏแ€ทแ€‘แ€ถแ€™แ€พ แ€•แ€ญแ€ฏแ€ทแ€…แ€บแ€™แ€ปแ€ฌแ€ธแ€”แ€พแ€„แ€ทแ€บ แŽแ€„แ€บแ€ธแ€แ€ญแ€ฏแ€ทแ€€แ€ญแ€ฏ แ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€‘แ€ฌแ€ธแ€žแ€ฑแ€ฌ แ€•แ€ญแ€ฏแ€ทแ€…แ€บแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏ แ€–แ€ปแ€ฑแ€ฌแ€€แ€บแ€‘แ€ฌแ€ธแ€™แ€Šแ€บแ€–แ€ผแ€…แ€บแ€•แ€ผแ€ฎแ€ธแŠ แ€žแ€ญแ€ฏแ€ทแ€žแ€ฑแ€ฌแ€บ แŽแ€„แ€บแ€ธแ€แ€ญแ€ฏแ€ทแ€žแ€Šแ€บ แ€žแ€„แ€ทแ€บแ€•แ€ญแ€ฏแ€ทแ€…แ€บแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏ แ€™แ€ผแ€„แ€บแ€”แ€ญแ€ฏแ€„แ€บแ€•แ€ผแ€ฎแ€ธ แ€žแ€„แ€ทแ€บแ€กแ€ฌแ€ธ แ€œแ€ญแ€ฏแ€€แ€บแ€€แ€ผแ€Šแ€ทแ€บแ€”แ€ญแ€ฏแ€„แ€บแ€…แ€ฑแ€™แ€Šแ€บแ€–แ€ผแ€…แ€บแ€žแ€Šแ€บแ‹", - "confirmations.mute.message": "{name} แ€€แ€ญแ€ฏ แ€™แ€™แ€ผแ€„แ€บแ€œแ€ญแ€ฏแ€žแ€Šแ€บแ€™แ€พแ€ฌ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ซแ€žแ€œแ€ฌแ€ธแ‹ ", "confirmations.redraft.confirm": "แ€–แ€ปแ€€แ€บแ€•แ€ผแ€ฎแ€ธ แ€•แ€ผแ€”แ€บแ€œแ€Šแ€บแ€›แ€ฑแ€ธแ€™แ€Šแ€บแ‹", "confirmations.redraft.message": "แ€žแ€„แ€บ แ€’แ€ฎแ€•แ€ญแ€ฏแ€…แ€บแ€ทแ€€แ€ญแ€ฏแ€–แ€ปแ€€แ€บแ€•แ€ผแ€ฎแ€ธ แ€•แ€ผแ€”แ€บแ€แ€Šแ€บแ€ธแ€–แ€ผแ€แ€บแ€™แ€พแ€ฌ แ€žแ€ฑแ€แ€ปแ€ฌแ€•แ€ผแ€ฎแ€œแ€ฌแ€ธแ‹ แ€€แ€ผแ€šแ€บแ€•แ€ฝแ€„แ€บแ€ทโ€‹แ€แ€ฝแ€ฑ แ€”แ€ฒแ€ท แ€•แ€ผแ€”แ€บแ€™แ€ปแ€พโ€‹แ€แ€ฑแ€™แ€พแ€ฏโ€‹แ€แ€ฝแ€ฑแ€€แ€ญแ€ฏแ€†แ€ฏแ€ถแ€ธแ€›แ€พแ€ฏแ€ถแ€ธแ€™แ€Šแ€บแ‹แ€™แ€ฐแ€›แ€„แ€บแ€ธแ€•แ€ญแ€ฏแ€ทแ€…แ€บแ€†แ€ฎแ€€แ€ญแ€ฏ แ€•แ€ผแ€”แ€บแ€…แ€ฌโ€‹แ€แ€ฝแ€ฑแ€™แ€พแ€ฌแ€œแ€Šแ€บแ€ธโ€‹ \nแ€•แ€ญแ€ฏแ€…แ€บแ€ทแ€€แ€ญแ€ฏโ€‹แ€แ€ฝแ€ฑแ€ทแ€›แ€™แ€Šแ€บแ€™แ€Ÿแ€ฏแ€แ€บโ€‹แ€แ€ฑแ€ฌแ€ทแ€•แ€ซแ‹.", "confirmations.reply.confirm": "แ€…แ€ฌแ€•แ€ผแ€”แ€บแ€™แ€Šแ€บ", @@ -292,7 +287,6 @@ "hashtag.follow": "Hashtag แ€€แ€ญแ€ฏ แ€…แ€ฑแ€ฌแ€„แ€ทแ€บแ€€แ€ผแ€Šแ€ทแ€บแ€™แ€šแ€บ", "hashtag.unfollow": "Hashtag แ€€แ€ญแ€ฏ แ€™แ€…แ€ฑแ€ฌแ€„แ€ทแ€บแ€€แ€ผแ€Šแ€ทแ€บแ€•แ€ซ", "hashtags.and_other": "{count, plural, other {# more}} แ€”แ€พแ€„แ€บแ€ท", - "home.column_settings.basic": "แ€กแ€แ€ผแ€ฑแ€แ€ถ", "home.column_settings.show_reblogs": "Boost แ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏ แ€•แ€ผแ€•แ€ซ", "home.column_settings.show_replies": "แ€•แ€ผแ€”แ€บแ€…แ€ฌแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏ แ€•แ€ผแ€•แ€ซ", "home.hide_announcements": "แ€€แ€ผแ€ฑแ€Šแ€ฌแ€แ€ปแ€€แ€บแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏ แ€–แ€ปแ€ฑแ€ฌแ€€แ€บแ€•แ€ซ", @@ -378,9 +372,6 @@ "loading_indicator.label": "แ€œแ€ฏแ€•แ€บแ€†แ€ฑแ€ฌแ€„แ€บแ€”แ€ฑแ€žแ€Šแ€บโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "{movedToAccount} แ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€žแ€ญแ€ฏแ€ทแ€•แ€ผแ€ฑแ€ฌแ€„แ€บแ€ธแ€œแ€ฒแ€‘แ€ฌแ€ธแ€žแ€–แ€ผแ€„แ€บแ€ท {disabledAccount} แ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€พแ€ฌแ€•แ€ญแ€แ€บแ€‘แ€ฌแ€ธแ€žแ€Šแ€บ", - "mute_modal.duration": "แ€€แ€ผแ€ฌแ€แ€ปแ€ญแ€”แ€บ", - "mute_modal.hide_notifications": "แ€คแ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€พแ€žแ€แ€ญแ€•แ€ฑแ€ธแ€แ€ปแ€€แ€บแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏแ€•แ€ญแ€แ€บแ€™แ€œแ€ฌแ€ธ?", - "mute_modal.indefinite": "แ€›แ€ฑแ€แ€ฝแ€€แ€บแ€œแ€ญแ€ฏแ€ทแ€™แ€›แ€•แ€ซ", "navigation_bar.about": "แ€กแ€€แ€ผแ€ฑแ€ฌแ€„แ€บแ€ธ", "navigation_bar.advanced_interface": "แ€กแ€†แ€„แ€ทแ€บแ€™แ€ผแ€„แ€ทแ€บแ€แ€˜แ€บแ€•แ€ฏแ€ถแ€…แ€ถ แ€–แ€ฝแ€„แ€บแ€ทแ€•แ€ซ", "navigation_bar.blocks": "แ€˜แ€œแ€ฑแ€ฌแ€ทแ€‘แ€ฌแ€ธแ€žแ€ฑแ€ฌแ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€™แ€ปแ€ฌแ€ธ", @@ -424,9 +415,6 @@ "notifications.column_settings.admin.sign_up": "แ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€กแ€žแ€…แ€บแ€™แ€ปแ€ฌแ€ธ -", "notifications.column_settings.alert": "Desktop แ€žแ€แ€ญแ€•แ€ฑแ€ธแ€แ€ปแ€€แ€บแ€™แ€ปแ€ฌแ€ธ", "notifications.column_settings.favourite": "Favorites:", - "notifications.column_settings.filter_bar.advanced": "แ€แ€ฑแ€ซแ€„แ€บแ€ธแ€…แ€ฅแ€บแ€กแ€ฌแ€ธแ€œแ€ฏแ€ถแ€ธแ€™แ€ปแ€ฌแ€ธแ€€แ€ญแ€ฏแ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€•แ€ซ", - "notifications.column_settings.filter_bar.category": "แ€กแ€™แ€ผแ€”แ€บแ€…แ€…แ€บแ€‘แ€ฏแ€แ€บแ€™แ€พแ€ฏแ€˜แ€ฌแ€ธ", - "notifications.column_settings.filter_bar.show_bar": "แ€…แ€…แ€บแ€‘แ€ฏแ€แ€บแ€™แ€พแ€ฏแ€˜แ€ฌแ€ธแ€€แ€ญแ€ฏ แ€•แ€ผแ€•แ€ซ", "notifications.column_settings.follow": "แ€…แ€ฑแ€ฌแ€„แ€ทแ€บแ€€แ€ผแ€Šแ€ทแ€บแ€žแ€ฐแ€กแ€žแ€…แ€บแ€™แ€ปแ€ฌแ€ธ -", "notifications.column_settings.follow_request": "แ€…แ€ฑแ€ฌแ€„แ€ทแ€บแ€€แ€ผแ€Šแ€ทแ€บแ€›แ€”แ€บ แ€แ€ฑแ€ฌแ€„แ€บแ€ธแ€†แ€ญแ€ฏแ€™แ€พแ€ฏแ€กแ€žแ€…แ€บแ€™แ€ปแ€ฌแ€ธ -", "notifications.column_settings.mention": "แ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€แ€ปแ€€แ€บแ€™แ€ปแ€ฌแ€ธ -", @@ -594,13 +582,10 @@ "server_banner.about_active_users": "แ€•แ€ผแ€ฎแ€ธแ€แ€ฒแ€ทแ€žแ€Šแ€ทแ€บ แ€›แ€€แ€บแ€•แ€ฑแ€ซแ€„แ€บแ€ธ แƒแ€ แ€กแ€แ€ฝแ€„แ€บแ€ธ แ€คแ€†แ€ฌแ€—แ€ฌแ€€แ€ญแ€ฏ แ€กแ€žแ€ฏแ€ถแ€ธแ€•แ€ผแ€ฏแ€žแ€ฐแ€™แ€ปแ€ฌแ€ธ (แ€œแ€กแ€œแ€ญแ€ฏแ€€แ€บ แ€œแ€€แ€บแ€›แ€พแ€ญแ€กแ€žแ€ฏแ€ถแ€ธแ€•แ€ผแ€ฏแ€žแ€ฐแ€™แ€ปแ€ฌแ€ธ)", "server_banner.active_users": "แ€œแ€€แ€บแ€›แ€พแ€ญแ€กแ€žแ€ฏแ€ถแ€ธแ€•แ€ผแ€ฏแ€žแ€ฐแ€™แ€ปแ€ฌแ€ธ", "server_banner.administered_by": "แ€™แ€พ แ€…แ€ฎแ€™แ€ถแ€แ€”แ€ทแ€บแ€แ€ฝแ€ฒแ€žแ€Šแ€บ -", - "server_banner.introduction": "{domain} แ€žแ€Šแ€บ {mastodon} แ€™แ€พ แ€•แ€ถแ€ทแ€•แ€ญแ€ฏแ€ธแ€•แ€ฑแ€ธแ€‘แ€ฌแ€ธแ€žแ€ฑแ€ฌ แ€—แ€Ÿแ€ญแ€ฏแ€แ€ปแ€ฏแ€•แ€บแ€€แ€ญแ€ฏแ€„แ€บแ€™แ€พแ€ฏแ€™แ€›แ€พแ€ญแ€žแ€Šแ€ทแ€บ แ€œแ€ฐแ€™แ€พแ€ฏแ€€แ€ฝแ€”แ€บแ€›แ€€แ€บแ€แ€…แ€บแ€แ€ฏแ€–แ€ผแ€…แ€บแ€žแ€Šแ€บแ‹", - "server_banner.learn_more": "แ€•แ€ญแ€ฏแ€™แ€ญแ€ฏแ€žแ€ญแ€›แ€พแ€ญแ€›แ€”แ€บ", "server_banner.server_stats": "แ€†แ€ฌแ€—แ€ฌแ€กแ€ฌแ€ธ แ€œแ€€แ€บแ€›แ€พแ€ญแ€กแ€žแ€ฏแ€ถแ€ธแ€•แ€ผแ€ฏแ€žแ€ฐแ€™แ€ปแ€ฌแ€ธ -", "sign_in_banner.create_account": "แ€กแ€€แ€ฑแ€ฌแ€„แ€บแ€ทแ€–แ€”แ€บแ€แ€ฎแ€ธแ€™แ€Šแ€บ", "sign_in_banner.sign_in": "แ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€แ€„แ€บแ€™แ€Šแ€บ", "sign_in_banner.sso_redirect": "แ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€แ€„แ€บแ€•แ€ซ แ€žแ€ญแ€ฏแ€ทแ€™แ€Ÿแ€ฏแ€แ€บ แ€™แ€พแ€แ€บแ€•แ€ฏแ€ถแ€แ€„แ€บแ€•แ€ซ", - "sign_in_banner.text": "แ€•แ€›แ€ญแ€ฏแ€–แ€ญแ€ฏแ€„แ€บแ€™แ€ปแ€ฌแ€ธ แ€žแ€ญแ€ฏแ€ทแ€™แ€Ÿแ€ฏแ€แ€บ hashtag แ€™แ€ปแ€ฌแ€ธแŠ favoriteแŠ แ€•แ€ญแ€ฏแ€ทแ€…แ€บแ€™แ€ปแ€พแ€แ€ฑแ€™แ€พแ€ฏแ€™แ€ปแ€ฌแ€ธแ€”แ€พแ€„แ€บแ€ท แ€•แ€ผแ€”แ€บแ€€แ€ผแ€ฌแ€ธแ€…แ€ฌแ€™แ€ปแ€ฌแ€ธแ€กแ€žแ€ฏแ€ถแ€ธแ€•แ€ผแ€ฏแ€›แ€”แ€บแ€กแ€แ€ฝแ€€แ€บ แ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€แ€„แ€บแ€•แ€ซแ‹ แ€กแ€แ€ผแ€ฌแ€ธแ€†แ€ฌแ€—แ€ฌแ€•แ€ฑแ€ซแ€บแ€›แ€พแ€ญ แ€žแ€„แ€ทแ€บแ€กแ€€แ€ฑแ€ฌแ€„แ€ทแ€บแ€™แ€พแ€œแ€Šแ€บแ€ธ แ€กแ€•แ€ผแ€”แ€บแ€กแ€œแ€พแ€”แ€บแ€–แ€œแ€พแ€šแ€บแ€”แ€ญแ€ฏแ€„แ€บแ€•แ€ซแ€žแ€Šแ€บแ‹", "status.admin_account": "@{name} แ€กแ€แ€ฝแ€€แ€บ แ€…แ€ญแ€…แ€…แ€บแ€แ€ผแ€„แ€บแ€ธแ€€แ€ผแ€ฌแ€ธแ€แ€ถแ€”แ€šแ€บแ€€แ€ญแ€ฏ แ€–แ€ฝแ€„แ€ทแ€บแ€•แ€ซ", "status.admin_domain": "{domain} แ€กแ€แ€ฝแ€€แ€บ แ€…แ€ญแ€…แ€…แ€บแ€แ€ผแ€„แ€บแ€ธแ€€แ€ผแ€ฌแ€ธแ€แ€ถแ€”แ€šแ€บแ€€แ€ญแ€ฏ แ€–แ€ฝแ€„แ€ทแ€บแ€•แ€ซ", "status.admin_status": "Open this status in the moderation interface", @@ -614,7 +599,6 @@ "status.direct": "@{name} แ€€แ€ญแ€ฏ แ€žแ€ฎแ€ธแ€žแ€”แ€ทแ€บแ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€™แ€Šแ€บ\n", "status.direct_indicator": "แ€žแ€ฎแ€ธแ€žแ€”แ€ทแ€บแ€–แ€ฑแ€ฌแ€บแ€•แ€ผแ€แ€ผแ€„แ€บแ€ธแ‹", "status.edit": "แ€•แ€ผแ€„แ€บแ€†แ€„แ€บแ€›แ€”แ€บ", - "status.edited": "{date} แ€€แ€ญแ€ฏ แ€•แ€ผแ€„แ€บแ€†แ€„แ€บแ€•แ€ผแ€ฎแ€ธแ€•แ€ซแ€•แ€ผแ€ฎ", "status.edited_x_times": "{count, plural, one {{count} time} other {{count} times}} แ€•แ€ผแ€„แ€บแ€†แ€„แ€บแ€แ€ฒแ€ทแ€žแ€Šแ€บ", "status.embed": "Embed", "status.favourite": "Favorite", diff --git a/app/javascript/mastodon/locales/ne.json b/app/javascript/mastodon/locales/ne.json index 86e24a15fb..500261a34b 100644 --- a/app/javascript/mastodon/locales/ne.json +++ b/app/javascript/mastodon/locales/ne.json @@ -50,6 +50,12 @@ "admin.dashboard.retention.cohort_size": "เคจเคฏเคพเค เคชเฅเคฐเคฏเฅ‹เค—เค•เคฐเฅเคคเคพเคนเคฐเฅ‚", "alert.rate_limited.message": "เค•เฅƒเคชเคฏเคพ {retry_time, time, medium} เคชเค›เคฟ เคชเฅเคจ: เคชเฅเคฐเคฏเคพเคธ เค—เคฐเฅเคจเฅเคนเฅ‹เคธเฅเฅค", "alert.unexpected.message": "เคเค‰เคŸเคพ เค…เคจเคชเฅ‡เค•เฅเคทเคฟเคค เคคเฅเคฐเฅเคŸเคฟ เคญเคฏเฅ‹เฅค", + "announcement.announcement": "เค˜เฅ‹เคทเคฃเคพ", + "block_modal.remote_users_caveat": "เคนเคพเคฎเฅ€ เคธเคฐเฅเคญเคฐ {domain} เคฒเคพเคˆ เคคเคชเคพเคˆเค‚เค•เฅ‹ เคจเคฟเคฐเฅเคฃเคฏเค•เฅ‹ เคธเคฎเฅเคฎเคพเคจ เค—เคฐเฅเคจ เคธเฅ‹เคงเฅเคจเฅ‡เค›เฅŒเค‚เฅค เคคเคฐ, เคนเคพเคฎเฅ€ เค…เคจเฅเคชเคพเคฒเคจเค•เฅ‹ เค—เฅเคฏเคพเคฐเฅ‡เคจเฅเคŸเฅ€ เคฆเคฟเคจ เคธเค•เฅเคฆเฅˆเคจเฅŒเค‚ เค•เคฟเคจเคญเคจเฅ‡ เค•เฅ‡เคนเฅ€ เคธเคฐเฅเคญเคฐเคนเคฐเฅ‚เคฒเฅ‡ เคฌเฅเคฒเค•เคนเคฐเฅ‚ เคซเคฐเค• เคฐเฅ‚เคชเคฎเคพ เคนเฅเคฏเคพเคจเฅเคกเคฒ เค—เคฐเฅเคจ เคธเค•เฅเค›เคจเฅเฅค เคธเคพเคฐเฅเคตเคœเคจเคฟเค• เคชเฅ‹เคธเฅเคŸเคนเคฐเฅ‚ เคฒเค— เค‡เคจ เคจเคญเคเค•เคพ เคชเฅเคฐเคฏเฅ‹เค—เค•เคฐเฅเคคเคพเคนเคฐเฅ‚เคฒเฅ‡ เคฆเฅ‡เค–เฅเคจ เคธเค•เฅเค›เคจเฅเฅค", + "block_modal.show_less": "เค•เคฎ เคฆเฅ‡เค–เคพเค‰เคจเฅเคนเฅ‹เคธเฅ", + "block_modal.show_more": "เคฅเคช เคฆเฅ‡เค–เคพเค‰เคจเฅเคนเฅ‹เคธเฅ", + "bundle_column_error.copy_stacktrace": "เคคเฅเคฐเฅเคŸเคฟ เคฐเคฟเคชเฅ‹เคฐเฅเคŸ เคชเฅเคฐเคคเคฟเคฒเคฟเคชเคฟ เค—เคฐเฅเคจเฅเคนเฅ‹เคธเฅ", + "bundle_column_error.network.title": "เคจเฅ‡เคŸเคตเคฐเฅเค• เคคเฅเคฐเฅเคŸเคฟ", "bundle_column_error.retry": "เคชเฅเคจ: เคชเฅเคฐเคฏเคพเคธ เค—เคฐเฅเคจเฅเคนเฅ‹เคธเฅ", "bundle_modal_error.close": "เคฌเคจเฅเคฆ เค—เคฐเฅเคจเฅเคนเฅ‹เคธเฅ", "bundle_modal_error.message": "เคฏเฅ‹ เค•เคฎเฅเคชเฅ‹เคจเฅ‡เคจเฅเคŸ เคฒเฅ‹เคก เค—เคฐเฅเคฆเคพ เค•เฅ‡เคนเฅ€ เค—เคกเคฌเคก เคญเคฏเฅ‹เฅค", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 24099f2d33..8246d8dfd2 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -89,6 +89,14 @@ "announcement.announcement": "Mededeling", "attachments_list.unprocessed": "(niet verwerkt)", "audio.hide": "Audio verbergen", + "block_modal.remote_users_caveat": "We vragen de server {domain} om je besluit te respecteren. Het naleven hiervan is echter niet gegarandeerd, omdat sommige servers blokkades anders kunnen interpreteren. Openbare berichten zijn mogelijk nog steeds zichtbaar voor niet-ingelogde gebruikers.", + "block_modal.show_less": "Minder tonen", + "block_modal.show_more": "Meer tonen", + "block_modal.they_cant_mention": "De persoon kan jou niet vermelden of volgen.", + "block_modal.they_cant_see_posts": "De persoon kan jouw berichten niet zien en jij ook niet diens berichten.", + "block_modal.they_will_know": "De persoon kan zien dat die wordt geblokkeerd.", + "block_modal.title": "Gebruiker blokkeren?", + "block_modal.you_wont_see_mentions": "Je ziet geen berichten meer die dit account vermelden.", "boost_modal.combo": "Je kunt {combo} klikken om dit de volgende keer over te slaan", "bundle_column_error.copy_stacktrace": "Foutrapportage kopiรซren", "bundle_column_error.error.body": "De opgevraagde pagina kon niet worden weergegeven. Dit kan het gevolg zijn van een fout in onze broncode, of van een compatibiliteitsprobleem met je webbrowser.", @@ -113,7 +121,7 @@ "column.community": "Lokale tijdlijn", "column.direct": "Privรฉberichten", "column.directory": "Gebruikersgids", - "column.domain_blocks": "Geblokkeerde domeinen", + "column.domain_blocks": "Geblokkeerde servers", "column.favourites": "Favorieten", "column.firehose": "Openbare tijdlijnen", "column.follow_requests": "Volgverzoeken", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Inhoudswaarschuwing toevoegen", "compose_form.spoiler_placeholder": "Inhoudswaarschuwing (optioneel)", "confirmation_modal.cancel": "Annuleren", - "confirmations.block.block_and_report": "Blokkeren en rapporteren", "confirmations.block.confirm": "Blokkeren", - "confirmations.block.message": "Weet je het zeker dat je {name} wilt blokkeren?", "confirmations.cancel_follow_request.confirm": "Verzoek annuleren", "confirmations.cancel_follow_request.message": "Weet je zeker dat je jouw verzoek om {name} te volgen wilt annuleren?", "confirmations.delete.confirm": "Verwijderen", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?", "confirmations.discard_edit_media.confirm": "Weggooien", "confirmations.discard_edit_media.message": "Je hebt niet-opgeslagen wijzigingen in de mediabeschrijving of voorvertonning, wil je deze toch weggooien?", - "confirmations.domain_block.confirm": "Blokkeer alles van deze server", - "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt blokkeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen berichten van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", + "confirmations.domain_block.confirm": "Server blokkeren", + "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt blokkeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je ziet geen berichten van deze server meer op openbare tijdlijnen of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", "confirmations.edit.confirm": "Bewerken", "confirmations.edit.message": "Door nu te reageren overschrijf je het bericht dat je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?", "confirmations.logout.confirm": "Uitloggen", "confirmations.logout.message": "Weet je zeker dat je wilt uitloggen?", "confirmations.mute.confirm": "Negeren", - "confirmations.mute.explanation": "Dit verbergt diens berichten en berichten waar diegene in wordt vermeld, maar diegene kan nog steeds jouw berichten bekijken en jou volgen.", - "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?", "confirmations.redraft.confirm": "Verwijderen en herschrijven", "confirmations.redraft.message": "Weet je zeker dat je dit bericht wilt verwijderen en herschrijven? Je verliest wel de boosts en favorieten, en de reacties op het originele bericht raak je kwijt.", "confirmations.reply.confirm": "Reageren", @@ -201,10 +205,31 @@ "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.", + "domain_block_modal.they_cant_follow": "Niemand op deze server kan jou volgen.", + "domain_block_modal.they_wont_know": "Ze krijgen niet te weten dat ze worden geblokkeerd.", + "domain_block_modal.title": "Server blokkeren?", + "domain_block_modal.you_will_lose_followers": "Al jouw volgers van deze server worden ontvolgd.", + "domain_block_modal.you_wont_see_posts": "Je ziet geen berichten of meldingen meer van gebruikers op deze server.", + "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 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 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.", "embed.preview": "Zo komt het eruit te zien:", "emoji_button.activity": "Activiteiten", @@ -229,18 +254,19 @@ "empty_column.blocks": "Je hebt nog geen gebruikers geblokkeerd.", "empty_column.bookmarked_statuses": "Jij hebt nog geen berichten aan je bladwijzers toegevoegd. Wanneer je er een aan jouw bladwijzers toevoegt, valt deze hier te zien.", "empty_column.community": "De lokale tijdlijn is nog leeg. Plaats een openbaar bericht om de spits af te bijten!", - "empty_column.direct": "Je hebt nog geen privรฉberichten. Wanneer je er een verstuurt of ontvangt, zullen deze hier verschijnen.", - "empty_column.domain_blocks": "Er zijn nog geen geblokkeerde domeinen.", + "empty_column.direct": "Je hebt nog geen privรฉberichten. Wanneer je er een verstuurt of ontvangt, komen deze hier te staan.", + "empty_column.domain_blocks": "Er zijn nog geen geblokkeerde servers.", "empty_column.explore_statuses": "Momenteel zijn er geen trends. Kom later terug!", "empty_column.favourited_statuses": "Jij hebt nog geen favoriete berichten. Wanneer je een bericht als favoriet markeert, valt deze hier te zien.", "empty_column.favourites": "Niemand heeft dit bericht nog als favoriet gemarkeerd. Wanneer iemand dit doet, valt dat hier te zien.", - "empty_column.follow_requests": "Je hebt nog geen volgverzoeken. Wanneer je er een ontvangt, zal dat hier te zien zijn.", - "empty_column.followed_tags": "Je hebt nog geen hashtags gevolgd. Wanneer je dit doet, zullen ze hier verschijnen.", + "empty_column.follow_requests": "Jij hebt nog enkel volgverzoek ontvangen. Wanneer je er eentje ontvangt, valt dat hier te zien.", + "empty_column.followed_tags": "Je hebt nog geen hashtags gevolgd. Nadat je dit doet, komen deze hier te staan.", "empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.", "empty_column.home": "Deze tijdlijn is leeg! Volg meer mensen om het te vullen.", "empty_column.list": "Er is nog niks te zien in deze lijst. Wanneer lijstleden nieuwe berichten plaatsen, zijn deze hier te zien.", - "empty_column.lists": "Je hebt nog geen lijsten. Wanneer je er een aanmaakt, zal dat hier verschijnen.", + "empty_column.lists": "Je hebt nog geen lijsten. Wanneer je er een aanmaakt, valt dat hier te zien.", "empty_column.mutes": "Jij hebt nog geen gebruikers genegeerd.", + "empty_column.notification_requests": "Helemaal leeg! Er is hier niets. Wanneer je nieuwe meldingen ontvangt, verschijnen deze hier volgens jouw instellingen.", "empty_column.notifications": "Je hebt nog geen meldingen. Begin met iemand een gesprek.", "empty_column.public": "Er is hier helemaal niks! Plaatst een openbaar bericht of volg mensen van andere servers om het te vullen", "error.unexpected_crash.explanation": "Als gevolg van een bug in onze broncode of als gevolg van een compatibiliteitsprobleem met jouw webbrowser, kan deze pagina niet goed worden weergegeven.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Deze server", "firehose.remote": "Andere servers", "follow_request.authorize": "Goedkeuren", "follow_request.reject": "Afwijzen", "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": "Keuze van de moderator(en)", + "follow_suggestions.curated_suggestion": "Speciaal geselecteerd", "follow_suggestions.dismiss": "Niet meer weergeven", + "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Hashtag volgen", "hashtag.unfollow": "Hashtag ontvolgen", "hashtags.and_other": "โ€ฆen {count, plural, one {}other {# meer}}", - "home.column_settings.basic": "Algemeen", "home.column_settings.show_reblogs": "Boosts tonen", "home.column_settings.show_replies": "Reacties tonen", "home.hide_announcements": "Mededelingen verbergen", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Alsnog het profiel tonen", "limited_account_hint.title": "Dit profiel is door de moderatoren van {domain} verborgen.", "link_preview.author": "Door {name}", + "link_preview.more_from_author": "Meer van {name}", + "link_preview.shares": "{count, plural, one {{counter} bericht} other {{counter} berichten}}", "lists.account.add": "Aan lijst toevoegen", "lists.account.remove": "Uit lijst verwijderen", "lists.delete": "Lijst verwijderen", @@ -395,9 +434,15 @@ "loading_indicator.label": "Ladenโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {afbeelding verbergen} other {afbeeldingen verbergen}}", "moved_to_account_banner.text": "Omdat je naar {movedToAccount} bent verhuisd is jouw account {disabledAccount} momenteel uitgeschakeld.", - "mute_modal.duration": "Tijdsduur", - "mute_modal.hide_notifications": "Verberg meldingen van deze persoon?", - "mute_modal.indefinite": "Voor onbepaalde tijd", + "mute_modal.hide_from_notifications": "Onder meldingen verbergen", + "mute_modal.hide_options": "Opties verbergen", + "mute_modal.indefinite": "Totdat ik ze niet meer negeer", + "mute_modal.show_options": "Opties tonen", + "mute_modal.they_can_mention_and_follow": "De persoon kan jou vermelden en volgen, maar jij ziet niks meer van deze persoon.", + "mute_modal.they_wont_know": "De persoon krijgt niet te weten dat die wordt genegeerd.", + "mute_modal.title": "Gebruiker negeren?", + "mute_modal.you_wont_see_mentions": "Je ziet geen berichten meer die dit account vermelden.", + "mute_modal.you_wont_see_posts": "De persoon kan nog steeds jouw berichten zien, maar diens berichten zie je niet meer.", "navigation_bar.about": "Over", "navigation_bar.advanced_interface": "In geavanceerde webinterface openen", "navigation_bar.blocks": "Geblokkeerde gebruikers", @@ -406,7 +451,7 @@ "navigation_bar.compose": "Nieuw bericht schrijven", "navigation_bar.direct": "Privรฉberichten", "navigation_bar.discover": "Ontdekken", - "navigation_bar.domain_blocks": "Geblokkeerde domeinen", + "navigation_bar.domain_blocks": "Geblokkeerde servers", "navigation_bar.explore": "Verkennen", "navigation_bar.favourites": "Favorieten", "navigation_bar.filters": "Filters", @@ -430,11 +475,29 @@ "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.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", + "notification_requests.dismiss": "Afwijzen", + "notification_requests.notifications_from": "Meldingen van {name}", + "notification_requests.title": "Gefilterde meldingen", "notifications.clear": "Meldingen verwijderen", "notifications.clear_confirmation": "Weet je het zeker dat je al jouw meldingen wilt verwijderen?", "notifications.column_settings.admin.report": "Nieuwe rapportages:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Filterbalk tonen", "notifications.column_settings.follow": "Nieuwe volgers:", "notifications.column_settings.follow_request": "Nieuw volgverzoek:", "notifications.column_settings.mention": "Vermeldingen:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Desktopmeldingen zijn niet beschikbaar omdat een eerdere browsertoestemming werd geweigerd", "notifications.permission_denied_alert": "Desktopmeldingen kunnen niet worden ingeschakeld, omdat een eerdere browsertoestemming werd geweigerd", "notifications.permission_required": "Desktopmeldingen zijn niet beschikbaar omdat de benodigde toestemming niet is verleend.", + "notifications.policy.filter_new_accounts.hint": "In de afgelopen {days, plural, one {24 uur} other {# dagen}} geregistreerd", + "notifications.policy.filter_new_accounts_title": "Nieuwe accounts", + "notifications.policy.filter_not_followers_hint": "Inclusief mensen die jou korter dan {days, plural, one {24 uur} other {# dagen}} volgen", + "notifications.policy.filter_not_followers_title": "Mensen die jou niet volgen", + "notifications.policy.filter_not_following_hint": "Totdat je ze handmatig goedkeurt", + "notifications.policy.filter_not_following_title": "Mensen die jij niet volgt", + "notifications.policy.filter_private_mentions_hint": "Onzichtbaar tenzij het een antwoord is op een privรฉbericht van jou of wanneer je de afzender volgt", + "notifications.policy.filter_private_mentions_title": "Ongevraagde privรฉberichten", + "notifications.policy.title": "Meldingen verbergen vanโ€ฆ", "notifications_permission_banner.enable": "Desktopmeldingen inschakelen", "notifications_permission_banner.how_to_control": "Om meldingen te ontvangen wanneer Mastodon niet open staat. Je kunt precies bepalen welke soort interacties wel of geen desktopmeldingen geven via de bovenstaande {icon} knop.", "notifications_permission_banner.title": "Mis nooit meer iets", @@ -478,7 +549,7 @@ "onboarding.actions.go_to_home": "Ga naar je starttijdlijn", "onboarding.compose.template": "Hallo #Mastodon!", "onboarding.follows.empty": "Helaas kunnen op dit moment geen resultaten worden getoond. Je kunt proberen te zoeken of op de verkenningspagina te bladeren om mensen te vinden die je kunt volgen, of probeer het later opnieuw.", - "onboarding.follows.lead": "Jouw starttijdlijn is de belangrijkste manier om Mastodon te ervaren. Hoe meer mensen je volgt, hoe actiever en interessanter het zal zijn. Om te beginnen, zijn hier enkele suggesties:", + "onboarding.follows.lead": "Jouw starttijdlijn is de belangrijkste manier om Mastodon te ervaren. Hoe meer mensen je volgt, hoe actiever en interessanter het wordt. Om te beginnen zijn hier enkele suggesties:", "onboarding.follows.title": "Je starttijdlijn aan jouw wensen aanpassen", "onboarding.profile.discoverable": "Maak mijn profiel vindbaar", "onboarding.profile.discoverable_hint": "Wanneer je akkoord gaat met het vindbaar zijn op Mastodon, verschijnen je berichten in zoekresultaten en kunnen ze trending worden, en je profiel kan aan andere mensen worden aanbevolen wanneer ze vergelijkbare interesses hebben.", @@ -502,7 +573,7 @@ "onboarding.steps.follow_people.title": "Je starttijdlijn aan jouw wensen aanpassen", "onboarding.steps.publish_status.body": "Zeg hallo tegen de wereld met tekst, foto's, video's of peilingen {emoji}", "onboarding.steps.publish_status.title": "Maak je eerste bericht", - "onboarding.steps.setup_profile.body": "Anderen zullen eerder met je in contact treden als je wat over jezelf vertelt.", + "onboarding.steps.setup_profile.body": "Wanneer je meer over jezelf vertelt, krijg je meer interactie met andere mensen.", "onboarding.steps.setup_profile.title": "Je profiel aanpassen", "onboarding.steps.share_profile.body": "Laat je vrienden weten waar je te vinden bent op Mastodon", "onboarding.steps.share_profile.title": "Deel je Mastodonprofiel", @@ -524,13 +595,13 @@ "poll_button.add_poll": "Peiling toevoegen", "poll_button.remove_poll": "Peiling verwijderen", "privacy.change": "Zichtbaarheid van bericht aanpassen", - "privacy.direct.long": "Iedereen die in het bericht wordt vermeld", - "privacy.direct.short": "Bepaalde mensen", + "privacy.direct.long": "Alleen voor mensen die specifiek in het bericht worden vermeld", + "privacy.direct.short": "Privรฉbericht", "privacy.private.long": "Alleen jouw volgers", "privacy.private.short": "Volgers", "privacy.public.long": "Iedereen op Mastodon en daarbuiten", "privacy.public.short": "Openbaar", - "privacy.unlisted.additional": "Dit is vergelijkbaar met openbaar, behalve dat het beticht niet verschijnt op openbare tijdlijnen of hashtags, onder verkennen of Mastodon zoeken, zelfs als je je account daarvoor hebt ingesteld.", + "privacy.unlisted.additional": "Dit is vergelijkbaar met openbaar, behalve dat het bericht niet op openbare tijdlijnen, onder hashtags, verkennen of zoeken verschijnt, zelfs als je je account daarvoor hebt ingesteld.", "privacy.unlisted.long": "Voor iedereen zichtbaar, maar niet onder trends, hashtags en op openbare tijdlijnen", "privacy.unlisted.short": "Minder openbaar", "privacy_policy.last_updated": "Laatst bijgewerkt op {date}", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Aantal gebruikers tijdens de afgelopen 30 dagen (MAU)", "server_banner.active_users": "actieve gebruikers", "server_banner.administered_by": "Beheerd door:", - "server_banner.introduction": "{domain} is onderdeel van het decentrale sociale netwerk {mastodon}.", - "server_banner.learn_more": "Meer leren", + "server_banner.is_one_of_many": "{domain} is een van de vele onafhankelijke Mastodon-servers die je kunt gebruiken om deel te nemen aan de fediverse.", "server_banner.server_stats": "Serverstats:", "sign_in_banner.create_account": "Registreren", + "sign_in_banner.follow_anyone": "Volg iedereen in de fediverse en zie het allemaal in chronologische volgorde. Geen algoritmes, advertenties of clickbaits.", + "sign_in_banner.mastodon_is": "Mastodon is de beste manier om wat er gebeurt bij te houden.", "sign_in_banner.sign_in": "Inloggen", "sign_in_banner.sso_redirect": "Inloggen of Registreren", - "sign_in_banner.text": "Wanneer je een account op deze server hebt, kun je inloggen om mensen of hashtags te volgen, op berichten te reageren of om deze te delen. Wanneer je een account op een andere server hebt, kun je daar inloggen en daar ook interactie met mensen op deze server hebben.", "status.admin_account": "Moderatie-omgeving van @{name} openen", "status.admin_domain": "Moderatie-omgeving van {domain} openen", "status.admin_status": "Dit bericht in de moderatie-omgeving tonen", @@ -645,10 +716,11 @@ "status.direct": "@{name} een privรฉbericht sturen", "status.direct_indicator": "Privรฉbericht", "status.edit": "Bewerken", - "status.edited": "Bewerkt op {date}", + "status.edited": "Laatste bewerking op {date}", "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.filter": "Dit bericht filteren", "status.filtered": "Gefilterd", "status.hide": "Bericht verbergen", @@ -661,7 +733,7 @@ "status.mention": "@{name} vermelden", "status.more": "Meer", "status.mute": "@{name} negeren", - "status.mute_conversation": "Negeer gesprek", + "status.mute_conversation": "Gesprek negeren", "status.open": "Volledig bericht tonen", "status.pin": "Aan profielpagina vastmaken", "status.pinned": "Vastgemaakt bericht", @@ -669,12 +741,13 @@ "status.reblog": "Boosten", "status.reblog_private": "Boost naar oorspronkelijke ontvangers", "status.reblogged_by": "{name} boostte", + "status.reblogs": "{count, plural, one {boost} other {boosts}}", "status.reblogs.empty": "Niemand heeft dit bericht nog geboost. Wanneer iemand dit doet, valt dat hier te zien.", "status.redraft": "Verwijderen en herschrijven", "status.remove_bookmark": "Bladwijzer verwijderen", "status.replied_to": "Reageerde op {name}", "status.reply": "Reageren", - "status.replyAll": "Reageer op iedereen", + "status.replyAll": "Op iedereen reageren", "status.report": "@{name} rapporteren", "status.sensitive_warning": "Gevoelige inhoud", "status.share": "Delen", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 2118eb5739..93b44f29a1 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -32,7 +32,7 @@ "account.featured_tags.last_status_never": "Ingen innlegg", "account.featured_tags.title": "{name} sine framheva emneknaggar", "account.follow": "Fylg", - "account.follow_back": "Fรธlg tilbake", + "account.follow_back": "Fylg tilbake", "account.followers": "Fylgjarar", "account.followers.empty": "Ingen fylgjer denne brukaren enno.", "account.followers_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjarar}}", @@ -40,7 +40,7 @@ "account.following_counter": "{count, plural, one {Fylgjer {counter}} other {Fylgjer {counter}}}", "account.follows.empty": "Denne brukaren fylgjer ikkje nokon enno.", "account.go_to_profile": "Gรฅ til profil", - "account.hide_reblogs": "Skjul framhevingar frรฅ @{name}", + "account.hide_reblogs": "Gรธym framhevingar frรฅ @{name}", "account.in_memoriam": "Til minne om.", "account.joined_short": "Vart med", "account.languages": "Endre sprรฅktingingar", @@ -49,7 +49,7 @@ "account.media": "Media", "account.mention": "Nemn @{name}", "account.moved_to": "{name} seier at deira nye konto no er:", - "account.mute": "Mรฅlbind @{name}", + "account.mute": "Demp @{name}", "account.mute_notifications_short": "Demp varslingar", "account.mute_short": "Demp", "account.muted": "Mรฅlbunden", @@ -69,9 +69,9 @@ "account.unblock_short": "Stopp blokkering", "account.unendorse": "Ikkje vis pรฅ profil", "account.unfollow": "Slutt รฅ fylgja", - "account.unmute": "Opphev mรฅlbinding av @{name}", + "account.unmute": "Opphev demping av @{name}", "account.unmute_notifications_short": "Opphev demping av varslingar", - "account.unmute_short": "Opphev mรฅlbinding", + "account.unmute_short": "Opphev demping", "account_note.placeholder": "Klikk for รฅ leggja til merknad", "admin.dashboard.daily_retention": "Mengda brukarar aktive ved dagar etter registrering", "admin.dashboard.monthly_retention": "Mengda brukarar aktive ved mรฅnader etter registrering", @@ -79,8 +79,8 @@ "admin.dashboard.retention.cohort": "Registrert mรฅnad", "admin.dashboard.retention.cohort_size": "Nye brukarar", "admin.impact_report.instance_accounts": "Kontoprofilar dette vil sletta", - "admin.impact_report.instance_followers": "Fรธlgjarar vรฅre brukarar vil mista", - "admin.impact_report.instance_follows": "Fรธlgjarar deira brukarar vil mista", + "admin.impact_report.instance_followers": "Fylgjarar som brukarane vรฅre ville mista", + "admin.impact_report.instance_follows": "Fylgjarar som brukarane deira ville mista", "admin.impact_report.title": "Samandrag av konsekvensane", "alert.rate_limited.message": "Ver venleg รฅ prรธv pรฅ nytt etter {retry_time, time, medium}.", "alert.rate_limited.title": "Redusert kapasitet", @@ -89,6 +89,14 @@ "announcement.announcement": "Kunngjering", "attachments_list.unprocessed": "(ubehandla)", "audio.hide": "Gรธym lyd", + "block_modal.remote_users_caveat": "Me vil be tenaren {domain} om รฅ respektere di avgjerd. Me kan ikkje garantera at det vert gjort, sidan nokre tenarar kan handtera blokkering ulikt. Offentlege innlegg kan framleis vera synlege for ikkje-innlogga brukarar.", + "block_modal.show_less": "Vis mindre", + "block_modal.show_more": "Vis meir", + "block_modal.they_cant_mention": "Dei kan ikkje nemna eller fylgja deg.", + "block_modal.they_cant_see_posts": "Dei kan ikkje sjรฅ innlegga dine, og du vil ikkje sjรฅ deira.", + "block_modal.they_will_know": "Dei kan sjรฅ at dei er blokkerte.", + "block_modal.title": "Blokker brukaren?", + "block_modal.you_wont_see_mentions": "Du ser ikkje innlegg som nemner dei.", "boost_modal.combo": "Du kan trykkja {combo} for รฅ hoppa over dette neste gong", "bundle_column_error.copy_stacktrace": "Kopier feilrapport", "bundle_column_error.error.body": "Den etterspurde sida kan ikke hentast fram. Det kan skuldast ein feil i koden vรฅr eller eit kompatibilitetsproblem.", @@ -113,7 +121,7 @@ "column.community": "Lokal tidsline", "column.direct": "Private omtaler", "column.directory": "Sjรฅ gjennom profilar", - "column.domain_blocks": "Skjulte domene", + "column.domain_blocks": "Blokkerte domene", "column.favourites": "Favorittar", "column.firehose": "Tidslinjer", "column.follow_requests": "Fylgjefรธrespurnadar", @@ -124,7 +132,7 @@ "column.pins": "Festa tut", "column.public": "Samla tidsline", "column_back_button.label": "Attende", - "column_header.hide_settings": "Gรธym innstillingar", + "column_header.hide_settings": "Gรธym innstillingane", "column_header.moveLeft_settings": "Flytt kolonne til venstre", "column_header.moveRight_settings": "Flytt kolonne til hรธgre", "column_header.pin": "Fest", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Legg til innhaldsรฅtvaring", "compose_form.spoiler_placeholder": "Innhaldsรฅtvaring (valfritt)", "confirmation_modal.cancel": "Avbryt", - "confirmations.block.block_and_report": "Blokker & rapporter", "confirmations.block.confirm": "Blokker", - "confirmations.block.message": "Er du sikker pรฅ at du vil blokkera {name}?", "confirmations.cancel_follow_request.confirm": "Trekk attende fรธrespurnad", "confirmations.cancel_follow_request.message": "Er du sikker pรฅ at du vil trekkje attende fรธrespurnaden din om รฅ fylgje {name}?", "confirmations.delete.confirm": "Slett", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Er du sikker pรฅ at du vil sletta denne lista for alltid?", "confirmations.discard_edit_media.confirm": "Forkast", "confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller fรธrehandsvisinga. Vil du forkasta dei likevel?", - "confirmations.domain_block.confirm": "Skjul alt frรฅ domenet", - "confirmations.domain_block.message": "Er du heilt, heilt sikker pรฅ at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og fรธretrekt med nokre fรฅ mรฅlretta blokkeringar eller mรฅlbindingar. Du kjem ikkje til รฅ sjรฅ innhald frรฅ domenet i fรธdererte tidsliner eller i varsla dine. Fylgjarane dine frรฅ domenet vert fjerna.", + "confirmations.domain_block.confirm": "Blokker tenaren", + "confirmations.domain_block.message": "Er du heilt, heilt sikker pรฅ at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og fรธretrekt med nokre fรฅ mรฅlretta blokkeringar eller dempingar. Du kjem ikkje til รฅ sjรฅ innhald frรฅ domenet i fรธdererte tidsliner eller i varsla dine. Fylgjarane dine frรฅ domenet vert fjerna.", "confirmations.edit.confirm": "Rediger", "confirmations.edit.message": "ร… redigera no vil overskriva den meldinga du er i ferd med รฅ skriva. Er du sikker pรฅ at du vil halda fram?", "confirmations.logout.confirm": "Logg ut", "confirmations.logout.message": "Er du sikker pรฅ at du vil logga ut?", - "confirmations.mute.confirm": "Mรฅlbind", - "confirmations.mute.explanation": "Dette vil skjula innlegg som kjem frรฅ og som nemner dei, men vil framleis la dei sjรฅ innlegga dine og fylgje deg.", - "confirmations.mute.message": "Er du sikker pรฅ at du vil mรฅlbinda {name}?", + "confirmations.mute.confirm": "Demp", "confirmations.redraft.confirm": "Slett & skriv pรฅ nytt", "confirmations.redraft.message": "Er du sikker pรฅ at du vil sletta denne statusen og skriva han pรฅ nytt? Dรฅ misser du favorittar og framhevingar, og svar til det opprinnelege innlegget vert foreldrelause.", "confirmations.reply.confirm": "Svar", @@ -204,7 +208,28 @@ "dismissable_banner.explore_links": "Desse nyhendesakene snakkast om av folk pรฅ denne og andre tenarar pรฅ det desentraliserte nettverket no.", "dismissable_banner.explore_statuses": "Dette er innlegg frรฅ det desentraliserte nettverket som er i stรธytet i dag. Nye statusar som er mykje framheva og merkte som favorittar er rangert hรธgare.", "dismissable_banner.explore_tags": "Desse emneknaggane er populรฆre blant folk pรฅ denne tenaren og andre tenarar i det desentraliserte nettverket nett no.", - "dismissable_banner.public_timeline": "Dette er dei nyaste offentlege innlegga frรฅ menneske pรฅ det sosiale nettet som folk pรฅ {domain} fรธlgjer.", + "dismissable_banner.public_timeline": "Dette er dei nyaste offentlege innlegga frรฅ menneske pรฅ det sosiale nettet som folk pรฅ {domain} fylgjer.", + "domain_block_modal.block": "Blokker tenaren", + "domain_block_modal.block_account_instead": "Blokker @{name} i staden", + "domain_block_modal.they_can_interact_with_old_posts": "Folk pรฅ denne tenaren kan samhandla med dei gamle innlegga dine.", + "domain_block_modal.they_cant_follow": "Ingen pรฅ denne tenaren kan fylgja deg.", + "domain_block_modal.they_wont_know": "Dei veit ikkje at dei er blokkerte.", + "domain_block_modal.title": "Blokker domenet?", + "domain_block_modal.you_will_lose_followers": "Alle fylgjarane dine frรฅ denne tenaren blir fjerna.", + "domain_block_modal.you_wont_see_posts": "Du vil ikkje sjรฅ innlegg eller varslingar frรฅ brukarar pรฅ denne tenaren.", + "domain_pill.activitypub_lets_connect": "Den lar deg kople til og samhandle med folk ikkje berre pรฅ Mastodon, men รฒg pรฅ tvers av forskjellige sosiale appar.", + "domain_pill.activitypub_like_language": "ActivityPub er som sprรฅket Mastodon snakkar med andre sosiale nettverk.", + "domain_pill.server": "Tenar", + "domain_pill.their_handle": "Deira handtak:", + "domain_pill.their_server": "Deira digitale heim, som alle innlegga deira bur.", + "domain_pill.their_username": "Deira unike identifikator pรฅ serveren deira. Det er mogleg รฅ finne brukarar med same brukarnamn pรฅ forskjellige tenarar.", + "domain_pill.username": "Brukarnamn", + "domain_pill.whats_in_a_handle": "Kva er i eit handtak?", + "domain_pill.who_they_are": "Sidan handtak seier kven nokon er og kvar dei er, kan du interagere med folk pรฅ tvers av det sosiale nettverket av .", + "domain_pill.who_you_are": "Sidan handtaket ditt seier kven du er og kvar du er, kan folk interagere med deg pรฅ tvers av det sosiale nettverket av .", + "domain_pill.your_handle": "Handtaket ditt:", + "domain_pill.your_server": "Din digitale heim, der alle innlegga dine bur i. Liker du ikkje dette? Byt til ein ny tenar nรฅr som helst og ta med fylgjarane dine รฒg.", + "domain_pill.your_username": "Din unike identifikator pรฅ denne tenaren. Det er mogleg รฅ finne brukarar med same brukarnamn pรฅ forskjellige tenarar.", "embed.instructions": "Bygg inn denne statusen pรฅ nettsida di ved รฅ kopiera koden nedanfor.", "embed.preview": "Slik kjem det til รฅ sjรฅ ut:", "emoji_button.activity": "Aktivitet", @@ -223,26 +248,27 @@ "emoji_button.symbols": "Symbol", "emoji_button.travel": "Reise & stader", "empty_column.account_hides_collections": "Denne brukaren har valt รฅ ikkje gjere denne informasjonen tilgjengeleg", - "empty_column.account_suspended": "Kontoen er suspendert", + "empty_column.account_suspended": "Kontoen er utestengd", "empty_column.account_timeline": "Ingen tut her!", "empty_column.account_unavailable": "Profil ikkje tilgjengeleg", "empty_column.blocks": "Du har ikkje blokkert nokon enno.", "empty_column.bookmarked_statuses": "Du har ikkje lagra noko bokmerke enno. Nรฅr du set bokmerke pรฅ eit innlegg, dukkar det opp her.", "empty_column.community": "Den lokale tidslina er tom. Skriv noko offentleg รฅ fรฅ ballen til รฅ rulle!", "empty_column.direct": "Du har ingen private omtaler enda. Etter du har sendt eller mottatt en, sรฅ vil den dukke opp her.", - "empty_column.domain_blocks": "Det er ingen skjulte domene til no.", + "empty_column.domain_blocks": "Det er ingen blokkerte domene enno.", "empty_column.explore_statuses": "Ingenting er i stรธytet nett no. Prรธv igjen seinare!", "empty_column.favourited_statuses": "Du har ingen favoritt-statusar ennรฅ. Nรฅr du merkjer ein som favoritt, dukkar han opp her.", "empty_column.favourites": "Ingen har merkt denne statusen som favoritt enno. Nรฅr nokon gjer det, dukkar dei opp her.", - "empty_column.follow_requests": "Du har ingen fรธlgjefรธrespurnadar ennรฅ. Nรฅr du fรฅr ein, sรฅ vil den dukke opp her.", + "empty_column.follow_requests": "Ingen har spurt om รฅ fylgja deg enno. Nรฅr nokon gjer det, vil det dukka opp her.", "empty_column.followed_tags": "Du fylgjer ingen emneknaggar enno. Nรฅr du gjer det, vil dei syna her.", "empty_column.hashtag": "Det er ingenting i denne emneknaggen enno.", - "empty_column.home": "Heime-tidslina di er tom! Fรธlg fleire folk for รฅ fylle ho med innhald. {suggestions}", + "empty_column.home": "Heime-tidslina di er tom! Fylg fleire folk for รฅ fylla ho med innhald. {suggestions}.", "empty_column.list": "Det er ingenting i denne lista enno. Nรฅr medlemer av denne lista legg ut nye statusar, sรฅ dukkar dei opp her.", "empty_column.lists": "Du har ingen lister enno. Nรฅr du lagar ei, sรฅ dukkar ho opp her.", "empty_column.mutes": "Du har ikkje mรฅlbunde nokon enno.", + "empty_column.notification_requests": "Ferdig! Her er det ingenting. Nรฅr du fรฅr nye varsel, kjem dei opp her slik du har valt.", "empty_column.notifications": "Du har ingen varsel enno. Kommuniser med andre for รฅ starte samtalen.", - "empty_column.public": "Det er ingenting her! Skriv noko offentleg, eller fรธlg brukarar frรฅ andre tenarar manuelt for รฅ fylle det opp", + "empty_column.public": "Det er ingenting her! Skriv noko offentleg, eller fylg brukarar frรฅ andre tenarar manuelt for รฅ fรฅ meir her", "error.unexpected_crash.explanation": "Pรฅ grunn av eit nettlesarkompatibilitetsproblem eller ein feil i koden vรฅr, kunne ikkje denne sida bli vist slik den skal.", "error.unexpected_crash.explanation_addons": "Denne sida kunne ikkje visast som den skulle. Feilen kjem truleg frรฅ ei nettleserutviding eller frรฅ automatiske omsetjingsverktรธy.", "error.unexpected_crash.next_steps": "Prรธv รฅ lasta inn sida pรฅ nytt. Hjelper ikkje dette kan du framleis nytta Mastodon i ein annan nettlesar eller app.", @@ -271,17 +297,30 @@ "filter_modal.select_filter.subtitle": "Bruk ein eksisterande kategori eller opprett ein ny", "filter_modal.select_filter.title": "Filtrer dette innlegget", "filter_modal.title.status": "Filtrer eit innlegg", + "filtered_notifications_banner.mentions": "{count, plural, one {omtale} other {omtaler}}", + "filtered_notifications_banner.pending_requests": "Varsel frรฅ {count, plural, =0 {ingen} one {ein person} other {# folk}} du kanskje kjenner", + "filtered_notifications_banner.title": "Filtrerte varslingar", "firehose.all": "Alle", "firehose.local": "Denne tenaren", "firehose.remote": "Andre tenarar", "follow_request.authorize": "Autoriser", "follow_request.reject": "Avvis", "follow_requests.unlocked_explanation": "Sjรธlv om kontoen din ikkje er lรฅst tenkte dei som driv {domain} at du kanskje ville gรฅ gjennom fรธrespurnadar frรฅ desse kontoane manuelt.", + "follow_suggestions.curated_suggestion": "Utvalt av staben", "follow_suggestions.dismiss": "Ikkje vis igjen", + "follow_suggestions.featured_longer": "Hanplukka av gjengen pรฅ {domain}", + "follow_suggestions.friends_of_friends_longer": "Populรฆrt hjรฅ dei du fylgjer", + "follow_suggestions.hints.featured": "Denne profilen er handplukka av folka pรฅ {domain}.", + "follow_suggestions.hints.friends_of_friends": "Denne profilen er populรฆr hjรฅ dei du fylgjer.", + "follow_suggestions.hints.most_followed": "Mange pรฅ {domain} fylgjer denne profilen.", + "follow_suggestions.hints.most_interactions": "Denne profilen har nyss fรฅtt mykje merksemd pรฅ {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Denne profilen liknar pรฅ dei andre profilane du har fylgt i det siste.", "follow_suggestions.personalized_suggestion": "Personleg forslag", "follow_suggestions.popular_suggestion": "Populรฆrt forslag", + "follow_suggestions.popular_suggestion_longer": "Populรฆrt pรฅ {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Liknar pรฅ profilar du har fylgt i det siste", "follow_suggestions.view_all": "Vis alle", - "follow_suggestions.who_to_follow": "Kven som skal fรธlgjast", + "follow_suggestions.who_to_follow": "Kven du kan fylgja", "followed_tags": "Fylgde emneknaggar", "footer.about": "Om", "footer.directory": "Profilmappe", @@ -308,7 +347,6 @@ "hashtag.follow": "Fylg emneknagg", "hashtag.unfollow": "Slutt รฅ fylgje emneknaggen", "hashtags.and_other": "โ€ฆog {count, plural, one {}other {# fleire}}", - "home.column_settings.basic": "Grunnleggjande", "home.column_settings.show_reblogs": "Vis framhevingar", "home.column_settings.show_replies": "Vis svar", "home.hide_announcements": "Skjul kunngjeringar", @@ -376,6 +414,8 @@ "limited_account_hint.action": "Vis profilen likevel", "limited_account_hint.title": "Denne profilen er skjult av moderatorane pรฅ {domain}.", "link_preview.author": "Av {name}", + "link_preview.more_from_author": "Meir frรฅ {name}", + "link_preview.shares": "{count, plural,one {{counter} innlegg} other {{counter} innlegg}}", "lists.account.add": "Legg til i liste", "lists.account.remove": "Fjern frรฅ liste", "lists.delete": "Slett liste", @@ -394,9 +434,15 @@ "loading_indicator.label": "Lastarโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Skjul bilete} other {Skjul bilete}}", "moved_to_account_banner.text": "Kontoen din, {disabledAccount} er for tida deaktivert fordi du har flytta til {movedToAccount}.", - "mute_modal.duration": "Varigheit", - "mute_modal.hide_notifications": "Skjul varsel frรฅ denne brukaren?", - "mute_modal.indefinite": "Pรฅ ubestemt tid", + "mute_modal.hide_from_notifications": "Ikkje vis varslingar", + "mute_modal.hide_options": "Gรธym val", + "mute_modal.indefinite": "Til eg avdempar dei", + "mute_modal.show_options": "Vis val", + "mute_modal.they_can_mention_and_follow": "Dei kan nemna og fylgja deg, men du vil ikkje sjรฅ dei.", + "mute_modal.they_wont_know": "Dei veit ikkje at dei er dempa.", + "mute_modal.title": "Demp brukaren?", + "mute_modal.you_wont_see_mentions": "Du vil ikkje sjรฅ innlegg som nemner dei.", + "mute_modal.you_wont_see_posts": "Dei kan framleis sjรฅ innlegga dine, men du vil ikkje sjรฅ deira.", "navigation_bar.about": "Om", "navigation_bar.advanced_interface": "Opne i avansert nettgrensesnitt", "navigation_bar.blocks": "Blokkerte brukarar", @@ -429,11 +475,29 @@ "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.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", + "notification_requests.dismiss": "Avvis", + "notification_requests.notifications_from": "Varslingar frรฅ {name}", + "notification_requests.title": "Filtrerte varslingar", "notifications.clear": "Tรธm varsel", "notifications.clear_confirmation": "Er du sikker pรฅ at du vil fjerna alle varsla dine for alltid?", "notifications.column_settings.admin.report": "Nye rapportar:", @@ -441,8 +505,7 @@ "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": "Snarfilterlinje", - "notifications.column_settings.filter_bar.show_bar": "Vis filterlinja", + "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:", @@ -468,6 +531,15 @@ "notifications.permission_denied": "Skrivebordsvarsel er ikkje tilgjengelege pรฅ grunn av at nettlesaren tidlegare ikkje har fรฅtt naudsynte rettar til รฅ vise dei", "notifications.permission_denied_alert": "Sidan nettlesaren tidlegare har blitt nekta naudsynte rettar, kan ikkje skrivebordsvarsel aktiverast", "notifications.permission_required": "Skrivebordsvarsel er utilgjengelege fordi naudsynte rettar ikkje er gitt.", + "notifications.policy.filter_new_accounts.hint": "Skrive siste {days, plural, one {dag} other {# dagar}}", + "notifications.policy.filter_new_accounts_title": "Nye brukarkontoar", + "notifications.policy.filter_not_followers_hint": "Inkludert folk som har fylgt deg mindre enn {days, plural, one {ein dag} other {# dagar}}", + "notifications.policy.filter_not_followers_title": "Folk som ikkje fylgjer deg", + "notifications.policy.filter_not_following_hint": "Til du godkjenner dei manuelt", + "notifications.policy.filter_not_following_title": "Folk du ikkje fylgjer", + "notifications.policy.filter_private_mentions_hint": "Filtrert viss det ikkje er eit svar pรฅ dine eigne nemningar eller viss du fylgjer avsendaren", + "notifications.policy.filter_private_mentions_title": "Masseutsende private nemningar", + "notifications.policy.title": "Filtrer ut varslingar frรฅโ€ฆ", "notifications_permission_banner.enable": "Skru pรฅ skrivebordsvarsel", "notifications_permission_banner.how_to_control": "Aktiver skrivebordsvarsel for รฅ fรฅ varsel nรฅr Mastodon ikkje er open. Du kan nรธye bestemme kva samhandlingar som skal fรธre til skrivebordsvarsel gjennom {icon}-knappen ovanfor etter at varsel er aktivert.", "notifications_permission_banner.title": "Gรฅ aldri glipp av noko", @@ -479,7 +551,8 @@ "onboarding.follows.empty": "Me kan ikkje visa deg nokon resultat no. Du kan prรธva รฅ sรธkja eller bla gjennom utforsk-sida for รฅ finna folk รฅ fylgja, eller du kan prรธva att seinare.", "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.title": "Popular on Mastodon", - "onboarding.profile.discoverable": "Gjรธr min profil synlig", + "onboarding.profile.discoverable": "Gjer profilen min synleg", + "onboarding.profile.discoverable_hint": "Nรฅr du vel รฅ gjera profilen din synleg pรฅ Mastodon, vil innlegga dine syna i sรธkjeresultat og populรฆre innlegg, og profilen din kan bli fรธreslegen for folk med liknande interesser som deg.", "onboarding.profile.display_name": "Synleg namn", "onboarding.profile.display_name_hint": "Det fulle namnet eller kallenamnet dittโ€ฆ", "onboarding.profile.lead": "Du kan alltid fullfรธra dette seinare i innstillingane, og der er det endรฅ fleire tilpassingsalternativ.", @@ -524,15 +597,16 @@ "privacy.change": "Endre personvernet pรฅ innlegg", "privacy.direct.long": "Alle nemnde i innlegget", "privacy.direct.short": "Spesifikke folk", - "privacy.private.long": "Berre dine fรธlgjarar", - "privacy.private.short": "Fรธlgjarar", + "privacy.private.long": "Berre dei som fylgjer deg", + "privacy.private.short": "Fylgjarar", "privacy.public.long": "Kven som helst pรฅ og av Mastodon", "privacy.public.short": "Offentleg", + "privacy.unlisted.additional": "Dette er akkurat som offentleg, bortsett frรฅ at innlegga ikkje dukkar opp i direktestraumar eller merkelappar, i oppdagingar eller Mastodon-sรธk, sjรธlv om du har sagt ja til at kontoen skal vera synleg.", "privacy.unlisted.long": "Fรฆrre algoritmiske fanfarar", "privacy.unlisted.short": "Stille offentleg", "privacy_policy.last_updated": "Sist oppdatert {date}", "privacy_policy.title": "Personvernsreglar", - "recommended": "Anbefalt", + "recommended": "Tilrรฅdd", "refresh": "Oppdater", "regeneration_indicator.label": "Lastarโ€ฆ", "regeneration_indicator.sublabel": "Heimetidslina di vert fรธrebudd!", @@ -564,7 +638,7 @@ "report.comment.title": "Er det noko anna du meiner me bรธr vite?", "report.forward": "Vidaresend til {target}", "report.forward_hint": "Kontoen er frรฅ ein annan tenar. Vil du senda ein anonymisert kopi av rapporten dit รฒg?", - "report.mute": "Mรฅlbind", + "report.mute": "Demp", "report.mute_explanation": "Du vil ikkje lenger sjรฅ innlegga deira. Dei kan framleis fylgje deg og sjรฅ innlegga dine, men vil ikkje vite at du har valt รฅ ikkje sjรฅ innlegga deira.", "report.next": "Neste", "report.placeholder": "Tilleggskommentarar", @@ -601,11 +675,11 @@ "search.quick_action.account_search": "Profiler som samsvarer med {x}", "search.quick_action.go_to_account": "Gรฅ til profil {x}", "search.quick_action.go_to_hashtag": "Gรฅ til emneknagg {x}", - "search.quick_action.open_url": "ร…pne URL i Mastodon", + "search.quick_action.open_url": "Opne adressa i Mastodon", "search.quick_action.status_search": "Innlegg som samsvarer med {x}", "search.search_or_paste": "Sรธk eller lim inn URL", "search_popout.full_text_search_disabled_message": "Ikkje tilgjengeleg pรฅ {domain}.", - "search_popout.full_text_search_logged_out_message": "Bare tilgjengelig nรฅr man er logget inn.", + "search_popout.full_text_search_logged_out_message": "Berre tilgjengeleg nรฅr du er logga inn.", "search_popout.language_code": "ISO-sprรฅkkode", "search_popout.options": "Sรธkjealternativ", "search_popout.quick_actions": "Hurtighandlinger", @@ -622,30 +696,28 @@ "server_banner.about_active_users": "Personar som har brukt denne tenaren dei siste 30 dagane (Mรฅnadlege Aktive Brukarar)", "server_banner.active_users": "aktive brukarar", "server_banner.administered_by": "Administrert av:", - "server_banner.introduction": "{domain} er del av det desentraliserte sosiale nettverket drive av {mastodon}.", - "server_banner.learn_more": "Lรฆr meir", "server_banner.server_stats": "Tenarstatistikk:", "sign_in_banner.create_account": "Opprett konto", "sign_in_banner.sign_in": "Logg inn", "sign_in_banner.sso_redirect": "Logg inn eller registrer deg", - "sign_in_banner.text": "Logg inn for รฅ fylgja profilar eller emneknaggar, og for รฅ lika, dela og svara pรฅ innlegg. Du kan รฒg samhandla med aktivitet pรฅ denne tenaren frรฅ kontoar pรฅ andre tenarar.", "status.admin_account": "Opne moderasjonsgrensesnitt for @{name}", "status.admin_domain": "Opna moderatorgrensesnittet for {domain}", "status.admin_status": "Opne denne statusen i moderasjonsgrensesnittet", "status.block": "Blokker @{name}", "status.bookmark": "Set bokmerke", "status.cancel_reblog_private": "Opphev framheving", - "status.cannot_reblog": "Denne posten kan ikkje framhevast", + "status.cannot_reblog": "Du kan ikkje framheva dette innlegget", "status.copy": "Kopier lenke til status", "status.delete": "Slett", "status.detailed_status": "Detaljert samtalevisning", "status.direct": "Nevn @{name} privat", "status.direct_indicator": "Privat omtale", "status.edit": "Rediger", - "status.edited": "Redigert {date}", + "status.edited": "Sist endra {date}", "status.edited_x_times": "Redigert {count, plural, one {{count} gong} other {{count} gonger}}", "status.embed": "Bygg inn", "status.favourite": "Favoritt", + "status.favourites": "{count, plural, one {favoritt} other {favorittar}}", "status.filter": "Filtrer dette innlegget", "status.filtered": "Filtrert", "status.hide": "Skjul innlegget", @@ -654,11 +726,11 @@ "status.load_more": "Last inn meir", "status.media.open": "Klikk for รฅ opne", "status.media.show": "Klikk for รฅ vise", - "status.media_hidden": "Medium gรธymd", + "status.media_hidden": "Mediet er gรธymt", "status.mention": "Nemn @{name}", "status.more": "Meir", - "status.mute": "Mรฅlbind @{name}", - "status.mute_conversation": "Mรฅlbind samtale", + "status.mute": "Demp @{name}", + "status.mute_conversation": "Demp samtale", "status.open": "Utvid denne statusen", "status.pin": "Fest pรฅ profil", "status.pinned": "Festa tut", @@ -666,6 +738,7 @@ "status.reblog": "Framhev", "status.reblog_private": "Framhev til dei originale mottakarane", "status.reblogged_by": "{name} framheva", + "status.reblogs": "{count, plural, one {framheving} other {framhevingar}}", "status.reblogs.empty": "Ingen har framheva dette tutet enno. Om nokon gjer, sรฅ dukkar det opp her.", "status.redraft": "Slett & skriv pรฅ nytt", "status.remove_bookmark": "Fjern bokmerke", @@ -681,11 +754,11 @@ "status.show_more": "Vis meir", "status.show_more_all": "Vis meir for alle", "status.show_original": "Vis original", - "status.title.with_attachments": "{user} postet {attachmentCount, plural, one {et vedlegg} other {{attachmentCount} vedlegg}}", + "status.title.with_attachments": "{user} la ut {attachmentCount, plural, one {eitt vedlegg} other {{attachmentCount} vedlegg}}", "status.translate": "Omset", "status.translated_from_with": "Omsett frรฅ {lang} ved bruk av {provider}", "status.uncached_media_warning": "Fรธrehandsvisning er ikkje tilgjengeleg", - "status.unmute_conversation": "Opphev mรฅlbinding av samtalen", + "status.unmute_conversation": "Opphev demping av samtalen", "status.unpin": "Lรธys frรฅ profil", "subscribed_languages.lead": "Kun innlegg pรฅ valde sprรฅk vil bli dukke opp i heimestraumen din og i listene dine etter denne endringa. For รฅ motta innlegg pรฅ alle sprรฅk, la vere รฅ velje nokon.", "subscribed_languages.save": "Lagre endringar", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 27ca611722..213ba8af12 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -160,9 +160,7 @@ "compose_form.spoiler.unmarked": "Legg til innholdsvarsel", "compose_form.spoiler_placeholder": "Innholdsadvarsel (valgfritt)", "confirmation_modal.cancel": "Avbryt", - "confirmations.block.block_and_report": "Blokker og rapporter", "confirmations.block.confirm": "Blokkรจr", - "confirmations.block.message": "Er du sikker pรฅ at du vil blokkere {name}?", "confirmations.cancel_follow_request.confirm": "Trekk tilbake forespรธrsel", "confirmations.cancel_follow_request.message": "Er du sikker pรฅ at du vil trekke tilbake forespรธrselen din for รฅ fรธlge {name}?", "confirmations.delete.confirm": "Slett", @@ -171,15 +169,12 @@ "confirmations.delete_list.message": "Er du sikker pรฅ at du vil slette denne listen permanent?", "confirmations.discard_edit_media.confirm": "Forkast", "confirmations.discard_edit_media.message": "Du har ulagrede endringer i mediebeskrivelsen eller i forhรฅndsvisning, forkast dem likevel?", - "confirmations.domain_block.confirm": "Skjul alt fra domenet", "confirmations.domain_block.message": "Er du sikker pรฅ at du vil skjule hele domenet {domain}? I de fleste tilfeller er det bedre med mรฅlrettet blokkering eller demping.", "confirmations.edit.confirm": "Redigรฉr", "confirmations.edit.message": "ร… redigere nรฅ vil overskrive meldingen du skriver for รธyeblikket. Er du sikker pรฅ at du vil fortsette?", "confirmations.logout.confirm": "Logg ut", "confirmations.logout.message": "Er du sikker pรฅ at du vil logge ut?", "confirmations.mute.confirm": "Demp", - "confirmations.mute.explanation": "Dette vil skjule innlegg fra dem og innlegg som nevner dem, men det vil fortsatt la dem se dine innlegg og รฅ fรธlge deg.", - "confirmations.mute.message": "Er du sikker pรฅ at du vil dempe {name}?", "confirmations.redraft.confirm": "Slett og skriv pรฅ nytt", "confirmations.redraft.message": "Er du sikker pรฅ at du vil slette dette innlegget og lagre det pรฅ nytt? Favoritter og fremhevinger vil gรฅ tapt, og svar til det originale innlegget vil bli foreldrelรธse.", "confirmations.reply.confirm": "Svar", @@ -277,6 +272,7 @@ "follow_request.authorize": "Autoriser", "follow_request.reject": "Avvis", "follow_requests.unlocked_explanation": "Selv om kontoen din ikke er lรฅst, tror {domain} ansatte at du kanskje vil gjennomgรฅ forespรธrsler fra disse kontoene manuelt.", + "follow_suggestions.view_all": "Vis alle", "followed_tags": "Fulgte emneknagger", "footer.about": "Om", "footer.directory": "Profilkatalog", @@ -303,7 +299,6 @@ "hashtag.follow": "Fรธlg emneknagg", "hashtag.unfollow": "Slutt รฅ fรธlge emneknagg", "hashtags.and_other": "โ€ฆog {count, plural, one{en til} other {# til}}", - "home.column_settings.basic": "Enkelt", "home.column_settings.show_reblogs": "Vis fremhevinger", "home.column_settings.show_replies": "Vis svar", "home.hide_announcements": "Skjul kunngjรธring", @@ -389,9 +384,6 @@ "loading_indicator.label": "Lasterโ€ฆ", "media_gallery.toggle_visible": "Veksle synlighet", "moved_to_account_banner.text": "Din konto {disabledAccount} er for รธyeblikket deaktivert fordi du flyttet til {movedToAccount}.", - "mute_modal.duration": "Varighet", - "mute_modal.hide_notifications": "Skjul varslinger fra denne brukeren?", - "mute_modal.indefinite": "Pรฅ ubestemt tid", "navigation_bar.about": "Om", "navigation_bar.advanced_interface": "ร…pne i det avanserte nettgrensesnittet", "navigation_bar.blocks": "Blokkerte brukere", @@ -435,9 +427,6 @@ "notifications.column_settings.admin.sign_up": "Nye registreringer:", "notifications.column_settings.alert": "Skrivebordsvarslinger", "notifications.column_settings.favourite": "Favoritter:", - "notifications.column_settings.filter_bar.advanced": "Vis alle kategorier", - "notifications.column_settings.filter_bar.category": "Hurtigfiltreringslinje", - "notifications.column_settings.filter_bar.show_bar": "Vis filterlinjen", "notifications.column_settings.follow": "Nye fรธlgere:", "notifications.column_settings.follow_request": "Nye fรธlgerforespรธrsler:", "notifications.column_settings.mention": "Nevnt:", @@ -617,13 +606,10 @@ "server_banner.about_active_users": "Personer som har brukt denne serveren i lรธpet av de siste 30 dagene (aktive brukere mรฅnedlig)", "server_banner.active_users": "aktive brukere", "server_banner.administered_by": "Administrert av:", - "server_banner.introduction": "{domain} er en del av det desentraliserte sosiale nettverket drevet av {mastodon}.", - "server_banner.learn_more": "Finn ut mer", "server_banner.server_stats": "Serverstatistikk:", "sign_in_banner.create_account": "Opprett konto", "sign_in_banner.sign_in": "Logg inn", "sign_in_banner.sso_redirect": "Logg inn eller registrer deg", - "sign_in_banner.text": "Logg inn for รฅ fรธlge profiler eller emneknagger, favorittmarkere, dele og svare pรฅ innlegg. Du kan ogsรฅ samhandle fra din konto pรฅ en annen server.", "status.admin_account": "ร…pne moderatorgrensesnittet for @{name}", "status.admin_domain": "ร…pne moderatorgrensesnittet for {domain}", "status.admin_status": "ร…pne denne statusen i moderatorgrensesnittet", @@ -637,7 +623,6 @@ "status.direct": "Nevn @{name} privat", "status.direct_indicator": "Privat omtale", "status.edit": "Rediger", - "status.edited": "Redigert {date}", "status.edited_x_times": "Redigert {count, plural,one {{count} gang} other {{count} ganger}}", "status.embed": "Bygge inn", "status.favourite": "Favoritt", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 5e122064fc..d8e1141588 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -137,9 +137,7 @@ "compose_form.spoiler.marked": "Lo tรจxte es rescondut jos lโ€™avertiment", "compose_form.spoiler.unmarked": "Lo tรจxte es pas rescondut", "confirmation_modal.cancel": "Anullar", - "confirmations.block.block_and_report": "Blocar e senhalar", "confirmations.block.confirm": "Blocar", - "confirmations.block.message": "Volรจtz vertadiรจrament blocar {name}โ€ฏ?", "confirmations.cancel_follow_request.confirm": "Retirar la demandar", "confirmations.cancel_follow_request.message": "Volรจtz vertadiรจrament retirar la demanda de seguiment de {name}โ€ฏ?", "confirmations.delete.confirm": "Escafar", @@ -147,14 +145,11 @@ "confirmations.delete_list.confirm": "Suprimir", "confirmations.delete_list.message": "Volรจtz vertadiรจrament suprimir aquesta lista per totjornโ€ฏ?", "confirmations.discard_edit_media.confirm": "Ignorar", - "confirmations.domain_block.confirm": "Amagar tot lo domeni", "confirmations.domain_block.message": "Volรจtz vertadiรจrament blocar complรจtament {domain}โ€ฏ? De cรฒps cal pas que blocar o rescondre unas personas solament.\nVeiretz pas cap de contengut dโ€™aquel domeni dins cap de flux public o dins vรฒstras notificacions. Vรฒstres seguidors dโ€™aquel domeni serร n levats.", "confirmations.edit.confirm": "Modificar", "confirmations.logout.confirm": "Desconnexion", "confirmations.logout.message": "Volรจtz vertadiรจrament vos desconnectar ?", "confirmations.mute.confirm": "Rescondre", - "confirmations.mute.explanation": "Aquรฒ lor escondrร  las publicacions e mencions, mas aquรฒ lor permetrร  encara de veire vรฒstra publicacions e de vos sรจgre.", - "confirmations.mute.message": "Volรจtz vertadiรจrament rescondre {name}โ€ฏ?", "confirmations.redraft.confirm": "Escafar & tornar formular", "confirmations.reply.confirm": "Respondre", "confirmations.reply.message": "Respondre remplaรงarร  lo messatge que sรจtz a escriure. Volรจtz vertadiรจrament contunharโ€ฏ?", @@ -262,7 +257,6 @@ "hashtag.follow": "Sรจgre lโ€™etiqueta", "hashtag.unfollow": "Quitar de sรจgre lโ€™etiqueta", "hashtags.and_other": "โ€ฆe {count, plural, one {}other {# de mai}}", - "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Mostrar los partatges", "home.column_settings.show_replies": "Mostrar las responsas", "home.hide_announcements": "Rescondre las anรณncias", @@ -334,9 +328,6 @@ "load_pending": "{count, plural, one {# nรฒu element} other {# nรฒu elements}}", "loading_indicator.label": "Cargamentโ€ฆ", "media_gallery.toggle_visible": "Modificar la visibilitat", - "mute_modal.duration": "Durada", - "mute_modal.hide_notifications": "Rescondre las notificacions dโ€™aquesta personaโ€ฏ?", - "mute_modal.indefinite": "Cap de data de fin", "navigation_bar.about": "A prepaus", "navigation_bar.advanced_interface": "Dobrir lโ€™interfร cia web avanรงada", "navigation_bar.blocks": "Personas blocadas", @@ -379,9 +370,6 @@ "notifications.column_settings.admin.sign_up": "Nรฒus inscritsโ€ฏ:", "notifications.column_settings.alert": "Notificacions localas", "notifications.column_settings.favourite": "Favorits :", - "notifications.column_settings.filter_bar.advanced": "Mostrar totas las categorias", - "notifications.column_settings.filter_bar.category": "Barra de recรจrca rapida", - "notifications.column_settings.filter_bar.show_bar": "Afichar la barra de filtres", "notifications.column_settings.follow": "Nรฒus seguidorsโ€ฏ:", "notifications.column_settings.follow_request": "Novรจla demanda dโ€™abonamentโ€ฏ:", "notifications.column_settings.mention": "Mencionsโ€ฏ:", @@ -511,8 +499,6 @@ "search_results.title": "Recรจrcaโ€ฏ: {q}", "server_banner.active_users": "utilizaires actius", "server_banner.administered_by": "Administrat perโ€ฏ:", - "server_banner.introduction": "{domain} fa part del malhum social descentralizat propulsat per {mastodon}.", - "server_banner.learn_more": "Ne saber mai", "server_banner.server_stats": "Estatisticas del servidorโ€ฏ:", "sign_in_banner.create_account": "Crear un compte", "sign_in_banner.sign_in": "Se connectar", @@ -529,7 +515,6 @@ "status.direct": "Mencionar @{name} en privat", "status.direct_indicator": "Mencion privada", "status.edit": "Modificar", - "status.edited": "Modificat {date}", "status.edited_x_times": "Modificat {count, plural, un {{count} cรฒp} other {{count} cรฒps}}", "status.embed": "Embarcar", "status.favourite": "Apondre als favorits", diff --git a/app/javascript/mastodon/locales/pa.json b/app/javascript/mastodon/locales/pa.json index ee47c1872d..46924d737d 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": "เจฎเฉเฉœ-เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเฉ‹", @@ -86,13 +100,11 @@ "compose_form.spoiler.unmarked": "เจธเจฎเฉฑเจ—เจฐเฉ€ เจฌเจพเจฐเฉ‡ เจšเฉ‡เจคเจพเจตเจจเฉ€ เจœเฉ‹เฉœเฉ‹", "compose_form.spoiler_placeholder": "เจธเจฎเฉฑเจ—เจฐเฉ€ เจฌเจพเจฐเฉ‡ เจšเฉ‡เจคเจพเจตเจจเฉ€ (เจšเฉ‹เจฃเจตเจพเจ‚)", "confirmation_modal.cancel": "เจฐเฉฑเจฆ เจ•เจฐเฉ‹", - "confirmations.block.block_and_report": "เจฐเฉ‹เจ• เจฒเจพเจ“ เจคเฉ‡ เจฐเจฟเจชเฉ‹เจฐเจŸ เจ•เจฐเฉ‹", "confirmations.block.confirm": "เจชเจพเจฌเฉฐเจฆเฉ€", "confirmations.delete.confirm": "เจนเจŸเจพเจ“", "confirmations.delete.message": "เจ•เฉ€ เจคเฉเจธเฉ€เจ‚ เจ‡เจน เจชเฉ‹เจธเจŸ เจจเฉ‚เฉฐ เจนเจŸเจพเจ‰เจฃเจพ เจšเจพเจนเฉเฉฐเจฆเฉ‡ เจนเฉ‹?", "confirmations.delete_list.confirm": "เจนเจŸเจพเจ“", "confirmations.discard_edit_media.confirm": "เจฐเฉฑเจฆ เจ•เจฐเฉ‹", - "confirmations.domain_block.confirm": "เจชเฉ‚เจฐเฉ€ เจกเฉ‹เจฎเฉ‡เจจ เจ‰เฉฑเจคเฉ‡ เจชเจพเจฌเฉฐเจฆเฉ€ เจฒเจพเจ“", "confirmations.edit.confirm": "เจธเฉ‹เจง", "confirmations.logout.confirm": "เจฌเจพเจนเจฐ เจนเฉ‹เจตเฉ‹", "confirmations.mute.confirm": "เจฎเฉŒเจจ เจ•เจฐเฉ‹", @@ -153,7 +165,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "เจนเฉˆเจถเจŸเฉˆเจ— เจจเฉ‚เฉฐ เจซเจผเจพเจฒเฉ‹ เจ•เจฐเฉ‹", "hashtag.unfollow": "เจนเฉˆเจถเจŸเฉˆเจ— เจจเฉ‚เฉฐ เจ…เจฃ-เจซเจผเจพเจฒเฉ‹ เจ•เจฐเฉ‹", - "home.column_settings.basic": "เจ†เจฎ", "home.pending_critical_update.link": "เจ…เฉฑเจชเจกเฉ‡เจŸ เจตเฉ‡เจ–เฉ‹", "interaction_modal.title.follow": "{name} เจจเฉ‚เฉฐ เจซเจผเจพเจฒเฉ‹ เจ•เจฐเฉ‹", "keyboard_shortcuts.back": "เจชเจฟเฉฑเจ›เฉ‡ เจœเจพเจ“", @@ -197,7 +208,6 @@ "lists.replies_policy.followed": "เจ•เฉ‹เจˆ เจตเฉ€ เจซเจผเจพเจฒเฉ‹ เจ•เฉ€เจคเจพ เจตเจฐเจคเฉ‹เจ‚เจ•เจพเจฐ", "lists.replies_policy.none": "เจ•เฉ‹เจˆ เจจเจนเฉ€เจ‚", "loading_indicator.label": "เจฒเฉ‹เจก เจนเฉ‹ เจฐเจฟเจนเจพ เจนเฉˆโ€ฆ", - "mute_modal.duration": "เจฎเจฟเจ†เจฆ", "navigation_bar.about": "เจ‡เจธ เจฌเจพเจฐเฉ‡", "navigation_bar.advanced_interface": "เจคเจ•เจจเฉ€เจ•เฉ€ เจตเฉˆเฉฑเจฌ เจ‡เฉฐเจŸเจฐเจซเฉ‡เจธ เจตเจฟเฉฑเจš เจ–เฉ‹เจฒเฉเจนเฉ‹", "navigation_bar.blocks": "เจชเจพเจฌเฉฐเจฆเฉ€ เจฒเจพเจ เจตเจฐเจคเฉ‹เจ‚เจ•เจพเจฐ", @@ -301,7 +311,6 @@ "search_results.see_all": "เจธเจญ เจตเฉ‡เจ–เฉ‹", "search_results.statuses": "เจชเฉ‹เจธเจŸเจพเจ‚", "search_results.title": "{q} เจฒเจˆ เจ–เฉ‹เจœ", - "server_banner.learn_more": "เจนเฉ‹เจฐ เจœเจพเจฃเฉ‹", "sign_in_banner.create_account": "เจ–เจพเจคเจพ เจฌเจฃเจพเจ“", "sign_in_banner.sign_in": "เจฒเจพเจ—เจ‡เจจ", "sign_in_banner.sso_redirect": "เจฒเจพเจ—เจ‡เจจ เจœเจพเจ‚ เจฐเจœเจฟเจธเจŸเจฐ เจ•เจฐเฉ‹", @@ -311,7 +320,6 @@ "status.copy": "เจชเฉ‹เจธเจŸ เจฒเจˆ เจฒเจฟเฉฐเจ• เจ•เจพเจชเฉ€ เจ•เจฐเฉ‹", "status.delete": "เจนเจŸเจพเจ“", "status.edit": "เจธเฉ‹เจง", - "status.edited": "{date} เจจเฉ‚เฉฐ เจธเฉ‹เจงเจฟเจ†", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "เจฎเฉœเฉเจนเฉ‹", "status.favourite": "เจชเจธเฉฐเจฆ", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 814d0f2de0..ddfe1d4fbc 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -89,6 +89,14 @@ "announcement.announcement": "Ogล‚oszenie", "attachments_list.unprocessed": "(nieprzetworzone)", "audio.hide": "Ukryj dลบwiฤ™k", + "block_modal.remote_users_caveat": "Poprosimy serwer {domain} o uszanowanie twojej decyzji. Zgodnoล›ฤ‡ nie jest jednak gwarantowana, bo niektรณre serwery mogฤ… inaczej obsล‚ugiwaฤ‡ blokowanie. Wpisy publiczne mogฤ… byฤ‡ widoczne dla niezalogowanych uลผytkownikรณw.", + "block_modal.show_less": "Pokaลผ mniej", + "block_modal.show_more": "Pokaลผ wiฤ™cej", + "block_modal.they_cant_mention": "Uลผytkownik nie moลผe Ciฤ™ obserwowaฤ‡ ani dodawaฤ‡ wzmianek o Tobie.", + "block_modal.they_cant_see_posts": "Uลผytkownik nie bฤ™dzie widzieฤ‡ Twoich wpisรณw, a Ty jego.", + "block_modal.they_will_know": "Uลผytkownik bฤ™dzie wiedziaล‚, ลผe jest zablokowany.", + "block_modal.title": "Zablokowaฤ‡ uลผytkownika?", + "block_modal.you_wont_see_mentions": "Nie zobaczysz wpisรณw, ktรณre wspominajฤ… tego uลผytkownika.", "boost_modal.combo": "Naciล›nij {combo}, aby pominฤ…ฤ‡ to nastฤ™pnym razem", "bundle_column_error.copy_stacktrace": "Skopiuj raport o bล‚ฤ™dzie", "bundle_column_error.error.body": "Nie moลผna zrenderowaฤ‡ ลผฤ…danej strony. Moลผe to byฤ‡ spowodowane bล‚ฤ™dem w naszym kodzie lub problemami z kompatybilnoล›ciฤ… przeglฤ…darki.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Dodaj ostrzeลผenie o treล›ci", "compose_form.spoiler_placeholder": "Ostrzeลผenie o treล›ci (opcjonalne)", "confirmation_modal.cancel": "Anuluj", - "confirmations.block.block_and_report": "Zablokuj i zgล‚oล›", "confirmations.block.confirm": "Zablokuj", - "confirmations.block.message": "Czy na pewno chcesz zablokowaฤ‡ {name}?", "confirmations.cancel_follow_request.confirm": "Wycofaj proล›bฤ™", "confirmations.cancel_follow_request.message": "Czy na pewno chcesz wycofaฤ‡ proล›bฤ™ o moลผliwoล›ฤ‡ obserwowania {name}?", "confirmations.delete.confirm": "Usuล„", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Czy na pewno chcesz bezpowrotnie usunฤ…ฤ‡ tฤ… listฤ™?", "confirmations.discard_edit_media.confirm": "Odrzuฤ‡", "confirmations.discard_edit_media.message": "Masz niezapisane zmiany w opisie lub podglฤ…dzie, odrzuciฤ‡ je mimo to?", - "confirmations.domain_block.confirm": "Ukryj wszystko z domeny", + "confirmations.domain_block.confirm": "Blokuj serwer", "confirmations.domain_block.message": "Czy na pewno chcesz zablokowaฤ‡ caล‚ฤ… domenฤ™ {domain}? Zwykle lepszym rozwiฤ…zaniem jest blokada lub wyciszenie kilku uลผytkownikรณw.", "confirmations.edit.confirm": "Edytuj", "confirmations.edit.message": "Edytowanie wpisu nadpisze wiadomoล›ฤ‡, ktรณrฤ… obecnie piszesz. Czy na pewno chcesz to zrobiฤ‡?", "confirmations.logout.confirm": "Wyloguj", "confirmations.logout.message": "Czy na pewno chcesz siฤ™ wylogowaฤ‡?", "confirmations.mute.confirm": "Wycisz", - "confirmations.mute.explanation": "To schowa ich i wspominajฤ…ce ich posty, ale wciฤ…ลผ pozwoli im widzieฤ‡ twoje posty i obserwowaฤ‡ ciฤ™.", - "confirmations.mute.message": "Czy na pewno chcesz wyciszyฤ‡ {name}?", "confirmations.redraft.confirm": "Usuล„ i przeredaguj", "confirmations.redraft.message": "Czy na pewno chcesz usunฤ…ฤ‡ i przeredagowaฤ‡ ten wpis? Polubienia i podbicia zostanฤ… utracone, a odpowiedzi do oryginalnego wpisu zostanฤ… osierocone.", "confirmations.reply.confirm": "Odpowiedz", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Obecnie te wpisy z tego serwera i pozostaล‚ych serwerรณw w zdecentralizowanej sieci zyskujฤ… popularnoล›ฤ‡ na tym serwerze.", "dismissable_banner.explore_tags": "Te hasztagi obecnie zyskujฤ… popularnoล›ฤ‡ wล›rรณd osรณb z tego serwera i pozostaล‚ych w zdecentralizowanej sieci.", "dismissable_banner.public_timeline": "Sฤ… to najnowsze publiczne wpisy osรณb w serwisie spoล‚ecznoล›ciowym, ktรณre obserwujฤ… ludzie w serwisie {domain}.", + "domain_block_modal.block": "Blokuj serwer", + "domain_block_modal.block_account_instead": "Zamiast tego zablokuj @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Ludzie z tego serwera mogฤ… wchodziฤ‡ w interakcje z Twoimi starymi wpisami.", + "domain_block_modal.they_cant_follow": "Nikt z tego serwera nie moลผe Ciฤ™ obserwowaฤ‡.", + "domain_block_modal.they_wont_know": "Uลผytkownik nie dowie siฤ™, ลผe zostaล‚ zablokowany.", + "domain_block_modal.title": "Zablokowaฤ‡ domenฤ™?", + "domain_block_modal.you_will_lose_followers": "Wszyscy twoi obserwujฤ…cy z tego serwera zostanฤ… usuniฤ™ci.", + "domain_block_modal.you_wont_see_posts": "Nie zobaczysz postรณw ani powiadomieล„ od uลผytkownikรณw na tym serwerze.", + "domain_pill.activitypub_lets_connect": "Pozwala poล‚ฤ…czyฤ‡ siฤ™ z ludลบmi na Mastodonie, jak i na innych serwisach spoล‚ecznoล›ciowych.", + "domain_pill.activitypub_like_language": "ActivityPub jest jฤ™zykiem uลผywanym przez Mastodon do wymiany danych z innymi serwisami spoล‚ecznoล›ciowymi.", + "domain_pill.server": "Serwer", + "domain_pill.their_handle": "Uchwyt:", + "domain_pill.their_server": "Cyfrowy dom, w ktรณrym znajdujฤ… siฤ™ wszystkie wpisy.", + "domain_pill.their_username": "Unikalny identyfikator na serwerze. Moลผliwe jest znalezienie uลผytkownikรณw o tej samej nazwie uลผytkownika na rรณลผnych serwerach.", + "domain_pill.username": "Nazwa uลผytkownika", + "domain_pill.whats_in_a_handle": "Co zawiera uchwyt uลผytkownika?", + "domain_pill.who_they_are": "Poniewaลผ uchwyty mรณwiฤ… kto jest kim i gdzie siฤ™ znajduje, moลผesz wchodziฤ‡ w interakcje z ludลบmi korzystajฤ…cymi z .", + "domain_pill.who_you_are": "Poniewaลผ Twรณj uchwyt mรณwi kim jesteล› i gdzie siฤ™ znajdujesz, inni mogฤ… wchodziฤ‡ z Tobฤ… w interakcje korzystajฤ…c z .", + "domain_pill.your_handle": "Twรณj uchwyt:", + "domain_pill.your_server": "Twรณj cyfrowy dom, w ktรณrym ลผyjฤ… wszystkie Twoje wpisy. Nie lubisz tego? Zmieล„ serwer w dowolnym momencie i przenieล› swoich obserwujฤ…cych.", + "domain_pill.your_username": "Twรณj unikalny identyfikator na tym serwerze. Uลผytkownicy o tej samej nazwie mogฤ… wspรณล‚istnieฤ‡ na rรณลผnych serwerach.", "embed.instructions": "Osadลบ ten wpis na swojej stronie wklejajฤ…c poniลผszy kod.", "embed.preview": "Bฤ™dzie to wyglฤ…daฤ‡ tak:", "emoji_button.activity": "Aktywnoล›ฤ‡", @@ -241,6 +266,7 @@ "empty_column.list": "Nie ma nic na tej liล›cie. Kiedy czล‚onkowie listy dodadzฤ… nowe wpisy, pojawia siฤ™ one tutaj.", "empty_column.lists": "Nie masz ลผadnych list. Kiedy utworzysz jednฤ…, pojawi siฤ™ tutaj.", "empty_column.mutes": "Nie wyciszyล‚eล›(-aล›) jeszcze ลผadnego uลผytkownika.", + "empty_column.notification_requests": "To wszystko โ€“ kiedy otrzymasz nowe powiadomienia, pokaลผฤ… siฤ™ tutaj zgodnie z twoimi ustawieniami.", "empty_column.notifications": "Nie masz ลผadnych powiadomieล„. Rozpocznij interakcje z innymi uลผytkownikami.", "empty_column.public": "Tu nic nie ma! Napisz coล› publicznie, lub dodaj ludzi z innych serwerรณw, aby to wyล›wietliฤ‡", "error.unexpected_crash.explanation": "W zwiฤ…zku z bล‚ฤ™dem w naszym kodzie lub braku kompatybilnoล›ci przeglฤ…darki, ta strona nie moลผe byฤ‡ poprawnie wyล›wietlona.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Ten serwer", "firehose.remote": "Inne serwery", "follow_request.authorize": "Autoryzuj", "follow_request.reject": "Odrzuฤ‡", "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": "Wybรณr redakcji", + "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}.", + "follow_suggestions.hints.most_interactions": "Ten profil otrzymuje duลผo interakcji na {domain}.", + "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Obserwuj hasztag", "hashtag.unfollow": "Przestaล„ obserwowaฤ‡ hashtag", "hashtags.and_other": "โ€ฆi {count, plural, other {jeszcze #}}", - "home.column_settings.basic": "Podstawowe", "home.column_settings.show_reblogs": "Pokazuj podbicia", "home.column_settings.show_replies": "Pokazuj odpowiedzi", "home.hide_announcements": "Ukryj ogล‚oszenia", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Pokaลผ profil mimo to", "limited_account_hint.title": "Ten profil zostaล‚ ukryty przez moderatorรณw {domain}.", "link_preview.author": "{name}", + "link_preview.more_from_author": "Wiฤ™cej od {name}", + "link_preview.shares": "{count, plural, one {{counter} wpis} few {{counter} wpisy} many {{counter} wpisรณw} other {{counter} wpisรณw}}", "lists.account.add": "Dodaj do listy", "lists.account.remove": "Usunฤ…ฤ‡ z listy", "lists.delete": "Usuล„ listฤ™", @@ -395,9 +434,15 @@ "loading_indicator.label": "ลadowanieโ€ฆ", "media_gallery.toggle_visible": "Przeล‚ฤ…cz widocznoล›ฤ‡", "moved_to_account_banner.text": "Twoje konto {disabledAccount} jest obecnie wyล‚ฤ…czone, poniewaลผ zostaล‚o przeniesione na {movedToAccount}.", - "mute_modal.duration": "Czas", - "mute_modal.hide_notifications": "Chcesz ukryฤ‡ powiadomienia od tego uลผytkownika?", - "mute_modal.indefinite": "Nieokreล›lony", + "mute_modal.hide_from_notifications": "Ukryj z powiadomieล„", + "mute_modal.hide_options": "Ukryj opcje", + "mute_modal.indefinite": "Do rฤ™cznego usuniฤ™cia wyciszenia", + "mute_modal.show_options": "Pokaลผ opcje", + "mute_modal.they_can_mention_and_follow": "Uลผytkownik moลผe Ciฤ™ obserwowaฤ‡ oraz dodawaฤ‡ wzmianki, ale Ty ich nie zobaczysz.", + "mute_modal.they_wont_know": "Uลผytkownik nie dowie siฤ™, ลผe zostaล‚ wyciszony.", + "mute_modal.title": "Wyciszyฤ‡ uลผytkownika?", + "mute_modal.you_wont_see_mentions": "Nie zobaczysz wpisรณw, ktรณre wspominajฤ… tego uลผytkownika.", + "mute_modal.you_wont_see_posts": "Uลผytkownik dalej bฤ™dzie widzieฤ‡ Twoje posty, ale Ty nie bฤ™dziesz widzieฤ‡ jego.", "navigation_bar.about": "O serwerze", "navigation_bar.advanced_interface": "Otwรณrz w zaawansowanym interfejsie uลผytkownika", "navigation_bar.blocks": "Zablokowani uลผytkownicy", @@ -430,11 +475,28 @@ "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", + "notification_requests.dismiss": "Odrzuฤ‡", + "notification_requests.notifications_from": "Powiadomienia od {name}", + "notification_requests.title": "Powiadomienia filtrowane", "notifications.clear": "Wyczyล›ฤ‡ powiadomienia", "notifications.clear_confirmation": "Czy na pewno chcesz bezpowrotnie usunฤ…ฤ‡ wszystkie powiadomienia?", "notifications.column_settings.admin.report": "Nowe zgล‚oszenia:", @@ -443,7 +505,6 @@ "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.filter_bar.show_bar": "Pokaลผ filtry", "notifications.column_settings.follow": "Nowi obserwujฤ…cy:", "notifications.column_settings.follow_request": "Nowe proล›by o moลผliwoล›ฤ‡ obserwacji:", "notifications.column_settings.mention": "Wspomnienia:", @@ -469,6 +530,15 @@ "notifications.permission_denied": "Powiadomienia na pulpicie nie sฤ… dostฤ™pne, poniewaลผ wczeล›niej nie udzielono uprawnieล„ w przeglฤ…darce", "notifications.permission_denied_alert": "Powiadomienia na pulpicie nie mogฤ… zostaฤ‡ wล‚ฤ…czone, poniewaลผ wczeล›niej odmรณwiono uprawnieล„", "notifications.permission_required": "Powiadomienia na pulpicie nie sฤ… dostฤ™pne, poniewaลผ nie przyznano wymaganego uprawnienia.", + "notifications.policy.filter_new_accounts.hint": "Utworzone w ciฤ…gu {days, plural, one {ostatniego dnia} other {ostatnich # dni}}", + "notifications.policy.filter_new_accounts_title": "Nowe konta", + "notifications.policy.filter_not_followers_hint": "Zawierajฤ…ce osoby ktรณre obserwujฤ… ciฤ™ krรณcej niลผ {days, plural, one {dzieล„} other {# dni}}", + "notifications.policy.filter_not_followers_title": "Ludzie, ktรณrzy ciฤ™ nie obserwujฤ…", + "notifications.policy.filter_not_following_hint": "Aลผ ich rฤ™cznie nie zatwierdzisz", + "notifications.policy.filter_not_following_title": "Ludzie, ktรณrych nie obserwujesz", + "notifications.policy.filter_private_mentions_hint": "Odfiltrowane, chyba ลผe sฤ… odpowiedziฤ… na twojฤ… wล‚asnฤ… wzmiankฤ™, lub obserwujesz wysyล‚ajฤ…cego", + "notifications.policy.filter_private_mentions_title": "Nieproszone prywatne wzmianki", + "notifications.policy.title": "Odfiltruj powiadomienia odโ€ฆ", "notifications_permission_banner.enable": "Wล‚ฤ…cz powiadomienia na pulpicie", "notifications_permission_banner.how_to_control": "Aby otrzymywaฤ‡ powiadomienia, gdy Mastodon nie jest otwarty, wล‚ฤ…cz powiadomienia pulpitu. Moลผesz dokล‚adnie kontrolowaฤ‡, oktรณrych dziaล‚aniach bฤ™dziesz powiadomienia na pulpicie za pomocฤ… przycisku {icon} powyลผej, jeลผeli tylko zostanฤ… wล‚ฤ…czone.", "notifications_permission_banner.title": "Nie przegap niczego", @@ -625,13 +695,13 @@ "server_banner.about_active_users": "Osoby korzystajฤ…ce z tego serwera w ciฤ…gu ostatnich 30 dni (Miesiฤ™cznie aktywni uลผytkownicy)", "server_banner.active_users": "aktywni uลผytkownicy", "server_banner.administered_by": "Zarzฤ…dzana przez:", - "server_banner.introduction": "{domain} jest czฤ™ล›ciฤ… zdecentralizowanej sieci spoล‚ecznoล›ciowej wspieranej przez {mastodon}.", - "server_banner.learn_more": "Dowiedz siฤ™ wiฤ™cej", + "server_banner.is_one_of_many": "{domain} jest jednฤ… z wielu niezaleลผnych serwerรณw Mastodon, ktรณrych moลผesz uลผyฤ‡ by uczestniczyฤ‡ w fediwersum.", "server_banner.server_stats": "Statystyki serwera:", "sign_in_banner.create_account": "Zaล‚รณลผ konto", + "sign_in_banner.follow_anyone": "Obserwuj kogokolwiek z fediwersum w kolejnoล›ci chronologicznej. Bez algorytmรณw ani reklam.", + "sign_in_banner.mastodon_is": "Mastodon to najlepszy sposรณb nadฤ…ลผania za bieลผฤ…cymi zdarzeniami.", "sign_in_banner.sign_in": "Zaloguj siฤ™", "sign_in_banner.sso_redirect": "Zaloguj/zarejestruj siฤ™", - "sign_in_banner.text": "Zaloguj siฤ™, aby obserwowaฤ‡ profile lub hashtagi, polubiฤ‡, udostฤ™pniฤ‡ oraz odpowiedzieฤ‡ na posty. Moลผesz rรณwnieลผ wejล›ฤ‡ w interakcjฤ™ z konta na innym serwerze.", "status.admin_account": "Otwรณrz interfejs moderacyjny dla @{name}", "status.admin_domain": "Otwรณrz interfejs moderacyjny dla {domain}", "status.admin_status": "Otwรณrz ten wpis w interfejsie moderacyjnym", @@ -645,10 +715,11 @@ "status.direct": "Prywatna wzmianka @{name}", "status.direct_indicator": "Prywatna wzmianka", "status.edit": "Edytuj", - "status.edited": "Edytowano {date}", + "status.edited": "Ostatnio edytowane {date}", "status.edited_x_times": "Edytowano {count, plural, one {{count} raz} other {{count} razy}}", "status.embed": "Osadลบ", "status.favourite": "Dodaj do ulubionych", + "status.favourites": "{count, plural, one {polubienie} few {polubienia} other {polubieล„}}", "status.filter": "Filtruj ten wpis", "status.filtered": "Filtrowany(-a)", "status.hide": "Ukryj post", @@ -669,6 +740,7 @@ "status.reblog": "Podbij", "status.reblog_private": "Podbij dla odbiorcรณw oryginalnego wpisu", "status.reblogged_by": "Podbite przez {name}", + "status.reblogs": "{count, plural, one {podbicie} few {podbicia} other {podbiฤ‡}}", "status.reblogs.empty": "Nikt nie podbiล‚ jeszcze tego wpisu. Gdy ktoล› to zrobi, pojawi siฤ™ tutaj.", "status.redraft": "Usuล„ i przeredaguj", "status.remove_bookmark": "Usuล„ zakล‚adkฤ™", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index eced6ca7ad..afe5490547 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -89,6 +89,14 @@ "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", "bundle_column_error.copy_stacktrace": "Copiar relatรณrio do erro", "bundle_column_error.error.body": "A pรกgina solicitada nรฃo pรดde ser renderizada. Pode ser devido a um erro no nosso cรณdigo, ou um problema de compatibilidade do seu navegador.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Sem Aviso de Conteรบdo", "compose_form.spoiler_placeholder": "Aviso de conteรบdo (opcional)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear e denunciar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "Vocรช tem certeza de que deseja bloquear {name}?", "confirmations.cancel_follow_request.confirm": "Cancelar a solicitaรงรฃo", "confirmations.cancel_follow_request.message": "Tem certeza de que deseja cancelar seu pedido para seguir {name}?", "confirmations.delete.confirm": "Excluir", @@ -171,15 +177,13 @@ "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": "Bloquear instรขncia", + "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?", "confirmations.logout.confirm": "Sair", "confirmations.logout.message": "Vocรช tem certeza de que deseja sair?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Isso ocultarรก toots do usuรกrio e toots que o mencionam, mas ainda permitirรก que ele veja teus toots e te siga.", - "confirmations.mute.message": "Vocรช tem certeza de que deseja silenciar {name}?", "confirmations.redraft.confirm": "Excluir e rascunhar", "confirmations.redraft.message": "Vocรช tem certeza de que quer apagar essa postagem e rascunhรก-la? Favoritos e impulsos serรฃo perdidos, e respostas ร  postagem original ficarรฃo รณrfรฃs.", "confirmations.reply.confirm": "Responder", @@ -205,6 +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", @@ -241,6 +266,7 @@ "empty_column.list": "Nada aqui. Quando membros da lista tootarem, eles aparecerรฃo aqui.", "empty_column.lists": "Nada aqui. Quando vocรช criar listas, elas aparecerรฃo aqui.", "empty_column.mutes": "Nada aqui.", + "empty_column.notification_requests": "Tudo limpo! Nรฃo hรก nada aqui. Quando vocรช receber novas notificaรงรตes, elas aparecerรฃo aqui de acordo com suas configuraรงรตes.", "empty_column.notifications": "Interaja com outros usuรกrios para comeรงar a conversar.", "empty_column.public": "Publique algo ou siga manualmente usuรกrios de outros servidores", "error.unexpected_crash.explanation": "Esta pรกgina nรฃo pรดde ser mostrada corretamente. Este erro provavelmente รฉ devido a um bug em nosso cรณdigo ou um problema de compatibilidade de navegador.", @@ -271,16 +297,28 @@ "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", "firehose.remote": "Outros servidores", "follow_request.authorize": "Aprovar", "follow_request.reject": "Recusar", "follow_requests.unlocked_explanation": "Apesar de seu perfil nรฃo ser trancado, {domain} exige que vocรช revise a solicitaรงรฃo para te seguir destes perfis manualmente.", - "follow_suggestions.curated_suggestion": "Escolha dos editores", + "follow_suggestions.curated_suggestion": "Escolha da equipe", "follow_suggestions.dismiss": "Nรฃo mostrar novamente", + "follow_suggestions.featured_longer": "Escolhido ร  mรฃo pela equipe de {domain}", + "follow_suggestions.friends_of_friends_longer": "Popular entre as pessoas que vocรช 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 em {domain}.", + "follow_suggestions.hints.most_interactions": "Este perfil tem recebido recentemente muita atenรงรฃo em {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Este perfil รฉ semelhante aos perfis que vocรช seguiu 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": "Similar a perfis que vocรช seguiu recentemente", "follow_suggestions.view_all": "Visualizar tudo", "follow_suggestions.who_to_follow": "Quem seguir", "followed_tags": "Hashtags seguidas", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir hashtag", "hashtag.unfollow": "Parar de seguir hashtag", "hashtags.and_other": "โ€ฆe {count, plural, one {}other {outros #}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Mostrar boosts", "home.column_settings.show_replies": "Mostrar respostas", "home.hide_announcements": "Ocultar comunicados", @@ -377,6 +414,7 @@ "limited_account_hint.action": "Exibir perfil mesmo assim", "limited_account_hint.title": "Este perfil foi ocultado pelos moderadores do {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mais de {name}", "lists.account.add": "Adicionar ร  lista", "lists.account.remove": "Remover da lista", "lists.delete": "Excluir lista", @@ -395,9 +433,15 @@ "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.duration": "Duraรงรฃo", - "mute_modal.hide_notifications": "Ocultar notificaรงรตes deste usuรกrio?", - "mute_modal.indefinite": "Indefinido", + "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.", + "mute_modal.title": "Silenciar usuรกrio?", + "mute_modal.you_wont_see_mentions": "Vocรช nรฃo verรก publicaรงรตes que os mencionem.", + "mute_modal.you_wont_see_posts": "Eles ainda poderรฃo ver suas publicaรงรตes, mas vocรช nรฃo verรก as deles.", "navigation_bar.about": "Sobre", "navigation_bar.advanced_interface": "Ativar na interface web avanรงada", "navigation_bar.blocks": "Usuรกrios bloqueados", @@ -430,20 +474,37 @@ "notification.follow": "{name} te seguiu", "notification.follow_request": "{name} quer te seguir", "notification.mention": "{name} te mencionou", + "notification.moderation-warning.learn_more": "Aprender mais", + "notification.moderation_warning": "Vocรช recebeu um aviso de moderaรงรฃo", + "notification.moderation_warning.action_delete_statuses": "Algumas das suas publicaรงรตes foram removidas.", + "notification.moderation_warning.action_disable": "Sua conta foi desativada.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicaรงรตes foram marcadas por ter conteรบdo sensรญvel.", + "notification.moderation_warning.action_none": "Sua conta recebeu um aviso de moderaรงรฃo.", + "notification.moderation_warning.action_sensitive": "Suas publicaรงรตes serรฃo marcadas como sensรญveis a partir de agora.", + "notification.moderation_warning.action_silence": "Sua conta foi limitada.", + "notification.moderation_warning.action_suspend": "Sua conta foi suspensa.", "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", + "notification_requests.dismiss": "Rejeitar", + "notification_requests.notifications_from": "Notificaรงรตes de {name}", + "notification_requests.title": "Notificaรงรตes filtradas", "notifications.clear": "Limpar notificaรงรตes", "notifications.clear_confirmation": "Vocรช tem certeza de que deseja limpar todas as suas notificaรงรตes?", "notifications.column_settings.admin.report": "Novas denรบncias:", "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": "Mostrar todas as categorias", - "notifications.column_settings.filter_bar.category": "Barra de filtro rรกpido das notificaรงรตes", - "notifications.column_settings.filter_bar.show_bar": "Mostrar barra de filtro", + "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:", @@ -469,6 +530,15 @@ "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", + "notifications.policy.filter_private_mentions_hint": "Filtrado, a menos que respondido em sua prรณpria menรงรฃo ou se vocรช segue o remetente", + "notifications.policy.filter_private_mentions_title": "Menรงรตes privadas nรฃo solicitadas", + "notifications.policy.title": "Filtrar notificaรงรตes deโ€ฆ", "notifications_permission_banner.enable": "Ativar notificaรงรตes no computador", "notifications_permission_banner.how_to_control": "Para receber notificaรงรตes quando o Mastodon nรฃo estiver aberto, ative as notificaรงรตes no computador. Vocรช pode controlar precisamente quais tipos de interaรงรตes geram notificaรงรตes no computador atravรฉs do botรฃo {icon}.", "notifications_permission_banner.title": "Nunca perca nada", @@ -530,6 +600,9 @@ "privacy.private.short": "Seguidores", "privacy.public.long": "Qualquer um dentro ou fora do Mastodon", "privacy.public.short": "Pรบblico", + "privacy.unlisted.additional": "Isso se comporta exatamente como pรบblico, exceto que a publicaรงรฃo nรฃo aparecerรก nos _feeds ao vivo_ ou nas _hashtags_, explorar, ou barra de busca, mesmo que vocรช seja escolhido em toda a conta.", + "privacy.unlisted.long": "Menos notificaรงรตes e recomendaรงรตes do algoritmo", + "privacy.unlisted.short": "Pรบblico (silencioso)", "privacy_policy.last_updated": "Atualizado {date}", "privacy_policy.title": "Polรญtica de privacidade", "recommended": "Recomendado", @@ -547,6 +620,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", @@ -621,13 +695,10 @@ "server_banner.about_active_users": "Pessoas usando este servidor durante os รบltimos 30 dias (Usuรกrios ativos mensalmente)", "server_banner.active_users": "usuรกrios ativos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} faz parte da rede social descentralizada desenvolvida por {mastodon}.", - "server_banner.learn_more": "Saiba mais", "server_banner.server_stats": "Estatรญsticas do servidor:", "sign_in_banner.create_account": "Criar conta", "sign_in_banner.sign_in": "Entrar", "sign_in_banner.sso_redirect": "Entrar ou Registrar-se", - "sign_in_banner.text": "Identifique-se para seguir perfis ou 'hashtags', favoritar, compartilhar e responder publicaรงรตes. Vocรช tambรฉm pode interagir a partir da sua conta em um servidor diferente.", "status.admin_account": "Abrir interface de moderaรงรฃo para @{name}", "status.admin_domain": "Abrir interface de moderaรงรฃo para {domain}", "status.admin_status": "Abrir este toot na interface de moderaรงรฃo", @@ -641,10 +712,11 @@ "status.direct": "Mencione em privado @{name}", "status.direct_indicator": "Menรงรฃo privada", "status.edit": "Editar", - "status.edited": "Editado em {date}", + "status.edited": "รšltima ediรงรฃo em {date}", "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", @@ -665,6 +737,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 3674126144..9446d5ee25 100644 --- a/app/javascript/mastodon/locales/pt-PT.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -89,6 +89,14 @@ "announcement.announcement": "Anรบncio", "attachments_list.unprocessed": "(nรฃo processado)", "audio.hide": "Ocultar รกudio", + "block_modal.remote_users_caveat": "Vamos pedir ao servidor {domain} para respeitar a sua decisรฃo. No entanto, nรฃo รฉ garantido o seu cumprimento, uma vez que alguns servidores podem tratar os bloqueios de forma diferente. As mensagens pรบblicas podem continuar a ser visรญveis para utilizadores nรฃo autenticados.", + "block_modal.show_less": "Mostrar menos", + "block_modal.show_more": "Mostrar mais", + "block_modal.they_cant_mention": "Eles nรฃo o podem mencionar ou seguir.", + "block_modal.they_cant_see_posts": "Eles nรฃo podem ver as suas publicaรงรตes e vocรช nรฃo verรก as deles.", + "block_modal.they_will_know": "Eles podem ver que estรฃo bloqueados.", + "block_modal.title": "Bloquear utilizador?", + "block_modal.you_wont_see_mentions": "Nรฃo verรก publicaรงรตes que os mencionem.", "boost_modal.combo": "Pode clicar {combo} para nรฃo voltar a ver", "bundle_column_error.copy_stacktrace": "Copiar relatรณrio de erros", "bundle_column_error.error.body": "A pรกgina solicitada nรฃo pรดde ser sintetizada. Isto pode ser devido a uma falha no nosso cรณdigo ou a um problema de compatibilidade com o navegador.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Juntar um aviso de conteรบdo", "compose_form.spoiler_placeholder": "Aviso de conteรบdo (opcional)", "confirmation_modal.cancel": "Cancelar", - "confirmations.block.block_and_report": "Bloquear e Denunciar", "confirmations.block.confirm": "Bloquear", - "confirmations.block.message": "De certeza que queres bloquear {name}?", "confirmations.cancel_follow_request.confirm": "Retirar pedido", "confirmations.cancel_follow_request.message": "Tem a certeza que pretende retirar o pedido para seguir {name}?", "confirmations.delete.confirm": "Eliminar", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Tens a certeza de que deseja eliminar permanentemente esta lista?", "confirmations.discard_edit_media.confirm": "Descartar", "confirmations.discard_edit_media.message": "Tem alteraรงรตes por guardar na descriรงรฃo ou prรฉ-visualizaรงรฃo do conteรบdo. Descartar mesmo assim?", - "confirmations.domain_block.confirm": "Esconder tudo deste domรญnio", + "confirmations.domain_block.confirm": "Bloquear servidor", "confirmations.domain_block.message": "De certeza que queres bloquear completamente o domรญnio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores รฉ suficiente e รฉ o recomendado. Nรฃo irรกs ver conteรบdo daquele domรญnio em cronologia alguma nem nas tuas notificaรงรตes. Os teus seguidores daquele domรญnio serรฃo removidos.", "confirmations.edit.confirm": "Editar", "confirmations.edit.message": "Editar agora irรก sobrescrever a mensagem que estรก a compor. Tem a certeza de que deseja continuar?", "confirmations.logout.confirm": "Terminar sessรฃo", "confirmations.logout.message": "Tem a certeza de que quer terminar a sessรฃo?", "confirmations.mute.confirm": "Silenciar", - "confirmations.mute.explanation": "Isto irรก esconder publicaรงรตes deles ou publicaรงรตes que os mencionem, mas irรก permitir que vejam as suas publicaรงรตes e sejam seus seguidores.", - "confirmations.mute.message": "De certeza que queres silenciar {name}?", "confirmations.redraft.confirm": "Eliminar & reescrever", "confirmations.redraft.message": "Tem a certeza de que quer eliminar e reescrever esta publicaรงรฃo? Os favoritos e partilhas perder-se-รฃo e as respostas ร  publicaรงรฃo original ficarรฃo รณrfรฃs.", "confirmations.reply.confirm": "Responder", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Estas sรฃo publicaรงรตes de toda a rede social que estรฃo a ganhar popularidade atualmente. As mensagens mais recentes com mais partilhas e favoritos obtรชm uma classificaรงรฃo mais elevada.", "dismissable_banner.explore_tags": "Estas #etiquetas estรฃo presentemente a ganhar atenรงรฃo entre as pessoas neste e noutros servidores da rede descentralizada.", "dismissable_banner.public_timeline": "Estas sรฃo as publicaรงรตes pรบblicas mais recentes de pessoas na rede social que as pessoas em {domain} seguem.", + "domain_block_modal.block": "Bloquear servidor", + "domain_block_modal.block_account_instead": "Bloquear @{name} em alternativa", + "domain_block_modal.they_can_interact_with_old_posts": "As pessoas deste servidor podem interagir com as suas publicaรงรตes antigas.", + "domain_block_modal.they_cant_follow": "Ninguรฉm deste servidor pode segui-lo.", + "domain_block_modal.they_wont_know": "Eles nรฃo saberรฃo que foram bloqueados.", + "domain_block_modal.title": "Bloquear domรญnio?", + "domain_block_modal.you_will_lose_followers": "Todos os seus seguidores deste servidor serรฃo removidos.", + "domain_block_modal.you_wont_see_posts": "Nรฃo verรก publicaรงรตes ou notificaรงรตes de utilizadores neste servidor.", + "domain_pill.activitypub_lets_connect": "Permite-lhe conectar e interagir com pessoas nรฃo sรณ no Mastodon, mas tambรฉm em diferentes aplicaรงรตes sociais.", + "domain_pill.activitypub_like_language": "O ActivityPub รฉ como a linguagem que o Mastodon fala com outras redes sociais.", + "domain_pill.server": "Servidor", + "domain_pill.their_handle": "O seu identificador:", + "domain_pill.their_server": "A sua casa digital, onde se encontram todas as suas publicaรงรตes.", + "domain_pill.their_username": "O seu identificador รบnico no seu servidor. ร‰ possรญvel encontrar utilizadores com o mesmo nome de utilizador em diferentes servidores.", + "domain_pill.username": "Nome de utilizador", + "domain_pill.whats_in_a_handle": "Em que consiste um identificador?", + "domain_pill.who_they_are": "Uma vez que os identificadores dizem quem รฉ alguรฉm e onde estรก, pode interagir com as pessoas atravรฉs da rede social de .", + "domain_pill.who_you_are": "Uma vez que o seu identificador indica quem รฉ e onde estรก, as pessoas podem interagir consigo atravรฉs da rede social de .", + "domain_pill.your_handle": "O seu identificador:", + "domain_pill.your_server": "A sua casa digital, onde se encontram todas as suas publicaรงรตes. Nรฃo gosta deste? Mude de servidor a qualquer momento e leve tambรฉm os seus seguidores.", + "domain_pill.your_username": "O seu identificador รบnico neste servidor. ร‰ possรญvel encontrar utilizadores com o mesmo nome de utilizador em diferentes servidores.", "embed.instructions": "Incorpore esta publicaรงรฃo no seu site copiando o cรณdigo abaixo.", "embed.preview": "Podes ver aqui como irรก ficar:", "emoji_button.activity": "Actividade", @@ -241,6 +266,7 @@ "empty_column.list": "Ainda nรฃo existem publicaรงรตes nesta lista. Quando membros desta lista fizerem novas publicaรงรตes, elas aparecerรฃo aqui.", "empty_column.lists": "Ainda nรฃo tem qualquer lista. Quando criar uma, ela irรก aparecer aqui.", "empty_column.mutes": "Ainda nรฃo silenciaste qualquer utilizador.", + "empty_column.notification_requests": "Tudo limpo! Nรฃo hรก nada aqui. Quando vocรช receber novas notificaรงรตes, elas aparecerรฃo aqui conforme as suas configuraรงรตes.", "empty_column.notifications": "Nรฃo tens notificaรงรตes. Interage com outros utilizadores para iniciar uma conversa.", "empty_column.public": "Nรฃo hรก nada aqui! Escreve algo publicamente ou segue outros utilizadores para veres aqui os conteรบdos pรบblicos", "error.unexpected_crash.explanation": "Devido a um erro no nosso cรณdigo ou a uma compatilidade com o seu navegador, esta pรกgina nรฃo pรดde ser apresentada correctamente.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Este servidor", "firehose.remote": "Outros servidores", "follow_request.authorize": "Autorizar", "follow_request.reject": "Rejeitar", "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 dos Editores", + "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}.", + "follow_suggestions.hints.most_interactions": "Este perfil tem recebido recentemente muita atenรงรฃo no {domain}.", + "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", @@ -309,7 +347,6 @@ "hashtag.follow": "Seguir #etiqueta", "hashtag.unfollow": "Deixar de seguir #etiqueta", "hashtags.and_other": "โ€ฆe {count, plural, other {mais #}}", - "home.column_settings.basic": "Bรกsico", "home.column_settings.show_reblogs": "Mostrar impulsos", "home.column_settings.show_replies": "Mostrar respostas", "home.hide_announcements": "Ocultar comunicaรงรตes", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Exibir perfil mesmo assim", "limited_account_hint.title": "Este perfil foi ocultado pelos moderadores de {domain}.", "link_preview.author": "Por {name}", + "link_preview.more_from_author": "Mais de {name}", + "link_preview.shares": "{count, plural, one {{counter} publicaรงรฃo} other {{counter} publicaรงรตes}}", "lists.account.add": "Adicionar ร  lista", "lists.account.remove": "Remover da lista", "lists.delete": "Eliminar lista", @@ -395,9 +434,15 @@ "loading_indicator.label": "A carregarโ€ฆ", "media_gallery.toggle_visible": "Alternar visibilidade", "moved_to_account_banner.text": "A sua conta {disabledAccount} estรก, no momento, desativada, porque vocรช migrou para {movedToAccount}.", - "mute_modal.duration": "Duraรงรฃo", - "mute_modal.hide_notifications": "Esconder notificaรงรตes deste utilizador?", - "mute_modal.indefinite": "Indefinidamente", + "mute_modal.hide_from_notifications": "Ocultar das notificaรงรตes", + "mute_modal.hide_options": "Ocultar opรงรตes", + "mute_modal.indefinite": "Atรฉ que eu os tire do silรชncio", + "mute_modal.show_options": "Mostrar opรงรตes", + "mute_modal.they_can_mention_and_follow": "Eles podem mencionรก-lo e segui-lo, mas vocรช nรฃo os verรก.", + "mute_modal.they_wont_know": "Eles nรฃo saberรฃo que foram silenciados.", + "mute_modal.title": "Silenciar utilizador?", + "mute_modal.you_wont_see_mentions": "Nรฃo verรก publicaรงรตes que os mencionem.", + "mute_modal.you_wont_see_posts": "Eles podem continuar a ver as suas publicaรงรตes, mas vocรช nรฃo verรก as deles.", "navigation_bar.about": "Sobre", "navigation_bar.advanced_interface": "Abrir na interface web avanรงada", "navigation_bar.blocks": "Utilizadores bloqueados", @@ -430,11 +475,29 @@ "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", + "notification_requests.dismiss": "Descartar", + "notification_requests.notifications_from": "Notificaรงรตes de {name}", + "notification_requests.title": "Notificaรงรตes filtradas", "notifications.clear": "Limpar notificaรงรตes", "notifications.clear_confirmation": "Queres mesmo limpar todas as notificaรงรตes?", "notifications.column_settings.admin.report": "Novas denรบncias:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Mostrar barra de filtros", "notifications.column_settings.follow": "Novos seguidores:", "notifications.column_settings.follow_request": "Novos pedidos de seguidor:", "notifications.column_settings.mention": "Menรงรตes:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Notificaรงรตes no ambiente de trabalho nรฃo estรฃo disponรญveis porque a permissรฃo, solicitada pelo navegador, foi recusada anteriormente", "notifications.permission_denied_alert": "Notificaรงรตes no ambiente de trabalho nรฃo podem ser ativadas, pois a permissรฃo do navegador foi recusada anteriormente", "notifications.permission_required": "Notificaรงรตes no ambiente de trabalho nรฃo estรฃo disponรญveis porque a permissรฃo necessรกria nรฃo foi concedida.", + "notifications.policy.filter_new_accounts.hint": "Criada nos รบltimos {days, plural, one {um dia} other {# dias}}", + "notifications.policy.filter_new_accounts_title": "Novas contas", + "notifications.policy.filter_not_followers_hint": "Incluindo pessoas que o seguem hรก menos de {days, plural, one {um dia} other {# dias}}", + "notifications.policy.filter_not_followers_title": "Pessoas nรฃo te seguem", + "notifications.policy.filter_not_following_hint": "Atรฉ que vocรช os aprove manualmente", + "notifications.policy.filter_not_following_title": "Pessoas que vocรช nรฃo segue", + "notifications.policy.filter_private_mentions_hint": "Filtrado, a menos que seja em resposta ร  sua prรณpria menรงรฃo ou se vocรช seguir o remetente", + "notifications.policy.filter_private_mentions_title": "Menรงรตes privadas nรฃo solicitadas", + "notifications.policy.title": "Filtrar notificaรงรตes deโ€ฆ", "notifications_permission_banner.enable": "Ativar notificaรงรตes no ambiente de trabalho", "notifications_permission_banner.how_to_control": "Para receber notificaรงรตes quando o Mastodon nรฃo estiver aberto, ative as notificaรงรตes no ambiente de trabalho. Depois da sua ativaรงรฃo, pode controlar precisamente quais tipos de interaรงรตes geram notificaรงรตes, atravรฉs do botรฃo {icon} acima.", "notifications_permission_banner.title": "Nunca perca nada", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Pessoas que utilizaram este servidor nos รบltimos 30 dias (Utilizadores Ativos Mensais)", "server_banner.active_users": "utilizadores ativos", "server_banner.administered_by": "Administrado por:", - "server_banner.introduction": "{domain} faz parte da rede social descentralizada baseada no {mastodon}.", - "server_banner.learn_more": "Saber mais", + "server_banner.is_one_of_many": "{domain} รฉ um dos muitos servidores Mastodon independentes que pode utilizar para participar no fediverso.", "server_banner.server_stats": "Estatรญsticas do servidor:", "sign_in_banner.create_account": "Criar conta", + "sign_in_banner.follow_anyone": "Siga alguรฉm no fediverso e veja tudo em ordem cronolรณgica. Sem algoritmos, anรบncios ou clickbait ร  vista.", + "sign_in_banner.mastodon_is": "O Mastodon รฉ a melhor maneira de acompanhar o que estรก a acontecer.", "sign_in_banner.sign_in": "Iniciar Sessรฃo", "sign_in_banner.sso_redirect": "Inicie Sessรฃo ou Registe-se", - "sign_in_banner.text": "Inicie sessรฃo para seguir perfis ou etiquetas, assinale como favorito, partilhe ou responda a publicaรงรตes. Pode ainda interagir atravรฉs da sua conta noutro servidor.", "status.admin_account": "Abrir a interface de moderaรงรฃo para @{name}", "status.admin_domain": "Abrir interface de moderaรงรฃo para {domain}", "status.admin_status": "Abrir esta publicaรงรฃo na interface de moderaรงรฃo", @@ -645,10 +716,11 @@ "status.direct": "Mencionar @{name} em privado", "status.direct_indicator": "Menรงรฃo privada", "status.edit": "Editar", - "status.edited": "Editado em {date}", + "status.edited": "รšltima ediรงรฃo em {date}", "status.edited_x_times": "Editado {count, plural,one {{count} vez} other {{count} vezes}}", "status.embed": "Embutir", "status.favourite": "Assinalar como favorito", + "status.favourites": "{count, plural, one {favorito} other {favoritos}}", "status.filter": "Filtrar esta publicaรงรฃo", "status.filtered": "Filtrada", "status.hide": "Ocultar publicaรงรฃo", @@ -669,6 +741,7 @@ "status.reblog": "Partilhar", "status.reblog_private": "Partilhar com a visibilidade original", "status.reblogged_by": "{name} reforรงou", + "status.reblogs": "{count, plural, one {partilha} other {partilhas}}", "status.reblogs.empty": "Ainda ninguรฉm reforรงou esta publicaรงรฃo. Quando alguรฉm o fizer, ele irรก aparecer aqui.", "status.redraft": "Apagar & reescrever", "status.remove_bookmark": "Retirar dos marcadores", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index 547493af18..3a2fab9056 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -155,9 +155,7 @@ "compose_form.spoiler.unmarked": "Adaugฤƒ un avertisment privind conศ›inutul", "compose_form.spoiler_placeholder": "Atenศ›ionare de conศ›inut (opศ›ional)", "confirmation_modal.cancel": "Anuleazฤƒ", - "confirmations.block.block_and_report": "Blocheazฤƒ ศ™i raporteazฤƒ", "confirmations.block.confirm": "Blocheazฤƒ", - "confirmations.block.message": "Eศ™ti sigur cฤƒ vrei sฤƒ blochezi pe {name}?", "confirmations.cancel_follow_request.confirm": "Retrage cererea", "confirmations.cancel_follow_request.message": "Sunteศ›i sigur cฤƒ doriศ›i sฤƒ retrageศ›i cererea dvs. de urmฤƒrire pentru {name}?", "confirmations.delete.confirm": "Eliminฤƒ", @@ -166,15 +164,12 @@ "confirmations.delete_list.message": "Eศ™ti sigur cฤƒ vrei sฤƒ elimini definitiv aceastฤƒ listฤƒ?", "confirmations.discard_edit_media.confirm": "Renunศ›ฤƒ", "confirmations.discard_edit_media.message": "Ai modificฤƒri nesalvate รฎn descrierea sau previzualizarea media, renunศ›i oricum?", - "confirmations.domain_block.confirm": "Blocheazฤƒ รฎntregul domeniu", "confirmations.domain_block.message": "Eศ™ti absolut sigur cฤƒ vrei sฤƒ blochezi tot domeniul {domain}? รŽn cele mai multe cazuri, raportarea sau blocarea anumitor lucruri este suficientฤƒ ศ™i de preferat. Nu vei mai vedea niciun conศ›inut din acest domeniu รฎn vreun flux public sau รฎn vreo notificare. Abonaศ›ii tฤƒi din acest domeniu vor fi eliminaศ›i.", "confirmations.edit.confirm": "Modificฤƒ", "confirmations.edit.message": "Editarea acum va suprascrie mesajul pe care รฎl compuneศ›i รฎn prezent. Sunteศ›i sigur cฤƒ vreศ›i sฤƒ continuaศ›i?", "confirmations.logout.confirm": "Deconectare", "confirmations.logout.message": "Eศ™ti sigur cฤƒ vrei sฤƒ te deconectezi?", "confirmations.mute.confirm": "Ignorฤƒ", - "confirmations.mute.explanation": "Postฤƒrile acestei persoane ศ™i postฤƒrile รฎn care este menศ›ionatฤƒ vor fi ascunse, รฎnsฤƒ tot va putea sฤƒ รฎศ›i vadฤƒ postฤƒrile ศ™i sฤƒ se aboneze la tine.", - "confirmations.mute.message": "Eศ™ti sigur cฤƒ vrei sฤƒ ignori pe {name}?", "confirmations.redraft.confirm": "ศ˜terge ศ™i scrie din nou", "confirmations.reply.confirm": "Rฤƒspunde", "confirmations.reply.message": "Dacฤƒ rฤƒspunzi acum, mesajul pe care รฎl scrii รฎn acest moment va fi ศ™ters. Eศ™ti sigur cฤƒ vrei sฤƒ continui?", @@ -265,7 +260,6 @@ "follow_request.authorize": "Acceptฤƒ", "follow_request.reject": "Respinge", "follow_requests.unlocked_explanation": "Chiar dacฤƒ contul tฤƒu nu este blocat, personalul {domain} a considerat cฤƒ ai putea prefera sฤƒ consulศ›i manual cererile de abonare de la aceste conturi.", - "follow_suggestions.curated_suggestion": "Alegerile Editorilor", "follow_suggestions.dismiss": "Nu mai afiศ™a din nou", "follow_suggestions.personalized_suggestion": "Sugestie personalizatฤƒ", "follow_suggestions.popular_suggestion": "Sugestie popularฤƒ", @@ -293,7 +287,6 @@ "hashtag.column_settings.tag_toggle": "Adaugฤƒ etichete suplimentare pentru aceastฤƒ coloanฤƒ", "hashtag.follow": "Urmฤƒreศ™te haศ™tagul", "hashtag.unfollow": "Nu mai urmฤƒri haศ™tagul", - "home.column_settings.basic": "De bazฤƒ", "home.column_settings.show_reblogs": "Afiศ™eazฤƒ distribuirile", "home.column_settings.show_replies": "Afiศ™eazฤƒ rฤƒspunsurile", "home.hide_announcements": "Ascunde anunศ›urile", @@ -372,9 +365,6 @@ "load_pending": "{count, plural, one {# element nou} other {# elemente noi}}", "media_gallery.toggle_visible": "{number, plural, one {Ascunde imaginea} other {Ascunde imaginile}}", "moved_to_account_banner.text": "Contul tฤƒu {disabledAccount} este รฎn acest moment dezactivat deoarece te-ai mutat la {movedToAccount}.", - "mute_modal.duration": "Durata", - "mute_modal.hide_notifications": "Ascunde notificฤƒrile de la acest utilizator?", - "mute_modal.indefinite": "Nedeterminat", "navigation_bar.about": "Despre", "navigation_bar.advanced_interface": "Deschide รฎn interfaศ›a web avansatฤƒ", "navigation_bar.blocks": "Utilizatori blocaศ›i", @@ -415,9 +405,6 @@ "notifications.column_settings.admin.report": "Raportฤƒri noi:", "notifications.column_settings.admin.sign_up": "รŽnscrieri noi:", "notifications.column_settings.alert": "Notificฤƒri pe desktop", - "notifications.column_settings.filter_bar.advanced": "Afiศ™eazฤƒ toate categoriile", - "notifications.column_settings.filter_bar.category": "Barฤƒ de filtrare rapidฤƒ", - "notifications.column_settings.filter_bar.show_bar": "Aratฤƒ bara de filtrare", "notifications.column_settings.follow": "Noi urmฤƒritori:", "notifications.column_settings.follow_request": "Noi cereri de abonare:", "notifications.column_settings.mention": "Menศ›iuni:", @@ -563,8 +550,6 @@ "server_banner.about_active_users": "Persoane care au folosit acest server รฎn ultimele 30 de zile (Utilizatori Lunari Activi)", "server_banner.active_users": "utilizatori activi", "server_banner.administered_by": "Administrat de:", - "server_banner.introduction": "{domain} face parte din reศ›eaua socialฤƒ descentralizatฤƒ alimentatฤƒ de {mastodon}.", - "server_banner.learn_more": "Aflฤƒ mai multe", "server_banner.server_stats": "Statisticile serverului:", "sign_in_banner.create_account": "Creeazฤƒ-ศ›i un cont", "sign_in_banner.sign_in": "Conecteazฤƒ-te", @@ -581,7 +566,6 @@ "status.direct": "Menศ›ioneazฤƒ @{name} รฎn privat", "status.direct_indicator": "Menศ›iune privatฤƒ", "status.edit": "Modificฤƒ", - "status.edited": "Modificat รฎn data de {date}", "status.edited_x_times": "Modificatฤƒ {count, plural, one {o datฤƒ} few {de {count} ori} other {de {count} de ori}}", "status.embed": "รŽnglobeazฤƒ", "status.filter": "Filtreazฤƒ aceastฤƒ postare", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 623b403832..40ca848147 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": "ะ—ะฐะฟั€ะพัˆะตะฝะฝะฐั ัั‚ั€ะฐะฝะธั†ะฐ ะฝะต ะผะพะถะตั‚ ะฑั‹ั‚ัŒ ะพั‚ะพะฑั€ะฐะถะตะฝะฐ. ะญั‚ะพ ะผะพะถะตั‚ ะฑั‹ั‚ัŒ ะฒั‹ะทะฒะฐะฝะพ ะพัˆะธะฑะบะพะน ะฒ ะฝะฐัˆะตะผ ะบะพะดะต ะธะปะธ ะฟั€ะพะฑะปะตะผะพะน ัะพะฒะผะตัั‚ะธะผะพัั‚ะธ ะฑั€ะฐัƒะทะตั€ะฐ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ะขะตะบัั‚ ะฝะต ัะบั€ั‹ั‚", "compose_form.spoiler_placeholder": "ะŸั€ะตะดัƒะฟั€ะตะถะดะตะฝะธะต ะพ ะบะพะฝั‚ะตะฝั‚ะต (ะพะฟั†ะธะพะฝะฐะปัŒะฝะพ)", "confirmation_modal.cancel": "ะžั‚ะผะตะฝะฐ", - "confirmations.block.block_and_report": "ะ—ะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ะธ ะฟะพะถะฐะปะพะฒะฐั‚ัŒัั", "confirmations.block.confirm": "ะ—ะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ", - "confirmations.block.message": "ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะทะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ {name}?", "confirmations.cancel_follow_request.confirm": "ะžั‚ะผะตะฝะธั‚ัŒ ะทะฐะฟั€ะพั", "confirmations.cancel_follow_request.message": "ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะพั‚ะพะทะฒะฐั‚ัŒ ัะฒะพะน ะทะฐะฟั€ะพั ะฝะฐ ะฟะพะดะฟะธัะบัƒ {name}?", "confirmations.delete.confirm": "ะฃะดะฐะปะธั‚ัŒ", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ะ’ั‹ ะดะตะนัั‚ะฒะธั‚ะตะปัŒะฝะพ ั…ะพั‚ะธั‚ะต ะฝะฐะฒัะตะณะดะฐ ัƒะดะฐะปะธั‚ัŒ ัั‚ะพั‚ ัะฟะธัะพะบ?", "confirmations.discard_edit_media.confirm": "ะžั‚ะผะตะฝะธั‚ัŒ", "confirmations.discard_edit_media.message": "ะฃ ะฒะฐั ะตัั‚ัŒ ะฝะตัะพั…ั€ะฐะฝั‘ะฝะฝั‹ะต ะธะทะผะตะฝะตะฝะธั ะพะฟะธัะฐะฝะธั ะผัƒะปัŒั‚ะธะผะตะดะธะฐ ะธะปะธ ะฟั€ะตะดะฟั€ะพัะผะพั‚ั€ะฐ, ะพั‚ะผะตะฝะธั‚ัŒ ะธั…?", - "confirmations.domain_block.confirm": "ะ”ะฐ, ะทะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ัƒะทะตะป", + "confirmations.domain_block.confirm": "ะ—ะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ ัะตั€ะฒะตั€", "confirmations.domain_block.message": "ะ’ั‹ ั‚ะพั‡ะฝะพ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะทะฐะฑะปะพะบะธั€ะพะฒะฐั‚ัŒ {domain} ะฟะพะปะฝะพัั‚ัŒัŽ? ะ’ ะฑะพะปัŒัˆะธะฝัั‚ะฒะต ัะปัƒั‡ะฐะตะฒ ะฝะตัะบะพะปัŒะบะธั… ะฑะปะพะบะธั€ะพะฒะพะบ ะธ ะธะณะฝะพั€ะธั€ะพะฒะฐะฝะธะน ะฒะฟะพะปะฝะต ะดะพัั‚ะฐั‚ะพั‡ะฝะพ. ะ’ั‹ ะฟะตั€ะตัั‚ะฐะฝะตั‚ะต ะฒะธะดะตั‚ัŒ ะฟัƒะฑะปะธั‡ะฝัƒัŽ ะปะตะฝั‚ัƒ ะธ ัƒะฒะตะดะพะผะปะตะฝะธั ะพั‚ั‚ัƒะดะฐ. ะ’ะฐัˆะธ ะฟะพะดะฟะธัั‡ะธะบะธ ะธะท ัั‚ะพะณะพ ะดะพะผะตะฝะฐ ะฑัƒะดัƒั‚ ัƒะดะฐะปะตะฝั‹.", "confirmations.edit.confirm": "ะ ะตะดะฐะบั‚ะธั€ะพะฒะฐั‚ัŒ", "confirmations.edit.message": "ะ’ ะดะฐะฝะฝั‹ะน ะผะพะผะตะฝั‚, ั€ะตะดะฐะบั‚ะธั€ะพะฒะฐะฝะธะต ะฟะตั€ะตะทะฐะฟะธัˆะตั‚ ัะพัั‚ะฐะฒะปัะตะผะพะต ะฒะฐะผะธ ัะพะพะฑั‰ะตะฝะธะต. ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะฟั€ะพะดะพะปะถะธั‚ัŒ?", "confirmations.logout.confirm": "ะ’ั‹ะนั‚ะธ", "confirmations.logout.message": "ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะฒั‹ะนั‚ะธ?", "confirmations.mute.confirm": "ะ˜ะณะฝะพั€ะธั€ะพะฒะฐั‚ัŒ", - "confirmations.mute.explanation": "ะญั‚ะพ ะดะตะนัั‚ะฒะธะต ัะบั€ะพะตั‚ ะฟะพัั‚ั‹ ะดะฐะฝะฝะพะณะพ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปั ะธ ั‚ะต, ะฒ ะบะพั‚ะพั€ั‹ั… ะพะฝ ัƒะฟะพะผะธะฝะฐะตั‚ัั, ะฝะพ ะฟั€ะธ ัั‚ะพะผ ะพะฝ ะฟะพ-ะฟั€ะตะถะฝะตะผัƒ ัะผะพะถะตั‚ ะฟะพะดะฟะธัะฐั‚ัŒัั ะธ ัะผะพั‚ั€ะตั‚ัŒ ะฒะฐัˆะธ ะฟะพัั‚ั‹.", - "confirmations.mute.message": "ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ะดะพะฑะฐะฒะธั‚ัŒ {name} ะฒ ัะฟะธัะพะบ ะธะณะฝะพั€ะธั€ัƒะตะผั‹ั…?", "confirmations.redraft.confirm": "ะฃะดะฐะปะธั‚ัŒ ะธ ะธัะฟั€ะฐะฒะธั‚ัŒ", "confirmations.redraft.message": "ะ’ั‹ ัƒะฒะตั€ะตะฝั‹, ั‡ั‚ะพ ั…ะพั‚ะธั‚ะต ัƒะดะฐะปะธั‚ัŒ ะธ ะฟะตั€ะตะฟะธัะฐั‚ัŒ ัั‚ะพั‚ ะฟะพัั‚? ะžั‚ะผะตั‚ะบะธ ยซะธะทะฑั€ะฐะฝะฝะพะณะพยป, ะฟั€ะพะดะฒะธะถะตะฝะธั ะธ ะพั‚ะฒะตั‚ั‹ ะบ ะพั€ะธะณะธะฝะฐะปัŒะฝะพะผัƒ ะฟะพัั‚ัƒ ะฑัƒะดัƒั‚ ัƒะดะฐะปะตะฝั‹.", "confirmations.reply.confirm": "ะžั‚ะฒะตั‚ะธั‚ัŒ", @@ -205,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": "ะ—ะฐะฝัั‚ะธั", @@ -241,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": "ะ˜ะท-ะทะฐ ะฝะตัะพะฒะผะตัั‚ะธะผะพะณะพ ะฑั€ะฐัƒะทะตั€ะฐ ะธะปะธ ะพัˆะธะฑะบะธ ะฒ ะฝะฐัˆะตะผ ะบะพะดะต, ัั‚ะฐ ัั‚ั€ะฐะฝะธั†ะฐ ะฝะต ะผะพะถะตั‚ ะฑั‹ั‚ัŒ ะบะพั€ั€ะตะบั‚ะฝะพ ะพั‚ะพะฑั€ะฐะถะตะฝะฐ.", @@ -271,16 +297,28 @@ "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 {ะฝะธะบะพะณะพ} 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.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}.", + "follow_suggestions.hints.most_interactions": "ะญั‚ะพั‚ ะฟั€ะพั„ะธะปัŒ ะฒ ะฟะพัะปะตะดะฝะตะต ะฒั€ะตะผั ะฟั€ะธะฒะปะตะบะฐะตั‚ ะผะฝะพะณะพ ะฒะฝะธะผะฐะฝะธั ะฝะฐ {domain}.", + "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": "ะžั‚ัะปะตะถะธะฒะฐะตะผั‹ะต ั…ััˆั‚ะตะณะธ", @@ -309,7 +347,6 @@ "hashtag.follow": "ะŸะพะดะฟะธัะฐั‚ัŒัั ะฝะฐ ะฝะพะฒั‹ะต ะฟะพัั‚ั‹", "hashtag.unfollow": "ะžั‚ะฟะธัะฐั‚ัŒัั", "hashtags.and_other": "...ะธ {count, plural, other {# ะตั‰ั‘}}", - "home.column_settings.basic": "ะžัะฝะพะฒะฝั‹ะต", "home.column_settings.show_reblogs": "ะŸะพะบะฐะทั‹ะฒะฐั‚ัŒ ะฟั€ะพะดะฒะธะถะตะฝะธั", "home.column_settings.show_replies": "ะŸะพะบะฐะทั‹ะฒะฐั‚ัŒ ะพั‚ะฒะตั‚ั‹", "home.hide_announcements": "ะกะบั€ั‹ั‚ัŒ ะพะฑัŠัะฒะปะตะฝะธั", @@ -376,7 +413,9 @@ "lightbox.previous": "ะะฐะทะฐะด", "limited_account_hint.action": "ะ’ัะต ั€ะฐะฒะฝะพ ะฟะพะบะฐะทะฐั‚ัŒ ะฟั€ะพั„ะธะปัŒ", "limited_account_hint.title": "ะญั‚ะพั‚ ะฟั€ะพั„ะธะปัŒ ะฑั‹ะป ัะบั€ั‹ั‚ ะผะพะดะตั€ะฐั‚ะพั€ะฐะผะธ {domain}.", - "link_preview.author": "ะŸะพ ะฐะปั„ะฐะฒะธั‚ัƒ", + "link_preview.author": "ะะฒั‚ะพั€: {name}", + "link_preview.more_from_author": "ะ‘ะพะปัŒัˆะต ะพั‚ {name}", + "link_preview.shares": "{count, plural, one {{counter} ะฟะพัั‚} other {{counter} ะฟะพัั‚ั‹}}", "lists.account.add": "ะ”ะพะฑะฐะฒะธั‚ัŒ ะฒ ัะฟะธัะพะบ", "lists.account.remove": "ะฃะฑั€ะฐั‚ัŒ ะธะท ัะฟะธัะบะฐ", "lists.delete": "ะฃะดะฐะปะธั‚ัŒ ัะฟะธัะพะบ", @@ -395,9 +434,15 @@ "loading_indicator.label": "ะ—ะฐะณั€ัƒะทะบะฐโ€ฆ", "media_gallery.toggle_visible": "ะŸะพะบะฐะทะฐั‚ัŒ/ัะบั€ั‹ั‚ัŒ {number, plural, =1 {ะธะทะพะฑั€ะฐะถะตะฝะธะต} other {ะธะทะพะฑั€ะฐะถะตะฝะธั}}", "moved_to_account_banner.text": "ะ’ะฐัˆะฐ ัƒั‡ะตั‚ะฝะฐั ะทะฐะฟะธััŒ {disabledAccount} ะฒ ะฝะฐัั‚ะพัั‰ะตะต ะฒั€ะตะผั ะทะฐะผะพั€ะพะถะตะฝะฐ, ะฟะพั‚ะพะผัƒ ั‡ั‚ะพ ะฒั‹ ะฟะตั€ะตะตั…ะฐะปะธ ะฝะฐ {movedToAccount}.", - "mute_modal.duration": "ะŸั€ะพะดะพะปะถะธั‚ะตะปัŒะฝะพัั‚ัŒ", - "mute_modal.hide_notifications": "ะกะบั€ั‹ั‚ัŒ ัƒะฒะตะดะพะผะปะตะฝะธั ะพั‚ ัั‚ะพะณะพ ะฟะพะปัŒะทะพะฒะฐั‚ะตะปั?", - "mute_modal.indefinite": "ะะต ะพะฟั€ะตะดะตะปะตะฝะฐ", + "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": "ะ—ะฐะฑะปะพะบะธั€ะพะฒะฐะฝะฝั‹ะต ะฟะพะปัŒะทะพะฒะฐั‚ะตะปะธ", @@ -430,11 +475,29 @@ "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.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": "ะะพะฒั‹ะต ะถะฐะปะพะฑั‹:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "ะ˜ะทะฑั€ะฐะฝะฝั‹ะต:", "notifications.column_settings.filter_bar.advanced": "ะžั‚ะพะฑั€ะฐะถะฐั‚ัŒ ะฒัะต ะบะฐั‚ะตะณะพั€ะธะธ", "notifications.column_settings.filter_bar.category": "ะŸะฐะฝะตะปัŒ ัะพั€ั‚ะธั€ะพะฒะบะธ", - "notifications.column_settings.filter_bar.show_bar": "ะžั‚ะพะฑั€ะฐะถะฐั‚ัŒ ะฟะฐะฝะตะปัŒ ัะพั€ั‚ะธั€ะพะฒะบะธ", "notifications.column_settings.follow": "ะฃ ะฒะฐั ะฝะพะฒั‹ะน ะฟะพะดะฟะธัั‡ะธะบ:", "notifications.column_settings.follow_request": "ะะพะฒั‹ะต ะทะฐะฟั€ะพัั‹ ะฝะฐ ะฟะพะดะฟะธัะบัƒ:", "notifications.column_settings.mention": "ะ’ะฐั ัƒะฟะพะผัะฝัƒะปะธ ะฒ ะฟะพัั‚ะต:", @@ -469,6 +531,14 @@ "notifications.permission_denied": "ะฃะฒะตะดะพะผะปะตะฝะธั ะฝะฐ ั€ะฐะฑะพั‡ะตะผ ัั‚ะพะปะต ะฝะตะดะพัั‚ัƒะฟะฝั‹, ั‚ะฐะบ ะบะฐะบ ะฒั‹ ะทะฐะฟั€ะตั‚ะธะปะธ ะธั… ะพั‚ะฟั€ะฐะฒะบัƒ ะฒ ะฑั€ะฐัƒะทะตั€ะต. ะŸั€ะพะฒะตั€ัŒั‚ะต ะฝะฐัั‚ั€ะพะนะบะธ ะดะปั ัะฐะนั‚ะฐ, ั‡ั‚ะพะฑั‹ ะฒะบะปัŽั‡ะธั‚ัŒ ะธั… ะพะฑั€ะฐั‚ะฝะพ.", "notifications.permission_denied_alert": "ะฃะฒะตะดะพะผะปะตะฝะธั ะฝะฐ ั€ะฐะฑะพั‡ะตะผ ัั‚ะพะปะต ะฝะตะดะพัั‚ัƒะฟะฝั‹, ั‚ะฐะบ ะบะฐะบ ะฒั‹ ั€ะฐะฝะตะต ะพั‚ะบะปะพะฝะธะปะธ ะทะฐะฟั€ะพั ะฝะฐ ะธั… ะพั‚ะฟั€ะฐะฒะบัƒ.", "notifications.permission_required": "ะงั‚ะพะฑั‹ ะฒะบะปัŽั‡ะธั‚ัŒ ัƒะฒะตะดะพะผะปะตะฝะธั ะฝะฐ ั€ะฐะฑะพั‡ะตะผ ัั‚ะพะปะต, ะฝะตะพะฑั…ะพะดะธะผะพ ั€ะฐะทั€ะตัˆะธั‚ัŒ ะธั… ะฒ ะฑั€ะฐัƒะทะตั€ะต.", + "notifications.policy.filter_new_accounts.hint": "ะกะพะทะดะฐะฝะพ ะฒ ั‚ะตั‡ะตะฝะธะต ะฟะพัะปะตะดะฝะธั… {days, plural, one {ะพะดะธะฝ ะดะตะฝัŒ} few {# ะดะฝะตะน} many {# ะดะฝะตะน} other {# ะดะฝั}}", + "notifications.policy.filter_new_accounts_title": "ะะพะฒั‹ะต ัƒั‡ั‘ั‚ะฝั‹ะต ะทะฐะฟะธัะธ", + "notifications.policy.filter_not_followers_title": "ะ›ัŽะดะธ, ะฝะต ะฟะพะดะฟะธัะฐะฝะฝั‹ะต ะฝะฐ ะฒะฐั", + "notifications.policy.filter_not_following_hint": "ะŸะพะบะฐ ะฒั‹ ะฝะต ะพะดะพะฑั€ะธั‚ะต ะธั… ะฒั€ัƒั‡ะฝัƒัŽ", + "notifications.policy.filter_not_following_title": "ะ›ัŽะดะธ, ะฝะฐ ะบะพั‚ะพั€ั‹ั… ะฒั‹ ะฝะต ะฟะพะดะฟะธัะฐะฝั‹", + "notifications.policy.filter_private_mentions_hint": "ะคะธะปัŒั‚ั€ัƒะตั‚ัั, ะตัะปะธ ั‚ะพะปัŒะบะพ ัั‚ะพ ะฝะต ะพั‚ะฒะตั‚ ะฝะฐ ะฒะฐัˆะต ัะพะฑัั‚ะฒะตะฝะฝะพะต ัƒะฟะพะผะธะฝะฐะฝะธะต ะธะปะธ ะตัะปะธ ะฒั‹ ะฟะพะดะฟะธัะฐะฝั‹ ะฝะฐ ะพั‚ะฟั€ะฐะฒะธั‚ะตะปั", + "notifications.policy.filter_private_mentions_title": "ะะตะถะตะปะฐั‚ะตะปัŒะฝั‹ะต ะปะธั‡ะฝั‹ะต ัƒะฟะพะผะธะฝะฐะฝะธั", + "notifications.policy.title": "ะคะธะปัŒั‚ั€ะพะฒะฐั‚ัŒ ัƒะฒะตะดะพะผะปะตะฝะธั ะพั‚โ€ฆ", "notifications_permission_banner.enable": "ะ’ะบะปัŽั‡ะธั‚ัŒ ัƒะฒะตะดะพะผะปะตะฝะธั", "notifications_permission_banner.how_to_control": "ะŸะพะปัƒั‡ะฐะนั‚ะต ัƒะฒะตะดะพะผะปะตะฝะธั ะดะฐะถะต ะบะพะณะดะฐ Mastodon ะทะฐะบั€ั‹ั‚, ะฒะบะปัŽั‡ะธะฒ ัƒะฒะตะดะพะผะปะตะฝะธั ะฝะฐ ั€ะฐะฑะพั‡ะตะผ ัั‚ะพะปะต. ะ ั‡ั‚ะพะฑั‹ ะปะธัˆะฝะธะน ัˆัƒะผ ะฝะต ะพั‚ะฒะปะตะบะฐะป, ะฒั‹ ะผะพะถะตั‚ะต ะฝะฐัั‚ั€ะพะธั‚ัŒ ะบะฐะบะธะต ัƒะฒะตะดะพะผะปะตะฝะธั ะฒั‹ ั…ะพั‚ะธั‚ะต ะฟะพะปัƒั‡ะฐั‚ัŒ, ะฝะฐะถะฐะฒ ะฝะฐ ะบะฝะพะฟะบัƒ {icon} ะฒั‹ัˆะต.", "notifications_permission_banner.title": "ะ‘ัƒะดัŒั‚ะต ะฒ ะบัƒั€ัะต ะฟั€ะพะธัั…ะพะดัั‰ะตะณะพ", @@ -625,13 +695,10 @@ "server_banner.about_active_users": "ะ›ัŽะดะธ, ะทะฐั…ะพะดะธะฒัˆะธะต ะฝะฐ ัั‚ะพั‚ ัะตั€ะฒะตั€ ะทะฐ ะฟะพัะปะตะดะฝะธะต 30 ะดะฝะตะน (ะตะถะตะผะตััั‡ะฝั‹ะต ะฐะบั‚ะธะฒะฝั‹ะต ะฟะพะปัŒะทะพะฒะฐั‚ะตะปะธ)", "server_banner.active_users": "ะฐะบั‚ะธะฒะฝั‹ะต ะฟะพะปัŒะทะพะฒะฐั‚ะตะปะธ", "server_banner.administered_by": "ะฃะฟั€ะฐะฒะปัะตั‚ัั:", - "server_banner.introduction": "{domain} ัะฒะปัะตั‚ัั ั‡ะฐัั‚ัŒัŽ ะดะตั†ะตะฝั‚ั€ะฐะปะธะทะพะฒะฐะฝะฝะพะน ัะพั†ะธะฐะปัŒะฝะพะน ัะตั‚ะธ, ะพัะฝะพะฒะฐะฝะฝะพะน ะฝะฐ {mastodon}.", - "server_banner.learn_more": "ะฃะทะฝะฐั‚ัŒ ะฑะพะปัŒัˆะต", "server_banner.server_stats": "ะกั‚ะฐั‚ะธัั‚ะธะบะฐ ัะตั€ะฒะตั€ะฐ:", "sign_in_banner.create_account": "ะกะพะทะดะฐั‚ัŒ ัƒั‡ั‘ั‚ะฝัƒัŽ ะทะฐะฟะธััŒ", "sign_in_banner.sign_in": "ะ’ะพะนั‚ะธ", "sign_in_banner.sso_redirect": "ะ’ะพะนะดะธั‚ะต ะธะปะธ ะ—ะฐั€ะตะณะธัั‚ั€ะธั€ัƒะนั‚ะตััŒ", - "sign_in_banner.text": "ะ’ะพะนะดะธั‚ะต, ั‡ั‚ะพะฑั‹ ะพั‚ัะปะตะถะธะฒะฐั‚ัŒ ะฟั€ะพั„ะธะปะธ, ั…ััˆั‚ะตะณะธ ะธะปะธ ะธะทะฑั€ะฐะฝะฝะพะต, ะดะตะปะธั‚ัŒัั ัะพะพะฑั‰ะตะฝะธัะผะธ ะธ ะพั‚ะฒะตั‡ะฐั‚ัŒ ะฝะฐ ะฝะธั…. ะ’ั‹ ั‚ะฐะบะถะต ะผะพะถะตั‚ะต ะฒะทะฐะธะผะพะดะตะนัั‚ะฒะพะฒะฐั‚ัŒ ั ะฒะฐัˆะตะน ัƒั‡ั‘ั‚ะฝะพะน ะทะฐะฟะธััŒัŽ ะฝะฐ ะดั€ัƒะณะพะผ ัะตั€ะฒะตั€ะต.", "status.admin_account": "ะžั‚ะบั€ั‹ั‚ัŒ ะธะฝั‚ะตั€ั„ะตะนั ะผะพะดะตั€ะฐั‚ะพั€ะฐ ะดะปั @{name}", "status.admin_domain": "ะžั‚ะบั€ั‹ั‚ัŒ ะธะฝั‚ะตั€ั„ะตะนั ะผะพะดะตั€ะฐั†ะธะธ {domain}", "status.admin_status": "ะžั‚ะบั€ั‹ั‚ัŒ ัั‚ะพั‚ ะฟะพัั‚ ะฒ ะธะฝั‚ะตั€ั„ะตะนัะต ะผะพะดะตั€ะฐั‚ะพั€ะฐ", @@ -645,7 +712,7 @@ "status.direct": "ะ›ะธั‡ะฝะพ ัƒะฟะพะผะธะฝะฐั‚ัŒ @{name}", "status.direct_indicator": "ะ›ะธั‡ะฝั‹ะต ัƒะฟะพะผะธะฝะฐะฝะธั", "status.edit": "ะ˜ะทะผะตะฝะธั‚ัŒ", - "status.edited": "ะŸะพัะปะตะดะฝะตะต ะธะทะผะตะฝะตะฝะธะต: {date}", + "status.edited": "ะ”ะฐั‚ะฐ ะฟะพัะปะตะดะฝะตะณะพ ะธะทะผะตะฝะตะฝะธั: {date}", "status.edited_x_times": "{count, plural, one {{count} ะธะทะผะตะฝะตะฝะธะต} many {{count} ะธะทะผะตะฝะตะฝะธะน} other {{count} ะธะทะผะตะฝะตะฝะธั}}", "status.embed": "ะ’ัั‚ั€ะพะธั‚ัŒ ะฝะฐ ัะฒะพะน ัะฐะนั‚", "status.favourite": "ะ˜ะทะฑั€ะฐะฝะฝะพะต", diff --git a/app/javascript/mastodon/locales/ry.json b/app/javascript/mastodon/locales/ry.json index 0967ef424b..67aad91005 100644 --- a/app/javascript/mastodon/locales/ry.json +++ b/app/javascript/mastodon/locales/ry.json @@ -1 +1,80 @@ -{} +{ + "about.blocks": "ะœะพะดะตั€ะพะฒะฐะฝั– ัะตั€ะฒะตั€ั‹", + "about.contact": "ะšะพะฝั‚ะฐะบั‚:", + "about.disclaimer": "Mastodon ั” ะทะฐะดะฐั€ัŒะฝะพะฒ ะฟั€ะพา‘ั€ะฐะผะพะฒ ะธะท ัƒะดะฟะตั€ั‚ั‹ะผ ะบะพะดะพะผ ั‚ะฐะน ั‚ะพั€ะณะพะฒะพะฒ ะทะฝะฐั‡ะบะพะฒ Mastodon gGmbH.", + "about.domain_blocks.no_reason_available": "ะŸั€ะธั‡ะธะฝั‹ ะฝะต ััะฝั–", + "about.domain_blocks.silenced.title": "ะžะฑะผะตะถะตะฝะพ", + "about.domain_blocks.suspended.explanation": "ะะธัะบั– ะฟะพะดะฐั‚ะบั‹ ะธะท ััŒะพะณะพ ัะตั€ะฒะตั€ะฐ ะฝะต ะฑัƒะดัƒั‚ ัƒะฑั€ะพะฑะปะตะฝั–, ัƒัะพะบะพั‡ะตะฝั– ั†ะธ ะฟะพะผั–ะฝัะฝั–, ัˆั‚ะพ ั‡ะธะฝะธั‚ ะฝะตะฒะพะทะผะพะถะฝะพะฒ ั…ะพั‚ัŒ-ัะบัƒ ั–ะฝั‚ะตั€ะฐะบั†ั–ัŽ ั†ะธ ะทัะทะพะบ ะธะท ั…ะพัะฝะพะฒะฐั‡ะฐะผะธ ะธะท ััŒะพะณะพ ัะตั€ะฒะตั€ะฐ.", + "about.domain_blocks.suspended.title": "ะ—ะฐะฑะปะพะบะพะฒะฐะฝะพ", + "about.not_available": "ะ˜ัั ั–ะฝั„ะพั€ะผะฐั†ั–ั ะฝะต ะฑั‹ะปะฐ ะดะพัั‚ัƒะฟะฝะฐ ะฝะฐ ััŽะผ ัะตั€ะฒะตั€ั–.", + "about.powered_by": "ะ”ะตั†ะตะฝั‚ั€ะฐะปั–ะทะพะฒะฐะฝะฐ ะผะตะดั–ะฐ ะพัะฝะพะฒะฐะฝะฐ ะฝะฐ {mastodon}", + "about.rules": "ะŸั€ะฐะฒะธะปะฐ ัะตั€ะฒะตั€ะฐ", + "account.account_note_header": "ะŸั€ะธะผั–ั‚ะบะฐ", + "account.add_or_remove_from_list": "ะ”ะฐั‚ะธ ะฐะฒะฐะดัŒ ะทะฐะฑั€ะฐั‚ะธ ะธะท ะธัะฟะธัะฐ", + "account.badges.bot": "ะะฒั‚ะพะผะฐั‚ั–ั‡ะฝะพ", + "account.badges.group": "าั€ัƒะฟะฐ", + "account.block": "ะ—ะฐะฑะปะพะบะพะฒะฐั‚ะธ @{name}", + "account.block_domain": "ะ—ะฐะฑะปะพะบะพะฒะฐั‚ะธ ะดะพะผะตะฝ {domain}", + "account.block_short": "ะ—ะฐะฑะปะพะบะพะฒะฐั‚ะธ", + "account.blocked": "ะ—ะฐะฑะปะพะบะพะฒะฐะฝะพ", + "account.browse_more_on_origin_server": "ะŸะพะทะธั€ะฐะนั‚ะต ะฑัƒะปัŒัˆะต ะฝะฐ ะพั€ะธา‘ั–ะฝะฐะปะฝัƒะผ ะฟั€ะพั„ั–ะปัŽ", + "account.cancel_follow_request": "ะฃะดะผั–ะฝะธั‚ะธ ะฟัƒะดะฟะธัะบัƒ", + "account.copy": "ะ—ะบะพะฟั–ั€ะพะฒะฐั‚ะธ ัƒะดะบะปะธะบะพะฒะฐะฝั ะฝะฐ ะฟั€ะพั„ั–ะป", + "account.disable_notifications": "ะ‘ัƒะปัŒัˆะต ะฝะต ัะฟะพะฒั–ั‰ะฐั‚ะธ ะผะธ ะบะพะปะธ {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.featured_tags.title": "ะฃะฑะปัŽะฑะปะตะฝั– ะณะตัˆั‚ะตา‘ั‹ {name}", + "account.follow": "ะŸัƒะดะฟะธัะฐั‚ะธ ัั", + "account.follow_back": "ะŸัƒะดะฟะธัะฐั‚ะธ ัั ั‚ะพะถะต", + "account.followers": "ะŸัƒะดะฟะธัะฝะธะบั‹", + "account.followers.empty": "ะฃ ััŒะพะณะพ ั…ะพัะฝะพะฒะฐั‡ะฐ ั€ะฐะท ะฝะธั” ะฟัƒะดะฟะธัะฝะธะบัƒะฒ.", + "account.following": "ะกะปั–ะดัƒั”ั‚ะต", + "account.follows.empty": "ะกะธััŒ ั…ะพัะฝะพะฒะฐั‡ ั‰ะธ ะฝะธะบะพะณะพ ะฝะต ัะปั–ะดัƒั”.", + "account.go_to_profile": "ะŸะตั€ะตะนั‚ะธ ะฝะฐ ะฟั€ะพั„ั–ะป", + "account.hide_reblogs": "ะกะฟั€ัั‚ะฐั‚ะธ ะดั€ัƒะปะตะฝั ัƒะด @{name}", + "account.joined_short": "ะ”ะฐั‚ัƒะผ ะฟั€ะธะบะฐะฟั‡ะพะฒะฐะฝั", + "account.languages": "ะŸะพะผั–ะฝัั‚ะธ ัƒะฑั€ะฐะฝั– ัะทั‹ะบั‹", + "account.link_verified_on": "ะ’ะปะฐัั‚ะฝะพัั‚ัŒ ััŒะพะณะพ ัƒะดะบะปะธะบะพะฒะฐะฝั ะฑั‹ะปะพ ะทะฒั–ั€ะตะฝะพ {date}", + "account.media": "ะœะตะดั–ะฐ", + "account.moved_to": "ะฅะพัะฝะพะฒะฐั‡ {name} ัƒะบะฐะทะฐะฒ, ะพะถ ะฝะพะฒั‹ะน ะฟั€ะพั„ั–ะป ะนะธะผ ั”:", + "account.mute": "ะกั‚ะธัˆะธั‚ะธ {name}", + "account.mute_notifications_short": "ะกั‚ะธัˆะธั‚ะธ ะณะพะปะพัˆั–ะฝั", + "account.mute_short": "ะกั‚ะธัˆะธั‚ะธ", + "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.show_reblogs": "ะฃะบะฐะทะฐั‚ะธ ะดั€ัƒะปะตะฝั ัƒะด {name}", + "account.unblock": "ะ ะพะทะฑะปะพะบะพะฒะฐั‚ะธ {name}", + "account.unblock_domain": "ะ ะพะทะฑะปะพะบะพะฒะฐั‚ะธ ะดะพะผะตะฝ {domain}", + "account.unblock_short": "ะ ะพะทะฑะปะพะบะพะฒะฐั‚ะธ", + "account.unendorse": "ะะต ัƒะบะฐะทะพะฒะฐั‚ะธ ะฝะฐ ะฟั€ะพั„ั–ะปะพะฒะธ", + "account.unfollow": "ะฃะดะฟะธัะฐั‚ะธ ัั", + "account.unmute_notifications_short": "ะฃะบะฐะทะพะฒะฐั‚ะธ ะณะพะปะพัˆั–ะฝั", + "account.unmute_short": "ะฃะบะฐะทะพะฒะฐั‚ะธ", + "account_note.placeholder": "ะšะปะพะฟะบะฝั–ั‚ ะพะฑั‹ ะดะพะดะฐั‚ะธ ะฟั€ะธะผั–ั‚ะบัƒ", + "admin.dashboard.retention.cohort_size": "ะะพะฒั– ั…ะพัะฝะพะฒะฐั‡ั–", + "admin.impact_report.instance_accounts": "ะŸั€ะพั„ั–ะปั– ะธะท ะฐะบะฐัƒะฝั‚ัƒะฒ, ะบะพั‚ั€ั– ัั ัƒะดะฐะปัั‚", + "admin.impact_report.instance_followers": "ะŸัƒะดะฟะธัะฝะธะบั‹, ะบะพั‚ั€ั‹ั… ัั‚ั€ะฐั‚ัั‚ ะฝะฐัˆั– ั…ะพัะฝะพะฒะฐั‡ั–", + "admin.impact_report.instance_follows": "ะŸัƒะดะฟะธัะฝะธะบั‹, ะบะพั‚ั€ั‹ั… ัั‚ั€ะฐั‚ัั‚ ั—ั…ะฝั– ั…ะพัะฝะพะฒะฐั‡ั–", + "admin.impact_report.title": "ะ’ะฟะปั‹ะฒ ั†ั–ะปะบะพะผ", + "alert.rate_limited.message": "ะŸะพะฟั€ะพะฑัƒะนั‚ะต ะทะฐััŒ ะฟะพ {retry_time, time, medium}.", + "alert.rate_limited.title": "ะงะฐัั‚ะพั‚ะฐ ะพะฑะผะตะถะตะฝะฐ", + "bundle_column_error.return": "ะ’ะตั€ะฝัƒั‚ะธ ัั ะฝะฐ ะณะพะปะพะฒะฝัƒ", + "bundle_column_error.routing.body": "ะะต ะผะพะถะตะผะต ะฝะฐะนั‚ะธ ััะบัƒ ัั‚ะพั€ัƒะฝะบัƒ. ะ‘ะธะทัƒะฒะฝั– ััŒั‚ะต, ะพะถ URL ัƒ ะฐะดั€ะตัะฝะพะผัƒ ัˆะพั€ะธะบะพะฒะธ ั” ะดะพะฑั€ั‹ะน?", + "bundle_column_error.routing.title": "404", + "bundle_modal_error.close": "ะ—ะฐะฟะตั€ั‚ะธ", + "bundle_modal_error.message": "ะจั‚ะพััŒ ัั ะฟะพะบะฐะทะธะปะพ, ะทะฐะบะธะดัŒ ััŒะผะต ะปะฐะดะพะฒะฐะปะธ ัะธััŒ ะบะพะผะฟะพะฝะตะฝั‚.", + "bundle_modal_error.retry": "ะŸะพะฟั€ะพะฑะพะฒะฐั‚ะธ ะทะฐััŒ", + "closed_registrations.other_server_instructions": "Mastodon ั” ะดะตั†ะตะฝั‚ั€ะฐะปั–ะทะพะฒะฐะฝะพะฒ ะฟะปะฐั‚ั„ะพั€ะผะพะฒ, ะผะพะถะตั‚ะต ัะธ ัƒั‡ะธะฝะธั‚ะธ ะฟั€ะพั„ั–ะป ะธ ะฝะฐ ะดั€ัƒะณะพะผัƒ ัะตั€ะฒะตั€ะพะฒะธ ั‚ะฐะน ะบะพะผัƒะฝั–ะบะพะฒะฐั‚ะธ ะธะท ัะธะผ." +} diff --git a/app/javascript/mastodon/locales/sa.json b/app/javascript/mastodon/locales/sa.json index 469930c3ed..58654deb03 100644 --- a/app/javascript/mastodon/locales/sa.json +++ b/app/javascript/mastodon/locales/sa.json @@ -135,9 +135,7 @@ "compose_form.spoiler.marked": "เคชเฅเคฐเคšเฅเค›เคพเคจเฅเคจเคพเค•เฅเคทเคฐเค‚ เคตเคฟเคฆเฅเคฏเคคเฅ‡", "compose_form.spoiler.unmarked": "เค…เคชเฅเคฐเคšเฅเค›เคจเฅเคจเคพเค•เฅเคทเคฐเค‚ เคตเคฟเคฆเฅเคฏเคคเฅ‡", "confirmation_modal.cancel": "เคจเคถเฅเคฏเคคเคพเคฎเฅ", - "confirmations.block.block_and_report": "เค…เคตเคฐเฅเคงเฅเคฏ เค†เคตเคฟเคฆเฅเคฏเคคเคพเคฎเฅ", "confirmations.block.confirm": "เคจเคฟเคทเฅ‡เคงเคƒ", - "confirmations.block.message": "เคจเคฟเคถเฅเคšเคฏเฅ‡เคจเคพเคฝเคตเคฐเฅ‹เคงเฅ‹ เคตเคฟเคงเฅ‡เคฏเคƒ {name}?", "confirmations.cancel_follow_request.confirm": "เค…เคจเฅเคฐเฅ‹เคงเคจเคฎเคชเคจเคฏ", "confirmations.cancel_follow_request.message": "{name} เค…เคจเฅเคธเคฐเคฃเคธเฅเคฏเคพเคจเฅเคฐเฅ‹เคงเคฎเคชเคจเฅ‡เคคเฅเค‚ เคฆเฅƒเคขเฅ€เค•เฅƒเคคเค‚ เคตเคพ?", "confirmations.delete.confirm": "เคฎเคพเคฐเฅเคœเคฏ", @@ -146,15 +144,12 @@ "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": "เคธเคฎเฅเคชเคพเคฆเคจเคฎเคฟเคฆเคพเคจเฅ€เค‚ เคฒเคฟเค–เฅเคฏเคคเฅ‡ เคคเคฐเฅเคนเคฟ เคชเฅ‚เคฐเฅเคตเคฒเคฟเค–เคฟเคคเคธเคจเฅเคฆเฅ‡เคถเค‚ เคตเคฟเคจเคถเฅเคฏ เคชเฅเคจเคƒ เคฒเคฟเค–เฅเคฏเคคเฅ‡เฅค เคจเคฟเคถเฅเคšเคฏเฅ‡เคจเฅˆเคตเค‚ เค•เคฐเฅเคคเคตเฅเคฏเคฎเฅ?", "confirmations.logout.confirm": "เคฌเคนเคฟเคฐเฅเค—เคฎเฅเคฏเคคเคพเคฎเฅ", "confirmations.logout.message": "เคจเคฟเคถเฅเคšเคฏเฅ‡เคจเฅˆเคต เคฌเคนเคฟเคฐเฅเค—เคฎเคจเค‚ เคตเคพเคžเฅเค›เคฟเคคเคฎเฅ?", "confirmations.mute.confirm": "เคจเคฟเคƒเคถเคฌเฅเคฆเคฎเฅ", - "confirmations.mute.explanation": "เคเคคเฅ‡เคจ เคคเฅ‡เคทเคพเค‚ เคชเคคเฅเคฐเคพเคฃเคฟ เคคเคฅเคพ เคš เคฏเคคเฅเคฐ เคคเฅ‡ เค‰เคฒเฅเคฒเคฟเค–เคฟเคคเคพเคƒ เคคเคพเคจเคฟ เค›เคพเคฆเฅเคฏเคจเฅเคคเฅ‡, เค•เคฟเคจเฅเคคเฅเคตเฅ‡เคตเค‚ เคธเคคเฅเคฏเคชเคฟ เคคเฅ‡ เคคเฅเคตเคพเคฎเคจเฅเคธเคฐเฅเคคเฅเค‚ เคคเคคเคถเฅเคš เคชเคคเฅเคฐเคพเคฃเคฟ เคฆเฅเคฐเคทเฅเคŸเฅเค‚ เคถเค•เฅเคจเฅเคตเคจเฅเคคเคฟ เฅค", - "confirmations.mute.message": "เค•เคฟเค‚ เคจเคฟเคถเฅเคšเคฏเฅ‡เคจ เคจเคฟเคƒเคถเคฌเฅเคฆเค‚ เคญเคตเฅ‡เคคเฅ {name} เคฎเคฟเคคเฅเคฐเคฎเฅ‡เคคเคคเฅ ?", "confirmations.redraft.confirm": "เคฎเคพเคฐเฅเคœเคฏ เคชเฅเคจเคถเฅเคš เคฒเคฟเค–เฅเคฏเคคเคพเคฎเฅ", "confirmations.reply.confirm": "เค‰เคคเฅเคคเคฐเคฎเฅ", "confirmations.reply.message": "เคชเฅเคฐเคคเฅเคฏเฅเคคเฅเคคเคฐเคฎเคฟเคฆเคพเคจเฅ€เค‚ เคฒเคฟเค–เฅเคฏเคคเฅ‡ เคคเคฐเฅเคนเคฟ เคชเฅ‚เคฐเฅเคตเคฒเคฟเค–เคฟเคคเคธเคจเฅเคฆเฅ‡เคถเค‚ เคตเคฟเคจเคถเฅเคฏ เคชเฅเคจเคƒ เคฒเคฟเค–เฅเคฏเคคเฅ‡ เฅค เคจเคฟเคถเฅเคšเคฏเฅ‡เคจเฅˆเคตเค‚ เค•เคฐเฅเคคเคตเฅเคฏเคฎเฅ ?", @@ -264,7 +259,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "เคชเฅเคฐเคšเคฒเคฟเคคเคตเคธเฅเคคเฅ เค…เคจเฅเคธเคฐ", "hashtag.unfollow": "เคชเฅเคฐเคšเคฒเคฟเคคเคตเคธเฅเคคเฅ เค…เคจเฅเคธเคฐเคฃเค‚ เคตเคพเคฐเคฏ", - "home.column_settings.basic": "เคฎเฅ‚เคฒเคญเฅ‚เคคเคฎเฅ", "home.column_settings.show_reblogs": "เคฌเฅเคธเฅเคคเฅ เคฆเคฐเฅเคถเคฏ", "home.column_settings.show_replies": "เค‰เคคเฅเคคเคฐเคพเคฃเคฟ เคฆเคฐเฅเคถเคฏ", "home.hide_announcements": "เคตเคฟเคœเฅเคžเคพเคชเคจเคพเคจเคฟ เคชเฅเคฐเคšเฅเค›เคพเคฆเคฏ", @@ -335,9 +329,6 @@ "load_pending": "{count, plural, one {# เคจเฅ‚เคคเคจเคตเคธเฅเคคเฅ} other {# เคจเฅ‚เคคเคจเคตเคธเฅเคคเฅ‚เคจเคฟ}}", "media_gallery.toggle_visible": "{number, plural, one {เคšเคฟเคคเฅเคฐเค‚ เคชเฅเคฐเคšเฅเค›เคพเคฆเคฏ} other {เคšเคฟเคคเฅเคฐเคพเคฃเคฟ เคชเฅเคฐเคšเฅเค›เคพเคฆเคฏ}}", "moved_to_account_banner.text": "เคคเคต เคเค•เฅŒเคฃเฅเคŸเฅ {disabledAccount} เค…เคงเฅเคจเคพ เคจเคฟเคทเฅเค•เฅƒเคคเฅ‹ เคฏเคคเฅ‹เคนเคฟ {movedToAccount} เค…เคธเฅเคฎเคฟเคจเฅเคคเฅเคตเคฎเคธเคพเคฐเฅเคทเฅ€เคƒเฅค", - "mute_modal.duration": "เคชเคฐเคฟเคฎเคพเคฃเคฎเฅ", - "mute_modal.hide_notifications": "เค…เคธเฅเคฎเคพเคฆเฅเคชเคญเฅ‹เค•เฅเคคเฅเคฐเฅเคตเคฟเคœเฅเคžเคพเคชเคจเคพเคจเคฟ เคชเฅเคฐเคšเฅเค›เคพเคฆเคฏเคฟเคคเฅเคฎเคฟเคšเฅเค›เคธเคฟ เคตเคพ?", - "mute_modal.indefinite": "เค…เฅ‘เคชเคฐเคฟเคฎเคฟเคคเคฎเฅ", "navigation_bar.about": "เคตเคฟเคทเคฏเฅ‡", "navigation_bar.blocks": "เคจเคฟเคทเคฟเคฆเฅเคงเคญเฅ‹เค•เฅเคคเคพเคฐเคƒ", "navigation_bar.bookmarks": "เคชเฅเคŸเคšเคฟเคนเฅเคจเคพเคจเคฟ", @@ -376,9 +367,6 @@ "notifications.column_settings.admin.report": "เคจเฅ‚เคคเคจเคพเคตเฅ‡เคฆเคจเคพเคจเคฟ", "notifications.column_settings.admin.sign_up": "เคจเฅ‚เคคเคจเคชเคžเฅเคœเฅ€เค•เคฐเคฃเคฎเฅ:", "notifications.column_settings.alert": "เคฆเฅ‡เคธเฅเค•เฅเคŸเคชเฅเคตเคฟเคœเฅเคžเคพเคชเคจเคพเคจเคฟ", - "notifications.column_settings.filter_bar.advanced": "เคธเคฐเฅเคตเคพเคฃเคฟ เคตเคฐเฅเค—เคพเคฃเคฟ เคชเฅเคฐเคฆเคฐเฅเคถเคฏ", - "notifications.column_settings.filter_bar.category": "เคฆเฅเคฐเฅเคคเคถเฅ‹เคงเค•เคถเคฒเคพเค•เคพ", - "notifications.column_settings.filter_bar.show_bar": "เคถเฅ‹เคงเค•เคถเคพเคฒเค•เคพเค‚ เคฆเคฐเฅเคถเคฏ", "notifications.column_settings.follow": "เคจเฅ‚เคคเคจเคพเคจเฅเคธเคพเคฐเคฟเคฃเคƒ:", "notifications.column_settings.follow_request": "เคจเฅ‚เคคเคจเคพเคจเฅเคธเคฐเคฃเคพเคจเฅเคฐเฅ‹เคงเคพเคƒ:", "notifications.column_settings.mention": "เค‰เคฒเฅเคฒเคฟเค–เคฟเคคเคพเคจเคฟ :", @@ -511,8 +499,6 @@ "server_banner.about_active_users": "เคตเคฟเค—เคคเฅ‡เคทเฅ เฅฉเฅฆ เคฆเคฟเคจเฅ‡เคทเฅ เคธเคฐเฅเคตเคฐเคฎเคฟเคฎเคฎเฅเคชเคฏเฅเคœเฅเคฏเคฎเคพเคฃเคพ เคœเคจเคพเคƒ (เคฎเคพเคธเคฟเค•เคธเค•เฅเคฐเคฟเคฏเฅ‹เคชเคญเฅ‹เค•เฅเคคเคพเคฐเคƒ)", "server_banner.active_users": "เคธเค•เฅเคฐเคฟเคฏเฅ‹เคชเคญเฅ‹เค•เฅเคคเคพเคฐเคƒ", "server_banner.administered_by": "เค‡เคคเฅเคฏเคจเฅ‡เคจ เค…เคงเคฟเค•เฅƒเคคเคƒ : ", - "server_banner.introduction": "{domain} {mastodon} เค‡เคคเฅเคฏเคจเฅ‡เคจ เคธเคพเคฎเคฐเฅเคฅเคฟเคคเฅ‹ เคตเคฟเค•เฅ‡เคจเฅเคฆเฅเคฐเฅ€เคฏเคธเคพเคฎเคพเคœเคฟเค•เคœเคพเคฒเค•เคฐเฅเคฎเคฃเฅ‹เค‚เคฝเคถเฅ‹เคฝเคธเฅเคคเคฟเฅค", - "server_banner.learn_more": "เค…เคงเคฟเค•เค‚ เคœเฅเคžเคพเคฏเคคเคพเคฎเฅ", "server_banner.server_stats": "เคธเคฐเฅเคตเคฐเคƒ เคธเฅเคฅเคฟเคคเคฟเคตเคฟเคทเคฏเค•เคพเคจเคฟ :", "sign_in_banner.create_account": "เคธเคฎเคฏเค‚ เคธเค‚เคธเฅƒเคœ", "sign_in_banner.sign_in": "เคธเคฎเฅเคชเฅเคฐเคตเฅ‡เคถเค‚ เค•เฅเคฐเฅ", @@ -527,7 +513,6 @@ "status.delete": "เคฎเคพเคฐเฅเคœเคฏ", "status.detailed_status": "เคตเคฟเคธเฅเคคเฅƒเคคเคธเค‚เคญเคพเคทเคฃเคฆเฅƒเคถเฅเคฏเคฎเฅ", "status.edit": "เคธเคฎเฅเคชเคพเคฆเคฏ", - "status.edited": "เคธเคฎเฅเคชเคพเคฆเคฟเคคเค‚ {date}", "status.edited_x_times": "Edited {count, plural, one {{count} เคตเคพเคฐเคฎเฅ} other {{count} เคตเคพเคฐเคฎเฅ}}", "status.embed": "เคจเคฟเคนเคฟเคคเคฎเฅ", "status.filter": "เคชเคคเฅเคฐเคฎเคฟเคฆเค‚ เคซเคฟเคฒเฅเคคเคฐเค‚ เค•เฅเคฐเฅ", diff --git a/app/javascript/mastodon/locales/sc.json b/app/javascript/mastodon/locales/sc.json index 90b663aea7..a0b5b32711 100644 --- a/app/javascript/mastodon/locales/sc.json +++ b/app/javascript/mastodon/locales/sc.json @@ -106,21 +106,16 @@ "compose_form.spoiler.marked": "Boga avisu de cuntenutu", "compose_form.spoiler.unmarked": "Agiunghe avisu de cuntenutu", "confirmation_modal.cancel": "Annulla", - "confirmations.block.block_and_report": "Bloca e signala", "confirmations.block.confirm": "Bloca", - "confirmations.block.message": "Seguru chi boles blocare {name}?", "confirmations.delete.confirm": "Cantzella", "confirmations.delete.message": "Seguru chi boles cantzellare custa publicatzione?", "confirmations.delete_list.confirm": "Cantzella", "confirmations.delete_list.message": "Seguru chi boles cantzellare custa lista in manera permanente?", - "confirmations.domain_block.confirm": "Bloca totu su domรฌniu", "confirmations.domain_block.message": "Boles de seguru, ma a beru a beru, blocare {domain}? In sa parte manna de is casos, pagos blocos o silentziamentos de persones sunt sufitzientes e preferรฌbiles. No as a bรฌdere cuntenutos dae custu domรฌniu in peruna lรฌnia de tempus pรนblica o in is notรฌficas tuas. Sa gente chi ti sighit dae cussu domรฌniu at a รจssere bogada.", "confirmations.edit.confirm": "Modรฌfica", "confirmations.logout.confirm": "Essiยทnche", "confirmations.logout.message": "Seguru chi boles essire?", "confirmations.mute.confirm": "A sa muda", - "confirmations.mute.explanation": "Custu at a cuare is publicatziones issoro e is messร gios chi ddos mรจntovant, ma ant a pรฒdere bรฌdere is messร gios tuos e t'ant a pรฒdere sighire.", - "confirmations.mute.message": "Seguru chi boles pรฒnnere a {name} a sa muda?", "confirmations.redraft.confirm": "Cantzella e torra a fร ghere", "confirmations.reply.confirm": "Risponde", "confirmations.reply.message": "Rispondende immoe as a subrascrรฌere su messร giu chi ses iscriende. Seguru chi boles sighire?", @@ -200,7 +195,6 @@ "hashtag.column_settings.tag_mode.none": "Perunu de custos", "hashtag.column_settings.tag_toggle": "Include etichetas additzionales pro custa colunna", "hashtag.follow": "Sighi su hashtag", - "home.column_settings.basic": "Bร sicu", "home.column_settings.show_reblogs": "Ammustra is cumpartziduras", "home.column_settings.show_replies": "Ammustra rispostas", "home.hide_announcements": "Cua annรนntzios", @@ -266,9 +260,6 @@ "load_pending": "{count, plural, one {# elementu nou} other {# elementos noos}}", "loading_indicator.label": "Carrighendeโ€ฆ", "media_gallery.toggle_visible": "Cua {number, plural, one {immร gine} other {immร gines}}", - "mute_modal.duration": "Durada", - "mute_modal.hide_notifications": "Boles cuare is notรฌficas de custa persone?", - "mute_modal.indefinite": "Indefinida", "navigation_bar.about": "Informatziones", "navigation_bar.blocks": "Persones blocadas", "navigation_bar.bookmarks": "Sinnalibros", @@ -300,8 +291,6 @@ "notifications.clear": "Lรฌmpia notรฌficas", "notifications.clear_confirmation": "Seguru chi boles isboidare in manera permanente totu is notรฌficas tuas?", "notifications.column_settings.alert": "Notรฌficas de iscrivania", - "notifications.column_settings.filter_bar.advanced": "Ammustra totu is categorias", - "notifications.column_settings.filter_bar.category": "Barra lestra de filtros", "notifications.column_settings.follow": "Sighiduras noas:", "notifications.column_settings.follow_request": "Rechestas noas de sighidura:", "notifications.column_settings.mention": "Mรจntovos:", @@ -386,7 +375,6 @@ "search_results.hashtags": "Etichetas", "search_results.statuses": "Publicatziones", "server_banner.administered_by": "Amministradu dae:", - "server_banner.learn_more": "ร€teras informatziones", "server_banner.server_stats": "Istatรฌsticas de su serbidore:", "sign_in_banner.sign_in": "Sign in", "status.admin_account": "Aberi s'interfache de moderatzione pro @{name}", diff --git a/app/javascript/mastodon/locales/sco.json b/app/javascript/mastodon/locales/sco.json index b7563022a9..53501a5937 100644 --- a/app/javascript/mastodon/locales/sco.json +++ b/app/javascript/mastodon/locales/sco.json @@ -131,9 +131,7 @@ "compose_form.spoiler.marked": "Tak aff the content warnin", "compose_form.spoiler.unmarked": "Pit on a content warnin", "confirmation_modal.cancel": "Stap", - "confirmations.block.block_and_report": "Dingie & Clype", "confirmations.block.confirm": "Dingie", - "confirmations.block.message": "Ye shair thit ye'r wantin tae dingie {name}?", "confirmations.cancel_follow_request.confirm": "Tak back yer request", "confirmations.cancel_follow_request.message": "Ye shair thit ye'r wantin tae tak back yer request fir tae follae {name}?", "confirmations.delete.confirm": "Delete", @@ -142,13 +140,10 @@ "confirmations.delete_list.message": "Ye shair thit ye'r wantin fir tae delete this post fir ever?", "confirmations.discard_edit_media.confirm": "Fling awa", "confirmations.discard_edit_media.message": "Ye'v chynges tae the media description or preview thit ye'v no saved, fling them awa onie weys?", - "confirmations.domain_block.confirm": "Dingie the hail domain", "confirmations.domain_block.message": "Ye a hunner percent shair thit ye'r wantin tae dingie the hail {domain}? In maist cases a haunfae tairgtit dingies an wheeshts are eneuch an preferit. Ye wullnae see content fae that domain in onie public timelines or in yer notes. Yer follaers fae that domain wull be taen awa.", "confirmations.logout.confirm": "Log oot", "confirmations.logout.message": "Ye shair thit ye'r wantin tae log oot?", "confirmations.mute.confirm": "Wheesht", - "confirmations.mute.explanation": "This'll hide posts fae them an posts mentionin them, but it'll stull alloo them tae see yer posts an follae ye.", - "confirmations.mute.message": "Ye sure thit ye'r wantin tae wheesht {name}?", "confirmations.redraft.confirm": "Delete an stert anew", "confirmations.reply.confirm": "Reply", "confirmations.reply.message": "Replyin noo'll owerwrite the message ye'r screivin the noo. Ur ye sure thit ye'r wantin tae dae that?", @@ -249,7 +244,6 @@ "hashtag.column_settings.tag_toggle": "Pit in mair hashtags fir this column", "hashtag.follow": "Follae hashtag", "hashtag.unfollow": "Unfollae hashtag", - "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Shaw boosts", "home.column_settings.show_replies": "Shaw replies", "home.hide_announcements": "Hide annooncements", @@ -320,9 +314,6 @@ "load_pending": "{count, plural, one {# new item} other {# new items}}", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "moved_to_account_banner.text": "Yer accoont {disabledAccount} is disabilt the noo acause ye flittit tae {movedToAccount}.", - "mute_modal.duration": "Lenth", - "mute_modal.hide_notifications": "Hide notifications fae this uiser?", - "mute_modal.indefinite": "Indefinite", "navigation_bar.about": "Aboot", "navigation_bar.blocks": "Dingied uisers", "navigation_bar.bookmarks": "Buikmairks", @@ -359,9 +350,6 @@ "notifications.column_settings.admin.report": "New reports:", "notifications.column_settings.admin.sign_up": "New sign-ups:", "notifications.column_settings.alert": "Desktap notes", - "notifications.column_settings.filter_bar.advanced": "Shaw aw caitegories", - "notifications.column_settings.filter_bar.category": "Quick filter baur", - "notifications.column_settings.filter_bar.show_bar": "Shaw filter baur", "notifications.column_settings.follow": "New follaers:", "notifications.column_settings.follow_request": "New follae requests:", "notifications.column_settings.mention": "Menshies:", @@ -483,8 +471,6 @@ "server_banner.about_active_users": "Fowk uisin this server in the last 30 days (Monthly Active Uisers)", "server_banner.active_users": "active uisers", "server_banner.administered_by": "Administert bi:", - "server_banner.introduction": "{domain} is pairt o the decentralized social network pooery bi {mastodon}.", - "server_banner.learn_more": "Lairn mair", "server_banner.server_stats": "Server stats:", "sign_in_banner.create_account": "Mak accoont", "sign_in_banner.sign_in": "Sign in", @@ -498,7 +484,6 @@ "status.delete": "Delete", "status.detailed_status": "Detailt conversation view", "status.edit": "Edit", - "status.edited": "Editit {date}", "status.edited_x_times": "Editit {count, plural, one {{count} time} other {{count} times}}", "status.embed": "Embed", "status.filter": "Filter this post", diff --git a/app/javascript/mastodon/locales/si.json b/app/javascript/mastodon/locales/si.json index 2058d1415b..22320daefc 100644 --- a/app/javascript/mastodon/locales/si.json +++ b/app/javascript/mastodon/locales/si.json @@ -18,6 +18,7 @@ "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.followers": "เถ…เถฑเท”เถœเทเถธเท’เถšเถบเท’เถฑเทŠ", @@ -104,25 +105,22 @@ "compose_form.poll.duration": "เถธเถญ เท€เท’เถธเทƒเท“เถธเทš เถšเทเถฝเถบ", "compose_form.poll.switch_to_multiple": "เถญเทšเถปเท“เถธเทŠ เถšเท’เท„เท’เถดเถบเถšเถง เถธเถญ เท€เท’เถธเทƒเท”เถธ เท€เท™เถฑเทƒเทŠ เถšเถปเถฑเทŠเถฑ", "compose_form.poll.switch_to_single": "เถญเถฑเท’ เถญเทšเถปเท“เถธเถšเถง เถธเถญ เท€เท’เถธเทƒเท”เถธ เท€เท™เถฑเทƒเทŠ เถšเถปเถฑเทŠเถฑ", + "compose_form.publish": "เถดเทŠโ€เถปเถšเทเทเถฑเถบ", "compose_form.publish_form": "เถฑเท€ เถฝเท’เถดเท’เถบ", "compose_form.spoiler.marked": "เถ…เถฑเทŠเถญเถปเทŠเถœเถญ เถ…เท€เท€เทเถฏเถบ เถ‰เท€เถญเทŠ เถšเถปเถฑเทŠเถฑ", "compose_form.spoiler.unmarked": "เถ…เถฑเทŠเถญเถปเทŠเถœเถญ เถ…เท€เท€เทเถฏเถบเถšเทŠ เถ‘เถšเทŠ เถšเถปเถฑเทŠเถฑ", "confirmation_modal.cancel": "เถ…เท€เถฝเถ‚เถœเท”", - "confirmations.block.block_and_report": "เถ…เท€เท„เท’เถป เถšเถป เท€เทเถปเทŠเถญเท เถšเถปเถฑเทŠเถฑ", "confirmations.block.confirm": "เถ…เท€เท„เท’เถป", - "confirmations.block.message": "เถ”เถถเถง {name} เถ…เท€เท„เท’เถป เถšเท’เถปเท“เถธเถง เท€เท”เท€เถธเถฑเท เถฏ?", "confirmations.delete.confirm": "เถธเถšเถฑเทŠเถฑ", "confirmations.delete.message": "เถ”เถถเถง เถธเท™เถธ เถฝเท’เถดเท’เถบ เถธเทเถšเท“เถธเถง เท€เท”เท€เถธเถฑเท เถฏ?", "confirmations.delete_list.confirm": "เถธเถšเถฑเทŠเถฑ", "confirmations.delete_list.message": "เถ”เถถเถง เถธเท™เถธ เถฝเทเถบเท’เทƒเทŠเถญเท”เท€ เทƒเถฏเท„เถงเถธ เถธเทเถšเท“เถธเถง เท€เท”เท€เถธเถฑเท เถฏ?", "confirmations.discard_edit_media.confirm": "เถ‰เท€เถญ เถฝเถฑเทŠเถฑ", "confirmations.discard_edit_media.message": "เถ”เถถเถง เถธเทเถฐเทŠโ€เถบ เท€เท’เทƒเทŠเถญเถปเถบเถง เท„เท เถดเท™เถปเถฏเทƒเท”เถฑเถง เถฑเทœเทƒเท”เถปเถšเท’เถฑ เถฝเถฏ เท€เท™เถฑเทƒเทŠเถšเถธเทŠ เถญเท’เถถเทš, เถšเท™เทƒเทš เท€เท™เถญเถญเทŠ เถ’เท€เท เถ‰เท€เถญ เถฏเถธเถฑเทŠเถฑเถฏ?", - "confirmations.domain_block.confirm": "เทƒเถธเทŠเถดเท–เถปเทŠเถซ เท€เทƒเถธ เถ…เท€เท„เท’เถป เถšเถปเถฑเทŠเถฑ", "confirmations.edit.confirm": "เทƒเถ‚เทƒเทŠเถšเถปเถซเถบ", "confirmations.logout.confirm": "เถฑเท’เถšเทŠเถธเท™เถฑเทŠเถฑ", "confirmations.logout.message": "เถ”เถถเถง เถฑเท’เถšเทŠเถธเท™เถฑเทŠเถฑ เถ…เท€เทเทŠโ€เถบ เถถเท€ เท€เท’เทเทŠเท€เทเทƒเถฏ?", "confirmations.mute.confirm": "เถฑเท’เทเทŠเทเถถเทŠเถฏ", - "confirmations.mute.message": "{name} เถฑเท’เท„เถฌ เถšเท’เถปเท“เถธเถง เท€เท”เท€เถธเถฑเท เถฏ?", "confirmations.reply.confirm": "เถดเท’เท…เท’เถญเท”เถป", "conversation.delete": "เทƒเถ‚เท€เทเถฏเถบ เถธเถšเถฑเทŠเถฑ", "conversation.mark_as_read": "เถšเท’เถบเท€เท– เถถเท€ เถบเทœเถฏเถฑเทŠเถฑ", @@ -158,6 +156,7 @@ "empty_column.bookmarked_statuses": "เถ”เถถ เทƒเถญเท”เท€ เถดเทœเถญเทŠเถบเทœเถธเท” เถญเถถเถฑ เถฝเถฏ เถฝเท’เถดเท’ เถšเท’เทƒเท’เท€เถšเทŠ เถฑเทเถญ. เถ”เถถ เถดเทœเถญเทŠเถบเทœเถธเท”เท€เถšเทŠ เถญเถถเถฑ เท€เท’เถง, เถ‘เถบ เถธเท™เท„เท’ เถฏเท’เทƒเทŠเท€เถฑเท” เถ‡เถญ.", "empty_column.domain_blocks": "เถ…เท€เท„เท’เถป เถšเถปเถฑ เถฝเถฏ เท€เทƒเถธเทŠ เถฑเทเถญ.", "empty_column.explore_statuses": "เถฏเทเถฑเทŠ เถšเท’เทƒเท’เท€เถšเทŠ เถฑเทเถนเท”เถปเท” เถฑเทœเท€เทš. เถดเทƒเท”เท€ เถฑเทเท€เถญ เถดเถปเท“เถšเทŠเท‚เท เถšเถปเถฑเทŠเถฑ!", + "empty_column.favourited_statuses": "เถ”เถถ เทƒเถญเท”เท€ เถดเทŠโ€เถปเท’เถบเถญเถธ เถฝเท’เถดเท’ เถšเท’เทƒเท’เท€เถšเทŠ เถฑเทเถญ. เถ”เถถ เถบเถธเถšเถง เถดเทŠโ€เถปเท’เถบ เถšเท… เท€เท’เถง เถ‘เถบ เถธเท™เท„เท’ เถดเท™เถฑเทŠเท€เถฑเท” เถ‡เถญ.", "empty_column.follow_requests": "เถ”เถถเถง เถญเท€เถธเถญเทŠ เถ…เถฑเท”เถœเถธเถฑ เถ‰เถฝเทŠเถฝเท“เถธเทŠ เถฝเทเถถเท“ เถฑเทเถญ. เถ‰เถฝเทŠเถฝเท“เถธเถšเทŠ เถฝเทเถถเท”เถซเท” เท€เท’เถง, เถ‘เถบ เถธเท™เท„เท’ เถดเท™เถฑเทŠเท€เถฑเท” เถ‡เถญ.", "empty_column.home": "เถธเท”เถฝเทŠ เถดเท’เถงเท”เท€ เท„เท’เทƒเทŠ เถบ! เถธเท™เถบ เถดเท’เถปเท€เท“เถธเถง เถถเทœเท„เท เถดเท”เถฏเทŠเถœเถฝเถบเท’เถฑเทŠ เถ…เถฑเท”เถœเถธเถฑเถบ เถšเถปเถฑเทŠเถฑ.", "empty_column.lists": "เถ”เถถเถง เถญเท€เถธเถญเทŠ เถฝเทเถบเท’เทƒเทŠเถญเท” เถšเท’เทƒเท’เท€เถšเทŠ เถฑเทเถญ. เถ”เถถ เถ‘เถšเถšเทŠ เทƒเทเถฏเถฑ เท€เท’เถง, เถ‘เถบ เถธเท™เท„เท’ เถดเท™เถฑเทŠเท€เถฑเท” เถ‡เถญ.", @@ -201,7 +200,6 @@ "hashtag.column_settings.tag_mode.all": "เถธเทš เทƒเท’เถบเถฝเทŠเถฝเถธ", "hashtag.column_settings.tag_mode.none": "เถธเทš เถšเท’เทƒเท’เท€เถšเทŠ เถฑเทเถญ", "hashtag.column_settings.tag_toggle": "เถธเท™เถธ เถญเท“เถปเท”เท€เทš เถ…เถธเถญเถป เถงเทเถœเทŠ เถ‡เถญเท”เท…เถญเทŠ เถšเถปเถฑเทŠเถฑ", - "home.column_settings.basic": "เถธเท–เถฝเท’เถš", "home.column_settings.show_replies": "เถดเท’เท…เท’เถญเท”เถปเท” เถดเท™เถฑเทŠเท€เถฑเทŠเถฑ", "home.hide_announcements": "เถฑเท’เท€เทšเถฏเถฑ เทƒเถŸเท€เถฑเทŠเถฑ", "home.pending_critical_update.link": "เถบเทเท€เถญเทŠเถšเทเถฝ เถถเถฝเถฑเทŠเถฑ", @@ -210,6 +208,7 @@ "interaction_modal.on_this_server": "เถธเท™เถธ เทƒเทšเท€เทเถฏเทเถบเถšเถบเท™เท„เท’", "interaction_modal.title.favourite": "{name}เถœเทš เถฝเท’เถดเท’เถบ เถดเทŠโ€เถปเท’เถบ เถšเถปเถฑเทŠเถฑ", "interaction_modal.title.follow": "{name} เถ…เถฑเท”เถœเถธเถฑเถบ", + "interaction_modal.title.reply": "{name}เถœเทš เถฝเท’เถดเท’เถบเถง เถดเท’เท…เท’เถญเท”เถปเท”", "intervals.full.days": "{number, plural, one {เถฏเท€เทƒเทŠ #} other {เถฏเท€เทƒเทŠ #}}", "intervals.full.hours": "{number, plural, one {เถดเทเถบ #} other {เถดเทเถบ #}}", "intervals.full.minutes": "{number, plural, one {เท€เท’เถฑเทเถฉเท’ #} other {เท€เท’เถฑเทเถฉเท’ #}}", @@ -244,13 +243,12 @@ "lists.delete": "เถฝเทเถบเท’เทƒเทŠเถญเท”เท€ เถธเถšเถฑเทŠเถฑ", "lists.edit": "เถฝเทเถบเท’เทƒเทŠเถญเท”เท€ เทƒเถ‚เทƒเทŠเถšเถปเถซเถบ", "lists.edit.submit": "เทƒเท’เถปเทเทƒเท’เถบ เทƒเถ‚เทเทเถฐเถฑเถบ", + "lists.new.create": "เถ‘เถšเถญเท”", "lists.new.title_placeholder": "เถฑเท€ เถฝเทเถบเท’เทƒเทŠเถญเท”เท€เทš เทƒเท’เถปเทเทƒเท’เถบ", "lists.replies_policy.list": "เถฝเทเถบเท’เทƒเทŠเถญเท”เท€เทš เทƒเทเถธเทเถขเท’เถšเถบเท’เถฑเทŠ", "lists.replies_policy.none": "เถšเท’เทƒเท’เท€เท™เถšเทŠ เถฑเทเถญ", "lists.replies_policy.title": "เถดเท’เท…เท’เถญเท”เถปเท” เถดเท™เถฑเทŠเท€เถฑเทŠเถฑ:", "lists.subheading": "เถ”เถถเถœเทš เถฝเทเถบเท’เทƒเทŠเถญเท”", - "mute_modal.duration": "เถดเถปเทเทƒเถบ", - "mute_modal.hide_notifications": "เถธเท™เถธ เถดเท”เถฏเทŠเถœเถฝเถบเทเถœเทš เถฏเทเถฑเท”เถธเทŠเถฏเท“เถธเทŠ เทƒเถŸเท€เถฑเทŠเถฑเถฏ?", "navigation_bar.about": "เถดเท’เท…เท’เถถเถณเท€", "navigation_bar.blocks": "เถ…เท€เท„เท’เถป เถšเท… เถ…เถบ", "navigation_bar.bookmarks": "เถดเทœเถญเทŠเถบเทœเถธเท”", @@ -273,6 +271,7 @@ "navigation_bar.search": "เทƒเทœเถบเถฑเทŠเถฑ", "navigation_bar.security": "เถ†เถปเถšเทŠเท‚เทเท€", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", + "notification.favourite": "{name} เถ”เถถเถœเทš เถฝเท’เถดเท’เถบเถง เถดเทŠโ€เถปเท’เถบ เถšเท…เท", "notification.follow": "{name} เถ”เถถเท€ เถ…เถฑเท”เถœเถธเถฑเถบ เถšเท…เท", "notification.mention": "{name} เถ”เถถเท€ เทƒเถณเท„เถฑเทŠ เถšเถป เถ‡เถญ", "notification.own_poll": "เถ”เถถเถœเทš เถธเถญ เท€เท’เถธเทƒเท”เถธ เถฑเท’เถธเถบเท’", @@ -285,9 +284,6 @@ "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.filter_bar.show_bar": "เถดเท™เถปเท„เถฑเทŠ เถญเท“เถปเท”เท€ เถดเท™เถฑเทŠเท€เถฑเทŠเถฑ", "notifications.column_settings.follow": "เถฑเท€ เถ…เถฑเท”เถœเทเถธเท’เถšเถบเท’เถฑเทŠ:", "notifications.column_settings.follow_request": "เถฑเท€ เถ…เถฑเท”เถœเถธเถฑ เถ‰เถฝเทŠเถฝเท“เถธเทŠ:", "notifications.column_settings.mention": "เทƒเทเถณเท„เท”เถธเทŠ:", @@ -399,16 +395,15 @@ "search_results.statuses": "เถฝเท’เถดเท’", "search_results.title": "{q} เทƒเทœเถบเถฑเทŠเถฑ", "server_banner.active_users": "เทƒเถšเทŠโ€เถปเท’เถบ เถดเถปเท’เทเทŠโ€เถปเท“เถฝเถšเถบเท’เถฑเทŠ", - "server_banner.learn_more": "เถญเท€ เถฏเทเถฑเถœเถฑเทŠเถฑ", "sign_in_banner.create_account": "เถœเท’เถซเท”เถธเถšเทŠ เทƒเทเถฏเถฑเทŠเถฑ", "sign_in_banner.sign_in": "เถดเท’เท€เท’เทƒเท™เถฑเทŠเถฑ", "status.admin_status": "เถธเท™เถธ เถฝเท’เถดเท’เถบ เถธเทเถฏเท’เท„เถญเทŠเถšเถปเถซ เถ…เถญเท”เถปเท”เถธเท”เท„เท”เถซเถญเท™เท„เท’ เถ…เถปเท’เถฑเทŠเถฑ", "status.block": "@{name} เถ…เท€เท„เท’เถป", "status.bookmark": "เถดเทœเถญเทŠเถบเทœเถธเท”เท€เถšเทŠ", + "status.copy": "เถฝเท’เถดเท’เถบเถง เทƒเถถเทเถณเท’เถบเทš เถดเท’เถงเถดเถญเถšเทŠ", "status.delete": "เถธเถšเถฑเทŠเถฑ", "status.detailed_status": "เท€เท’เทƒเทŠเถญเถปเทเถญเทŠเถธเถš เทƒเถ‚เท€เทเถฏ เถฏเทเถšเทŠเถธ", "status.edit": "เทƒเถ‚เทƒเทŠเถšเถปเถซเถบ", - "status.edited": "เทƒเถ‚เทเทเถฐเท’เถญเถบเท’ {date}", "status.edited_x_times": "เทƒเถ‚เทเทเถฐเท’เถญเถบเท’ {count, plural, one {เท€เทเถป {count}} other {เท€เทเถป {count}}}", "status.embed": "เถšเทเท€เทเถฏเทŠเถฏเท–", "status.filter": "เถธเท™เถธ เถฝเท’เถดเท’เถบ เถดเท™เถปเถฑเทŠเถฑ", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index da76e98687..4c152a2143 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -1,741 +1,773 @@ { "about.blocks": "Moderovanรฉ servery", "about.contact": "Kontakt:", - "about.disclaimer": "Mastodon je bezplatnรฝ softvรฉr s otvorenรฝm zdrojovรฝm kรณdom a ochrannรก znรกmka spoloฤnosti Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Dรดvod nie je k dispozรญcii", - "about.domain_blocks.preamble": "Mastodon vo vลกeobecnosti umoลพลˆuje prezeraลฅ obsah a komunikovaลฅ s pouลพรญvateฤพmi z akรฉhokoฤพvek inรฉho servera vo fediverse. Toto sรบ vรฝnimky, ktorรฉ boli urobenรฉ na tomto konkrรฉtnom serveri.", - "about.domain_blocks.silenced.explanation": "Vo vลกeobecnosti neuvidรญte profily a obsah z tohto servera, pokiaฤพ si ho nevyhฤพadรกte alebo sa neprihlรกsite k jeho sledovaniu.", - "about.domain_blocks.silenced.title": "Obmedzenรก", + "about.disclaimer": "Mastodon je bezplatnรฝ open-source softvรฉr s otvorenรฝm zdrojovรฝm kรณdom a ochrannรก znรกmka spoloฤnosti Mastodon gGmbH.", + "about.domain_blocks.no_reason_available": "Dรดvod nebol uvedenรฝ", + "about.domain_blocks.preamble": "Mastodon vo vลกeobecnosti umoลพลˆuje prezeraลฅ obsah a komunikovaลฅ s pouลพรญvateฤพmi z akรฉhokoฤพvek inรฉho servera vo fediverze. Tu sรบ uvedenรฉ vรฝnimky, ktorรฉ boli urobenรฉ na tomto konkrรฉtnom serveri.", + "about.domain_blocks.silenced.explanation": "Vo vลกeobecnosti neuvidรญte profily a obsah z tohto servera, pokiaฤพ si ich nevyhฤพadรกte alebo sa neprihlรกsite k ich sledovaniu.", + "about.domain_blocks.silenced.title": "Obmedzenรฝ", "about.domain_blocks.suspended.explanation": "ลฝiadne รบdaje z tohto servera nebudรบ spracovรกvanรฉ, ukladanรฉ ani vymieลˆanรฉ, ฤo znemoลพnรญ akรบkoฤพvek interakciu alebo komunikรกciu s pouลพรญvateฤพmi z tohto servera.", - "about.domain_blocks.suspended.title": "Vylรบฤenรก", + "about.domain_blocks.suspended.title": "Vylรบฤenรฝ", "about.not_available": "Tieto informรกcie neboli sprรญstupnenรฉ na tomto serveri.", - "about.powered_by": "Decentralizovanรฉ sociรกlne mรฉdiรก pohรกลˆanรฉ technolรณgiou {mastodon}", + "about.powered_by": "Decentralizovanรก sociรกlna sieลฅ na zรกklade technolรณgie {mastodon}", "about.rules": "Pravidlรก servera", "account.account_note_header": "Poznรกmka", - "account.add_or_remove_from_list": "Pridaj alebo odober zo zoznamov", + "account.add_or_remove_from_list": "Pridaลฅ alebo odobraลฅ zo zoznamov", "account.badges.bot": "Bot", "account.badges.group": "Skupina", - "account.block": "Blokuj @{name}", - "account.block_domain": "Skry vลกetko z {domain}", - "account.block_short": "Blokuj", - "account.blocked": "Blokovanรฝ/รก", - "account.browse_more_on_origin_server": "Prehฤพadรกvaj viac na pรดvodnom profile", - "account.cancel_follow_request": "Zruลก ลพiadosลฅ o sledovanie", - "account.copy": "Skopรญruj odkaz na profil", - "account.direct": "Spomeลˆ @{name} sรบkromne", - "account.disable_notifications": "Prestaลˆ mi oznamovaลฅ, keฤ mรก @{name} prรญspevky", - "account.domain_blocked": "Domรฉna skrytรก", - "account.edit_profile": "Uprav profil", - "account.enable_notifications": "Oznamuj mi, keฤ mรก @{name} prรญspevky", - "account.endorse": "Zobrazuj na profile", + "account.block": "Blokovaลฅ @{name}", + "account.block_domain": "Blokovaลฅ domรฉnu {domain}", + "account.block_short": "Blokovaลฅ", + "account.blocked": "รšฤet blokovanรฝ", + "account.browse_more_on_origin_server": "Zobraziลฅ viac na pรดvodnom profile", + "account.cancel_follow_request": "Zruลกiลฅ ลพiadosลฅ o sledovanie", + "account.copy": "Skopรญrovaลฅ odkaz na profil", + "account.direct": "Sรบkromne oznaฤiลฅ @{name}", + "account.disable_notifications": "Zruลกiลฅ upozornenia na prรญspevky od @{name}", + "account.domain_blocked": "Domรฉna blokovanรก", + "account.edit_profile": "Upraviลฅ profil", + "account.enable_notifications": "Zapnรบลฅ upozornenia na prรญspevky od @{name}", + "account.endorse": "Zobraziลฅ na vlastnom profile", "account.featured_tags.last_status_at": "Poslednรฝ prรญspevok dลˆa {date}", "account.featured_tags.last_status_never": "ลฝiadne prรญspevky", - "account.featured_tags.title": "Odporรบฤanรฉ hashtagy pouลพรญvateฤพa {name}", - "account.follow": "Sleduj", - "account.follow_back": "Nasleduj spรคลฅ", + "account.featured_tags.title": "Odporรบฤanรฉ hashtagy รบฤtu {name}", + "account.follow": "Sledovaลฅ", + "account.follow_back": "Sledovaลฅ spรคลฅ", "account.followers": "Sledovatelia", - "account.followers.empty": "Tohto pouลพรญvateฤพa eลกte nikto nenasleduje.", - "account.followers_counter": "{count, plural, one {{counter} Sledujรบci} other {{counter} Sledujรบci}}", - "account.following": "Sledujem", - "account.following_counter": "{count, plural, one {{counter} Sledovanรฝch} other {{counter} Sledujรบcich}}", - "account.follows.empty": "Tento pouลพรญvateฤพ eลกte nikoho nesleduje.", - "account.go_to_profile": "Prejdi na profil", - "account.hide_reblogs": "Skry zdieฤพania od @{name}", - "account.in_memoriam": "In Memoriam.", - "account.joined_short": "Pridal/a sa", + "account.followers.empty": "Tento รบฤet eลกte nikto nesleduje.", + "account.followers_counter": "{count, plural, one {{counter} sledujรบci รบฤet} few {{counter} sledujรบce รบฤty} many {{counter} sledujรบcich รบฤtov} other {{counter} sledujรบcich รบฤtov}}", + "account.following": "Sledovanรฝ รบฤet", + "account.following_counter": "{count, plural, one {{counter} sledovanรฝ รบฤet} few {{counter} sledovanรฉ รบฤty} many {{counter} sledovanรฝch รบฤtov} other {{counter} sledovanรฝch รบฤtov}}", + "account.follows.empty": "Tento รบฤet eลกte nikoho nesleduje.", + "account.go_to_profile": "Prejsลฅ na profil", + "account.hide_reblogs": "Skryลฅ zdieฤพania od @{name}", + "account.in_memoriam": "In memoriam.", + "account.joined_short": "Dรกtum registrรกcie", "account.languages": "Zmeniลฅ odoberanรฉ jazyky", "account.link_verified_on": "Vlastnรญctvo tohto odkazu bolo skontrolovanรฉ {date}", "account.locked_info": "Stav sรบkromia pre tento รบฤet je nastavenรฝ na zamknutรฝ. Jeho vlastnรญk sa sรกm rozhoduje, kto ho mรดลพe sledovaลฅ.", "account.media": "Mรฉdiรก", - "account.mention": "Spomeลˆ @{name}", - "account.moved_to": "{name} uvรกdza, ลพe jeho/jej novรฝ รบฤet je teraz:", - "account.mute": "Stรญลก @{name}", - "account.mute_notifications_short": "Stรญลก oznรกmenia", - "account.mute_short": "Stรญลก", - "account.muted": "Stรญลกenรฝ", + "account.mention": "Oznaฤiลฅ @{name}", + "account.moved_to": "{name} uvรกdza, ลพe mรก novรฝ รบฤet:", + "account.mute": "Stรญลกiลฅ @{name}", + "account.mute_notifications_short": "Stรญลกiลฅ upozornenia", + "account.mute_short": "Stรญลกiลฅ", + "account.muted": "รšฤet stรญลกenรฝ", "account.mutual": "Spoloฤnรฉ", "account.no_bio": "Nie je uvedenรฝ ลพiadny popis.", - "account.open_original_page": "Otvor pรดvodnรบ strรกnku", + "account.open_original_page": "Otvoriลฅ pรดvodnรบ strรกnku", "account.posts": "Prรญspevky", "account.posts_with_replies": "Prรญspevky a odpovede", - "account.report": "Nahlรกs @{name}", - "account.requested": "ฤŒakรก na schvรกlenie. Klikni pre zruลกenie ลพiadosti", - "account.requested_follow": "{name} ti poslal ลพiadosลฅ na sledovanie", - "account.share": "Zdieฤพaj @{name} profil", - "account.show_reblogs": "Ukรกลพ vyzdvihnutia od @{name}", - "account.statuses_counter": "{count, plural, one {{counter} prรญspevok} other {{counter} prรญspevkov}}", - "account.unblock": "Odblokuj @{name}", - "account.unblock_domain": "Prestaลˆ skrรฝvaลฅ {domain}", - "account.unblock_short": "Odblokuj", - "account.unendorse": "Nezobrazuj na profile", - "account.unfollow": "Prestaลˆ nasledovaลฅ", - "account.unmute": "Prestaลˆ ignorovaลฅ @{name}", - "account.unmute_notifications_short": "Zruลก nevลกรญmanie si obznรกmenรญ", - "account.unmute_short": "Zruลก nevลกรญmanie", - "account_note.placeholder": "Klikni pre vloลพenie poznรกmky", + "account.report": "Nahlรกsiลฅ @{name}", + "account.requested": "ฤŒakรก na schvรกlenie. ลฝiadosลฅ zruลกรญte kliknutรญm sem", + "account.requested_follow": "{name} vรกs chce sledovaลฅ", + "account.share": "Zdieฤพaj profil @{name}", + "account.show_reblogs": "Zobrazovaลฅ zdieฤพania od @{name}", + "account.statuses_counter": "{count, plural, one {{counter} prรญspevok} few {{counter} prรญspevky} many {{counter} prรญspevkov} other {{counter} prรญspevkov}}", + "account.unblock": "Odblokovaลฅ @{name}", + "account.unblock_domain": "Odblokovaลฅ domรฉnu {domain}", + "account.unblock_short": "Odblokovaลฅ", + "account.unendorse": "Nezobrazovaลฅ na vlastnom profile", + "account.unfollow": "Zruลกiลฅ sledovanie", + "account.unmute": "Vypnรบลฅ stรญลกenie @{name}", + "account.unmute_notifications_short": "Vypnรบลฅ stรญลกenie upozornenรญ", + "account.unmute_short": "Zruลกiลฅ stรญลกenie", + "account_note.placeholder": "Kliknutรญm pridaลฅ poznรกmku", "admin.dashboard.daily_retention": "Miera udrลพania pouลพรญvateฤพov podฤพa dลˆa po registrรกcii", "admin.dashboard.monthly_retention": "Miera udrลพania pouลพรญvateฤพov podฤพa mesiaca po registrรกcii", "admin.dashboard.retention.average": "Priemer", - "admin.dashboard.retention.cohort": "Mesiac zaregistrovania sa", - "admin.dashboard.retention.cohort_size": "Novรญ uลพรญvatelia", + "admin.dashboard.retention.cohort": "Dรกtum registrรกcie", + "admin.dashboard.retention.cohort_size": "Novรฉ รบฤty", "admin.impact_report.instance_accounts": "Profily รบฤtov, ktorรฉ by boli odstrรกnenรฉ", "admin.impact_report.instance_followers": "Sledovatelia, o ktorรฝch by naลกi pouลพรญvatelia priลกli", "admin.impact_report.instance_follows": "Sledovatelia, o ktorรฝch by ich pouลพรญvatelia priลกli", "admin.impact_report.title": "Zhrnutie dopadu", - "alert.rate_limited.message": "Prosรญm, skรบs to znova za {retry_time, time, medium}.", - "alert.rate_limited.title": "Tempo obmedzenรฉ", + "alert.rate_limited.message": "Prosรญm, skรบste to znova o {retry_time, time, medium}.", + "alert.rate_limited.title": "Priveฤพa ลพiadostรญ", "alert.unexpected.message": "Vyskytla sa neฤakanรก chyba.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Oznรกmenie", "attachments_list.unprocessed": "(nespracovanรฉ)", - "audio.hide": "Skry zvuk", - "boost_modal.combo": "Nabudรบce mรดลพeลก kliknรบลฅ {combo} pre preskoฤenie", + "audio.hide": "Skryลฅ zvuk", + "block_modal.show_less": "Zobraziลฅ menej", + "block_modal.show_more": "Zobraziลฅ viac", + "block_modal.title": "Blokovaลฅ uลพรญvateฤพa?", + "boost_modal.combo": "Nabudรบce mรดลพete preskoฤiลฅ stlaฤenรญm {combo}", "bundle_column_error.copy_stacktrace": "Kopรญrovaลฅ chybovรบ hlรกลกku", "bundle_column_error.error.body": "Poลพadovanรบ strรกnku nebolo moลพnรฉ vykresliลฅ. Mรดลพe to byลฅ spรดsobenรฉ chybou v naลกom kรณde alebo problรฉmom s kompatibilitou prehliadaฤa.", "bundle_column_error.error.title": "Ale nie!", - "bundle_column_error.network.body": "Pri pokuse o naฤรญtanie tejto strรกnky sa vyskytla chyba. Mรดลพe to byลฅ spรดsobenรฉ doฤasnรฝm problรฉmom s Vaลกรญm internetovรฝm pripojenรญm alebo tรฝmto serverom.", + "bundle_column_error.network.body": "Pri pokuse o naฤรญtanie tejto strรกnky sa vyskytla chyba. Mรดลพe to byลฅ spรดsobenรฉ doฤasnรฝm problรฉmom s vaลกรญm internetovรฝm pripojenรญm alebo tรฝmto serverom.", "bundle_column_error.network.title": "Chyba siete", - "bundle_column_error.retry": "Skรบs to znova", - "bundle_column_error.return": "Prejdi spรคลฅ na domovskรบ strรกnku", - "bundle_column_error.routing.body": "ลฝiadanรก strรกnka nebola nรกjdenรก. Ste si istรฝ, ลพe zadanรก adresa URL je sprรกvna?", + "bundle_column_error.retry": "Skรบste to znova", + "bundle_column_error.return": "Prejdite spรคลฅ na domovskรบ strรกnku", + "bundle_column_error.routing.body": "ลฝiadanรก strรกnka nebola nรกjdenรก. Ste si istรญ, ลพe zadanรก adresa URL je sprรกvna?", "bundle_column_error.routing.title": "404", - "bundle_modal_error.close": "Zatvor", - "bundle_modal_error.message": "Nastala chyba pri naฤรญtanรญ tohto komponentu.", + "bundle_modal_error.close": "Zatvoriลฅ", + "bundle_modal_error.message": "Pri naฤรญtavanรญ tohto komponentu nastala chyba.", "bundle_modal_error.retry": "Skรบsiลฅ znova", "closed_registrations.other_server_instructions": "Keฤลพe Mastodon je decentralizovanรฝ, mรดลพete si vytvoriลฅ รบฤet na inom serveri a stรกle komunikovaลฅ s tรฝmto serverom.", - "closed_registrations_modal.description": "Vytvorenie รบฤtu na {domain} nie je v sรบฤasnosti moลพnรฉ, ale majte prosรญm na pamรคti, ลพe nepotrebujete รบฤet prรกve na {domain}, aby bolo moลพnรฉ pouลพรญvaลฅ Mastodon.", - "closed_registrations_modal.find_another_server": "Nรกjdi inรฝ server", + "closed_registrations_modal.description": "Vytvorenie รบฤtu na {domain} nie je v sรบฤasnosti moลพnรฉ, ale myslite na to, ลพe na pouลพรญvanie Mastodonu nepotrebujete รบฤet prรกve na {domain}.", + "closed_registrations_modal.find_another_server": "Nรกjsลฅ inรฝ server", "closed_registrations_modal.preamble": "Mastodon je decentralizovanรฝ, takลพe bez ohฤพadu na to, kde si vytvorรญte รบฤet, budete mรดcลฅ sledovaลฅ a komunikovaลฅ s kรฝmkoฤพvek na tomto serveri. Mรดลพete ho dokonca hostiลฅ sami!", - "closed_registrations_modal.title": "Registrรกcia na Mastodon", + "closed_registrations_modal.title": "Registrรกcia na Mastodone", "column.about": "O tomto serveri", - "column.blocks": "Blokovanรญ uลพรญvatelia", + "column.blocks": "Blokovanรฉ รบฤty", "column.bookmarks": "Zรกloลพky", "column.community": "Miestna ฤasovรก os", - "column.direct": "Sรบkromnรฉ spomenutia", - "column.directory": "Prehฤพadรกvaj profily", - "column.domain_blocks": "Skrytรฉ domรฉny", + "column.direct": "Sรบkromnรฉ oznaฤenia", + "column.directory": "Prehฤพadรกvaลฅ profily", + "column.domain_blocks": "Blokovanรฉ domรฉny", "column.favourites": "Obฤพรบbenรฉ", "column.firehose": "ลฝivรฉ kanรกly", "column.follow_requests": "ลฝiadosti o sledovanie", "column.home": "Domov", "column.lists": "Zoznamy", - "column.mutes": "Nevลกรญmanรญ uลพรญvatelia", - "column.notifications": "Oznรกmenia", + "column.mutes": "Stรญลกenรฉ รบฤty", + "column.notifications": "Upozornenia", "column.pins": "Pripnutรฉ prรญspevky", "column.public": "Federovanรก ฤasovรก os", "column_back_button.label": "Spรคลฅ", "column_header.hide_settings": "Skryลฅ nastavenia", - "column_header.moveLeft_settings": "Presuลˆ stฤบpec doฤพava", - "column_header.moveRight_settings": "Presuลˆ stฤบpec doprava", - "column_header.pin": "Pripni", - "column_header.show_settings": "Ukรกลพ nastavenia", - "column_header.unpin": "Odopni", + "column_header.moveLeft_settings": "Presunรบลฅ stฤบpec doฤพava", + "column_header.moveRight_settings": "Presunรบลฅ stฤบpec doprava", + "column_header.pin": "Pripnรบลฅ", + "column_header.show_settings": "Zobraziลฅ nastavenia", + "column_header.unpin": "Odopnรบลฅ", "column_subheading.settings": "Nastavenia", - "community.column_settings.local_only": "Iba miestna", + "community.column_settings.local_only": "Iba miestne", "community.column_settings.media_only": "Iba mรฉdiรก", - "community.column_settings.remote_only": "Iba odฤพahlรฉ", - "compose.language.change": "Zmeลˆ jazyk", - "compose.language.search": "Hฤพadaj medzi jazykmi...", + "community.column_settings.remote_only": "Iba vzdialenรฉ", + "compose.language.change": "Zmeniลฅ jazyk", + "compose.language.search": "Vyhฤพadรกvaลฅ jazykyโ€ฆ", "compose.published.body": "Prรญspevok zverejnenรฝ.", - "compose.published.open": "Otvor", + "compose.published.open": "Otvoriลฅ", "compose.saved.body": "Prรญspevok uloลพenรฝ.", - "compose_form.direct_message_warning_learn_more": "Zisti viac", - "compose_form.encryption_warning": "Prรญspevky na Mastodon nie sรบ end-to-end ลกifrovanรฉ. Nezdieฤพajte cez Mastodon ลพiadne citlivรฉ informรกcie.", - "compose_form.hashtag_warning": "Tento prรญspevok nebude zobrazenรฝ pod ลพiadnรฝm haลกtagom, lebo nieje verejne listovanรฝ. Iba verejnรฉ prรญspevky mรดลพu byลฅ nรกjdenรฉ podฤพa haลกtagu.", - "compose_form.lock_disclaimer": "Tvoj รบฤet nie je {locked}. Ktokoฤพvek ลฅa mรดลพe nasledovaลฅ a vidieลฅ tvoje prรญspevky pre sledujรบcich.", + "compose_form.direct_message_warning_learn_more": "Viac informรกciรญ", + "compose_form.encryption_warning": "Prรญspevky na Mastodone nie sรบ ลกifrovanรฉ end-to-end. Nezdieฤพajte cez Mastodon ลพiadne citlivรฉ informรกcie.", + "compose_form.hashtag_warning": "Tento prรญspevok nebude zobrazenรฝ pod ลพiadnรฝm hashtagom, lebo nie je verejnรฝ. Iba verejnรฉ prรญspevky mรดลพu byลฅ nรกjdenรฉ podฤพa hashtagu.", + "compose_form.lock_disclaimer": "Vรกลก รบฤet nie je {locked}. Ktokoฤพvek vรกs mรดลพe sledovaลฅ a vidieลฅ vaลกe prรญspevky pre sledujรบcich.", "compose_form.lock_disclaimer.lock": "zamknutรฝ", - "compose_form.placeholder": "ฤŒo mรกลก na mysli?", + "compose_form.placeholder": "Na ฤo prรกve myslรญte?", "compose_form.poll.duration": "Trvanie ankety", "compose_form.poll.multiple": "Viacero moลพnostรญ", - "compose_form.poll.option_placeholder": "Voฤพba {number}", - "compose_form.poll.single": "Vyber jednu", - "compose_form.poll.switch_to_multiple": "Zmeลˆ anketu pre povolenie viacerรฝch moลพnostรญ", - "compose_form.poll.switch_to_single": "Zmeลˆ anketu na takรบ s jedinou voฤพbou", + "compose_form.poll.option_placeholder": "Moลพnosลฅ {number}", + "compose_form.poll.single": "Jedinรฝ vรฝber", + "compose_form.poll.switch_to_multiple": "Zmeniลฅ anketu a povoliลฅ viacerรฉ moลพnosti", + "compose_form.poll.switch_to_single": "Zmeniลฅ anketu na jedinรฝ povolenรฝ vรฝber", "compose_form.poll.type": "Typ", - "compose_form.publish": "Prispej", - "compose_form.publish_form": "Zverejniลฅ", - "compose_form.reply": "Odpovedz", - "compose_form.save_changes": "Aktualizรกcia", - "compose_form.spoiler.marked": "Text je ukrytรฝ za varovanรญm", - "compose_form.spoiler.unmarked": "Text nieje ukrytรฝ", + "compose_form.publish": "Uverejniลฅ", + "compose_form.publish_form": "Novรฝ prรญspevok", + "compose_form.reply": "Odpovedaลฅ", + "compose_form.save_changes": "Aktualizovaลฅ", + "compose_form.spoiler.marked": "Odstrรกniลฅ varovanie o obsahu", + "compose_form.spoiler.unmarked": "Pridaลฅ varovanie o obsahu", "compose_form.spoiler_placeholder": "Varovanie o obsahu (voliteฤพnรฉ)", "confirmation_modal.cancel": "Zruลก", - "confirmations.block.block_and_report": "Zablokuj a nahlรกs", - "confirmations.block.confirm": "Blokuj", - "confirmations.block.message": "Si si istรฝ/รก, ลพe chceลก blokovaลฅ {name}?", - "confirmations.cancel_follow_request.confirm": "Odvolanie ลพiadosti", - "confirmations.cancel_follow_request.message": "Naozaj chcete stiahnuลฅ svoju ลพiadosลฅ o sledovanie {name}?", - "confirmations.delete.confirm": "Vymaลพ", - "confirmations.delete.message": "Si si istรฝ/รก, ลพe chceลก vymazaลฅ tรบto sprรกvu?", - "confirmations.delete_list.confirm": "Vymaลพ", - "confirmations.delete_list.message": "Si si istรฝ/รก, ลพe chceลก natrvalo vymazaลฅ tento zoznam?", - "confirmations.discard_edit_media.confirm": "Zahoฤ", + "confirmations.block.confirm": "Zablokovaลฅ", + "confirmations.cancel_follow_request.confirm": "Stiahnuลฅ ลพiadosลฅ", + "confirmations.cancel_follow_request.message": "Urฤite chcete stiahnuลฅ svoju ลพiadosลฅ o sledovanie {name}?", + "confirmations.delete.confirm": "Vymazaลฅ", + "confirmations.delete.message": "Urฤite chcete tento prรญspevok vymazaลฅ?", + "confirmations.delete_list.confirm": "Vymazaลฅ", + "confirmations.delete_list.message": "Urฤite chcete tento zoznam trvalo vymazaลฅ?", + "confirmations.discard_edit_media.confirm": "Zahodiลฅ", "confirmations.discard_edit_media.message": "Mรกte neuloลพenรฉ zmeny v popise alebo nรกhฤพade mรฉdia, zahodiลฅ ich aj tak?", - "confirmations.domain_block.confirm": "Skry celรบ domรฉnu", - "confirmations.domain_block.message": "Si si naozaj istรฝ/รก, ลพe chceลก blokovaลฅ celรบ domรฉnu {domain}? Vo vรคฤลกine prรญpadov staฤรญ blokovaลฅ alebo ignorovaลฅ pรกr konkrรฉtnych uลพรญvateฤพov, ฤo sa doporuฤuje. Neuvidรญลก obsah z tejto domรฉny v ลพiadnej verejnej ฤasovej osi, ani v oznรกmeniach. Tvoji nรกsledovnรญci pochรกdzajรบci z tejto domรฉny budรบ odstrรกnenรญ.", - "confirmations.edit.confirm": "Uprav", - "confirmations.edit.message": "รšpravou teraz prepรญลกeลก sprรกvu, ktorรบ prรกve zostavujeลก. Si si istรฝ/รก, ลพe chceลก pokraฤovaลฅ?", - "confirmations.logout.confirm": "Odhlรกs sa", - "confirmations.logout.message": "Si si istรฝ/รก, ลพe sa chceลก odhlรกsiลฅ?", - "confirmations.mute.confirm": "Nevลกรญmaj si", - "confirmations.mute.explanation": "Toto nastavenie skryje ich prรญspevky, alebo prรญspevky od inรฝch v ktorรฝch sรบ spomenutรญ, ale umoลพnรญ im vidieลฅ tvoje prรญspevky, aj ลฅa nasledovaลฅ.", - "confirmations.mute.message": "Naozaj si chceลก nevลกรญmaลฅ {name}?", - "confirmations.redraft.confirm": "Vyฤisti a prepรญลก", - "confirmations.redraft.message": "Ste si istรฝ, ลพe chcete premazaลฅ a prepรญsaลฅ tento prรญspevok? Jeho nadobudnutรฉ vyzdvihnutia a obฤพรบbenia, ale i odpovede na pรดvodnรฝ prรญspevok budรบ odlรบฤenรฉ.", - "confirmations.reply.confirm": "Odpovedz", + "confirmations.domain_block.confirm": "Blokovaลฅ server", + "confirmations.domain_block.message": "Urฤite chcete blokovaลฅ celรบ domรฉnu {domain}? Vo vรคฤลกine prรญpadov staฤรญ blokovaลฅ alebo ignorovaลฅ pรกr konkrรฉtnych รบฤtov, ฤo aj odporรบฤame. Obsah z tejto domรฉny neuvidรญte v ลพiadnej verejnej ฤasovej osi ani v upozorneniach. Vaลกi sledujรบci pochรกdzajรบci z tejto domรฉny budรบ odstrรกnenรญ.", + "confirmations.edit.confirm": "Upraviลฅ", + "confirmations.edit.message": "รšpravou prepรญลกete prรญspevok, ktorรฝ mรกte rozpรญsanรฝ. Urฤite chcete pokraฤovaลฅ?", + "confirmations.logout.confirm": "Odhlรกsiลฅ sa", + "confirmations.logout.message": "Urฤite sa chcete odhlรกsiลฅ?", + "confirmations.mute.confirm": "Stรญลกiลฅ", + "confirmations.redraft.confirm": "Vymazaลฅ a prepรญsaลฅ", + "confirmations.redraft.message": "Urฤite chcete tento prรญspevok vymazaลฅ a prepรญsaลฅ? Prรญdete o jeho zdieฤพania a ohviezdiฤkovania a odpovede na pรดvodnรฝ prรญspevok budรบ odlรบฤenรฉ.", + "confirmations.reply.confirm": "Odpovedaลฅ", "confirmations.reply.message": "Odpovedanรญm akurรกt teraz prepรญลกeลก sprรกvu, ktorรบ mรกลก prรกve rozpรญsanรบ. Si si istรฝ/รก, ลพe chceลก pokraฤovaลฅ?", - "confirmations.unfollow.confirm": "Prestaลˆ sledovaลฅ", - "confirmations.unfollow.message": "Naozaj chceลก prestaลฅ sledovaลฅ {name}?", - "conversation.delete": "Vymaลพ konverzรกciu", - "conversation.mark_as_read": "Oznaฤ za preฤรญtanรฉ", - "conversation.open": "Ukรกลพ konverzรกciu", + "confirmations.unfollow.confirm": "Prestaลฅ sledovaลฅ", + "confirmations.unfollow.message": "Urฤite chcete prestaลฅ sledovaลฅ {name}?", + "conversation.delete": "Vymazaลฅ konverzรกciu", + "conversation.mark_as_read": "Oznaฤiลฅ ako preฤรญtanรบ", + "conversation.open": "Zobraziลฅ konverzรกciu", "conversation.with": "S {names}", - "copy_icon_button.copied": "Skopรญrovanรฝ do schrรกnky", + "copy_icon_button.copied": "Skopรญrovanรฉ do schrรกnky", "copypaste.copied": "Skopรญrovanรฉ", - "copypaste.copy_to_clipboard": "Skopรญruj do schrรกnky", - "directory.federated": "Zo znรกmรฉho fedivesmรญru", + "copypaste.copy_to_clipboard": "Skopรญrovaลฅ do schrรกnky", + "directory.federated": "Zo znรกmรฉho fediverza", "directory.local": "Iba z {domain}", "directory.new_arrivals": "Novรฉ prรญchody", - "directory.recently_active": "Nedรกvno aktรญvne", + "directory.recently_active": "Nedรกvna aktivita", "disabled_account_banner.account_settings": "Nastavenia รบฤtu", - "disabled_account_banner.text": "Vaลกe konto {disabledAccount} je momentรกlne vypnutรฉ.", - "dismissable_banner.community_timeline": "Toto sรบ najnovลกie verejnรฉ prรญspevky od ฤพudรญ, ktorรฝch รบฤty sรบ hostovanรฉ na {domain}.", + "disabled_account_banner.text": "Vรกลก รบฤet {disabledAccount} je momentรกlne deaktivovanรฝ.", + "dismissable_banner.community_timeline": "Toto sรบ najnovลกie verejnรฉ prรญspevky od รบฤtov hostenรฝch na {domain}.", "dismissable_banner.dismiss": "Zruลกiลฅ", - "dismissable_banner.explore_links": "Tieto sprรกvy sรบ dnes najviac zdieฤพanรฉ naprieฤ sociรกlnou sieลฅou. Novลกie sprรกvy, zdieฤพanรฉ viacerรฝmi rรดznymi ฤพudmi sรบ zoradenรฉ vyลกลกie.", - "dismissable_banner.explore_statuses": "Toto sรบ prรญspevky naprieฤ celej sociรกlnej sieti, ktorรฉ dnes naberajรบ na ลฅahu. Novลกie prรญspevky s viacerรฝmi vyzdvihnutiami sรบ radenรฉ vyลกลกie.", - "dismissable_banner.explore_tags": "Tieto haลกtagy prรกve teraz zรญskavajรบ popularitu, medzi ฤพuฤmi na tomto a ฤalลกรญch serveroch decentralizovanej siete.", - "dismissable_banner.public_timeline": "Toto sรบ najnovลกie verejnรฉ prรญspevky od ฤพudรญ, ktorรญ sledujรบ {domain}, cez celรบ sociรกlnu sieลฅ.", - "embed.instructions": "Umiestni kรณd uvedenรฝ niลพลกie pre pridanie tohto statusu na tvoju web strรกnku.", - "embed.preview": "Tu je ako to bude vyzeraลฅ:", + "dismissable_banner.explore_links": "Toto sรบ sprรกvy zo sociรกlnej siete, ktorรฉ sรบ dnes populรกrne. Novลกie sprรกvy s viacerรฝmi ohviezdiฤkovaniami a zdieฤพaniami sรบ radenรฉ vyลกลกie.", + "dismissable_banner.explore_statuses": "Toto sรบ prรญspevky z celej sociรกlnej siete, ktorรฉ sรบ dnes populรกrne. Novลกie prรญspevky s viacerรฝmi ohviezdiฤkovaniami a zdieฤพaniami sรบ radenรฉ vyลกลกie.", + "dismissable_banner.explore_tags": "Toto sรบ hashtagy zo sociรกlnej siete, ktorรฉ sรบ dnes populรกrne. Novลกie hashtagy pouลพรญvanรฉ viacerรฝmi ฤพuฤmi sรบ radenรฉ vyลกลกie.", + "dismissable_banner.public_timeline": "Toto sรบ najnovลกie verejnรฉ prรญspevky od รบฤtov na sociรกlnej sieti, ktorรฉ sรบ sledovanรฉ รบฤtami z {domain}.", + "domain_block_modal.block": "Blokovaลฅ server", + "domain_block_modal.block_account_instead": "Namiesto toho zablokuj @{name}", + "domain_block_modal.title": "Blokovaลฅ domรฉnu?", + "domain_pill.server": "Server", + "domain_pill.their_server": "Ich digitรกlny domov, kde ลพijรบ vลกetky ich prรญspevky.", + "domain_pill.username": "Pouลพรญvateฤพskรฉ meno", + "embed.instructions": "Tento prรญspevok mรดลพete pridaลฅ na svoju webovรบ strรกnku pouลพitรญm tohto kรณdu.", + "embed.preview": "Takto bude vyzeraลฅ:", "emoji_button.activity": "Aktivita", - "emoji_button.clear": "Vyฤisti", + "emoji_button.clear": "Vyฤistiลฅ", "emoji_button.custom": "Vlastnรฉ", "emoji_button.flags": "Vlajky", "emoji_button.food": "Jedlรก a nรกpoje", - "emoji_button.label": "Vloลพ emotikony", - "emoji_button.nature": "Prรญrodnรฉ", - "emoji_button.not_found": "Nie emotikony!! (โ•ฏยฐโ–กยฐ๏ผ‰โ•ฏ๏ธต โ”ปโ”โ”ป", + "emoji_button.label": "Vloลพiลฅ emotikony", + "emoji_button.nature": "Prรญroda", + "emoji_button.not_found": "ลฝiadne emotikony", "emoji_button.objects": "Predmety", "emoji_button.people": "ฤฝudia", "emoji_button.recent": "ฤŒasto pouลพรญvanรฉ", - "emoji_button.search": "Hฤพadaj...", + "emoji_button.search": "Hฤพadaลฅโ€ฆ", "emoji_button.search_results": "Vรฝsledky hฤพadania", "emoji_button.symbols": "Symboly", "emoji_button.travel": "Cestovanie a miesta", - "empty_column.account_hides_collections": "Tento uลพรญvateฤพ si zvolil nesprรญstupniลฅ tรบto informรกciu", + "empty_column.account_hides_collections": "Tento รบฤet sa rozhodol tรบto informรกciu nesprรญstupniลฅ", "empty_column.account_suspended": "รšฤet bol pozastavenรฝ", - "empty_column.account_timeline": "Nie sรบ tu ลพiadne prรญspevky!", + "empty_column.account_timeline": "Nie sรบ tu ลพiadne prรญspevky.", "empty_column.account_unavailable": "Profil nedostupnรฝ", - "empty_column.blocks": "Eลกte si nikoho nezablokoval/a.", - "empty_column.bookmarked_statuses": "Eลกte nemรกลก ลพiadnรฉ zรกloลพky. Keฤ si pridรกลก prรญspevok k zรกloลพkรกm, zobrazรญ sa tu.", - "empty_column.community": "Lokรกlna ฤasovรก os je prรกzdna. Napรญลกte nieฤo, aby sa to tu zaฤalo hรฝbaลฅ!", - "empty_column.direct": "Eลกte nemรกลก ลพiadne priame zmienky. Keฤ nejakรบ poลกleลก alebo dostaneลก, ukรกลพe sa tu.", - "empty_column.domain_blocks": "ลฝiadne domรฉny eลกte niesรบ skrytรฉ.", - "empty_column.explore_statuses": "Momentรกlne nie je niฤ trendovรฉ. Pozrite sa neskรดr!", - "empty_column.favourited_statuses": "Zatiaฤพ nemรกลก ลพiadne obฤพรบbenรฉ prรญspevky. Akonรกhle oznaฤรญลก nejakรฝ ako obฤพรบbenรฝ, zobrazรญ sa tu.", - "empty_column.favourites": "Nikto si zatiaฤพ tento prรญspevok neobฤพรบbil. Akonรกhle tak niekto urobรญ, zobrazรญ sa tu.", - "empty_column.follow_requests": "Eลกte nemรกลก ลพiadne poลพiadavky o nรกsledovanie. Keฤ nejakรฉ dostaneลก, budรบ tu zobrazenรฉ.", - "empty_column.followed_tags": "Eลกte nenasledujeลก ลพiadne haลกtagy. Keฤ tak urobรญลก, zobrazia sa tu.", + "empty_column.blocks": "Nemรกte blokovanรฉ ลพiadne รบฤty.", + "empty_column.bookmarked_statuses": "Eลกte nemรกte zรกloลพku v ลพiadnom prรญspevku. Keฤ si ju do nejakรฉho prรญspevkuk pridรกte, zobrazรญ sa tu.", + "empty_column.community": "Miesta ฤasovรก os je prรกzdna. Napรญลกte nieฤo, aby to tu oลพilo!", + "empty_column.direct": "Eลกte nemรกte ลพiadne sรบkromnรฉ oznaฤenia. Keฤ nejakรฉ poลกlete alebo dostanete, zobrazรญ sa tu.", + "empty_column.domain_blocks": "ลฝiadne domรฉny eลกte nie sรบ blokovanรฉ.", + "empty_column.explore_statuses": "Momentรกlne nie je niฤ populรกrne. Skontrolujte to zas neskรดr.", + "empty_column.favourited_statuses": "Zatiaฤพ nemรกte ลพiadne ohviezdiฤkovanรฉ prรญspevky. Akonรกhle nejakรฝ ohviezdiฤkujete, zobrazรญ sa tu.", + "empty_column.favourites": "Zatiaฤพ tento prรญspevok nikto neohviezdiฤkoval. Akonรกhle sa tak stane, zobrazรญ sa tu.", + "empty_column.follow_requests": "Zatiaฤพ nemรกte ลพiadne ลพiadosti o sledovanie. Keฤ nejakรบ dostanete, zobrazรญ sa tu.", + "empty_column.followed_tags": "Zatiaฤพ nesledujete ลพiadne hashtagy. Keฤ tak urobรญte, zobrazia sa tu.", "empty_column.hashtag": "Pod tรฝmto hashtagom sa eลกte niฤ nenachรกdza.", - "empty_column.home": "Tvoja lokรกlna osa je zatiaฤพ prรกzdna! Pre zaฤiatok navลกtรญv {public}, alebo pouลพi vyhฤพadรกvanie a nรกjdi tak aj inรฝch uลพรญvateฤพov.", - "empty_column.list": "Tento zoznam je eลกte prรกzdny. Keฤ ale ฤlenovia tohoto zoznamu napรญลกu novรฉ sprรกvy, tak tie sa objavia priamo tu.", - "empty_column.lists": "Nemรกลก eลกte ลพiadne zoznamy. Keฤ nejakรฝ vytvorรญลก, bude zobrazenรฝ prรกve tu.", - "empty_column.mutes": "Eลกte si nestฤบmil ลพiadnรฝch uลพรญvateฤพov.", - "empty_column.notifications": "Eลกte nemรกลก ลพiadne oznรกmenia. Zaฤni komunikovaลฅ s ostatnรฝmi, aby diskusia mohla zaฤaลฅ.", - "empty_column.public": "Eลกte tu niฤ nie je. Napรญลก nieฤo verejne, alebo zaฤni sledovaลฅ uลพรญvateฤพov z inรฝch serverov, aby tu nieฤo pribudlo", - "error.unexpected_crash.explanation": "Kvรดli chybe v naลกom kรณde, alebo problรฉmu s kompatibilitou prehliadaฤa, tรบto strรกnku nebolo moลพnรฉ zobraziลฅ sprรกvne.", - "error.unexpected_crash.explanation_addons": "Tรบto strรกnku sa nepodarilo zobraziลฅ sprรกvne. Tรกto chyba je pravdepodobne spรดsobenรก rozลกรญrenรญm v prehliadaฤi, alebo nรกstrojmi automatickรฉho prekladu.", - "error.unexpected_crash.next_steps": "Skรบs obnoviลฅ strรกnku. Ak to nepomรดลพe, pravdepodobne budeลก stรกle mรดcลฅ pouลพรญvaลฅ Mastodon cez inรฝ prehliadaฤ, alebo natรญvnu aplikรกciu.", - "error.unexpected_crash.next_steps_addons": "Skรบs ich vypnรบลฅ, a obnoviลฅ tรบto strรกnku. Ak to nepomรดลพe, pravdepodobne budeลก stรกle mรดcลฅ Mastodon pouลพรญvaลฅ cez inรฝ prehliadaฤ, alebo natรญvnu aplikรกciu.", - "errors.unexpected_crash.copy_stacktrace": "Skopรญruj stacktrace do schrรกnky", - "errors.unexpected_crash.report_issue": "Nahlรกs problรฉm", + "empty_column.home": "Vaลกa domรกca ฤasovรก os je zatiaฤพ prรกzdna. Zaฤnite sledovaลฅ ostatnรฝch a naplลˆte si ju.", + "empty_column.list": "Tento zoznam je zatiaฤพ prรกzdny. Keฤ ale ฤlenovia tohoto zoznamu uverejnia novรฉ prรญspevky, objavia sa tu.", + "empty_column.lists": "Zatiaฤพ nemรกte ลพiadne zoznamy. Keฤ nejakรฝ vytvorรญte, zobrazรญ sa tu.", + "empty_column.mutes": "Zatiaฤพ ste si nikoho nestรญลกili.", + "empty_column.notification_requests": "Vลกetko ฤistรฉ! Niฤ tu nieje. Keฤ dostaneลก novรฉ oboznรกmenia, zobrazia sa tu podฤพa tvojich nastavenรญ.", + "empty_column.notifications": "Zatiaฤพ nemรกte ลพiadne upozornenia. Zaฤnรบ vรกm pribรบdaลฅ, keฤ s vami zaฤnรบ interagovaลฅ ostatnรญ.", + "empty_column.public": "Zatiaฤพ tu niฤ nie je. Napรญลกte nieฤo verejnรฉ alebo zaฤnite sledovaลฅ รบฤty z inรฝch serverov, aby tu nieฤo pribudlo.", + "error.unexpected_crash.explanation": "Pre chybu v naลกom kรณde alebo problรฉm s kompatibilitou prehliadaฤa nebolo tรบto strรกnku moลพnรฉ zobraziลฅ sprรกvne.", + "error.unexpected_crash.explanation_addons": "Tรบto strรกnku sa nepodarilo zobraziลฅ sprรกvne. Tรกto chyba je pravdepodobne spรดsobenรก rozลกรญrenรญm v prehliadaฤi alebo nรกstrojmi automatickรฉho prekladu.", + "error.unexpected_crash.next_steps": "Skรบste strรกnku obnoviลฅ. Ak to nepomรดลพe, pravdepodobne budete stรกle mรดcลฅ pouลพรญvaลฅ Mastodon cez inรฝ prehliadaฤ alebo natรญvnu aplikรกciu.", + "error.unexpected_crash.next_steps_addons": "Skรบste ich vypnรบลฅ a strรกnku obnoviลฅ. Ak to nepomรดลพe, pravdepodobne budete stรกle mรดcลฅ Mastodon pouลพรญvaลฅ cez inรฝ prehliadaฤ alebo natรญvnu aplikรกciu.", + "errors.unexpected_crash.copy_stacktrace": "Kopรญrovaลฅ stacktrace do schrรกnky", + "errors.unexpected_crash.report_issue": "Nahlรกsiลฅ problรฉm", "explore.search_results": "Vรฝsledky hฤพadania", "explore.suggested_follows": "ฤฝudia", - "explore.title": "Objavuj", - "explore.trending_links": "Novinky", + "explore.title": "Objavovaลฅ", + "explore.trending_links": "Sprรกvy", "explore.trending_statuses": "Prรญspevky", - "explore.trending_tags": "Haลกtagy", + "explore.trending_tags": "Hashtagy", "filter_modal.added.context_mismatch_explanation": "Tรกto kategรณria filtrov sa nevzลฅahuje na kontext, v ktorom ste zรญskali prรญstup k tomuto prรญspevku. Ak chcete, aby sa prรญspevok filtroval aj v tomto kontexte, budete musieลฅ filter upraviลฅ.", "filter_modal.added.context_mismatch_title": "Nesรบlad kontextu!", "filter_modal.added.expired_explanation": "Platnosลฅ tejto kategรณrie filtra vyprลกala, aby sa pouลพila, je potrebnรฉ zmeniลฅ dรกtum vyprลกania platnosti.", "filter_modal.added.expired_title": "Vyprลกala platnosลฅ filtra!", "filter_modal.added.review_and_configure": "Ak chcete skontrolovaลฅ a ฤalej konfigurovaลฅ tรบto kategรณriu filtrov, prejdite na odkaz {settings_link}.", - "filter_modal.added.review_and_configure_title": "Nastavenie triedenia", - "filter_modal.added.settings_link": "strรกnka s nastaveniami", + "filter_modal.added.review_and_configure_title": "Nastavenia filtrov", + "filter_modal.added.settings_link": "strรกnka nastavenรญ", "filter_modal.added.short_explanation": "Tento prรญspevok bol pridanรฝ do nasledujรบcej kategรณrie filtrov: {title}.", - "filter_modal.added.title": "Triedenie pridanรฉ!", + "filter_modal.added.title": "Filter bol pridanรฝ.", "filter_modal.select_filter.context_mismatch": "sa na tento kontext nevzลฅahuje", - "filter_modal.select_filter.expired": "vyprลกalo", + "filter_modal.select_filter.expired": "vyprลกal", "filter_modal.select_filter.prompt_new": "Novรก kategรณria: {name}", - "filter_modal.select_filter.search": "Vyhฤพadรกvaลฅ alebo vytvoriลฅ", + "filter_modal.select_filter.search": "Vyhฤพadaลฅ alebo vytvoriลฅ", "filter_modal.select_filter.subtitle": "Pouลพite existujรบcu kategรณriu alebo vytvorte novรบ", "filter_modal.select_filter.title": "Filtrovanie tohto prรญspevku", "filter_modal.title.status": "Filtrovanie prรญspevku", - "firehose.all": "Vลกetky", + "filtered_notifications_banner.pending_requests": "Oboznรกmenia od {count, plural, =0 {nikoho} one {jednรฉho ฤloveka} other {# ฤพudรญ}} ฤo mรดลพeลก poznaลฅ", + "filtered_notifications_banner.title": "Filtrovanรฉ oznรกmenia", + "firehose.all": "Vลกetko", "firehose.local": "Tento server", - "firehose.remote": "Inรฉ servery", - "follow_request.authorize": "Povoฤพ prรญstup", - "follow_request.reject": "Odmietni", - "follow_requests.unlocked_explanation": "Sรญce Vรกลก uฤet nie je uzamknutรฝ, ale {domain} tรญm si myslel ลพe mรดลพete chcieลฅ skontrolovaลฅ ลพiadosti o sledovanie z tรฝchto รบฤtov manuรกlne.", - "follow_suggestions.curated_suggestion": "Vรฝber zo servera", - "follow_suggestions.dismiss": "Znovu nezobrazuj", - "follow_suggestions.personalized_suggestion": "Prispรดsobenรฉ odporรบฤania", - "follow_suggestions.popular_suggestion": "Populรกrne nรกvrhy", - "follow_suggestions.view_all": "Zobraz vลกetky", - "follow_suggestions.who_to_follow": "Koho nasledovaลฅ", - "followed_tags": "Nasledovanรฉ haลกtagy", - "footer.about": "O", + "firehose.remote": "Ostatnรฉ servery", + "follow_request.authorize": "Povoliลฅ", + "follow_request.reject": "Zamietnuลฅ", + "follow_requests.unlocked_explanation": "Aj keฤ vรกลก รบฤet nie je uzamknutรฝ, tรญm domรฉny {domain} si myslel, ลพe mรดลพete chcieลฅ skontrolovaลฅ ลพiadosti o sledovanie z tรฝchto รบฤtov manuรกlne.", + "follow_suggestions.curated_suggestion": "Vรฝber redakcie", + "follow_suggestions.dismiss": "Znova nezobrazovaลฅ", + "follow_suggestions.hints.featured": "Tento profil bol ruฤne zvolenรฝ tรญmom domรฉny {domain}.", + "follow_suggestions.hints.friends_of_friends": "Tento profil je obฤพรบbenรฝ medzi รบฤtami, ktorรฉ sledujete.", + "follow_suggestions.hints.most_followed": "Tento profil patrรญ na domรฉne {domain} medzi najsledovanejลกie.", + "follow_suggestions.hints.most_interactions": "Tento profil mรก v poslednej dobe na domรฉne {domain} veฤพa interakciรญ.", + "follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobnรฝ profilom, ktorรฉ ste nedรกvno zaฤali sledovaลฅ.", + "follow_suggestions.personalized_suggestion": "Prispรดsobenรฝ nรกvrh", + "follow_suggestions.popular_suggestion": "Obฤพรบbenรฝ nรกvrh", + "follow_suggestions.popular_suggestion_longer": "Populรกrne na {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Podobnรฉ profilom, ktorรฉ si nedรกvno nasledoval/a", + "follow_suggestions.view_all": "Zobraziลฅ vลกetky", + "follow_suggestions.who_to_follow": "Koho sledovaลฅ", + "followed_tags": "Sledovanรฉ hashtagy", + "footer.about": "Viac informรกciรญ", "footer.directory": "Adresรกr profilov", "footer.get_app": "Stiahnuลฅ aplikรกciu", - "footer.invite": "Pozvi ฤพudรญ", + "footer.invite": "Pozvaลฅ ฤพudรญ", "footer.keyboard_shortcuts": "Klรกvesovรฉ skratky", - "footer.privacy_policy": "Zรกsady sรบkromia", + "footer.privacy_policy": "Pravidlรก ochrany sรบkromia", "footer.source_code": "Zobraziลฅ zdrojovรฝ kรณd", "footer.status": "Stav", "generic.saved": "Uloลพenรฉ", - "getting_started.heading": "Zaฤni tu", + "getting_started.heading": "Zaฤรญname", "hashtag.column_header.tag_mode.all": "a {additional}", "hashtag.column_header.tag_mode.any": "alebo {additional}", "hashtag.column_header.tag_mode.none": "bez {additional}", "hashtag.column_settings.select.no_options_message": "ลฝiadne nรกvrhy neboli nรกjdenรฉ", - "hashtag.column_settings.select.placeholder": "Zadaj haลกtagyโ€ฆ", + "hashtag.column_settings.select.placeholder": "Zadajte hashtagyโ€ฆ", "hashtag.column_settings.tag_mode.all": "Vลกetky tieto", - "hashtag.column_settings.tag_mode.any": "Hociktorรฝ z tรฝchto", + "hashtag.column_settings.tag_mode.any": "ฤฝubovoฤพnรฉ z tรฝchto", "hashtag.column_settings.tag_mode.none": "ลฝiaden z tรฝchto", - "hashtag.column_settings.tag_toggle": "Vloลพ dodatoฤnรฉ haลกtagy pre tento stฤบpec", - "hashtag.counter_by_accounts": "{count, plural, one {{counter} รบฤastnรญk} other {{counter} รบฤastnรญci}}", + "hashtag.column_settings.tag_toggle": "Vloลพte dodatoฤnรฉ hashtagy pre tento stฤบpec", + "hashtag.counter_by_accounts": "{count, plural, one {{counter} prispievateฤพ} few {{counter} prispievatelia} many {{counter} prispievateฤพov} other {{counter} prispievateฤพov}}", "hashtag.counter_by_uses": "{count, plural, one {{counter} prรญspevok} few {{counter} prรญspevky} many {{counter} prรญspevkov} other {{counter} prรญspevkov}}", "hashtag.counter_by_uses_today": "{count, plural, one {{counter} prรญspevok} few {{counter} prรญspevky} many {{counter} prรญspevkov} other {{counter} prรญspevkov}} dnes", - "hashtag.follow": "Sleduj haลกtag", - "hashtag.unfollow": "Nesleduj haลกtag", - "hashtags.and_other": "โ€ฆa {count, plural, one {} few {# ฤalลกie} many {# ฤalลกรญch}other {# ฤalลกรญch}}", - "home.column_settings.basic": "Zรกkladnรฉ", - "home.column_settings.show_reblogs": "Ukรกลพ vyzdvihnutรฉ", - "home.column_settings.show_replies": "Ukรกลพ odpovede", - "home.hide_announcements": "Skry oznรกmenia", - "home.pending_critical_update.body": "Prosรญm aktualizuj si svoj Mastodon server, ako nรกhle to bude moลพnรฉ!", - "home.pending_critical_update.link": "Pozri aktualizรกcie", - "home.pending_critical_update.title": "Je dostupnรก kritickรก bezpeฤnostnรก aktualizรกcia!", - "home.show_announcements": "Ukรกลพ oznรกmenia", - "interaction_modal.description.favourite": "S รบฤtom na Mastodone si mรดลพeลก tento prรญspevok obฤพรบbiลฅ, aby si dal/a autorovi vedieลฅ, ลพe ho oceลˆujeลก, a uloลพiลฅ si ho na neskรดr.", - "interaction_modal.description.follow": "Ak mรกte konto na Mastodone, mรดลพete sledovaลฅ {name} a dostรกvaลฅ prรญspevky do svojho domovskรฉho kanรกla.", - "interaction_modal.description.reblog": "Ak mรกte รบฤet na Mastodone, mรดลพete tento prรญspevok posilniลฅ a zdieฤพaลฅ ho s vlastnรฝmi sledovateฤพmi.", - "interaction_modal.description.reply": "Ak mรกte รบฤet na Mastodone, mรดลพete reagovaลฅ na tento prรญspevok.", + "hashtag.follow": "Sledovaลฅ hashtag", + "hashtag.unfollow": "Prestaลฅ sledovaลฅ hashtag", + "hashtags.and_other": "โ€ฆa {count, plural, other {# ฤalลกรญch}}", + "home.column_settings.show_reblogs": "Zobraziลฅ zdieฤพania", + "home.column_settings.show_replies": "Zobraziลฅ odpovede", + "home.hide_announcements": "Skryลฅ oznรกmenia", + "home.pending_critical_update.body": "Prosรญme, aktualizujte si svoj Mastodon server, hneฤ ako to bude moลพnรฉ.", + "home.pending_critical_update.link": "Zobraziลฅ aktualizรกcie", + "home.pending_critical_update.title": "Je dostupnรก kritickรก bezpeฤnostnรก aktualizรกcia.", + "home.show_announcements": "Zobraziลฅ oznรกmenia", + "interaction_modal.description.favourite": "S รบฤtom na Mastodone mรดลพete tento prรญspevok ohviezdiฤkovaลฅ, tak daลฅ autorovi vedieลฅ, ลพe sa vรกm pรกฤi, a uloลพiลฅ si ho na neskรดr.", + "interaction_modal.description.follow": "S รบฤtom na Mastodone mรดลพete {name} sledovaลฅ a vidieลฅ ich prรญspevky vo svojom domovskom kanรกli.", + "interaction_modal.description.reblog": "S รบฤtom na Mastodone mรดลพete tento prรญspevok zdeฤพaลฅ so svojimi sledovateฤพmi.", + "interaction_modal.description.reply": "S รบฤtom na Mastodone mรดลพete na tento prรญspevok odpovedaลฅ.", "interaction_modal.login.action": "Prejsลฅ domov", - "interaction_modal.login.prompt": "Domรฉna tvojho domovskรฉho servera, napr. mastodon.social", - "interaction_modal.no_account_yet": "Niesi na Mastodone?", + "interaction_modal.login.prompt": "Domรฉna vรกลกho domovskรฉho servera, napr. mastodon.social", + "interaction_modal.no_account_yet": "Nie ste na Mastodone?", "interaction_modal.on_another_server": "Na inom serveri", "interaction_modal.on_this_server": "Na tomto serveri", - "interaction_modal.sign_in": "Nie si prihlรกseรฝ/รก na tomto serveri. Kde je tvoj รบฤet hostovanรฝ?", - "interaction_modal.sign_in_hint": "Tip: Toto je webovรก strรกnka, na ktorej ste sa zaregistrovali. Ak si nepamรคtรกte, pohฤพadajte uvรญtacรญ e-mail vo svojej schrรกnke. Mรดลพete tieลพ zadaลฅ svoje celรฉ pouลพรญvateฤพskรฉ meno! (napr. @Mastodon@mastodon.social)", - "interaction_modal.title.favourite": "Obฤพรบb si {name} ov/in prรญspevok", - "interaction_modal.title.follow": "Nasleduj {name}", - "interaction_modal.title.reblog": "Vyzdvihni {name}ov/in prรญspevok", - "interaction_modal.title.reply": "Odpovedz na {name}ov/in prรญspevok", - "intervals.full.days": "{number, plural, one {# deลˆ} few {# dnรญ} many {# dnรญ} other {# dnรญ}}", - "intervals.full.hours": "{number, plural, one {# hodina} few {# hodรญn} many {# hodรญn} other {# hodรญn}}", - "intervals.full.minutes": "{number, plural, one {# minรบta} few {# minรบt} many {# minรบt} other {# minรบt}}", - "keyboard_shortcuts.back": "dostaลฅ sa naspรคลฅ", - "keyboard_shortcuts.blocked": "otvor zoznam blokovanรฝch uลพรญvateฤพov", - "keyboard_shortcuts.boost": "Vyzdvihni prรญspevok", - "keyboard_shortcuts.column": "zameraj sa na prรญspevok v jednom zo stฤบpcov", - "keyboard_shortcuts.compose": "zameraj sa na pรญsaciu plochu", + "interaction_modal.sign_in": "Na tomto serveri nie ste prihlรกsenรฝ. Kde je vรกลก รบฤet hostenรฝ?", + "interaction_modal.sign_in_hint": "Tip: Toto je webovรก strรกnka, na ktorej ste sa zaregistrovali. Ak si nepamรคtรกte, pohฤพadajte uvรญtacรญ e-mail vo svojej schrรกnke. Mรดลพete tieลพ zadaลฅ svoje celรฉ pouลพรญvateฤพskรฉ meno (napr. @Mastodon@mastodon.social).", + "interaction_modal.title.favourite": "Ohviezdiฤkovaลฅ prรญspevok od {name}", + "interaction_modal.title.follow": "Sledovaลฅ {name}", + "interaction_modal.title.reblog": "Zdieฤพaลฅ prรญspevok od {name}", + "interaction_modal.title.reply": "Odpovedaลฅ na prรญspevok od {name}", + "intervals.full.days": "{number, plural, one {# deลˆ} few {# dni} many {# dnรญ} other {# dnรญ}}", + "intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodรญn} other {# hodรญn}}", + "intervals.full.minutes": "{number, plural, one {# minรบta} few {# minรบty} many {# minรบt} other {# minรบt}}", + "keyboard_shortcuts.back": "รsลฅ spรคลฅ", + "keyboard_shortcuts.blocked": "Otvoriลฅ zoznam blokovanรฝch uลพรญvateฤพov", + "keyboard_shortcuts.boost": "Zdieฤพaลฅ prรญspevok", + "keyboard_shortcuts.column": "Prejsลฅ na stฤบpec", + "keyboard_shortcuts.compose": "Prejsลฅ na textovรฉ pole", "keyboard_shortcuts.description": "Popis", - "keyboard_shortcuts.direct": "to open direct messages column", - "keyboard_shortcuts.down": "posunรบลฅ sa dole v zozname", - "keyboard_shortcuts.enter": "Otvor prรญspevok", - "keyboard_shortcuts.favourite": "Obฤพรบb si prรญspevok", - "keyboard_shortcuts.favourites": "Otvor zoznam obฤพรบbenรฝch", - "keyboard_shortcuts.federated": "otvor federovanรบ ฤasovรบ os", + "keyboard_shortcuts.direct": "Otvoriลฅ stฤบpec sรบkromnรฝch oznaฤenรญ", + "keyboard_shortcuts.down": "Posunรบลฅ sa dole v zozname", + "keyboard_shortcuts.enter": "Otvoriลฅ prรญspevok", + "keyboard_shortcuts.favourite": "Ohviezdiฤkovaลฅ prรญspevok", + "keyboard_shortcuts.favourites": "Otvoriลฅ zoznam ohviezdiฤkovanรฝch", + "keyboard_shortcuts.federated": "Otvoriลฅ federovanรบ ฤasovรบ os", "keyboard_shortcuts.heading": "Klรกvesovรฉ skratky", - "keyboard_shortcuts.home": "otvor domรกcu ฤasovรบ os", - "keyboard_shortcuts.hotkey": "Klรกvesa", - "keyboard_shortcuts.legend": "zobraz tรบto legendu", - "keyboard_shortcuts.local": "otvor miestnu ฤasovรบ os", - "keyboard_shortcuts.mention": "spomeลˆ autora", - "keyboard_shortcuts.muted": "otvor zoznam stรญลกenรฝch uลพรญvateฤพov", - "keyboard_shortcuts.my_profile": "otvor svoj profil", - "keyboard_shortcuts.notifications": "Otvor panel oznรกmenรญ", - "keyboard_shortcuts.open_media": "Otvorenie mรฉdiรญ", - "keyboard_shortcuts.pinned": "otvor zoznam pripnutรฝch prรญspevkov", - "keyboard_shortcuts.profile": "otvor autorov profil", - "keyboard_shortcuts.reply": "odpovedaลฅ", - "keyboard_shortcuts.requests": "otvor zoznam ลพiadostรญ o sledovanie", - "keyboard_shortcuts.search": "zameraj sa na vyhฤพadรกvanie", - "keyboard_shortcuts.spoilers": "to show/hide CW field", - "keyboard_shortcuts.start": "otvor panel ''zaฤรญname''", - "keyboard_shortcuts.toggle_hidden": "ukรกลพ/skry text za CW", - "keyboard_shortcuts.toggle_sensitivity": "Ukรกลพ/skry mรฉdiรก", - "keyboard_shortcuts.toot": "zaฤni รบplne novรฝ prรญspevok", - "keyboard_shortcuts.unfocus": "nesรบstreฤ sa na pรญsaciu plochu, alebo hฤพadanie", - "keyboard_shortcuts.up": "posuลˆ sa vyลกลกie v zozname", - "lightbox.close": "Zatvor", + "keyboard_shortcuts.home": "Otvoriลฅ domรกcu ฤasovรบ os", + "keyboard_shortcuts.hotkey": "Klรกves", + "keyboard_shortcuts.legend": "Zobraziลฅ tรบto legendu", + "keyboard_shortcuts.local": "Otvoriลฅ miestnu ฤasovรบ os", + "keyboard_shortcuts.mention": "Oznaฤiลฅ autora", + "keyboard_shortcuts.muted": "Otvoriลฅ zoznam stรญลกenรฝch uลพรญvateฤพov", + "keyboard_shortcuts.my_profile": "Otvoriลฅ svoj profil", + "keyboard_shortcuts.notifications": "Otvoriลฅ panel upozornenรญ", + "keyboard_shortcuts.open_media": "Otvoriลฅ mรฉdiรก", + "keyboard_shortcuts.pinned": "Otvoriลฅ zoznam pripnutรฝch prรญspevkov", + "keyboard_shortcuts.profile": "Otvoriลฅ autorov profil", + "keyboard_shortcuts.reply": "Odpovedaลฅ na prรญspevok", + "keyboard_shortcuts.requests": "Otvoriลฅ zoznam ลพiadostรญ o sledovanie", + "keyboard_shortcuts.search": "Prejsลฅ na vyhฤพadรกvacie pole", + "keyboard_shortcuts.spoilers": "Zobraziลฅ/skryลฅ pole varovania o obsahu", + "keyboard_shortcuts.start": "Otvoriลฅ panel โ€žZaฤรญnameโ€œ", + "keyboard_shortcuts.toggle_hidden": "Zobraziลฅ/skryลฅ text za varovanรญm o obsahu", + "keyboard_shortcuts.toggle_sensitivity": "Zobraziลฅ/skryลฅ mรฉdiรก", + "keyboard_shortcuts.toot": "Vytvoriลฅ novรฝ prรญspevok", + "keyboard_shortcuts.unfocus": "Odรญsลฅ z textovรฉho poฤพa", + "keyboard_shortcuts.up": "Posunรบลฅ sa vyลกลกie v zozname", + "lightbox.close": "Zatvoriลฅ", "lightbox.compress": "Zmenลกiลฅ nรกhฤพad obrรกzku", "lightbox.expand": "Rozลกรญriลฅ nรกhฤพad obrรกzku", - "lightbox.next": "ฤŽalลกie", - "lightbox.previous": "Predchรกdzajรบci", - "limited_account_hint.action": "Ukรกลพ profil aj tak", - "limited_account_hint.title": "Tento profil bol skrytรฝ moderรกtormi strรกnky {domain}.", - "link_preview.author": "Podฤพa {name}", - "lists.account.add": "Pridaj do zoznamu", - "lists.account.remove": "Odober zo zoznamu", - "lists.delete": "Vymaลพ list", - "lists.edit": "Uprav zoznam", - "lists.edit.submit": "Zmeลˆ nรกzov", + "lightbox.next": "ฤŽalej", + "lightbox.previous": "Spรคลฅ", + "limited_account_hint.action": "Aj tak zobraziลฅ profil", + "limited_account_hint.title": "Tento profil bol skrytรฝ sprรกvcami servera {domain}.", + "link_preview.author": "Autor: {name}", + "link_preview.more_from_author": "Viac od {name}", + "lists.account.add": "Pridaลฅ do zoznamu", + "lists.account.remove": "Odstrรกniลฅ zo zoznamu", + "lists.delete": "Vymazaลฅ zoznam", + "lists.edit": "Upraviลฅ zoznam", + "lists.edit.submit": "Zmeniลฅ nรกzov", "lists.exclusive": "Skryลฅ tieto prรญspevky z domovskej strรกnky", - "lists.new.create": "Pridaj zoznam", + "lists.new.create": "Pridaลฅ zoznam", "lists.new.title_placeholder": "Nรกzov novรฉho zoznamu", - "lists.replies_policy.followed": "Akรฝkoฤพvek nasledovanรฝ uลพรญvateฤพ", - "lists.replies_policy.list": "ฤŒlenovia na zozname", - "lists.replies_policy.none": "Nikto", - "lists.replies_policy.title": "Ukรกลพ odpovede na:", - "lists.search": "Vyhฤพadรกvaj medzi uลพรญvateฤพmi, ktorรฝch sledujeลก", - "lists.subheading": "Tvoje zoznamy", - "load_pending": "{count, plural, one {# novรก poloลพka} other {# novรฝch poloลพiek}}", - "loading_indicator.label": "Naฤรญtamโ€ฆ", - "media_gallery.toggle_visible": "Zapni/Vypni viditeฤพnosลฅ", - "moved_to_account_banner.text": "Vaลกe konto {disabledAccount} je momentรกlne zablokovanรฉ, pretoลพe ste sa presunuli na {movedToAccount}.", - "mute_modal.duration": "Trvanie", - "mute_modal.hide_notifications": "Skry oznรกmenia od tohto pouลพรญvateฤพa?", - "mute_modal.indefinite": "Bez obmedzenia", + "lists.replies_policy.followed": "Akรฉmukoฤพvek sledovanรฉmu รบฤtu", + "lists.replies_policy.list": "ฤŒlenom zoznamu", + "lists.replies_policy.none": "Nikomu", + "lists.replies_policy.title": "Zobraziลฅ odpovede:", + "lists.search": "Vyhฤพadรกvaลฅ medzi รบฤtami, ktorรฉ sledujete", + "lists.subheading": "Vaลกe zoznamy", + "load_pending": "{count, plural, one {# novรก poloลพka} few {# novรฉ poloลพky} many {# novรฝch poloลพiek} other {# novรฝch poloลพiek}}", + "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.indefinite": "Pokiaฤพ ich neodtรญลกim", + "mute_modal.show_options": "Zobraziลฅ moลพnosti", + "mute_modal.title": "Stรญลกiลฅ uลพรญvateฤพa?", "navigation_bar.about": "O tomto serveri", - "navigation_bar.advanced_interface": "Otvor v pokroฤilom webovom rozhranรญ", - "navigation_bar.blocks": "Blokovanรญ uลพรญvatelia", + "navigation_bar.advanced_interface": "Otvoriลฅ v pokroฤilom webovom rozhranรญ", + "navigation_bar.blocks": "Blokovanรฉ รบฤty", "navigation_bar.bookmarks": "Zรกloลพky", "navigation_bar.community_timeline": "Miestna ฤasovรก os", - "navigation_bar.compose": "Napรญลก novรฝ prรญspevok", - "navigation_bar.direct": "Sรบkromnรฉ spomenutia", - "navigation_bar.discover": "Objavuj", - "navigation_bar.domain_blocks": "Skrytรฉ domรฉny", - "navigation_bar.explore": "Objavuj", - "navigation_bar.favourites": "Obฤพรบbenรฉ", + "navigation_bar.compose": "Vytvoriลฅ novรฝ prรญspevok", + "navigation_bar.direct": "Sรบkromnรฉ oznaฤenia", + "navigation_bar.discover": "Objavovanie", + "navigation_bar.domain_blocks": "Blokovanรฉ domรฉny", + "navigation_bar.explore": "Objavovaลฅ", + "navigation_bar.favourites": "Ohviezdiฤkovanรฉ", "navigation_bar.filters": "Filtrovanรฉ slovรก", "navigation_bar.follow_requests": "ลฝiadosti o sledovanie", - "navigation_bar.followed_tags": "Nasledovanรฉ haลกtagy", - "navigation_bar.follows_and_followers": "Sledovania a nรกsledovatelia", + "navigation_bar.followed_tags": "Sledovanรฉ hashtagy", + "navigation_bar.follows_and_followers": "Sledovania a sledovatelia", "navigation_bar.lists": "Zoznamy", - "navigation_bar.logout": "Odhlรกs sa", - "navigation_bar.mutes": "Stรญลกenรญ uลพรญvatelia", - "navigation_bar.opened_in_classic_interface": "Prรญspevky, รบฤty a inรฉ ลกpeciรกlne strรกnky, sรบ z vรฝchodiska otvรกranรฉ v klasickom webovom rozhranรญ.", + "navigation_bar.logout": "Odhlรกsiลฅ sa", + "navigation_bar.mutes": "Stรญลกenรฉ รบฤty", + "navigation_bar.opened_in_classic_interface": "Prรญspevky, รบฤty a inรฉ ลกpeciรกlne strรกnky sรบ predvolene otvรกranรฉ v klasickom webovom rozhranรญ.", "navigation_bar.personal": "Osobnรฉ", "navigation_bar.pins": "Pripnutรฉ prรญspevky", "navigation_bar.preferences": "Nastavenia", "navigation_bar.public_timeline": "Federovanรก ฤasovรก os", - "navigation_bar.search": "Hฤพadaj", - "navigation_bar.security": "Zabezbeฤenie", - "not_signed_in_indicator.not_signed_in": "Ak chcete zรญskaลฅ prรญstup k tomuto zdroju, musรญte sa prihlรกsiลฅ.", - "notification.admin.report": "{name} nahlรกsil/a {target}", - "notification.admin.sign_up": "{name} sa zaregistroval/a", - "notification.favourite": "{name} si obฤพรบbil/a tvoj prรญspevok", - "notification.follow": "{name} ลฅa zaฤal/a nasledovaลฅ", - "notification.follow_request": "{name} ลฅa ลพiada nasledovaลฅ", - "notification.mention": "{name} ลฅa spomenul/a", - "notification.own_poll": "Tvoja anketa sa skonฤila", - "notification.poll": "Anketa v ktorej si hlasoval/a sa skonฤila", - "notification.reblog": "{name} zdieฤพal/a tvoj prรญspevok", - "notification.status": "{name} prรกve uverejnil/a", - "notification.update": "{name} upravil/a prรญspevok", - "notifications.clear": "Vyฤisti oznรกmenia", - "notifications.clear_confirmation": "Naozaj chceลก nenรกvratne odstrรกniลฅ vลกetky tvoje oznรกmenia?", + "navigation_bar.search": "Hฤพadaลฅ", + "navigation_bar.security": "Zabezpeฤenie", + "not_signed_in_indicator.not_signed_in": "Ak chcete zรญskaลฅ prรญstup k tomuto zdroju, prihlรกste sa.", + "notification.admin.report": "รšฤet {name} nahlรกsil {target}", + "notification.admin.sign_up": "Novรก registrรกciu รบฤtu {name}", + "notification.favourite": "{name} hviezdiฤkuje vรกลก prรญspevok", + "notification.follow": "{name} vรกs sleduje", + "notification.follow_request": "{name} vรกs ลพiada sledovaลฅ", + "notification.mention": "{name} vรกs spomรญna", + "notification.moderation-warning.learn_more": "Zisti viac", + "notification.moderation_warning.action_disable": "Tvoj รบฤet bol vypnutรฝ.", + "notification.moderation_warning.action_silence": "Tvoj รบฤet bol obmedzenรฝ.", + "notification.moderation_warning.action_suspend": "Tvoj รบฤet bol pozastavenรฝ.", + "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": "Stratenรฉ prepojenia s {name}", + "notification.relationships_severance_event.account_suspension": "Sprรกvca z {from} pozastavil/a {target}, ฤo znamenรก, ลพe od nich viac nemรดลพeลก dostรกvaลฅ aktualizรกcie, alebo s nimi interaktovaลฅ.", + "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ลฅ", + "notification_requests.dismiss": "Zamietnuลฅ", + "notification_requests.notifications_from": "Oboznรกmenia od {name}", + "notification_requests.title": "Filtrovanรฉ oboznรกmenia", + "notifications.clear": "Vyฤistiลฅ upozornenia", + "notifications.clear_confirmation": "Urฤite chcete nenรกvratne odstrรกniลฅ vลกetky svoje upozornenia?", "notifications.column_settings.admin.report": "Novรฉ hlรกsenia:", "notifications.column_settings.admin.sign_up": "Novรฉ registrรกcie:", - "notifications.column_settings.alert": "Oznรกmenia na ploche", - "notifications.column_settings.favourite": "Obฤพรบbenรฉ:", - "notifications.column_settings.filter_bar.advanced": "Zobraz vลกetky kategรณrie", - "notifications.column_settings.filter_bar.category": "Rรฝchle triedenie", - "notifications.column_settings.filter_bar.show_bar": "Ukรกลพ filtrovacรญ panel", - "notifications.column_settings.follow": "Novรญ sledujรบci:", - "notifications.column_settings.follow_request": "Novรฉ ลพiadosti o nรกsledovanie:", - "notifications.column_settings.mention": "Zmienenia:", - "notifications.column_settings.poll": "Vรฝsledky ankiet:", - "notifications.column_settings.push": "Push notifikรกcie", - "notifications.column_settings.reblog": "Vyzdvihnutia:", - "notifications.column_settings.show": "Ukรกลพ v stฤบpci", - "notifications.column_settings.sound": "Prehraj zvuk", + "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:", + "notifications.column_settings.poll": "Vรฝsledky ankety:", + "notifications.column_settings.push": "Upozornenia push", + "notifications.column_settings.reblog": "Zdieฤพania:", + "notifications.column_settings.show": "Zobraziลฅ v stฤบpci", + "notifications.column_settings.sound": "Prehraลฅ zvuk", "notifications.column_settings.status": "Novรฉ prรญspevky:", - "notifications.column_settings.unread_notifications.category": "Nepreฤรญtanรฉ oznรกmenia", - "notifications.column_settings.unread_notifications.highlight": "Zdรดrazni nepreฤรญtanรฉ oznรกmenia", + "notifications.column_settings.unread_notifications.category": "Nepreฤรญtanรฉ upozornenia", + "notifications.column_settings.unread_notifications.highlight": "Zvรฝrazniลฅ nepreฤรญtanรฉ upozornenia", "notifications.column_settings.update": "รšpravy:", "notifications.filter.all": "Vลกetky", - "notifications.filter.boosts": "Vyzdvihnutia", - "notifications.filter.favourites": "Obฤพรบbenรฉ", + "notifications.filter.boosts": "Zdieฤพania", + "notifications.filter.favourites": "Ohviezdiฤkovania", "notifications.filter.follows": "Sledovania", - "notifications.filter.mentions": "Iba spomenutia", + "notifications.filter.mentions": "Oznaฤenia", "notifications.filter.polls": "Vรฝsledky ankiet", - "notifications.filter.statuses": "Aktualizรกcie od ฤพudรญ, ktorรฝch nasledujeลก", - "notifications.grant_permission": "Udeฤพ povolenie.", - "notifications.group": "{count} Oznรกmenรญ", - "notifications.mark_as_read": "Oznaฤ kaลพdรฉ oznรกmenie za preฤรญtanรฉ", - "notifications.permission_denied": "Oznรกmenia na ploche sรบ nedostupnรฉ, kvรดli predtรฝm zamietnutej poลพiadavke prehliadaฤa", - "notifications.permission_denied_alert": "Oznรกmenia na ploche nemรดลพu byลฅ zapnutรฉ, pretoลพe poลพiadavka prehliadaฤa bola uลพ skรดr zamietnutรก", - "notifications.permission_required": "Oznรกmenia na ploche sรบ nedostupnรฉ, pretoลพe potrebnรฉ povolenia neboli udelenรฉ.", - "notifications_permission_banner.enable": "Povoliลฅ oznรกmenia na ploche", + "notifications.filter.statuses": "Novinky od ฤพudรญ, ktorรฝch sledujete", + "notifications.grant_permission": "Udeliลฅ povolenie.", + "notifications.group": "{count} upozornenรญ", + "notifications.mark_as_read": "Oznaฤiลฅ vลกetky upozornenia ako preฤรญtanรฉ", + "notifications.permission_denied": "Upozornenia na ploche sรบ nedostupnรฉ pre uลพ skรดr zamietnutรบ poลพiadavku prehliadaฤa", + "notifications.permission_denied_alert": "Upozornenia na ploche nemรดลพu byลฅ zapnutรฉ, pretoลพe poลพiadavka prehliadaฤa bola uลพ skรดr zamietnutรก", + "notifications.permission_required": "Upozornenia na ploche sรบ nedostupnรฉ, pretoลพe neboli udelenรฉ potrebnรฉ povolenia.", + "notifications.policy.filter_new_accounts_title": "Novรฉ รบฤty", + "notifications.policy.filter_not_followers_title": "ฤฝudia, ktorรญ ลฅa nenasledujรบ", + "notifications.policy.filter_not_following_title": "ฤฝudia, ktorรฝch nenasledujeลก", + "notifications.policy.filter_private_mentions_title": "Nevyลพiadanรฉ priame spomenutia", + "notifications.policy.title": "Filtrovaลฅ oznรกmenia odโ€ฆ", + "notifications_permission_banner.enable": "Povoliลฅ upozornenia na ploche", "notifications_permission_banner.how_to_control": "Ak chcete dostรกvaลฅ upozornenia, keฤ Mastodon nie je otvorenรฝ, povoฤพte upozornenia na ploche. Po ich zapnutรญ mรดลพete presne kontrolovaลฅ, ktorรฉ typy interakciรญ generujรบ upozornenia na ploche, a to prostrednรญctvom tlaฤidla {icon} vyลกลกie.", - "notifications_permission_banner.title": "Nikdy nezmeลกkaj jedinรบ vec", - "onboarding.action.back": "Vziaลฅ ma spรคลฅ", - "onboarding.actions.back": "Vziaลฅ ma spรคลฅ", - "onboarding.actions.go_to_explore": "See what's trending", - "onboarding.actions.go_to_home": "Go to your home feed", - "onboarding.compose.template": "Nazdar #Mastodon!", + "notifications_permission_banner.title": "Nenechajte si niฤ ujsลฅ", + "onboarding.action.back": "รsลฅ spรคลฅ", + "onboarding.actions.back": "รsลฅ spรคลฅ", + "onboarding.actions.go_to_explore": "Prejsลฅ na populรกrne", + "onboarding.actions.go_to_home": "Prejsลฅ na domovskรฝ kanรกl", + "onboarding.compose.template": "Ahoj, #Mastodon!", "onboarding.follows.empty": "ลฝiaฤพ, momentรกlne sa nedajรบ zobraziลฅ ลพiadne vรฝsledky. Mรดลพete skรบsiลฅ pouลพiลฅ vyhฤพadรกvanie alebo navลกtรญviลฅ strรกnku objavovania a nรกjsลฅ ฤพudรญ, ktorรฝch chcete sledovaลฅ, alebo to skรบste znova neskรดr.", - "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.title": "Popular on Mastodon", - "onboarding.profile.discoverable": "Urob mรดj profil objaviteฤพnรฝ", - "onboarding.profile.display_name": "Zobrazovanรฉ meno", - "onboarding.profile.display_name_hint": "Tvoje plnรฉ meno, alebo tvoje zรกbavnรฉ menoโ€ฆ", - "onboarding.profile.lead": "Toto mรดลพeลก vลพdy dokonฤiลฅ neskรดr v nastaveniach, kde je dostupnรฝch eลกte viac volieb na prispรดsobenie.", - "onboarding.profile.note": "O tebe", - "onboarding.profile.note_hint": "Mรดลพeลก @spomenรบลฅ inรฝch ฤพudรญ, alebo #haลกtagyโ€ฆ", - "onboarding.profile.save_and_continue": "Uloลพ a pokraฤuj", + "onboarding.follows.lead": "Vรกลก domovskรฝ kanรกl je vรกลก hlavnรฝ spรดsob objavovania Mastodonu. ฤŒรญm viac ฤพudรญ sledujete, tรฝm bude aktรญvnejลกรญ a zaujรญmavejลกรญ. Tu je pรกr tipov na zaฤiatok:", + "onboarding.follows.title": "Prispรดsobte si svoj domovskรฝ kanรกl", + "onboarding.profile.discoverable": "Nastavte svoj profil ako objaviteฤพnรฝ", + "onboarding.profile.discoverable_hint": "Keฤ si na Mastodone zapnete objaviteฤพnosลฅ, vaลกe prรญspevky sa mรดลพu zobrazovaลฅ vo vรฝsledkoch vyhฤพadรกvania a v populรกrnych. Vรกลก profil mรดลพe byลฅ navyลกe navrhovanรฝ ฤพuฤom, s ktorรฝmi mรกte podobnรฉ zรกujmy.", + "onboarding.profile.display_name": "Pouลพรญvateฤพskรฉ meno", + "onboarding.profile.display_name_hint": "Vaลกe celรฉ meno alebo pokojne aj vtipnรก prezรฝvkaโ€ฆ", + "onboarding.profile.lead": "Vลพdy si to mรดลพete doplniลฅ neskรดr v nastaveniach, kde nรกjdete aj ฤalลกie moลพnosti prispรดsobenia.", + "onboarding.profile.note": "Nieฤo o vรกs", + "onboarding.profile.note_hint": "Mรดลพete @oznaฤiลฅ inรฝch ฤพudรญ alebo #hashtagyโ€ฆ", + "onboarding.profile.save_and_continue": "Uloลพiลฅ a pokraฤovaลฅ", "onboarding.profile.title": "Nastavenie profilu", - "onboarding.profile.upload_avatar": "Nahraj profilovรฝ obrรกzok", - "onboarding.profile.upload_header": "Nahraj profilovรฉ zรกhlavie", - "onboarding.share.lead": "Daj ฤพudom vedieลฅ, ako ลฅa mรดลพu na Mastodone nรกjsลฅ!", - "onboarding.share.message": "Na Mastodone som {username}. Prรญฤ ma nasledovaลฅ na {url}", + "onboarding.profile.upload_avatar": "Nahraลฅ profilovรฝ obrรกzok", + "onboarding.profile.upload_header": "Nahraลฅ obrรกzok zรกhlavia profilu", + "onboarding.share.lead": "Dajte ostatnรฝm vedieลฅ, ako vรกs mรดลพu na Mastodone nรกjsลฅ.", + "onboarding.share.message": "Na #Mastodonโ e som {username}. Prรญฤ ma sledovaลฅ na {url}!", "onboarding.share.next_steps": "ฤŽalลกie moลพnรฉ kroky:", - "onboarding.share.title": "Zdieฤพaj svoj profil", - "onboarding.start.lead": "Teraz si sรบฤasลฅou Mastodonu, unikรกtnej, decentralizovanej sociรกlnej platformy, kde ty, nie algoritmus, spravujeลก svoj vlastnรฝ zรกลพitok. Poฤme ลฅa naลกtartovaลฅ na tomto novom sociรกlnom pomedzรญ:", - "onboarding.start.skip": "Want to skip right ahead?", + "onboarding.share.title": "Zdieฤพajte svoj profil", + "onboarding.start.lead": "Teraz ste sรบฤasลฅou Mastodonu, jedineฤnej decentralizovanej sociรกlnej platformy, kde o vลกetkom rozhodujete vy, nie algoritmus. Poฤme sa pozrieลฅ, ako mรดลพete zaฤaลฅ:", + "onboarding.start.skip": "Nepotrebujete pomoc so zaฤiatkom?", "onboarding.start.title": "Zvlรกdli ste to!", - "onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", - "onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}", - "onboarding.steps.publish_status.body": "Say hello to the world.", - "onboarding.steps.publish_status.title": "Vytvor svoj prvรฝ prรญspevok", - "onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", - "onboarding.steps.setup_profile.title": "Customize your profile", - "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", - "onboarding.steps.share_profile.title": "Share your profile", + "onboarding.steps.follow_people.body": "Mastodon je vybudovanรฝ okolo sledovania zaujรญmavรฝch ฤพudรญ.", + "onboarding.steps.follow_people.title": "Prispรดsobte si svoj domovskรฝ kanรกl", + "onboarding.steps.publish_status.body": "Predstavte sa svetu textom, fotkami, videami ฤi anketami {emoji}", + "onboarding.steps.publish_status.title": "Vytvorte svoj prvรฝ prรญspevok", + "onboarding.steps.setup_profile.body": "Plnลกรญ profil vรกm pomรดลพe maลฅ viac interakciรญ.", + "onboarding.steps.setup_profile.title": "Upravte si profil", + "onboarding.steps.share_profile.body": "Dajte svojej partii vedieลฅ, ako vรกs mรดลพu na Mastodone nรกjsลฅ.", + "onboarding.steps.share_profile.title": "Zdieฤพajte svoj profil na Mastodone", "onboarding.tips.2fa": "Vedeli ste? Svoj รบฤet mรดลพete zabezpeฤiลฅ nastavenรญm dvojfaktorovรฉho overenia v nastaveniach รบฤtu. Funguje to s akoukoฤพvek aplikรกciou TOTP podฤพa vรกลกho vรฝberu, nie je potrebnรฉ ลพiadne telefรณnne ฤรญslo!", "onboarding.tips.accounts_from_other_servers": "Vedeli ste? Keฤลพe Mastodon je decentralizovanรฝ, niektorรฉ profily, s ktorรฝmi sa stretnete, budรบ na inรฝch serveroch, ako je vรกลก. Aj napriek tomu s nimi mรดลพete bezproblรฉmovo komunikovaลฅ! Ich server je v druhej ฤasti ich pouลพรญvateฤพskรฉho mena!", - "onboarding.tips.migration": "Vedeli ste? Ak mรกte pocit, ลพe domรฉna {domain} pre vรกs v budรบcnosti nebude skvelou voฤพbou, mรดลพete prejsลฅ na inรฝ server Mastodon bez straty svojich sledovateฤพov. Mรดลพete dokonca hostovaลฅ svoj vlastnรฝ server!", - "onboarding.tips.verification": "Vedeli ste? Svoj รบฤet mรดลพete overiลฅ umiestnenรญm odkazu na svoj profil Mastodon na svoju vlastnรบ webovรบ lokalitu a pridanรญm webovej lokality do svojho profilu. Nie sรบ potrebnรฉ ลพiadne poplatky ani doklady!", + "onboarding.tips.migration": "Vedeli ste? Ak mรกte pocit, ลพe domรฉna {domain} pre vรกs v budรบcnosti nebude skvelou voฤพbou, mรดลพete prejsลฅ na inรฝ server Mastodon bez straty svojich sledovateฤพov. Mรดลพete dokonca hostiลฅ svoj vlastnรฝ server!", + "onboarding.tips.verification": "Vedeli ste? Svoj รบฤet mรดลพete overiลฅ umiestnenรญm odkazu na svoj profil na Mastodone na svoju vlastnรบ webovรบ lokalitu a pridanรญm webovej lokality do svojho profilu. Nie sรบ potrebnรฉ ลพiadne poplatky ani doklady!", "password_confirmation.exceeds_maxlength": "Potvrdenรฉ heslo presahuje maximรกlnu dฤบลพku hesla", "password_confirmation.mismatching": "Zadanรฉ heslรก sa nezhodujรบ", "picture_in_picture.restore": "Vrรกtiลฅ spรคลฅ", "poll.closed": "Uzatvorenรก", "poll.refresh": "Obnoviลฅ", - "poll.reveal": "Pozri vรฝsledky", - "poll.total_people": "{count, plural, one {# ฤlovek} few {# ฤพudia} other {# ฤพudรญ}}", - "poll.total_votes": "{count, plural, one {# hlas} few {# hlasov} many {# hlasov} other {# hlasov}}", - "poll.vote": "Hlasuj", - "poll.voted": "Hlasoval/a si za tรบto voฤพbu", - "poll.votes": "{votes, plural, one {# hlas} few {# hlasov} many {# hlasov} other {# hlasy}}", - "poll_button.add_poll": "Pridaj anketu", - "poll_button.remove_poll": "Odstrรกลˆ anketu", - "privacy.change": "Uprav sรบkromie prรญspevku", + "poll.reveal": "Zobraziลฅ vรฝsledky", + "poll.total_people": "{count, plural, one {# ฤlovek} few {# ฤพudia} many {# ฤพudรญ} other {# ฤพudรญ}}", + "poll.total_votes": "{count, plural, one {# hlas} few {# hlasy} many {# hlasov} other {# hlasov}}", + "poll.vote": "Hlasovaลฅ", + "poll.voted": "Hlasovali ste za tรบto voฤพbu", + "poll.votes": "{votes, plural, one {# hlas} few {# hlasy} many {# hlasov} other {# hlasov}}", + "poll_button.add_poll": "Pridaลฅ anketu", + "poll_button.remove_poll": "Odstrรกniลฅ anketu", + "privacy.change": "Zmeniลฅ nastavenia sรบkromia prรญspevku", "privacy.direct.long": "Vลกetci spomenutรญ v prรญspevku", "privacy.direct.short": "Konkrรฉtni ฤพudia", - "privacy.private.long": "Iba tvoji nasledovatelia", + "privacy.private.long": "Iba vaลกi sledovatelia", "privacy.private.short": "Sledovatelia", - "privacy.public.long": "Ktokoฤพvek na, aj mimo Mastodonu", + "privacy.public.long": "Ktokoฤพvek na Mastodone aj mimo neho", "privacy.public.short": "Verejnรฉ", - "privacy.unlisted.short": "Verejnรฝ v tichosti", + "privacy.unlisted.additional": "Presne ako verejnรฉ, s tรฝm rozdielom, ลพe sa prรญspevok nezobrazรญ v ลพivรฝch kanรกloch, hashtagoch, objavovanรญ ฤi vo vyhฤพadรกvanรญ na Mastodone, aj keฤ mรกte pre รบฤet objaviteฤพnosลฅ zapnutรบ.", + "privacy.unlisted.long": "Menej algoritmickรฝch vรฝmyslov", + "privacy.unlisted.short": "Tichรฉ verejnรฉ", "privacy_policy.last_updated": "Poslednรก รบprava {date}", - "privacy_policy.title": "Zรกsady sรบkromia", + "privacy_policy.title": "Pravidlรก ochrany sรบkromia", "recommended": "Odporรบฤanรฉ", "refresh": "Obnoviลฅ", - "regeneration_indicator.label": "Naฤรญtava saโ€ฆ", - "regeneration_indicator.sublabel": "Tvoja domovskรก nรกstenka sa pripravuje!", - "relative_time.days": "{number}dnรญ", - "relative_time.full.days": "Ostรกva {number, plural, one {# deลˆ} few {# dnรญ} many {# dnรญ} other {# dni}}", - "relative_time.full.hours": "Pred {number, plural, one {# hodinou} few {# hodinami} many {# hodinami} other {# hodinami}}", - "relative_time.full.just_now": "prรกve teraz", - "relative_time.full.minutes": "Pred {number, plural, one {# minรบtou} few {# minรบtami} many {# minรบtami} other {# minรบtami}}", - "relative_time.full.seconds": "Pred {number, plural, one {# sekundou} few {# sekundami} many {# sekundami} other {# sekundami}}", - "relative_time.hours": "{number}hod", - "relative_time.just_now": "teraz", - "relative_time.minutes": "{number}min", - "relative_time.seconds": "{number}sek", - "relative_time.today": "dnes", + "regeneration_indicator.label": "Naฤรญtavanieโ€ฆ", + "regeneration_indicator.sublabel": "Vรกลก domovskรฝ kanรกl sa pripravuje.", + "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}}", + "relative_time.full.just_now": "Prรกve teraz", + "relative_time.full.minutes": "Pred {number, plural, one {# minรบtou} other {# minรบtami}}", + "relative_time.full.seconds": "Pred {number, plural, one {# sekundou} other {# sekundami}}", + "relative_time.hours": "{number} hod", + "relative_time.just_now": "Teraz", + "relative_time.minutes": "{number} min", + "relative_time.seconds": "{number} sek", + "relative_time.today": "Dnes", + "reply_indicator.attachments": "{count, plural, one {# prรญloha} few {# prรญlohy} other {# prรญloh}}", "reply_indicator.cancel": "Zruลกiลฅ", "reply_indicator.poll": "Anketa", - "report.block": "Blokuj", + "report.block": "Blokovaลฅ", "report.block_explanation": "Ich prรญspevky neuvidรญte. Nebudรบ mรดcลฅ vidieลฅ vaลกe prรญspevky ani vรกs sledovaลฅ. Budรบ mรดcลฅ zistiลฅ, ลพe sรบ zablokovanรญ.", - "report.categories.legal": "Prรกvne ujednania", + "report.categories.legal": "Prรกvne", "report.categories.other": "Ostatnรฉ", "report.categories.spam": "Spam", "report.categories.violation": "Obsah poruลกuje jedno alebo viacero pravidiel servera", - "report.category.subtitle": "Vyberte si najlepลกiu voฤพbu", - "report.category.title": "Povedzte nรกm, ฤo sa deje s tรฝmto {type}", - "report.category.title_account": "profilom", - "report.category.title_status": "prรญspevkom", + "report.category.subtitle": "Vyberte najlepลกiu voฤพbu", + "report.category.title": "Povedzte nรกm, ฤo je zlรฉ na tomto {type}", + "report.category.title_account": "profile", + "report.category.title_status": "prรญspevku", "report.close": "Hotovo", "report.comment.title": "Je eลกte nieฤo, ฤo by sme podฤพa vรกs mali vedieลฅ?", - "report.forward": "Posuลˆ ku {target}", - "report.forward_hint": "Tento รบฤet je z inรฉho serveru. Chceลก poslaลฅ anonymnรบ kรณpiu hlรกsenia aj tam?", - "report.mute": "Nevลกรญmaj si", - "report.mute_explanation": "Ich prรญspevky neuvidรญte. Stรกle vรกs mรดลพu sledovaลฅ a vidieลฅ vaลกe prรญspevky a nebudรบ vedieลฅ, ลพe sรบ stlmenรฉ.", + "report.forward": "Preposlaลฅ na {target}", + "report.forward_hint": "Tento รบฤet je z inรฉho serveru. Chcete poslaลฅ anonymnรบ kรณpiu hlรกsenia aj tam?", + "report.mute": "Stรญลกiลฅ", + "report.mute_explanation": "Ich prรญspevky neuvidรญte. Stรกle vรกs mรดลพu sledovaลฅ a vidieลฅ vaลกe prรญspevky a nebudรบ vedieลฅ, ลพe ste ich stรญลกili.", "report.next": "ฤŽalej", "report.placeholder": "ฤŽalลกie komentรกre", "report.reasons.dislike": "Nepรกฤi sa mi", - "report.reasons.dislike_description": "Nieje to nieฤo, ฤo chceลก vidieลฅ", - "report.reasons.legal": "Je to nelegรกlne", + "report.reasons.dislike_description": "Nie je to nieฤo, ฤo chcete vidieลฅ", + "report.reasons.legal": "Je nelegรกlny", "report.reasons.legal_description": "Domnievate sa, ลพe poruลกuje zรกkony vaลกej krajiny alebo krajiny servera", - "report.reasons.other": "Je to nieฤo inรฉ", + "report.reasons.other": "Ide o nieฤo inรฉ", "report.reasons.other_description": "Tento problรฉm nepatrรญ do inรฝch kategรณriรญ", "report.reasons.spam": "Je to spam", "report.reasons.spam_description": "ล kodlivรฉ odkazy, faloลกnรฉ zapojenie alebo opakovanรฉ odpovede", "report.reasons.violation": "Poruลกuje pravidlรก servera", "report.reasons.violation_description": "Ste si vedomรญ, ลพe poruลกuje ลกpecifickรฉ pravidlรก", - "report.rules.subtitle": "Vyberte vลกetky, ktorรฉ sa vzลฅahujรบ", - "report.rules.title": "Ktorรฉ pravidlรก sa poruลกujรบ?", - "report.statuses.subtitle": "Vyberte vลกetky, ktorรฉ sa vzลฅahujรบ", + "report.rules.subtitle": "Vyberte vลกetky prรญsluลกnรฉ moลพnosti", + "report.rules.title": "Ktorรฉ pravidlรก sรบ poruลกovanรฉ?", + "report.statuses.subtitle": "Vyberte vลกetky prรญsluลกnรฉ moลพnosti", "report.statuses.title": "Sรบ k dispozรญcii prรญspevky podporujรบce toto hlรกsenie?", - "report.submit": "Odoลกli", - "report.target": "Nahlรกs {target}", - "report.thanks.take_action": "Tu sรบ tvoje moลพnosti kontrolovaลฅ, ฤo vidรญลก na Mastodone:", - "report.thanks.take_action_actionable": "Kรฝm to vyhodnotรญme, mรดลพeลก podniknรบลฅ kroky voฤi @{name}:", - "report.thanks.title": "Nechceลก to vidieลฅ?", - "report.thanks.title_actionable": "Vฤaka za nahlรกsenie, pozrieme sa na to.", - "report.unfollow": "Nesleduj @{name}", - "report.unfollow_explanation": "Tento รบฤet sledujete. Ak uลพ nechcete vidieลฅ jeho prรญspevky vo svojom domovskom kanรกli, zruลกte jeho sledovanie.", - "report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached", - "report_notification.categories.legal": "Prรกvne ujednania", + "report.submit": "Odoslaลฅ", + "report.target": "Nahlรกsiลฅ {target}", + "report.thanks.take_action": "Tu sรบ vaลกe moลพnosti kontrolovaลฅ to, ฤo vidรญte na Mastodone:", + "report.thanks.take_action_actionable": "Kรฝm to vyhodnotรญme, mรดลพete podniknรบลฅ kroky voฤi @{name}:", + "report.thanks.title": "Nechcete to vidieลฅ?", + "report.thanks.title_actionable": "ฤŽakujeme za nahlรกsenie, pozrieme sa na to.", + "report.unfollow": "Prestaลฅ sledovaลฅ @{name}", + "report.unfollow_explanation": "Tento รบฤet sledujete. Ak uลพ nechcete vidieลฅ jeho prรญspevky vo svojom domovskom kanรกli, prestaลˆte ho sledovaลฅ.", + "report_notification.attached_statuses": "{count, plural, one {{count} prรญspevok} few {{count} prรญspevky} other {{count} prรญspevkov}} ako prรญloha", + "report_notification.categories.legal": "Prรกvne", "report_notification.categories.other": "Ostatnรฉ", "report_notification.categories.spam": "Spam", "report_notification.categories.violation": "Poruลกenie pravidla", - "report_notification.open": "Otvor hlรกsenie", + "report_notification.open": "Otvoriลฅ hlรกsenie", "search.no_recent_searches": "ลฝiadne nedรกvne vyhฤพadรกvania", - "search.placeholder": "Hฤพadaj", + "search.placeholder": "Hฤพadaลฅ", "search.quick_action.account_search": "Profily zodpovedajรบce {x}", - "search.quick_action.go_to_account": "Prejdi na profil {x}", - "search.quick_action.go_to_hashtag": "Choฤ na haลกtag {x}", - "search.quick_action.open_url": "Otvor URL v rรกmci Mastodonu", + "search.quick_action.go_to_account": "Prejsลฅ na profil {x}", + "search.quick_action.go_to_hashtag": "Prejsลฅ na hashtag {x}", + "search.quick_action.open_url": "Otvoriลฅ URL v rรกmci Mastodonu", "search.quick_action.status_search": "Prรญspevky zodpovedajรบce {x}", - "search.search_or_paste": "Hฤพadaj, alebo vloลพ URL adresu", + "search.search_or_paste": "Hฤพadaลฅ alebo vloลพiลฅ adresu URL", "search_popout.full_text_search_disabled_message": "Nie je k dispozรญcii v domรฉne {domain}.", - "search_popout.full_text_search_logged_out_message": "Dostupnรฉ iba keฤ si prihlรกsenรฝ/รก.", - "search_popout.language_code": "ISO kรณd jazyka", + "search_popout.full_text_search_logged_out_message": "Dostupnรฉ iba po prihlรกsenรญ.", + "search_popout.language_code": "Kรณd jazyka ISO", "search_popout.options": "Moลพnosti vyhฤพadรกvania", "search_popout.quick_actions": "Rรฝchle akcie", "search_popout.recent": "Nedรกvne vyhฤพadรกvania", - "search_popout.specific_date": "presnรฝ dรกtum", - "search_popout.user": "uลพรญvateฤพ", + "search_popout.specific_date": "Presnรฝ dรกtum", + "search_popout.user": "รšฤet", "search_results.accounts": "Profily", "search_results.all": "Vลกetky", - "search_results.hashtags": "Haลกtagy", - "search_results.nothing_found": "Pre tieto vรฝrazy nemoลพno niฤ nรกjsลฅ", - "search_results.see_all": "Ukรกลพ vลกetky", + "search_results.hashtags": "Hashtagy", + "search_results.nothing_found": "Pre tieto vรฝrazy nebolo moลพnรฉ niฤ nรกjsลฅ", + "search_results.see_all": "Zobraziลฅ vลกetky", "search_results.statuses": "Prรญspevky", - "search_results.title": "Hฤพadaj {q}", - "server_banner.about_active_users": "ฤฝudia pouลพรญvajรบci tento server za poslednรฝch 30 dnรญ (Aktรญvni pouลพรญvatelia za mesiac)", - "server_banner.active_users": "aktรญvni uลพรญvatelia", - "server_banner.administered_by": "Sprรกvcom je:", - "server_banner.introduction": "{domain} je sรบฤasลฅou decentralizovanej sociรกlnej siete vyuลพรญvajรบcej technolรณgiu {mastodon}.", - "server_banner.learn_more": "Zisti viac", - "server_banner.server_stats": "Serverovรฉ ลกtatistiky:", - "sign_in_banner.create_account": "Vytvor รบฤet", - "sign_in_banner.sign_in": "Prihlรกs sa", - "sign_in_banner.sso_redirect": "Prihlรกs sa, alebo zaregistruj", - "sign_in_banner.text": "Prihlรกste sa, aby ste mohli sledovaลฅ profily alebo haลกtagy, obฤพรบbenรฉ veci, zdieฤพaลฅ ich a odpovedaลฅ na prรญspevky. Mรดลพete tieลพ komunikovaลฅ zo svojho รบฤtu na inom serveri.", - "status.admin_account": "Otvor moderovacie rozhranie uลพรญvateฤพa @{name}", - "status.admin_domain": "Otvor rozhranie na moderovanie domรฉny {domain}", - "status.admin_status": "Otvor tento prรญspevok v moderovacom rozhranรญ", - "status.block": "Blokuj @{name}", - "status.bookmark": "Zรกloลพka", - "status.cancel_reblog_private": "Nezdieฤพaj", - "status.cannot_reblog": "Tento prรญspevok nemรดลพe byลฅ zdieฤพanรฝ", - "status.copy": "Skopรญruj odkaz na prรญspevok", - "status.delete": "Zmazaลฅ", + "search_results.title": "Hฤพadaลฅ {q}", + "server_banner.about_active_users": "ฤฝudia pouลพรญvajรบci tento server za poslednรฝch 30 dnรญ (aktรญvni pouลพรญvatelia za mesiac)", + "server_banner.active_users": "Aktรญvne รบฤty", + "server_banner.administered_by": "Sprรกva servera:", + "server_banner.server_stats": "ล tatistiky servera:", + "sign_in_banner.create_account": "Vytvoriลฅ รบฤet", + "sign_in_banner.sign_in": "Prihlรกsiลฅ sa", + "sign_in_banner.sso_redirect": "Prihlรกsenie alebo registrรกcia", + "status.admin_account": "Moderovaลฅ @{name}", + "status.admin_domain": "Moderovaลฅ {domain}", + "status.admin_status": "Moderovaลฅ prรญspevok", + "status.block": "Blokovaลฅ @{name}", + "status.bookmark": "Pridaลฅ zรกloลพku", + "status.cancel_reblog_private": "Zruลกiลฅ zdieฤพanie", + "status.cannot_reblog": "Tento prรญspevok nie je moลพnรฉ zdieฤพaลฅ", + "status.copy": "Kopรญrovaลฅ odkaz na prรญspevok", + "status.delete": "Vymazaลฅ", "status.detailed_status": "Podrobnรฝ nรกhฤพad celej konverzรกcie", - "status.direct": "Spomeลˆ @{name} v sรบkromรญ", - "status.direct_indicator": "Sรบkromnรฉ spomenutie", - "status.edit": "Uprav", - "status.edited": "Upravenรฉ {date}", - "status.edited_x_times": "Upravenรฝ {count, plural, one {{count} krรกt} other {{count} krรกt}}", + "status.direct": "Sรบkromne oznaฤiลฅ @{name}", + "status.direct_indicator": "Sรบkromnรฉ oznaฤenie", + "status.edit": "Upraviลฅ", + "status.edited": "Naposledy upravenรฝ {date}", + "status.edited_x_times": "Upravenรฝ {count, plural, other {{count}ร—}}", "status.embed": "Vloลพiลฅ", - "status.favourite": "Pรกฤi sa mi", + "status.favourite": "Ohviezdiฤkovanรฉ", "status.filter": "Filtrovanie tohto prรญspevku", "status.filtered": "Filtrovanรฉ", - "status.hide": "Skry prรญspevok", - "status.history.created": "{name} vytvoril/a {date}", - "status.history.edited": "{name} upravil/a {date}", - "status.load_more": "Ukรกลพ viac", - "status.media.open": "Klikni pre otvorenie", - "status.media.show": "Kliknutรญm zobrazรญลก", + "status.hide": "Skryลฅ prรญspevok", + "status.history.created": "Vytvorenรฉ รบฤtom {name} {date}", + "status.history.edited": "Upravenรฉ รบฤtom {name} {date}", + "status.load_more": "Naฤitaลฅ viac", + "status.media.open": "Otvoriลฅ kliknutรญm", + "status.media.show": "Zobraziลฅ kliknutรญm", "status.media_hidden": "Skrytรฉ mรฉdiรก", - "status.mention": "Spomeลˆ @{name}", + "status.mention": "Oznaฤiลฅ @{name}", "status.more": "Viac", - "status.mute": "Nevลกรญmaj si @{name}", - "status.mute_conversation": "Nevลกรญmaj si konverzรกciu", - "status.open": "Otvor tento prรญspevok", - "status.pin": "Pripni na profil", + "status.mute": "Stรญลกiลฅ @{name}", + "status.mute_conversation": "Stรญลกiลฅ konverzรกciu", + "status.open": "Rozbaliลฅ prรญspevok", + "status.pin": "Pripnรบลฅ na profil", "status.pinned": "Pripnutรฝ prรญspevok", "status.read_more": "ฤŒรญtaj ฤalej", - "status.reblog": "Vyzdvihni", - "status.reblog_private": "Vyzdvihni k pรดvodnรฉmu publiku", - "status.reblogged_by": "{name} vyzdvihli", - "status.reblogs.empty": "Nikto eลกte nevyzdvihol tento prรญspevok. Keฤ tak niekto urobรญ, bude to zobrazenรฉ prรกve tu.", - "status.redraft": "Vymaลพ a prepรญลก", - "status.remove_bookmark": "Odstrรกลˆ zรกloลพku", + "status.reblog": "Zdieฤพaลฅ", + "status.reblog_private": "Zdieฤพaลฅ pรดvodnรฉmu publiku", + "status.reblogged_by": "{name} zdieฤพa", + "status.reblogs.empty": "Nikto eลกte tento prรญspevok nezdieฤพal. Keฤ tak niekto urobรญ, zobrazรญ sa to tu.", + "status.redraft": "Vymazaลฅ a prepรญsaลฅ", + "status.remove_bookmark": "Odstrรกniลฅ zรกloลพku", "status.replied_to": "Odpoveฤ na {name}", "status.reply": "Odpovedaลฅ", - "status.replyAll": "Odpovedz na diskusiu", - "status.report": "Nahlรกs @{name}", - "status.sensitive_warning": "Chรบlostivรฝ obsah", - "status.share": "Zdieฤพaj", - "status.show_filter_reason": "Ukรกลพ aj tak", - "status.show_less": "Zobraz menej", - "status.show_less_all": "Vลกetkรฝm ukรกลพ menej", - "status.show_more": "Ukรกลพ viac", - "status.show_more_all": "Vลกetkรฝm ukรกลพ viac", - "status.show_original": "Ukรกลพ pรดvodnรฝ", - "status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}", + "status.replyAll": "Odpovedaลฅ vo vlรกkne", + "status.report": "Nahlรกsiลฅ @{name}", + "status.sensitive_warning": "Citlivรฝ obsah", + "status.share": "Zdieฤพaลฅ", + "status.show_filter_reason": "Aj tak zobraziลฅ", + "status.show_less": "Zobraziลฅ menej", + "status.show_less_all": "Vลกetkรฝm zobraziลฅ menej", + "status.show_more": "Zobraziลฅ viac", + "status.show_more_all": "Vลกetkรฝm zobraziลฅ viac", + "status.show_original": "Zobraziลฅ originรกl", + "status.title.with_attachments": "รšฤet {user} nahral {attachmentCount, plural, one {prรญlohu} few {{attachmentCount} prรญlohy} many {{attachmentCount} prรญloh} other {{attachmentCount} prรญloh}}", "status.translate": "Preloลพiลฅ", "status.translated_from_with": "Preloลพenรฉ z {lang} pomocou {provider}", "status.uncached_media_warning": "Nรกhฤพad nie je k dispozรญcii", - "status.unmute_conversation": "Prestaลˆ si nevลกรญmaลฅ konverzรกciu", - "status.unpin": "Odopni z profilu", + "status.unmute_conversation": "Zruลกiลฅ stรญลกenie konverzรกcie", + "status.unpin": "Odopnรบลฅ z profilu", "subscribed_languages.lead": "Po zmene sa na vaลกej domovskej strรกnke a ฤasovej osi zoznamu zobrazia iba prรญspevky vo vybranรฝch jazykoch. Ak chcete dostรกvaลฅ prรญspevky vo vลกetkรฝch jazykoch, vyberte moลพnosลฅ ลพiadne.", - "subscribed_languages.save": "Uloลพ zmeny", + "subscribed_languages.save": "Uloลพiลฅ zmeny", "subscribed_languages.target": "Zmeniลฅ prihlรกsenรฉ jazyky pre {target}", "tabs_bar.home": "Domov", - "tabs_bar.notifications": "Oznรกmenia", - "time_remaining.days": "Ostรกva {number, plural, one {# deลˆ} few {# dnรญ} many {# dnรญ} other {# dnรญ}}", - "time_remaining.hours": "Ostรกva {number, plural, one {# hodina} few {# hodรญn} many {# hodรญn} other {# hodiny}}", - "time_remaining.minutes": "Ostรกva {number, plural, one {# minรบta} few {# minรบt} many {# minรบt} other {# minรบty}}", + "tabs_bar.notifications": "Upozornenia", + "time_remaining.days": "Ostรกva{number, plural, one { # deลˆ} few {jรบ # dni} many { # dnรญ} other { # dnรญ}}", + "time_remaining.hours": "Ostรกva{number, plural, one { # hodina} few {jรบ # hodiny} many { # hodรญn} other { # hodรญn}}", + "time_remaining.minutes": "Ostรกva{number, plural, one { # minรบta} few {jรบ # minรบty} many { # minรบt} other { # minรบt}}", "time_remaining.moments": "Ostรกva uลพ iba chviฤพka", - "time_remaining.seconds": "Ostรกva {number, plural, one {# sekunda} few {# sekรบnd} many {# sekรบnd} other {# sekรบnd}}", - "timeline_hint.remote_resource_not_displayed": "{resource} z inรฝch serverov sa nezobrazรญ.", + "time_remaining.seconds": "Ostรกva{number, plural, one { # sekunda} few {jรบ # sekundy} many { # sekรบnd} other { # sekรบnd}}", + "timeline_hint.remote_resource_not_displayed": "{resource} z inรฝch serverov sa nezobrazia.", "timeline_hint.resources.followers": "Sledujรบci", - "timeline_hint.resources.follows": "Nasleduje", + "timeline_hint.resources.follows": "Sledovanรญ", "timeline_hint.resources.statuses": "Starลกie prรญspevky", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} osoba} few {{counter} ฤพudia} many {{counter} ฤพudรญ} other {{counter} ฤพudรญ}} za posledn{days, plural, one {รฝ deลˆ} few {รฉ {days} dni} many {รฝch {days} dnรญ} other {รฝch {days} dnรญ}}", "trends.trending_now": "Teraz populรกrne", - "ui.beforeunload": "ฤŒo mรกลก rozpรญsanรฉ sa stratรญ, ak opustรญลก Mastodon.", - "units.short.billion": "{count}mld.", - "units.short.million": "{count}mil.", - "units.short.thousand": "{count}tis.", - "upload_area.title": "Pretiahni a pusลฅ pre nahratie", - "upload_button.label": "Pridaj obrรกzky, video, alebo zvukovรฝ sรบbor", + "ui.beforeunload": "Po opustenรญ Mastodonu prรญdete o to, ฤo mรกte rozpรญsanรฉ.", + "units.short.billion": "{count} mld.", + "units.short.million": "{count} mil.", + "units.short.thousand": "{count} tis.", + "upload_area.title": "Nahrรกte potiahnutรญm a pustenรญm", + "upload_button.label": "Pridaลฅ obrรกzky, video alebo zvukovรฝ sรบbor", "upload_error.limit": "Limit pre nahrรกvanie sรบborov bol prekroฤenรฝ.", - "upload_error.poll": "Nahrรกvanie sรบborov pri anketรกch nieje moลพnรฉ.", - "upload_form.audio_description": "Popรญลก, pre ฤพudรญ so stratou sluchu", - "upload_form.description": "Opis pre slabo vidiacich", - "upload_form.edit": "Uprav", + "upload_error.poll": "Nahrรกvanie sรบborov nie je pri anketรกch moลพnรฉ.", + "upload_form.audio_description": "Popis pre sluchovo postihnutรฝch ฤพudรญ", + "upload_form.description": "Popis pre zrakovo postihnutรฝch ฤพudรญ", + "upload_form.edit": "Upraviลฅ", "upload_form.thumbnail": "Zmeniลฅ miniatรบru", - "upload_form.video_description": "Popรญลก, pre ฤพudรญ so stratou sluchu, alebo oฤnรฝm znevรฝhodnenรญm", - "upload_modal.analyzing_picture": "Analyzujem obrรกzokโ€ฆ", - "upload_modal.apply": "Pouลพi", - "upload_modal.applying": "Nastavovanieโ€ฆ", - "upload_modal.choose_image": "Vyber obrรกzok", - "upload_modal.description_placeholder": "Rรฝchla hnedรก lรญลกka skรกฤe ponad lenivรฉho psa", - "upload_modal.detect_text": "Rozpoznaj text z obrรกzka", - "upload_modal.edit_media": "Uprav mรฉdiรก", - "upload_modal.hint": "Klikni, alebo potiahni okruh ukรกลพky pre zvolenie z ktorรฉho vรฝchodzieho bodu bude vลพdy v dohฤพadne na vลกetkรฝch nรกhฤพadoch.", - "upload_modal.preparing_ocr": "Pripravujem OCRโ€ฆ", + "upload_form.video_description": "Popรญs pre ฤพudรญ so zrakovรฝm alebo sluchovรฝm postihnutรญm", + "upload_modal.analyzing_picture": "Prebieha analรฝza obrรกzkaโ€ฆ", + "upload_modal.apply": "Pouลพiลฅ", + "upload_modal.applying": "Ukladanieโ€ฆ", + "upload_modal.choose_image": "Vybraลฅ obrรกzok", + "upload_modal.description_placeholder": "Kde bolo, tam bolo, bol raz jeden Mastodon", + "upload_modal.detect_text": "Rozpoznaลฅ text z obrรกzka", + "upload_modal.edit_media": "Upraviลฅ mรฉdiรก", + "upload_modal.hint": "Kliknite alebo potiahnite kruh na ukรกลพke, a tak vyberte bod, ktorรฝ bude viditeฤพnรฝ na vลกetkรฝch nรกhฤพadoch.", + "upload_modal.preparing_ocr": "Pripravujem rozpoznรกvanieโ€ฆ", "upload_modal.preview_label": "Nรกhฤพad ({ratio})", - "upload_progress.label": "Nahrรกva sa...", + "upload_progress.label": "Nahrรกva saโ€ฆ", "upload_progress.processing": "Spracovรกvanieโ€ฆ", "username.taken": "Pouลพรญvateฤพskรฉ meno je obsadenรฉ. Skรบste inรฉ", - "video.close": "Zavri video", - "video.download": "Stiahni sรบbor", - "video.exit_fullscreen": "Vypni zobrazenie na celรบ obrazovku", - "video.expand": "Zvรคฤลกi video", - "video.fullscreen": "Zobraz na celรบ obrazovku", - "video.hide": "Skry video", - "video.mute": "Stlm zvuk", - "video.pause": "Pauza", - "video.play": "Prehraj", - "video.unmute": "Zapni zvuk" + "video.close": "Zatvoriลฅ video", + "video.download": "Stiahnuลฅ sรบbor", + "video.exit_fullscreen": "Ukonฤiลฅ reลพim celej obrazovky", + "video.expand": "Zvรคฤลกiลฅ video", + "video.fullscreen": "Zobraziลฅ na celรบ obrazovku", + "video.hide": "Skryลฅ video", + "video.mute": "Stlmiลฅ zvuk", + "video.pause": "Pozastaviลฅ", + "video.play": "Prehraลฅ", + "video.unmute": "Zapnรบลฅ zvuk" } diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 3aae75dc36..195797143b 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -89,6 +89,14 @@ "announcement.announcement": "Obvestilo", "attachments_list.unprocessed": "(neobdelano)", "audio.hide": "Skrij zvok", + "block_modal.remote_users_caveat": "Od streลพnika {domain} bomo zahtevali, da spoลกtuje vaลกo odloฤitev. Izpolnjevanje zahteve ni zagotovljeno, ker nekateri streลพniki blokiranja obravnavajo drugaฤe. Javne objave bodo morda ลกe vedno vidne neprijavljenim uporabnikom.", + "block_modal.show_less": "Pokaลพi manj", + "block_modal.show_more": "Pokaลพi veฤ", + "block_modal.they_cant_mention": "Ne morejo vas omenjati ali vam slediti.", + "block_modal.they_cant_see_posts": "Ne vidijo vaลกih objav, vi pa ne njihovih.", + "block_modal.they_will_know": "Ne morejo videti, da so blokirani.", + "block_modal.title": "Blokiraj uporabnika?", + "block_modal.you_wont_see_mentions": "Objav, ki jih omenjajo, ne boste videli.", "boost_modal.combo": "ฤŒe ลพelite preskoฤiti to, lahko pritisnete {combo}", "bundle_column_error.copy_stacktrace": "Kopiraj poroฤilo o napaki", "bundle_column_error.error.body": "Zahtevane strani ni mogoฤe upodobiti. Vzrok teลพave je morda hroลกฤ v naลกi kodi ali pa nezdruลพljivost z brskalnikom.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Dodaj opozorilo o vsebini", "compose_form.spoiler_placeholder": "Opozorilo o vsebini (ni obvezno)", "confirmation_modal.cancel": "Prekliฤi", - "confirmations.block.block_and_report": "Blokiraj in prijavi", "confirmations.block.confirm": "Blokiraj", - "confirmations.block.message": "Ali ste prepriฤani, da ลพelite blokirati {name}?", "confirmations.cancel_follow_request.confirm": "Umakni zahtevo", "confirmations.cancel_follow_request.message": "Ali ste prepriฤani, da ลพelite umakniti svojo zahtevo, da bi sledili {name}?", "confirmations.delete.confirm": "Izbriลกi", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Ali ste prepriฤani, da ลพelite trajno izbrisati ta seznam?", "confirmations.discard_edit_media.confirm": "Opusti", "confirmations.discard_edit_media.message": "Imate ne shranjene spremembe za medijski opis ali predogled; jih ลพelite kljub temu opustiti?", - "confirmations.domain_block.confirm": "Blokiraj celotno domeno", + "confirmations.domain_block.confirm": "Blokiraj streลพnik", "confirmations.domain_block.message": "Ali ste res, res prepriฤani, da ลพelite blokirati celotno {domain}? V veฤini primerov je nekaj ciljnih blokiranj ali utiลกanj dovolj in boljลกe. Vsebino iz te domene ne boste videli v javnih ฤasovnicah ali obvestilih. Vaลกi sledilci iz te domene bodo odstranjeni.", "confirmations.edit.confirm": "Uredi", "confirmations.edit.message": "Urejanje bo prepisalo sporoฤilo, ki ga trenutno sestavljate. Ali ste prepriฤani, da ลพelite nadaljevati?", "confirmations.logout.confirm": "Odjava", "confirmations.logout.message": "Ali ste prepriฤani, da se ลพelite odjaviti?", "confirmations.mute.confirm": "Utiลกanje", - "confirmations.mute.explanation": "S tem boste skrili objave pred njimi in objave, ki jih omenjajo, ลกe vedno pa bodo lahko videli vaลกe objave in vam sledili.", - "confirmations.mute.message": "Ali ste prepriฤani, da ลพelite utiลกati {name}?", "confirmations.redraft.confirm": "Izbriลกi in preoblikuj", "confirmations.redraft.message": "Ali ste prepriฤani, da ลพelite izbrisati ta status in ga preoblikovati? Vzljubi in izpostavitve bodo izgubljeni, odgovori na izvirno objavo pa bodo osiroteli.", "confirmations.reply.confirm": "Odgovori", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Te objave s tega in drugih streลพnikov v decentraliziranem omreลพju pridobivajo ravno zdaj veliko pozornosti na tem streลพniku.", "dismissable_banner.explore_tags": "Ravno zdaj dobivajo ti kljuฤniki veliko pozoronosti med osebami na tem in drugih streลพnikih decentraliziranega omreลพja.", "dismissable_banner.public_timeline": "To so najnovejลกe javne objave oseb z druลพabnega omreลพja, ki jim sledijo osebe na {domain}.", + "domain_block_modal.block": "Blokiraj streลพnik", + "domain_block_modal.block_account_instead": "Namesto tega blokiraj @{name}", + "domain_block_modal.they_can_interact_with_old_posts": "Osebe s tega streลพnika se lahko odzivajo na vaลกe stare objave.", + "domain_block_modal.they_cant_follow": "Nihฤe s tega streลพnika vam ne more slediti.", + "domain_block_modal.they_wont_know": "Ne bodo vedeli, da so blokirani.", + "domain_block_modal.title": "Blokiraj domeno?", + "domain_block_modal.you_will_lose_followers": "Vsi vaลกi sledilci s tega streลพnika bodo odstranjeni.", + "domain_block_modal.you_wont_see_posts": "Objav ali obvestil uporabnikov s tega streลพnika ne boste videli.", + "domain_pill.activitypub_lets_connect": "Omogoฤa vam povezovanje in interakcijo z ljudmi, ki niso samo na Mastodonu, ampak tudi na drugih druลพabnih platformah.", + "domain_pill.activitypub_like_language": "Protokol ActivityPub je kot jezik, s katerim se Mastodon pogovarja z drugimi druลพabnimi omreลพji.", + "domain_pill.server": "Streลพnik", + "domain_pill.their_handle": "Njihova roฤica:", + "domain_pill.their_server": "Njihovo digitalno domovanje, kjer bivajo vse njihove objave.", + "domain_pill.their_username": "Njihov edinstveni identifikator na njihovem streลพniku. Uporabnike z istim uporabniลกkim imenom lahko najdete na razliฤnih streลพnikih.", + "domain_pill.username": "Uporabniลกko ime", + "domain_pill.whats_in_a_handle": "Kaj je v roฤici?", + "domain_pill.who_they_are": "Ker roฤice povedo, kdo je kdo in kje so, ste lahko z osebami v interakciji prek druลพabnega spleta .", + "domain_pill.who_you_are": "Ker roฤice povedo, kdo ste in kje ste, ste lahko z osebami v interakciji prek druลพabnega spleta .", + "domain_pill.your_handle": "Vaลกa roฤica:", + "domain_pill.your_server": "Vaลกe digitalno domovanje, kjer bivajo vse vaลกe objave. Vam ta ni vลกeฤ? Prenesite ga med streลพniki kadar koli in z njim tudi svoje sledilce.", + "domain_pill.your_username": "Vaลก edinstveni identifikator na tem streลพniku. Uporabnike z istim uporabniลกkim imenom je moลพno najti na razliฤnih streลพnikih.", "embed.instructions": "Vstavite to objavo na svojo spletno stran tako, da kopirate spodnjo kodo.", "embed.preview": "Tako bo izgledalo:", "emoji_button.activity": "Dejavnost", @@ -241,6 +266,7 @@ "empty_column.list": "Na tem seznamu ni niฤesar. Ko bodo ฤlani tega seznama objavili nove statuse, se bodo pojavili tukaj.", "empty_column.lists": "Nimate seznamov. Ko ga boste ustvarili, se bo prikazal tukaj.", "empty_column.mutes": "Niste utiลกali ลกe nobenega uporabnika.", + "empty_column.notification_requests": "Vse prebrano! Tu ni niฤesar veฤ. Ko prejmete nova obvestila, se bodo pojavila tu glede na vaลกe nastavitve.", "empty_column.notifications": "Nimate ลกe nobenih obvestil. Poveลพite se z drugimi, da zaฤnete pogovor.", "empty_column.public": "Tukaj ni niฤesar! Da ga napolnite, napiลกite nekaj javnega ali pa roฤno sledite uporabnikom iz drugih streลพnikov", "error.unexpected_crash.explanation": "Zaradi hroลกฤa v naลกi kodi ali teลพave z zdruลพljivostjo brskalnika te strani ni mogoฤe ustrezno prikazati.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Ta streลพnik", "firehose.remote": "Drugi streลพniki", "follow_request.authorize": "Overi", "follow_request.reject": "Zavrni", "follow_requests.unlocked_explanation": "ฤŒeprav vaลก raฤun ni zaklenjen, zaposleni pri {domain} menijo, da bi morda ลพeleli pregledati zahteve za sledenje teh raฤunov roฤno.", - "follow_suggestions.curated_suggestion": "Izbor urednikov", + "follow_suggestions.curated_suggestion": "Izbor osebja", "follow_suggestions.dismiss": "Ne pokaลพi veฤ", + "follow_suggestions.featured_longer": "Osebno izbrala ekipa {domain}", + "follow_suggestions.friends_of_friends_longer": "Priljubljeno med osebami, ki jim sledite", + "follow_suggestions.hints.featured": "Ta profil so izbrali skrbniki streลพnika {domain}.", + "follow_suggestions.hints.friends_of_friends": "Ta profil je priljubljen med osebami, ki jim sledite.", + "follow_suggestions.hints.most_followed": "Ta profil na streลพniku {domain} je en izmed najbolj sledenih.", + "follow_suggestions.hints.most_interactions": "Ta profil na streลพniku {domain} je nedavno prejel veliko pozornosti.", + "follow_suggestions.hints.similar_to_recently_followed": "Ta profil je podoben profilom, ki ste jim nedavno zaฤeli slediti.", "follow_suggestions.personalized_suggestion": "Osebno prilagojen predlog", "follow_suggestions.popular_suggestion": "Priljubljen predlog", + "follow_suggestions.popular_suggestion_longer": "Priljubljeno na {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Podobno profilom, ki ste jim pred kratkim sledili", "follow_suggestions.view_all": "Pokaลพi vse", "follow_suggestions.who_to_follow": "Komu slediti", "followed_tags": "Sledeni kljuฤniki", @@ -309,7 +347,6 @@ "hashtag.follow": "Sledi kljuฤniku", "hashtag.unfollow": "Nehaj slediti kljuฤniku", "hashtags.and_other": "โ€ฆin ลกe {count, plural, other {#}}", - "home.column_settings.basic": "Osnovno", "home.column_settings.show_reblogs": "Pokaลพi izpostavitve", "home.column_settings.show_replies": "Pokaลพi odgovore", "home.hide_announcements": "Skrij obvestila", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Vseeno pokaลพi profil", "limited_account_hint.title": "Profil so moderatorji streลพnika {domain} skrili.", "link_preview.author": "Avtor_ica {name}", + "link_preview.more_from_author": "Veฤ od {name}", + "link_preview.shares": "{count, plural, one {{counter} objava} two {{counter} objavi} few {{counter} objave} other {{counter} objav}}", "lists.account.add": "Dodaj na seznam", "lists.account.remove": "Odstrani s seznama", "lists.delete": "Izbriลกi seznam", @@ -395,9 +434,15 @@ "loading_indicator.label": "Nalaganje โ€ฆ", "media_gallery.toggle_visible": "{number, plural,one {Skrij sliko} two {Skrij sliki} other {Skrij slike}}", "moved_to_account_banner.text": "Vaลก raฤun {disabledAccount} je trenutno onemogoฤen, ker ste se prestavili na {movedToAccount}.", - "mute_modal.duration": "Trajanje", - "mute_modal.hide_notifications": "Ali ลพelite skriti obvestila tega uporabnika?", - "mute_modal.indefinite": "Nedoloฤeno", + "mute_modal.hide_from_notifications": "Skrijte se pred obvestili", + "mute_modal.hide_options": "Skrij moลพnosti", + "mute_modal.indefinite": "Dokler jim ne povrnem glasu", + "mute_modal.show_options": "Pokaลพi moลพnosti", + "mute_modal.they_can_mention_and_follow": "Lahko vas omenijo ali vam sledijo, vi pa jih ne morete videti.", + "mute_modal.they_wont_know": "Ne bodo vedeli, da so utiลกani.", + "mute_modal.title": "Utiลกaj uporabnika?", + "mute_modal.you_wont_see_mentions": "Objav, ki jih omenjajo, ne boste videli.", + "mute_modal.you_wont_see_posts": "ล e vedno vidijo vaลกe objave, vi pa ne njihovih.", "navigation_bar.about": "O Mastodonu", "navigation_bar.advanced_interface": "Odpri v naprednem spletnem vmesniku", "navigation_bar.blocks": "Blokirani uporabniki", @@ -430,11 +475,29 @@ "notification.follow": "{name} vam sledi", "notification.follow_request": "{name} vam ลพeli slediti", "notification.mention": "{name} vas je omenil/a", + "notification.moderation-warning.learn_more": "Veฤ o tem", + "notification.moderation_warning": "Prejeli ste opozorilo moderatorjev", + "notification.moderation_warning.action_delete_statuses": "Nekatere vaลกe objave so odstranjene.", + "notification.moderation_warning.action_disable": "Vaลก raฤun je bil onemogoฤen.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Nekatere vaลกe objave so bile oznaฤene kot obฤutljive.", + "notification.moderation_warning.action_none": "Vaลก raฤun je prejel opozorilo moderatorjev.", + "notification.moderation_warning.action_sensitive": "Vaลกe objave bodo odslej oznaฤene kot obฤutljive.", + "notification.moderation_warning.action_silence": "Vaลก raฤun je bil omejen.", + "notification.moderation_warning.action_suspend": "Vaลก raฤun je bil suspendiran.", "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.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", + "notification_requests.dismiss": "Zavrni", + "notification_requests.notifications_from": "Obvestila od {name}", + "notification_requests.title": "Filtrirana obvestila", "notifications.clear": "Poฤisti obvestila", "notifications.clear_confirmation": "Ali ste prepriฤani, da ลพelite trajno izbrisati vsa svoja obvestila?", "notifications.column_settings.admin.report": "Nove prijave:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Pokaลพi vrstico s filtri", "notifications.column_settings.follow": "Novi sledilci:", "notifications.column_settings.follow_request": "Nove proลกnje za sledenje:", "notifications.column_settings.mention": "Omembe:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Namizna obvestila niso na voljo zaradi poprej zavrnjene zahteve dovoljenja brskalnika.", "notifications.permission_denied_alert": "Namiznih obvestil ni mogoฤe omogoฤiti, ker je bilo dovoljenje brskalnika ลพe prej zavrnjeno", "notifications.permission_required": "Namizna obvestila niso na voljo, ker zahtevano dovoljenje ni bilo podeljeno.", + "notifications.policy.filter_new_accounts.hint": "Ustvarjen v {days, plural, one {zadnjem # dnevu} two {zadnjih # dnevih} few {zadnjih # dnevih} other {zadnjih # dnevih}}", + "notifications.policy.filter_new_accounts_title": "Novi raฤuni", + "notifications.policy.filter_not_followers_hint": "Vkljuฤujoฤ ljudi, ki vam sledijo manj kot {days, plural, one {# dan} two {# dneva} few {# dni} other {# dni}}", + "notifications.policy.filter_not_followers_title": "Ljudje, ki vam ne sledijo", + "notifications.policy.filter_not_following_hint": "Dokler jih roฤno ne odobrite", + "notifications.policy.filter_not_following_title": "Ljudje, ki jim ne sledite", + "notifications.policy.filter_private_mentions_hint": "Filtrirano, razen ฤe je odgovor na vaลกo lastno omembo ali ฤe sledite poลกiljatelju", + "notifications.policy.filter_private_mentions_title": "Neลพelene zasebne omembe", + "notifications.policy.title": "Filtriraj obvestila od โ€ฆ", "notifications_permission_banner.enable": "Omogoฤi obvestila na namizju", "notifications_permission_banner.how_to_control": "ฤŒe ลพelite prejemati obvestila, ko Mastodon ni odprt, omogoฤite namizna obvestila. Natanฤno lahko nadzirate, katere vrste interakcij naj tvorijo namizna obvestila; ko so omogoฤena, za to uporabite gumb {icon} zgoraj.", "notifications_permission_banner.title": "Nikoli ne zamudite niฤesar", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Osebe, ki so uporabljale ta streลพnik zadnjih 30 dni (dejavni uporabniki meseca)", "server_banner.active_users": "dejavnih uporabnikov", "server_banner.administered_by": "Upravlja:", - "server_banner.introduction": "{domain} je del decentraliziranega druลพbenega omreลพja, ki ga poganja {mastodon}.", - "server_banner.learn_more": "Veฤ o tem", + "server_banner.is_one_of_many": "{domain} je en izmed mnogih neodvisnih streลพnikov Mastodon, ki ga lahko uporabljate za sodelovanje v fediverzumu.", "server_banner.server_stats": "Statistika streลพnika:", "sign_in_banner.create_account": "Ustvari raฤun", + "sign_in_banner.follow_anyone": "Sledite komurkoli iz fediverzuma in vidite vse objave v ฤasovnem vrstnem redu. Brez skritih algoritmov ter brez oglasov in vab za klikanje na vidiku.", + "sign_in_banner.mastodon_is": "Mastodon je najboljลกi naฤin, da ste na tekoฤem z dogajanjem.", "sign_in_banner.sign_in": "Prijava", "sign_in_banner.sso_redirect": "Prijavite ali registrirajte se", - "sign_in_banner.text": "Prijavite se, da sledite profilom ali kljuฤnikom, dodajate med priljubljene, delite z drugimi ter odgovarjate na objave. V interakciji ste lahko tudi iz svojega raฤuna na drugem streลพniku.", "status.admin_account": "Odpri vmesnik za moderiranje za @{name}", "status.admin_domain": "Odpri vmesnik za moderiranje za {domain}", "status.admin_status": "Odpri to objavo v vmesniku za moderiranje", @@ -645,10 +716,11 @@ "status.direct": "Zasebno omeni @{name}", "status.direct_indicator": "Zasebna omemba", "status.edit": "Uredi", - "status.edited": "Urejeno {date}", + "status.edited": "Zadnje urejanje {date}", "status.edited_x_times": "Urejeno {count, plural, one {#-krat} two {#-krat} few {#-krat} other {#-krat}}", "status.embed": "Vdelaj", "status.favourite": "Priljubljen_a", + "status.favourites": "{count, plural, one {priljubitev} two {priljubitvi} few {priljubitve} other {priljubitev}}", "status.filter": "Filtriraj to objavo", "status.filtered": "Filtrirano", "status.hide": "Skrij objavo", @@ -669,6 +741,7 @@ "status.reblog": "Izpostavi", "status.reblog_private": "Izpostavi z izvirno vidljivostjo", "status.reblogged_by": "{name} je izpostavil/a", + "status.reblogs": "{count, plural, one {izpostavitev} two {izpostavitvi} few {izpostavitve} other {izpostavitev}}", "status.reblogs.empty": "Nihฤe ลกe ni izpostavil te objave. Ko se bo to zgodilo, se bodo pojavile tukaj.", "status.redraft": "Izbriลกi in preoblikuj", "status.remove_bookmark": "Odstrani zaznamek", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 496e35fe76..6903bceff6 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -89,6 +89,14 @@ "announcement.announcement": "Lajmรซrim", "attachments_list.unprocessed": "(e papรซrpunuar)", "audio.hide": "Fshihe audion", + "block_modal.remote_users_caveat": "Do tโ€™i kรซrkojmรซ shรซrbyesit {domain} tรซ respektojรซ vendimin tuaj. Por, pajtimi sโ€™รซshtรซ i garantuar, ngaqรซ disa shรซrbyes mund tโ€™i trajtojnรซ ndryshe bllokimet. Psotimet publike mundet tรซ jenรซ ende tรซ dukshme pรซr pรซrdorues pa bรซrรซ hyrje nรซ llogari.", + "block_modal.show_less": "Shfaq mรซ pak", + "block_modal.show_more": "Shfaq mรซ tepรซr", + "block_modal.they_cant_mention": "Sโ€™mund tโ€™u pรซrmendin, ose tโ€™ju ndjekin.", + "block_modal.they_cant_see_posts": "Sโ€™mund tรซ shohin postimet tuaja dhe as ju tรซ tyret.", + "block_modal.they_will_know": "Mund tรซ shohin se janรซ bllokuar.", + "block_modal.title": "Tรซ bllokohet pรซrdoruesi?", + "block_modal.you_wont_see_mentions": "Sโ€™do tรซ shihni postimet ku pรซrmenden.", "boost_modal.combo": "Qรซ kjo tรซ anashkalohet herรซs tjetรซr, mund tรซ shtypni {combo}", "bundle_column_error.copy_stacktrace": "Kopjo raportim gabimi", "bundle_column_error.error.body": "Faqja e kรซrkuar sโ€™u vizatua dot. Kjo mund tรซ vijรซ nga njรซ e metรซ nรซ kodin tonรซ, ose nga njรซ problem pรซrputhshmรซrie i shfletuesit.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Shtoni sinjalizim lรซnde", "compose_form.spoiler_placeholder": "Sinjalizim lรซnde (opsional)", "confirmation_modal.cancel": "Anuloje", - "confirmations.block.block_and_report": "Bllokojeni & Raportojeni", "confirmations.block.confirm": "Bllokoje", - "confirmations.block.message": "Jeni i sigurt se doni tรซ bllokohet {name}?", "confirmations.cancel_follow_request.confirm": "Tรซrhiqeni mbrapsht kรซrkesรซn", "confirmations.cancel_follow_request.message": "Jeni i sigurt se doni tรซ tรซrhiqni mbrapsht kรซrkesรซn tuaj pรซr ndjekje tรซ {name}?", "confirmations.delete.confirm": "Fshije", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Jeni i sigurt se doni tรซ fshihet pรซrgjithmonรซ kjo listรซ?", "confirmations.discard_edit_media.confirm": "Hidhe tej", "confirmations.discard_edit_media.message": "Keni ndryshime tรซ paruajtura te pรซrshkrimi ose paraparja e medias, tรซ hidhen tej, sido qoftรซ?", - "confirmations.domain_block.confirm": "Bllokoje krejt pรซrkatรซsinรซ", + "confirmations.domain_block.confirm": "Bllokoje shรซrbyesin", "confirmations.domain_block.message": "Jeni i sigurt, shumรซ i sigurt se doni tรซ bllokohet krejt {domain}? Nรซ shumicรซn e rasteve, ndoca bllokime ose heshtime me synim tรซ caktuar janรซ tรซ mjaftueshme dhe tรซ parapรซlqyera. Sโ€™keni pรซr tรซ parรซ lรซndรซ nga kjo pรซrkatรซsi nรซ ndonjรซ rrjedhรซ kohore publike, apo te njoftimet tuaja. Ndjekรซsit tuaj prej asaj pรซrkatรซsie do tรซ hiqen.", "confirmations.edit.confirm": "Pรซrpunojeni", "confirmations.edit.message": "Pรซrpunimi tani do tรซ sjellรซ mbishkrim tรซ mesazhit qรซ po hartoni aktualisht. Jeni i sigurt se doni tรซ vazhdohet?", "confirmations.logout.confirm": "Dilni", "confirmations.logout.message": "Jeni i sigurt se doni tรซ dilet?", "confirmations.mute.confirm": "Heshtoje", - "confirmations.mute.explanation": "Kjo do tโ€™u fshehรซ postimet dhe pรซrmendje postimesh, por ende do tโ€™u lejojรซ tรซ shohin postimet tuaja dhe tโ€™ju ndjekin.", - "confirmations.mute.message": "Jeni i sigurt se doni tรซ heshtohet {name}?", "confirmations.redraft.confirm": "Fshijeni & rihartojeni", "confirmations.redraft.message": "Jeni i sigurt se doni tรซ fshihet kjo gjendje dhe tรซ rihartohet? Tรซ parapรซlqyerit dhe pรซrforcimet do tรซ humbin, ndรซrsa pรซrgjigjet te postimi origjinal do tรซ bรซhen jetime.", "confirmations.reply.confirm": "Pรซrgjigjuni", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Kรซto janรซ postime nga rrjeti shoqรซror qรซ po tรซrheqin vรซmendjen tani. Postimet mรซ tรซ reja me mรซ pรซrforcime dhe mรซ tรซ parapรซlqyera nga njerรซzit renditen mรซ sipรซr.", "dismissable_banner.explore_tags": "Kรซta hashtag-รซ po tรซrheqin vรซmendjen mes personave nรซ kรซtรซ shรซrbyes dhe tรซ tjerรซ tรซ tillรซ tรซ rrjetit tรซ decentralizuar mu tani.", "dismissable_banner.public_timeline": "Kรซto janรซ postimet mรซ tรซ reja publike prej personash nรซ rrjetin shoqรซror qรซ ndjekin njerรซzit nรซ {domain}.", + "domain_block_modal.block": "Bllokoje shรซrbyesin", + "domain_block_modal.block_account_instead": "Blloko @{name} nรซ vend tรซ kรซsaj", + "domain_block_modal.they_can_interact_with_old_posts": "Persona nga ky shรซrbyes mund tรซ ndรซrveprojnรซ me postimet tuaja tรซ vjetra.", + "domain_block_modal.they_cant_follow": "Sโ€™mund tโ€™ju ndjekรซ askush nga ky shรซrbyes.", + "domain_block_modal.they_wont_know": "Sโ€™do ta dinรซ se janรซ bllokuar.", + "domain_block_modal.title": "Tรซ bllokohet pรซrkatรซsia?", + "domain_block_modal.you_will_lose_followers": "Krejt ndjekรซsit tuaj nga ky shรซrbyes do tรซ hiqen.", + "domain_block_modal.you_wont_see_posts": "Sโ€™do tรซ shihni postime, apo njoftime nga pรซrdorues nรซ kรซtรซ shรซrbyes.", + "domain_pill.activitypub_lets_connect": "Ju lejon tรซ lidheni dhe ndรซrveproni me persona jo thjesht nรซ Mastodon, por edhe nรซpรซr aplikacione tรซ ndryshme shoqรซrore.", + "domain_pill.activitypub_like_language": "ActivityPub รซshtรซ si gjuha me tรซ cilรซn Mastodon-i komunikon me rrjete tรซ tjerรซ shoqรซrorรซ.", + "domain_pill.server": "Shรซrbyes", + "domain_pill.their_handle": "Targa e tij:", + "domain_pill.their_server": "Shtรซpia e tij dixhitale, ku rrinรซ krejt postimet prej tij.", + "domain_pill.their_username": "Identifikuesi i tij unik nรซ shรซrbyesin e vet. ร‹shtรซ e mundur tรซ gjenden pรซrdorues me tรซ njรซjtin emรซr pรซrdoruesi nรซ shรซrbyes tรซ ndryshรซm.", + "domain_pill.username": "Emรซr pรซrdoruesi", + "domain_pill.whats_in_a_handle": "ร‡โ€™รซshtรซ njรซ targรซ?", + "domain_pill.who_they_are": "Nga targat thonรซ se cili รซshtรซ dikush dhe se ku gjendet, ju mund tรซ ndรซrveproni me persona nรซpรซr web-in shoqรซror tรซ .", + "domain_pill.who_you_are": "Ngaqรซ targa juaj thotรซ se cili jeni dhe se ku gjendeni, njerรซzit mund tรซ ndรซrveprojnรซ me ju nรซpรซr web-in shoqรซror tรซ .", + "domain_pill.your_handle": "Targa juaj:", + "domain_pill.your_server": "Shtรซpia juaj dixhitale, kur gjenden krejt postimet tuaja. Sโ€™ju pรซlqen kjo kรซtu? Shpรซrngulni shรซrbyes kur tรซ doni dhe sillni edhe ndjekรซsit tuaj.", + "domain_pill.your_username": "Identifikuesi juja unik nรซ kรซtรซ shรซrbyes. ร‹shtรซ e mundur tรซ gjenden pรซrdorues me tรซ njรซjtin emรซr pรซrdoruesi nรซ shรซrbyes tรซ ndryshรซm.", "embed.instructions": "Trupรซzojeni kรซtรซ gjendje nรซ sajtin tuaj duke kopjuar kodin mรซ poshtรซ.", "embed.preview": "Ja si do tรซ duket:", "emoji_button.activity": "Veprimtari", @@ -241,6 +266,7 @@ "empty_column.list": "Nรซ kรซtรซ listรซ ende sโ€™ka gjรซ. Kur anรซtarรซ tรซ kรซsaj liste postojnรซ gjendje tรซ reja, ato do tรซ shfaqen kรซtu.", "empty_column.lists": "Ende sโ€™keni ndonjรซ listรซ. Kur tรซ krijoni njรซ tรซ tillรซ, do tรซ duket kรซtu.", "empty_column.mutes": "Sโ€™keni heshtuar ende ndonjรซ pรซrdorues.", + "empty_column.notification_requests": "Gjithรงka si duhet! Sโ€™ka รงโ€™bรซhet kรซtu. Kur merrni njoftime tรซ reja, do tรซ shfaqen kรซtu, nรซ pรซrputhje me rregullimet tuaja.", "empty_column.notifications": "Ende sโ€™keni ndonjรซ njoftim. Ndรซrveproni me tรซ tjerรซt qรซ tรซ nisรซ biseda.", "empty_column.public": "Sโ€™ka gjรซ kรซtu! Shkruani diรงka publikisht, ose ndiqni dorazi pรซrdorues prej instancash tรซ tjera, qรซ kjo tรซ mbushet", "error.unexpected_crash.explanation": "Pรซr shkak tรซ njรซ tรซ mete nรซ kodin tonรซ ose tรซ njรซ problemi pรซrputhshmรซrie tรซ shfletuesit, kjo faqe sโ€™mund tรซ shfaqet saktรซ.", @@ -271,16 +297,28 @@ "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.mentions": "{count, plural, one {pรซrmendje} other {pรซrmendje}}", + "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", "firehose.remote": "Shรซrbyes tรซ tjerรซ", "follow_request.authorize": "Autorizoje", "follow_request.reject": "Hidhe tej", "follow_requests.unlocked_explanation": "Edhe pse llogaria juaj sโ€™รซshtรซ e kyรงur, ekipi i {domain} mendoi se mund tรซ donit tรซ shqyrtonit dorazi kรซrkesa ndjekjeje prej kรซtyre llogarive.", - "follow_suggestions.curated_suggestion": "Zgjedhur nga Ekipi", + "follow_suggestions.curated_suggestion": "Zgjedhur nga ekipi", "follow_suggestions.dismiss": "Mos shfaq mรซ", + "follow_suggestions.featured_longer": "Zgjedhur enkas nga ekipi {domain}", + "follow_suggestions.friends_of_friends_longer": "Popullore mes personash qรซ ndiqni", + "follow_suggestions.hints.featured": "Ky profil รซshtรซ zgjedhur nga ekipi {domain}.", + "follow_suggestions.hints.friends_of_friends": "Ky profil รซshtรซ popullor mes personave qรซ ndiqni.", + "follow_suggestions.hints.most_followed": "Ky profil รซshtรซ njรซ nga mรซ tรซ ndjekur nรซ {domain}.", + "follow_suggestions.hints.most_interactions": "Ky profil ka tรซrhequr mjaft vรซmendjen sรซ fundi nรซ {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Ky profil รซshtรซ i ngjashรซm me profile qรซ keni ndjekur tani afรซr.", "follow_suggestions.personalized_suggestion": "Sugjerim i personalizuar", "follow_suggestions.popular_suggestion": "Sugjerim popullor", + "follow_suggestions.popular_suggestion_longer": "Popullore nรซ {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "I ngjashรซm me profile qรซ keni zรซnรซ tรซ ndiqni sรซ fundi", "follow_suggestions.view_all": "Shihni krejt", "follow_suggestions.who_to_follow": "Cilรซt tรซ ndiqen", "followed_tags": "Hashtag-รซ tรซ ndjekur", @@ -309,7 +347,6 @@ "hashtag.follow": "Ndiqe hashtag-un", "hashtag.unfollow": "Hiqe ndjekjen e hashtag-ut", "hashtags.and_other": "โ€ฆdhe {count, plural, one {}other {# mรซ tepรซr}}", - "home.column_settings.basic": "Bazรซ", "home.column_settings.show_reblogs": "Shfaq pรซrforcime", "home.column_settings.show_replies": "Shfaq pรซrgjigje", "home.hide_announcements": "Fshihi lajmรซrimet", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Shfaqe profilin sido qoftรซ", "limited_account_hint.title": "Ky profil รซshtรซ fshehur nga moderatorรซt e {domain}.", "link_preview.author": "Nga {name}", + "link_preview.more_from_author": "Mรซ tepรซr nga {name}", + "link_preview.shares": "{count, plural, one {{counter} post} other {{counter} postime}}", "lists.account.add": "Shto nรซ listรซ", "lists.account.remove": "Hiqe nga lista", "lists.delete": "Fshije listรซn", @@ -395,9 +434,15 @@ "loading_indicator.label": "Po ngarkohetโ€ฆ", "media_gallery.toggle_visible": "Fshihni {number, plural, one {figurรซ} other {figura}}", "moved_to_account_banner.text": "Llogaria juaj {disabledAccount} aktualisht รซshtรซ e รงaktivizuar, ngaqรซ kaluat te {movedToAccount}.", - "mute_modal.duration": "Kohรซzgjatje", - "mute_modal.hide_notifications": "Tรซ kalohen tรซ fshehura njoftimet prej kรซtij pรซrdoruesi?", - "mute_modal.indefinite": "E pacaktuar", + "mute_modal.hide_from_notifications": "Fshihe prej njoftimeve", + "mute_modal.hide_options": "Fshihi mundรซsitรซ", + "mute_modal.indefinite": "Deri sa tโ€™u heq heshtimin", + "mute_modal.show_options": "Shfaq mundรซsi", + "mute_modal.they_can_mention_and_follow": "Mund tโ€™ju pรซrmendin dhe ndjekin, por sโ€™do tโ€™i shihni.", + "mute_modal.they_wont_know": "Sโ€™do ta dinรซ se janรซ heshtuar.", + "mute_modal.title": "Tรซ heshtohet pรซrdoruesi?", + "mute_modal.you_wont_see_mentions": "Sโ€™do tรซ shihni postime ku pรซrmenden.", + "mute_modal.you_wont_see_posts": "Ata munden ende tรซ shohin postimet tuaja, por ju sโ€™do tรซ shihni tรซ tyret.", "navigation_bar.about": "Mbi", "navigation_bar.advanced_interface": "Hape nรซ ndรซrfaqe web tรซ thelluar", "navigation_bar.blocks": "Pรซrdorues tรซ bllokuar", @@ -430,11 +475,29 @@ "notification.follow": "{name} zuri tโ€™ju ndjekรซ", "notification.follow_request": "{name} ka kรซrkuar tโ€™ju ndjekรซ", "notification.mention": "{name} ju ka pรซrmendur", + "notification.moderation-warning.learn_more": "Mรซsoni mรซ tepรซr", + "notification.moderation_warning": "Ju รซshtรซ dhรซnรซ njรซ sinjalizim moderimi", + "notification.moderation_warning.action_delete_statuses": "Disa nga postimet tuaja janรซ hequr.", + "notification.moderation_warning.action_disable": "Llogaria juaj รซshtรซ รงaktivizuar.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Disa prej postimeve tuaja u รซshtรซ vรซnรซ shenjรซ si me spec.", + "notification.moderation_warning.action_none": "Llogaria juaj ka marrรซ njรซ sinjalizim moderimi.", + "notification.moderation_warning.action_sensitive": "Postimeve tuaja do tโ€™u vihet shenjรซ si me spec, nga tani e tutje.", + "notification.moderation_warning.action_silence": "Llogaria juaj รซshtรซ kufizuar.", + "notification.moderation_warning.action_suspend": "Llogaria juaj รซshtรซ pezulluar.", "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.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", + "notification_requests.dismiss": "Hidhe tej", + "notification_requests.notifications_from": "Njoftime prej {name}", + "notification_requests.title": "Njoftime tรซ filtruar", "notifications.clear": "Spastroji njoftimet", "notifications.clear_confirmation": "Jeni i sigurt se doni tรซ spastrohen pรซrgjithmonรซ krejt njoftimet tuaja?", "notifications.column_settings.admin.report": "Raportime tรซ reja:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Shfaq shtyllรซ filtrash", "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:", @@ -469,6 +531,15 @@ "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", + "notifications.policy.filter_private_mentions_hint": "Filtruar, hiq rastin nรซse gjendet te pรซrgjigje ndaj pรซrmendjes tuaj, ose nรซse dรซrguesin e ndiqni", + "notifications.policy.filter_private_mentions_title": "Pรซrmendje private tรซ pakรซrkuara", + "notifications.policy.title": "Filtroni njoftime ngaโ€ฆ", "notifications_permission_banner.enable": "Aktivizo njoftime nรซ desktop", "notifications_permission_banner.how_to_control": "Pรซr tรซ marrรซ njoftime, kur Mastodon-i sโ€™รซshtรซ i hapur, aktivizoni njoftime nรซ desktop. Pรซrmes butoni {icon} mรซ sipรซr, mund tรซ kontrolloni me pรซrpikรซri cilat lloje ndรซrveprimesh prodhojnรซ njoftime nรซ desktop, pasi tรซ jenรซ aktivizuar.", "notifications_permission_banner.title": "Mos tโ€™ju shpรซtojรซ gjรซ", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Persona qรซ pรซrdorin kรซtรซ shรซrbyes gjatรซ 30 ditรซve tรซ fundit (Pรซrdorues Mujorรซ Aktivรซ)", "server_banner.active_users": "pรซrdorues aktivรซ", "server_banner.administered_by": "Administruar nga:", - "server_banner.introduction": "{domain} รซshtรซ pjesรซ e rrjetit shoqรซror tรซ decentralizuar tรซ ngritur mbi {mastodon}.", - "server_banner.learn_more": "Mรซsoni mรซ tepรซr", + "server_banner.is_one_of_many": "{domain} รซshtรซ njรซ nga mjaft shรซrbyes tรซ pavarur Mastodon te tรซ cilรซt mund tรซ merrni pjesรซ nรซ Fedivers.", "server_banner.server_stats": "Statistika shรซrbyesi:", "sign_in_banner.create_account": "Krijoni llogari", + "sign_in_banner.follow_anyone": "Ndiqni kรซdo nรซ Fedivers dhe shihni gjithรงka nรซ rend kohor. Pa algortime, apo marifete.", + "sign_in_banner.mastodon_is": "Mastodon-i รซshtรซ rruga mรซ e mirรซ pรซr tรซ ndjekur se รงโ€™ndodh.", "sign_in_banner.sign_in": "Hyni", "sign_in_banner.sso_redirect": "Bรซni hyrjen, ose Regjistrohuni", - "sign_in_banner.text": "Qรซ tรซ ndiqni profile ose hashtagรซ, tโ€™u vini shenjรซ si tรซ parapรซlqyer, tรซ ndani me tรซ tjerรซ dhe tโ€™i ripostoni nรซ postime, bรซni hyrjen nรซ llogari. Mundeni edhe tรซ ndรซrveproni qรซ nga llogaria juaj nรซ njรซ shรซrbyes tjetรซr.", "status.admin_account": "Hap ndรซrfaqe moderimi pรซr @{name}", "status.admin_domain": "Hap ndรซrfaqe moderimi pรซr {domain}", "status.admin_status": "Hape kรซtรซ mesazh te ndรซrfaqja e moderimit", @@ -645,10 +716,11 @@ "status.direct": "Pรซrmendje private pรซr @{name}", "status.direct_indicator": "Pรซrmendje private", "status.edit": "Pรซrpunojeni", - "status.edited": "Pรซrpunuar mรซ {date}", + "status.edited": "Pรซrpunuar sรซ fundi mรซ {date}", "status.edited_x_times": "Pรซrpunuar {count, plural, one {{count} herรซ} other {{count} herรซ}}", "status.embed": "Trupรซzim", "status.favourite": "I vini shenjรซ si tรซ parapรซlqyer", + "status.favourites": "{count, plural, one {i parapรซlqyer} other {tรซ parapรซlqyer}}", "status.filter": "Filtroje kรซtรซ postim", "status.filtered": "I filtruar", "status.hide": "Fshihe postimin", @@ -669,6 +741,7 @@ "status.reblog": "Pรซrforcojeni", "status.reblog_private": "Pรซrforcim pรซr publikun origjinal", "status.reblogged_by": "{name} pรซrforcoi", + "status.reblogs": "{count, plural, one {pรซrforcim} other {pรซrforcime}}", "status.reblogs.empty": "Kรซtรซ mesazh sโ€™e ka pรซrforcuar njeri deri tani. Kur ta bรซjรซ dikush, kjo do tรซ duket kรซtu.", "status.redraft": "Fshijeni & rihartojeni", "status.remove_bookmark": "Hiqe faqerojtรซsin", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index d9490ef70d..63b2e03c96 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,16 +161,14 @@ "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", "compose_form.spoiler.unmarked": "Dodaj upozorenje o sadrลพaju", "compose_form.spoiler_placeholder": "Upozorenje o sadrลพaju (opciono)", "confirmation_modal.cancel": "Otkaลพi", - "confirmations.block.block_and_report": "Blokiraj i prijavi", "confirmations.block.confirm": "Blokiraj", - "confirmations.block.message": "Da li ste sigurni da ลพelite da blokirate korisnika {name}?", "confirmations.cancel_follow_request.confirm": "Povuci zahtev", "confirmations.cancel_follow_request.message": "Da li ste sigurni da ลพelite da povuฤete zahtev da pratite {name}?", "confirmations.delete.confirm": "Izbriลกi", @@ -171,15 +177,13 @@ "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 ceo domen", + "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?", "confirmations.logout.confirm": "Odjava", "confirmations.logout.message": "Da li ste sigurni da ลพelite da se odjavite?", "confirmations.mute.confirm": "Ignoriลกi", - "confirmations.mute.explanation": "Ovo ฤ‡e sakriti objave korisnika i objave koje ga pominju, ali ฤ‡e mu i dalje biti dozvoljeno da vidi Vaลกe objave i da Vas prati.", - "confirmations.mute.message": "Da li stvarno ลพelite da ignoriลกete korisnika {name}?", "confirmations.redraft.confirm": "Izbriลกi i prepravi", "confirmations.redraft.message": "Da li ste sigurni da ลพelite da izbriลกete ovu objavu i da je prepravite? Podrลพavanja i oznake kao omiljenih ฤ‡e biti izgubljeni, a odgovori ฤ‡e ostati bez originalne objave.", "confirmations.reply.confirm": "Odgovori", @@ -201,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", @@ -237,10 +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.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.", @@ -271,16 +297,28 @@ "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", "firehose.local": "Ovaj server", "firehose.remote": "Ostali serveri", "follow_request.authorize": "Odobri", "follow_request.reject": "Odbij", "follow_requests.unlocked_explanation": "Iako vaลก nalog nije zakljuฤan, osoblje {domain} smatra da biste moลพda ลพeleli da ruฤno pregledate zahteve za praฤ‡enje sa ovih naloga.", - "follow_suggestions.curated_suggestion": "Izbor urednika", + "follow_suggestions.curated_suggestion": "Izbor osoblja", "follow_suggestions.dismiss": "Ne prikazuj ponovo", + "follow_suggestions.featured_longer": "Ruฤno odabrao tim {domain}", + "follow_suggestions.friends_of_friends_longer": "Popularno meฤ‘u ljudima koje pratite", + "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_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", "follow_suggestions.popular_suggestion": "Popularni predlog", + "follow_suggestions.popular_suggestion_longer": "Popularno na {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Sliฤno profilima koje ste nedavno zapratili", "follow_suggestions.view_all": "Prikaลพi sve", "follow_suggestions.who_to_follow": "Koga pratiti", "followed_tags": "Praฤ‡ene heลก oznake", @@ -309,11 +347,10 @@ "hashtag.follow": "Zaprati heลก oznaku", "hashtag.unfollow": "Otprati heลก oznaku", "hashtags.and_other": "โ€ฆi {count, plural, one {joลก #} few {joลก #}other {joลก #}}", - "home.column_settings.basic": "Osnovna", "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 mogucฬ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", @@ -327,7 +364,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 secฬ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}", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Ipak prikaลพi profil", "limited_account_hint.title": "Ovaj profil su sakrili moderatori {domain}.", "link_preview.author": "Po {name}", + "link_preview.more_from_author": "Viลกe od {name}", + "link_preview.shares": "{count, plural, one {{counter} objava} few {{counter} objave} other {{counter} objava}}", "lists.account.add": "Dodaj na listu", "lists.account.remove": "Ukloni sa liste", "lists.delete": "Izbriลกi listu", @@ -395,9 +434,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.duration": "Trajanje", - "mute_modal.hide_notifications": "Sakriti obaveลกtenja od ovog korisnika?", - "mute_modal.indefinite": "Neodreฤ‘eno", + "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", @@ -430,11 +475,29 @@ "notification.follow": "{name} vas je zapratio", "notification.follow_request": "{name} je zatraลพio da vas prati", "notification.mention": "{name} vas je pomenuo", + "notification.moderation-warning.learn_more": "Saznajte viลกe", + "notification.moderation_warning": "Dobili ste moderatorsko upozorenje", + "notification.moderation_warning.action_delete_statuses": "Neke od vaลกih objava su uklonjene.", + "notification.moderation_warning.action_disable": "Vaลก nalog je onemoguฤ‡en.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Neke od vaลกih objava su obeleลพene kao osetljive.", + "notification.moderation_warning.action_none": "Vaลก nalog je dobio moderatorsko upozorenje.", + "notification.moderation_warning.action_sensitive": "Vaลกe objave ฤ‡e ubuduฤ‡e biti oznaฤene kao osetljive.", + "notification.moderation_warning.action_silence": "Vaลก nalog je ograniฤen.", + "notification.moderation_warning.action_suspend": "Vaลก nalog je suspendovan.", "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", + "notification_requests.dismiss": "Odbaci", + "notification_requests.notifications_from": "Obaveลกtenja od {name}", + "notification_requests.title": "Filtrirana obaveลกtenja", "notifications.clear": "Obriลกi obaveลกtenja", "notifications.clear_confirmation": "Da li ste sigurni da ลพelite trajno da obriลกete sva vaลกa obaveลกtenja?", "notifications.column_settings.admin.report": "Nove prijave:", @@ -443,7 +506,6 @@ "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.filter_bar.show_bar": "Prikaลพi traku sa filterima", "notifications.column_settings.follow": "Novi pratioci:", "notifications.column_settings.follow_request": "Novi zahtevi za praฤ‡enje:", "notifications.column_settings.mention": "Pominjanja:", @@ -469,19 +531,28 @@ "notifications.permission_denied": "Obaveลกtenja na radnoj povrลกini nisu dostupna zbog prethodno odbijenog zahteva za dozvolu pregledaฤa", "notifications.permission_denied_alert": "Obaveลกtenja na radnoj povrลกini ne mogu biti omoguฤ‡ena, jer je dozvola pregledaฤa ranije bila odbijena", "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_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", + "notifications.policy.filter_private_mentions_hint": "Filtrirano osim ako je odgovor na vaลกe pominjanje ili ako pratite poลกiljaoca", + "notifications.policy.filter_private_mentions_title": "Neลพeljena privatna pominjanja", + "notifications.policy.title": "Filtriraj obaveลกtenja odโ€ฆ", "notifications_permission_banner.enable": "Omoguฤ‡iti obaveลกtenja na radnoj povrลกini", "notifications_permission_banner.how_to_control": "Da biste primali obaveลกtenja kada Mastodon nije otvoren, omoguฤ‡ite obaveลกtenja na radnoj povrลกini. Kada su obaveลกtenja na radnoj povrลกini omoguฤ‡ena vrste interakcija koje ona generiลกu mogu se podeลกavati pomoฤ‡u dugmeta {icon}.", "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 omogucฬite mogucฬ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.", @@ -495,17 +566,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!", @@ -530,7 +601,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 necฬ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}", @@ -625,13 +696,10 @@ "server_banner.about_active_users": "Ljudi koji su koristili ovaj server u prethodnih 30 dana (meseฤno aktivnih korisnika)", "server_banner.active_users": "aktivnih korisnika", "server_banner.administered_by": "Administrira:", - "server_banner.introduction": "{domain} je deo decentralizovane druลกtvene mreลพe koju pokreฤ‡e {mastodon}.", - "server_banner.learn_more": "Saznajte viลกe", "server_banner.server_stats": "Statistike servera:", "sign_in_banner.create_account": "Napravite nalog", "sign_in_banner.sign_in": "Prijavite se", "sign_in_banner.sso_redirect": "Prijavite se ili se registrujte", - "sign_in_banner.text": "Prijavite se da biste pratili profile ili heลก oznake, oznaฤili objave kao omiljene, delili i odgovarali na njih. Takoฤ‘e moลพete komunicirati sa svog naloga na drugom serveru.", "status.admin_account": "Otvori moderatorsko okruลพenje za @{name}", "status.admin_domain": "Otvori moderatorsko okruลพenje za {domain}", "status.admin_status": "Otvori ovu objavu u moderatorskom okruลพenju", @@ -645,10 +713,11 @@ "status.direct": "Privatno pomeni @{name}", "status.direct_indicator": "Privatno pominjanje", "status.edit": "Uredi", - "status.edited": "Ureฤ‘eno {date}", + "status.edited": "Poslednje ureฤ‘ivanje {date}", "status.edited_x_times": "Ureฤ‘eno {count, plural, one {{count} put} other {{count} puta}}", "status.embed": "Ugradi", "status.favourite": "Omiljeno", + "status.favourites": "{count, plural, one {# omiljeno} few {# omiljena} other {# omiljenih}}", "status.filter": "Filtriraj ovu objavu", "status.filtered": "Filtrirano", "status.hide": "Sakrij objavu", @@ -669,6 +738,7 @@ "status.reblog": "Podrลพi", "status.reblog_private": "Podrลพi sa originalnom vidljivoลกฤ‡u", "status.reblogged_by": "{name} je podrลพao/la", + "status.reblogs": "{count, plural, one {# podrลพavanje} few {# podrลพavanja} other {# podrลพavanja}}", "status.reblogs.empty": "Joลก uvek niko nije podrลพao ovu objavu. Kada bude podrลพana, pojaviฤ‡e se ovde.", "status.redraft": "Izbriลกi i preoblikuj", "status.remove_bookmark": "Ukloni obeleลพivaฤ", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index fd09f5db49..c6b969e982 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.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": "ะะธั˜ะต ะผะพะณัƒั›ะต ะฟั€ะธะบะฐะทะฐั‚ะธ ั‚ั€ะฐะถะตะฝัƒ ัั‚ั€ะฐะฝะธั†ัƒ. ะ ะฐะทะปะพะณ ะผะพะถะต ะฑะธั‚ะธ ะณั€ะตัˆะบะฐ ัƒ ะฝะฐัˆะตะผ ะบะพะดัƒ ะธะปะธ ะฟั€ะพะฑะปะตะผ ัะฐ ะบะพะผะฟะฐั‚ะธะฑะธะปะฝะพัˆั›ัƒ ะฟั€ะตั‚ั€ะฐะถะธะฒะฐั‡ะฐ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ะ”ะพะดะฐั˜ ัƒะฟะพะทะพั€ะตัšะต ะพ ัะฐะดั€ะถะฐั˜ัƒ", "compose_form.spoiler_placeholder": "ะฃะฟะพะทะพั€ะตัšะต ะพ ัะฐะดั€ะถะฐั˜ัƒ (ะพะฟั†ะธะพะฝะพ)", "confirmation_modal.cancel": "ะžั‚ะบะฐะถะธ", - "confirmations.block.block_and_report": "ะ‘ะปะพะบะธั€ะฐั˜ ะธ ะฟั€ะธั˜ะฐะฒะธ", "confirmations.block.confirm": "ะ‘ะปะพะบะธั€ะฐั˜", - "confirmations.block.message": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ะฑะปะพะบะธั€ะฐั‚ะต ะบะพั€ะธัะฝะธะบะฐ {name}?", "confirmations.cancel_follow_request.confirm": "ะŸะพะฒัƒั†ะธ ะทะฐั…ั‚ะตะฒ", "confirmations.cancel_follow_request.message": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ะฟะพะฒัƒั‡ะตั‚ะต ะทะฐั…ั‚ะตะฒ ะดะฐ ะฟั€ะฐั‚ะธั‚ะต {name}?", "confirmations.delete.confirm": "ะ˜ะทะฑั€ะธัˆะธ", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ั‚ั€ะฐั˜ะฝะพ ะธะทะฑั€ะธัˆะตั‚ะต ะพะฒัƒ ะปะธัั‚ัƒ?", "confirmations.discard_edit_media.confirm": "ะžะดะฑะฐั†ะธ", "confirmations.discard_edit_media.message": "ะ˜ะผะฐั‚ะต ะฝะตัะฐั‡ัƒะฒะฐะฝะต ะฟั€ะพะผะตะฝะต ัƒ ะพะฟะธััƒ ะธะปะธ ะฟั€ะตะณะปะตะดัƒ ะผะตะดะธั˜ะฐ, ะดะฐ ะปะธ ะธะฟะฐะบ ั…ะพั›ะตั‚ะต ะดะฐ ะธั… ะพะดะฑะฐั†ะธั‚ะต?", - "confirmations.domain_block.confirm": "ะ‘ะปะพะบะธั€ะฐั˜ ั†ะตะพ ะดะพะผะตะฝ", + "confirmations.domain_block.confirm": "ะ‘ะปะพะบะธั€ะฐั˜ ัะตั€ะฒะตั€", "confirmations.domain_block.message": "ะ”ะฐ ะปะธ ัั‚ะต ะทะฐะธัั‚ะฐ ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ะฑะปะพะบะธั€ะฐั‚ะต ั†ะตะพ ะดะพะผะตะฝ {domain}? ะฃ ะฒะตั›ะธะฝะธ ัะปัƒั‡ะฐั˜ะตะฒะฐ, ะดะพะฒะพั™ะฝะพ ั˜ะต ะธ ะฟะพะถะตั™ะฝะพ ะฝะตะบะพะปะธะบะพ ั†ะธั™ะฐะฝะธั… ะฑะปะพะบะธั€ะฐัšะฐ ะธะปะธ ะธะณะฝะพั€ะธัะฐัšะฐ. ะะตั›ะตั‚ะต ะฒะธะดะตั‚ะธ ัะฐะดั€ะถะฐั˜ ัะฐ ั‚ะพะณ ะดะพะผะตะฝะฐ ะฝะธ ัƒ ั˜ะตะดะฝะพั˜ ั˜ะฐะฒะฝะพั˜ ะฒั€ะตะผะตะฝัะบะพั˜ ะปะธะฝะธั˜ะธ ะธะปะธ ัƒ ะฒะฐัˆะธะผ ะพะฑะฐะฒะตัˆั‚ะตัšะธะผะฐ. ะ’ะฐัˆะธ ะฟั€ะฐั‚ะธะพั†ะธ ัะฐ ั‚ะพะณ ะดะพะผะตะฝะฐ ั›ะต ะฑะธั‚ะธ ัƒะบะปะพัšะตะฝะธ.", "confirmations.edit.confirm": "ะฃั€ะตะดะธ", "confirmations.edit.message": "ะฃั€ะตั’ะธะฒะฐัšะตะผ ั›ะต ัะต ะพะฑั€ะธัะฐั‚ะธ ะฟะพั€ัƒะบะฐ ะบะพั˜ัƒ ั‚ั€ะตะฝัƒั‚ะฝะพ ัะฐัั‚ะฐะฒั™ะฐั‚ะต. ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ะฝะฐัั‚ะฐะฒะธั‚ะต?", "confirmations.logout.confirm": "ะžะดั˜ะฐะฒะฐ", "confirmations.logout.message": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ัะต ะพะดั˜ะฐะฒะธั‚ะต?", "confirmations.mute.confirm": "ะ˜ะณะฝะพั€ะธัˆะธ", - "confirmations.mute.explanation": "ะžะฒะพ ั›ะต ัะฐะบั€ะธั‚ะธ ะพะฑั˜ะฐะฒะต ะบะพั€ะธัะฝะธะบะฐ ะธ ะพะฑั˜ะฐะฒะต ะบะพั˜ะต ะณะฐ ะฟะพะผะธัšัƒ, ะฐะปะธ ั›ะต ะผัƒ ะธ ะดะฐั™ะต ะฑะธั‚ะธ ะดะพะทะฒะพั™ะตะฝะพ ะดะฐ ะฒะธะดะธ ะ’ะฐัˆะต ะพะฑั˜ะฐะฒะต ะธ ะดะฐ ะ’ะฐั ะฟั€ะฐั‚ะธ.", - "confirmations.mute.message": "ะ”ะฐ ะปะธ ัั‚ะฒะฐั€ะฝะพ ะถะตะปะธั‚ะต ะดะฐ ะธะณะฝะพั€ะธัˆะตั‚ะต ะบะพั€ะธัะฝะธะบะฐ {name}?", "confirmations.redraft.confirm": "ะ˜ะทะฑั€ะธัˆะธ ะธ ะฟั€ะตะฟั€ะฐะฒะธ", "confirmations.redraft.message": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ะดะฐ ะธะทะฑั€ะธัˆะตั‚ะต ะพะฒัƒ ะพะฑั˜ะฐะฒัƒ ะธ ะดะฐ ั˜ะต ะฟั€ะตะฟั€ะฐะฒะธั‚ะต? ะŸะพะดั€ะถะฐะฒะฐัšะฐ ะธ ะพะทะฝะฐะบะต ะบะฐะพ ะพะผะธั™ะตะฝะธั… ั›ะต ะฑะธั‚ะธ ะธะทะณัƒะฑั™ะตะฝะธ, ะฐ ะพะดะณะพะฒะพั€ะธ ั›ะต ะพัั‚ะฐั‚ะธ ะฑะตะท ะพั€ะธะณะธะฝะฐะปะฝะต ะพะฑั˜ะฐะฒะต.", "confirmations.reply.confirm": "ะžะดะณะพะฒะพั€ะธ", @@ -205,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": "ะะบั‚ะธะฒะฝะพัั‚ะธ", @@ -241,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": "ะ—ะฑะพะณ ะณั€ะตัˆะบะต ัƒ ะฝะฐัˆะตะผ ะบะพะดัƒ ะธะปะธ ะฟั€ะพะฑะปะตะผะฐ ัะฐ ะบะพะผะฟะฐั‚ะธะฑะธะปะฝะพัˆั›ัƒ ะฟั€ะตะณะปะตะดะฐั‡ะฐ, ะพะฒะฐ ัั‚ั€ะฐะฝะธั†ะฐ ัะต ะฝะธั˜ะต ะผะพะณะปะฐ ะฟั€ะฐะฒะธะปะฝะพ ะฟั€ะธะบะฐะทะฐั‚ะธ.", @@ -271,16 +297,28 @@ "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": "ะกะฒะต", "firehose.local": "ะžะฒะฐั˜ ัะตั€ะฒะตั€", "firehose.remote": "ะžัั‚ะฐะปะธ ัะตั€ะฒะตั€ะธ", "follow_request.authorize": "ะžะดะพะฑั€ะธ", "follow_request.reject": "ะžะดะฑะธั˜", "follow_requests.unlocked_explanation": "ะ˜ะฐะบะพ ะฒะฐัˆ ะฝะฐะปะพะณ ะฝะธั˜ะต ะทะฐะบั™ัƒั‡ะฐะฝ, ะพัะพะฑั™ะต {domain} ัะผะฐั‚ั€ะฐ ะดะฐ ะฑะธัั‚ะต ะผะพะถะดะฐ ะถะตะปะตะปะธ ะดะฐ ั€ัƒั‡ะฝะพ ะฟั€ะตะณะปะตะดะฐั‚ะต ะทะฐั…ั‚ะตะฒะต ะทะฐ ะฟั€ะฐั›ะตัšะต ัะฐ ะพะฒะธั… ะฝะฐะปะพะณะฐ.", - "follow_suggestions.curated_suggestion": "ะ˜ะทะฑะพั€ ัƒั€ะตะดะฝะธะบะฐ", + "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}.", + "follow_suggestions.hints.most_interactions": "ะžะฒะฐั˜ ะฟั€ะพั„ะธะป ั˜ะต ะฝะตะดะฐะฒะฝะพ ะดะพะฑะธะพ ะฒะตะปะธะบัƒ ะฟะฐะถัšัƒ ะฝะฐ {domain}.", + "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": "ะŸั€ะฐั›ะตะฝะต ั…ะตัˆ ะพะทะฝะฐะบะต", @@ -309,7 +347,6 @@ "hashtag.follow": "ะ—ะฐะฟั€ะฐั‚ะธ ั…ะตัˆ ะพะทะฝะฐะบัƒ", "hashtag.unfollow": "ะžั‚ะฟั€ะฐั‚ะธ ั…ะตัˆ ะพะทะฝะฐะบัƒ", "hashtags.and_other": "โ€ฆะธ {count, plural, one {ั˜ะพัˆ #} few {ั˜ะพัˆ #}other {ั˜ะพัˆ #}}", - "home.column_settings.basic": "ะžัะฝะพะฒะฝะฐ", "home.column_settings.show_reblogs": "ะŸั€ะธะบะฐะถะธ ะฟะพะดั€ะถะฐะฒะฐัšะฐ", "home.column_settings.show_replies": "ะŸั€ะธะบะฐะถะธ ะพะดะณะพะฒะพั€ะต", "home.hide_announcements": "ะกะฐะบั€ะธั˜ ะฝะฐั˜ะฐะฒะต", @@ -377,6 +414,8 @@ "limited_account_hint.action": "ะ˜ะฟะฐะบ ะฟั€ะธะบะฐะถะธ ะฟั€ะพั„ะธะป", "limited_account_hint.title": "ะžะฒะฐั˜ ะฟั€ะพั„ะธะป ััƒ ัะฐะบั€ะธะปะธ ะผะพะดะตั€ะฐั‚ะพั€ะธ {domain}.", "link_preview.author": "ะŸะพ {name}", + "link_preview.more_from_author": "ะ’ะธัˆะต ะพะด {name}", + "link_preview.shares": "{count, plural, one {{counter} ะพะฑั˜ะฐะฒะฐ} few {{counter} ะพะฑั˜ะฐะฒะต} other {{counter} ะพะฑั˜ะฐะฒะฐ}}", "lists.account.add": "ะ”ะพะดะฐั˜ ะฝะฐ ะปะธัั‚ัƒ", "lists.account.remove": "ะฃะบะปะพะฝะธ ัะฐ ะปะธัั‚ะต", "lists.delete": "ะ˜ะทะฑั€ะธัˆะธ ะปะธัั‚ัƒ", @@ -395,9 +434,15 @@ "loading_indicator.label": "ะฃั‡ะธั‚ะฐะฒะฐัšะตโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ะกะฐะบั€ะธั˜ ัะปะธะบัƒ} few {ะกะฐะบั€ะธั˜ ัะปะธะบะต} other {ะกะฐะบั€ะธั˜ ัะปะธะบะต}}", "moved_to_account_banner.text": "ะ’ะฐัˆ ะฝะฐะปะพะณ {disabledAccount} ั˜ะต ั‚ั€ะตะฝัƒั‚ะฝะพ ะพะฝะตะผะพะณัƒั›ะตะฝ ั˜ะตั€ ัั‚ะต ะฟั€ะตัˆะปะธ ะฝะฐ {movedToAccount}.", - "mute_modal.duration": "ะขั€ะฐั˜ะฐัšะต", - "mute_modal.hide_notifications": "ะกะฐะบั€ะธั‚ะธ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะพะด ะพะฒะพะณ ะบะพั€ะธัะฝะธะบะฐ?", - "mute_modal.indefinite": "ะะตะพะดั€ะตั’ะตะฝะพ", + "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": "ะ‘ะปะพะบะธั€ะฐะฝะธ ะบะพั€ะธัะฝะธั†ะธ", @@ -430,11 +475,29 @@ "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.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": "ะŸั€ะธั…ะฒะฐั‚ะธ", + "notification_requests.dismiss": "ะžะดะฑะฐั†ะธ", + "notification_requests.notifications_from": "ะžะฑะฐะฒะตัˆั‚ะตัšะฐ ะพะด {name}", + "notification_requests.title": "ะคะธะปั‚ั€ะธั€ะฐะฝะฐ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ", "notifications.clear": "ะžะฑั€ะธัˆะธ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ", "notifications.clear_confirmation": "ะ”ะฐ ะปะธ ัั‚ะต ัะธะณัƒั€ะฝะธ ะดะฐ ะถะตะปะธั‚ะต ั‚ั€ะฐั˜ะฝะพ ะดะฐ ะพะฑั€ะธัˆะตั‚ะต ัะฒะฐ ะฒะฐัˆะฐ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ?", "notifications.column_settings.admin.report": "ะะพะฒะต ะฟั€ะธั˜ะฐะฒะต:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "ะžะผะธั™ะตะฝะพ:", "notifications.column_settings.filter_bar.advanced": "ะŸั€ะธะบะฐะถะธ ัะฒะต ะบะฐั‚ะตะณะพั€ะธั˜ะต", "notifications.column_settings.filter_bar.category": "ะขั€ะฐะบะฐ ะทะฐ ะฑั€ะทะพ ั„ะธะปั‚ั€ะธั€ะฐัšะต", - "notifications.column_settings.filter_bar.show_bar": "ะŸั€ะธะบะฐะถะธ ั‚ั€ะฐะบัƒ ัะฐ ั„ะธะปั‚ะตั€ะธะผะฐ", "notifications.column_settings.follow": "ะะพะฒะธ ะฟั€ะฐั‚ะธะพั†ะธ:", "notifications.column_settings.follow_request": "ะะพะฒะธ ะทะฐั…ั‚ะตะฒะธ ะทะฐ ะฟั€ะฐั›ะตัšะต:", "notifications.column_settings.mention": "ะŸะพะผะธัšะฐัšะฐ:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "ะžะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ ะฝะธััƒ ะดะพัั‚ัƒะฟะฝะฐ ะทะฑะพะณ ะฟั€ะตั‚ั…ะพะดะฝะพ ะพะดะฑะธั˜ะตะฝะพะณ ะทะฐั…ั‚ะตะฒะฐ ะทะฐ ะดะพะทะฒะพะปัƒ ะฟั€ะตะณะปะตะดะฐั‡ะฐ", "notifications.permission_denied_alert": "ะžะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ ะฝะต ะผะพะณัƒ ะฑะธั‚ะธ ะพะผะพะณัƒั›ะตะฝะฐ, ั˜ะตั€ ั˜ะต ะดะพะทะฒะพะปะฐ ะฟั€ะตะณะปะตะดะฐั‡ะฐ ั€ะฐะฝะธั˜ะต ะฑะธะปะฐ ะพะดะฑะธั˜ะตะฝะฐ", "notifications.permission_required": "ะžะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ ะฝะธััƒ ะดะพัั‚ัƒะฟะฝะฐ ั˜ะตั€ ะฟะพั‚ั€ะตะฑะฝะฐ ะดะพะทะฒะพะปะฐ ะฝะธั˜ะต ะดะพะดะตั™ะตะฝะฐ.", + "notifications.policy.filter_new_accounts.hint": "ะšั€ะตะธั€ะฐะฝะพ {days, plural, one {ัƒ ะฟะพัะปะตะดัšะตะณ # ะดะฐะฝะฐ} few {ัƒ ะฟะพัะปะตะดัšะฐ # ะดะฐะฝะฐ} other {ัƒ ะฟะพัะปะตะดัšะธั… # ะดะฐะฝะฐ}}", + "notifications.policy.filter_new_accounts_title": "ะะพะฒะธ ะฝะฐะปะพะทะธ", + "notifications.policy.filter_not_followers_hint": "ะฃะบั™ัƒั‡ัƒั˜ัƒั›ะธ ั™ัƒะดะต ะบะพั˜ะธ ััƒ ะฒะฐั ะฟั€ะฐั‚ะธะปะธ ะผะฐัšะต ะพะด {days, plural, one {# ะดะฐะฝะฐ} few {# ะดะฐะฝะฐ} other {# ะดะฐะฝะฐ}}", + "notifications.policy.filter_not_followers_title": "ะ‰ัƒะดะธ ะบะพั˜ะธ ะฒะฐั ะฝะต ะฟั€ะฐั‚ะต", + "notifications.policy.filter_not_following_hint": "ะ”ะพะบ ะธั… ั€ัƒั‡ะฝะพ ะฝะต ะพะดะพะฑั€ะธั‚ะต", + "notifications.policy.filter_not_following_title": "ะ‰ัƒะดะธ ะบะพั˜ะต ะฝะต ะฟั€ะฐั‚ะธั‚ะต", + "notifications.policy.filter_private_mentions_hint": "ะคะธะปั‚ั€ะธั€ะฐะฝะพ ะพัะธะผ ะฐะบะพ ั˜ะต ะพะดะณะพะฒะพั€ ะฝะฐ ะฒะฐัˆะต ะฟะพะผะธัšะฐัšะต ะธะปะธ ะฐะบะพ ะฟั€ะฐั‚ะธั‚ะต ะฟะพัˆะธั™ะฐะพั†ะฐ", + "notifications.policy.filter_private_mentions_title": "ะะตะถะตั™ะตะฝะฐ ะฟั€ะธะฒะฐั‚ะฝะฐ ะฟะพะผะธัšะฐัšะฐ", + "notifications.policy.title": "ะคะธะปั‚ั€ะธั€ะฐั˜ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะพะดโ€ฆ", "notifications_permission_banner.enable": "ะžะผะพะณัƒั›ะธั‚ะธ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ", "notifications_permission_banner.how_to_control": "ะ”ะฐ ะฑะธัั‚ะต ะฟั€ะธะผะฐะปะธ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะบะฐะดะฐ Mastodon ะฝะธั˜ะต ะพั‚ะฒะพั€ะตะฝ, ะพะผะพะณัƒั›ะธั‚ะต ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ. Kะฐะดะฐ ััƒ ะพะฑะฐะฒะตัˆั‚ะตัšะฐ ะฝะฐ ั€ะฐะดะฝะพั˜ ะฟะพะฒั€ัˆะธะฝะธ ะพะผะพะณัƒั›ะตะฝะฐ ะฒั€ัั‚ะต ะธะฝั‚ะตั€ะฐะบั†ะธั˜ะฐ ะบะพั˜ะต ะพะฝะฐ ะณะตะฝะตั€ะธัˆัƒ ะผะพะณัƒ ัะต ะฟะพะดะตัˆะฐะฒะฐั‚ะธ ะฟะพะผะพั›ัƒ ะดัƒะณะผะตั‚ะฐ {icon}.", "notifications_permission_banner.title": "ะะธะบะฐะดะฐ ะฝะธัˆั‚ะฐ ะฝะต ะฟั€ะพะฟัƒัั‚ะธั‚ะต", @@ -503,7 +574,7 @@ "onboarding.steps.publish_status.body": "ะŸะพะทะดั€ะฐะฒะธั‚ะต ัะฒะตั‚ ั‚ะตะบัั‚ะพะผ, ัะปะธะบะฐะผะฐ, ะฒะธะดะตะพ ัะฝะธะผั†ะธะผะฐ ะธะปะธ ะฐะฝะบะตั‚ะฐะผะฐ {emoji}", "onboarding.steps.publish_status.title": "ะะฐะฟะธัˆะธั‚ะต ัะฒะพั˜ัƒ ะฟั€ะฒัƒ ะพะฑั˜ะฐะฒัƒ", "onboarding.steps.setup_profile.body": "ะŸะพั˜ะฐั‡ะฐั˜ั‚ะต ัะฒะพั˜ะต ะธะฝั‚ะตั€ะฐะบั†ะธั˜ะต ั‚ะฐะบะพ ัˆั‚ะพ ั›ะตั‚ะต ะธะผะฐั‚ะธ ัะฒะตะพะฑัƒั…ะฒะฐั‚ะฐะฝ ะฟั€ะพั„ะธะป.", - "onboarding.steps.setup_profile.title": "ะŸะตั€ัะพะฝะฐะปะธะทัƒั˜ั‚ะตะต ัะฒะพั˜ ะฟั€ะพั„ะธะป", + "onboarding.steps.setup_profile.title": "ะŸะตั€ัะพะฝะฐะปะธะทัƒั˜ั‚ะต ัะฒะพั˜ ะฟั€ะพั„ะธะป", "onboarding.steps.share_profile.body": "ะะตะบะฐ ะฒะฐัˆะธ ะฟั€ะธั˜ะฐั‚ะตั™ะธ ะทะฝะฐั˜ัƒ ะบะฐะบะพ ะดะฐ ะฒะฐั ะฟั€ะพะฝะฐั’ัƒ ะฝะฐ Mastodon-ัƒ!", "onboarding.steps.share_profile.title": "ะŸะพะดะตะปะธั‚ะต ัะฒะพั˜ Mastodon ะฟั€ะพั„ะธะป", "onboarding.tips.2fa": "ะ”ะฐ ะปะธ ัั‚ะต ะทะฝะฐะปะธ? ะœะพะถะตั‚ะต ะดะฐ ะทะฐัˆั‚ะธั‚ะธั‚ะต ัะฒะพั˜ ะฝะฐะปะพะณ ะฟะพะดะตัˆะฐะฒะฐัšะตะผ ะดะฒะพัั‚ั€ัƒะบะต ะฟะพั‚ะฒั€ะดะต ะธะดะตะฝั‚ะธั‚ะตั‚ะฐ ัƒ ะฟะพะดะตัˆะฐะฒะฐัšะธะผะฐ ะฝะฐะปะพะณะฐ. ะ ะฐะดะธ ัะฐ ะฑะธะปะพ ะบะพั˜ะพะผ TOTP ะฐะฟะปะธะบะฐั†ะธั˜ะพะผ ะฟะพ ะฒะฐัˆะตะผ ะธะทะฑะพั€ัƒ, ะฝะธั˜ะต ะฟะพั‚ั€ะตะฑะฐะฝ ะฑั€ะพั˜ ั‚ะตะปะตั„ะพะฝะฐ!", @@ -625,13 +696,10 @@ "server_banner.about_active_users": "ะ‰ัƒะดะธ ะบะพั˜ะธ ััƒ ะบะพั€ะธัั‚ะธะปะธ ะพะฒะฐั˜ ัะตั€ะฒะตั€ ัƒ ะฟั€ะตั‚ั…ะพะดะฝะธั… 30 ะดะฐะฝะฐ (ะผะตัะตั‡ะฝะพ ะฐะบั‚ะธะฒะฝะธั… ะบะพั€ะธัะฝะธะบะฐ)", "server_banner.active_users": "ะฐะบั‚ะธะฒะฝะธั… ะบะพั€ะธัะฝะธะบะฐ", "server_banner.administered_by": "ะะดะผะธะฝะธัั‚ั€ะธั€ะฐ:", - "server_banner.introduction": "{domain} ั˜ะต ะดะตะพ ะดะตั†ะตะฝั‚ั€ะฐะปะธะทะพะฒะฐะฝะต ะดั€ัƒัˆั‚ะฒะตะฝะต ะผั€ะตะถะต ะบะพั˜ัƒ ะฟะพะบั€ะตั›ะต {mastodon}.", - "server_banner.learn_more": "ะกะฐะทะฝะฐั˜ั‚ะต ะฒะธัˆะต", "server_banner.server_stats": "ะกั‚ะฐั‚ะธัั‚ะธะบะต ัะตั€ะฒะตั€ะฐ:", "sign_in_banner.create_account": "ะะฐะฟั€ะฐะฒะธั‚ะต ะฝะฐะปะพะณ", "sign_in_banner.sign_in": "ะŸั€ะธั˜ะฐะฒะธั‚ะต ัะต", "sign_in_banner.sso_redirect": "ะŸั€ะธั˜ะฐะฒะธั‚ะต ัะต ะธะปะธ ัะต ั€ะตะณะธัั‚ั€ัƒั˜ั‚ะต", - "sign_in_banner.text": "ะŸั€ะธั˜ะฐะฒะธั‚ะต ัะต ะดะฐ ะฑะธัั‚ะต ะฟั€ะฐั‚ะธะปะธ ะฟั€ะพั„ะธะปะต ะธะปะธ ั…ะตัˆ ะพะทะฝะฐะบะต, ะพะทะฝะฐั‡ะธะปะธ ะพะฑั˜ะฐะฒะต ะบะฐะพ ะพะผะธั™ะตะฝะต, ะดะตะปะธะปะธ ะธ ะพะดะณะพะฒะฐั€ะฐะปะธ ะฝะฐ ัšะธั…. ะขะฐะบะพั’ะต ะผะพะถะตั‚ะต ะบะพะผัƒะฝะธั†ะธั€ะฐั‚ะธ ัะฐ ัะฒะพะณ ะฝะฐะปะพะณะฐ ะฝะฐ ะดั€ัƒะณะพะผ ัะตั€ะฒะตั€ัƒ.", "status.admin_account": "ะžั‚ะฒะพั€ะธ ะผะพะดะตั€ะฐั‚ะพั€ัะบะพ ะพะบั€ัƒะถะตัšะต ะทะฐ @{name}", "status.admin_domain": "ะžั‚ะฒะพั€ะธ ะผะพะดะตั€ะฐั‚ะพั€ัะบะพ ะพะบั€ัƒะถะตัšะต ะทะฐ {domain}", "status.admin_status": "ะžั‚ะฒะพั€ะธ ะพะฒัƒ ะพะฑั˜ะฐะฒัƒ ัƒ ะผะพะดะตั€ะฐั‚ะพั€ัะบะพะผ ะพะบั€ัƒะถะตัšัƒ", @@ -645,10 +713,11 @@ "status.direct": "ะŸั€ะธะฒะฐั‚ะฝะพ ะฟะพะผะตะฝะธ @{name}", "status.direct_indicator": "ะŸั€ะธะฒะฐั‚ะฝะพ ะฟะพะผะธัšะฐัšะต", "status.edit": "ะฃั€ะตะดะธ", - "status.edited": "ะฃั€ะตั’ะตะฝะพ {date}", + "status.edited": "ะŸะพัะปะตะดัšะต ัƒั€ะตั’ะธะฒะฐัšะต {date}", "status.edited_x_times": "ะฃั€ะตั’ะตะฝะพ {count, plural, one {{count} ะฟัƒั‚} other {{count} ะฟัƒั‚ะฐ}}", "status.embed": "ะฃะณั€ะฐะดะธ", "status.favourite": "ะžะผะธั™ะตะฝะพ", + "status.favourites": "{count, plural, one {# ะพะผะธั™ะตะฝะพ} few {# ะพะผะธั™ะตะฝะฐ} other {# ะพะผะธั™ะตะฝะธั…}}", "status.filter": "ะคะธะปั‚ั€ะธั€ะฐั˜ ะพะฒัƒ ะพะฑั˜ะฐะฒัƒ", "status.filtered": "ะคะธะปั‚ั€ะธั€ะฐะฝะพ", "status.hide": "ะกะฐะบั€ะธั˜ ะพะฑั˜ะฐะฒัƒ", @@ -669,6 +738,7 @@ "status.reblog": "ะŸะพะดั€ะถะธ", "status.reblog_private": "ะŸะพะดั€ะถะธ ัะฐ ะพั€ะธะณะธะฝะฐะปะฝะพะผ ะฒะธะดั™ะธะฒะพัˆั›ัƒ", "status.reblogged_by": "{name} ั˜ะต ะฟะพะดั€ะถะฐะพ/ะปะฐ", + "status.reblogs": "{count, plural, one {# ะฟะพะดั€ะถะฐะฒะฐัšะต} few {# ะฟะพะดั€ะถะฐะฒะฐัšะฐ} other {# ะฟะพะดั€ะถะฐะฒะฐัšะฐ}}", "status.reblogs.empty": "ะˆะพัˆ ัƒะฒะตะบ ะฝะธะบะพ ะฝะธั˜ะต ะฟะพะดั€ะถะฐะพ ะพะฒัƒ ะพะฑั˜ะฐะฒัƒ. ะšะฐะดะฐ ะฑัƒะดะต ะฟะพะดั€ะถะฐะฝะฐ, ะฟะพั˜ะฐะฒะธั›ะต ัะต ะพะฒะดะต.", "status.redraft": "ะ˜ะทะฑั€ะธัˆะธ ะธ ะฟั€ะตะพะฑะปะธะบัƒั˜", "status.remove_bookmark": "ะฃะบะปะพะฝะธ ะพะฑะตะปะตะถะธะฒะฐั‡", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 4a15c60ed8..ced6c36054 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -89,6 +89,14 @@ "announcement.announcement": "Meddelande", "attachments_list.unprocessed": "(obehandlad)", "audio.hide": "Dรถlj audio", + "block_modal.remote_users_caveat": "Vi kommer att be servern {domain} att respektera ditt beslut. Dock garanteras inte efterlevnad eftersom vissa servrar kan hantera blockeringar pรฅ olika sรคtt. Offentliga inlรคgg kan fortfarande vara synliga fรถr icke-inloggade anvรคndare.", + "block_modal.show_less": "Visa mindre", + "block_modal.show_more": "Visa mer", + "block_modal.they_cant_mention": "De kan inte nรคmna eller fรถlja dig.", + "block_modal.they_cant_see_posts": "De kan inte se dina inlรคgg och du kan inte se deras.", + "block_modal.they_will_know": "De kan se att de รคr blockerade.", + "block_modal.title": "Blockera anvรคndare?", + "block_modal.you_wont_see_mentions": "Du kommer inte att se inlรคgg som nรคmner dem.", "boost_modal.combo": "Du kan trycka pรฅ {combo} fรถr att hoppa รถver detta nรคsta gรฅng", "bundle_column_error.copy_stacktrace": "Kopiera felrapport", "bundle_column_error.error.body": "Den begรคrda sidan kunde inte visas. Det kan bero pรฅ ett fel i vรฅr kod eller ett problem med webblรคsarens kompatibilitet.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Texten รคr inte dold", "compose_form.spoiler_placeholder": "Innehรฅllsvarning (valfritt)", "confirmation_modal.cancel": "Avbryt", - "confirmations.block.block_and_report": "Blockera & rapportera", "confirmations.block.confirm": "Blockera", - "confirmations.block.message": "ร„r du sรคker pรฅ att du vill blockera {name}?", "confirmations.cancel_follow_request.confirm": "ร…terkalla fรถrfrรฅgan", "confirmations.cancel_follow_request.message": "ร„r du sรคker pรฅ att du vill รฅterkalla din begรคran om att fรถlja {name}?", "confirmations.delete.confirm": "Radera", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ร„r du sรคker pรฅ att du vill radera denna lista permanent?", "confirmations.discard_edit_media.confirm": "Kasta", "confirmations.discard_edit_media.message": "Du har osparade รคndringar till mediabeskrivningen eller fรถrhandsgranskningen, kasta bort dem รคndรฅ?", - "confirmations.domain_block.confirm": "Dรถlj hela domรคnen", + "confirmations.domain_block.confirm": "Blockera server", "confirmations.domain_block.message": "ร„r du verkligen, verkligen sรคker pรฅ att du vill blockera hela {domain}? I de flesta fall รคr nรฅgra riktade blockeringar eller nedtystade konton tillrรคckligt och att fรถredra. Du kommer inte se innehรฅll frรฅn den domรคnen i den allmรคnna tidslinjen eller i dina aviseringar. Dina fรถljare frรฅn den domรคnen komer att tas bort.", "confirmations.edit.confirm": "Redigera", "confirmations.edit.message": "Om du svarar nu kommer det att ersรคtta meddelandet du hรฅller pรฅ att skapa. ร„r du sรคker pรฅ att du vill fortsรคtta?", "confirmations.logout.confirm": "Logga ut", "confirmations.logout.message": "ร„r du sรคker pรฅ att du vill logga ut?", "confirmations.mute.confirm": "Tysta", - "confirmations.mute.explanation": "Detta kommer dรถlja inlรคgg frรฅn hen och inlรคgg som nรคmner hen, men hen tillรฅts fortfarande se dina inlรคgg och fรถlja dig.", - "confirmations.mute.message": "ร„r du sรคker pรฅ att du vill tysta {name}?", "confirmations.redraft.confirm": "Radera & gรถr om", "confirmations.redraft.message": "ร„r du sรคker pรฅ att du vill radera detta inlรคgg och gรถra om det? Favoritmarkeringar, boostar och svar till det ursprungliga inlรคgget kommer fรถrlora sitt sammanhang.", "confirmations.reply.confirm": "Svara", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Dessa inlรคgg, frรฅn denna och andra servrar i det decentraliserade nรคtverket, pratas det om just nu pรฅ denna server.", "dismissable_banner.explore_tags": "Dessa hashtaggar pratas det om just nu bland folk pรฅ denna och andra servrar i det decentraliserade nรคtverket.", "dismissable_banner.public_timeline": "De hรคr รคr de aktuella publika inlรคgg frรฅn personer pรฅ det sociala nรคtet som personer i {domain} fรถljer.", + "domain_block_modal.block": "Blockera server", + "domain_block_modal.block_account_instead": "Blockera @{name} istรคllet", + "domain_block_modal.they_can_interact_with_old_posts": "Personer frรฅn denna server kan interagera med dina gamla inlรคgg.", + "domain_block_modal.they_cant_follow": "Ingen frรฅn denna server kan fรถlja dig.", + "domain_block_modal.they_wont_know": "De kommer inte veta att de har blockerats.", + "domain_block_modal.title": "Blockera domรคn?", + "domain_block_modal.you_will_lose_followers": "Alla dina fรถljare frรฅn denna server kommer att tas bort.", + "domain_block_modal.you_wont_see_posts": "Du kommer inte att se inlรคgg eller meddelanden frรฅn anvรคndare pรฅ den hรคr servern.", + "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:", "emoji_button.activity": "Aktivitet", @@ -241,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.", @@ -271,16 +297,30 @@ "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.mentions": "{count, plural, one {omnรคmning} other {omnรคmnanden}}", + "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", "follow_request.authorize": "Godkรคnn", "follow_request.reject": "Avvisa", - "follow_requests.unlocked_explanation": "ร„ven om ditt konto inte รคr lรฅst tror {domain} personalen att du kanske vill granska dessa fรถljares fรถrfrรฅgningar manuellt.", + "follow_requests.unlocked_explanation": "ร„ven om ditt konto inte รคr lรฅst tror {domain}-personalen att du kanske vill granska dessa fรถljares fรถrfrรฅgningar manuellt.", + "follow_suggestions.curated_suggestion": "Utvald av personalen", "follow_suggestions.dismiss": "Visa inte igen", + "follow_suggestions.featured_longer": "Handplockad av {domain}-teamet", + "follow_suggestions.friends_of_friends_longer": "Populรคrt bland personer du fรถljer", + "follow_suggestions.hints.featured": "Denna profil รคr handplockad av {domain}-teamet.", + "follow_suggestions.hints.friends_of_friends": "Denna profil รคr populรคr bland de personer du fรถljer.", + "follow_suggestions.hints.most_followed": "Denna profil รคr en av de mest fรถljda pรฅ {domain}.", + "follow_suggestions.hints.most_interactions": "Denna profil har nyligen fรฅtt mycket uppmรคrksamhet pรฅ {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Denna profil liknar de profiler som du nyligen har fรถljt.", "follow_suggestions.personalized_suggestion": "Personligt fรถrslag", "follow_suggestions.popular_suggestion": "Populรคrt fรถrslag", + "follow_suggestions.popular_suggestion_longer": "Populรคrt pรฅ {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Liknar profiler du nyligen fรถljde", "follow_suggestions.view_all": "Visa alla", + "follow_suggestions.who_to_follow": "Rekommenderade profiler", "followed_tags": "Fรถljda hashtags", "footer.about": "Om", "footer.directory": "Profilkatalog", @@ -307,7 +347,6 @@ "hashtag.follow": "Fรถlj hashtagg", "hashtag.unfollow": "Avfรถlj hashtagg", "hashtags.and_other": "โ€ฆoch {count, plural, one {}other {# mer}}", - "home.column_settings.basic": "Grundlรคggande", "home.column_settings.show_reblogs": "Visa boostar", "home.column_settings.show_replies": "Visa svar", "home.hide_announcements": "Dรถlj notiser", @@ -375,6 +414,8 @@ "limited_account_hint.action": "Visa profil รคndรฅ", "limited_account_hint.title": "Denna profil har dolts av {domain}s moderatorer.", "link_preview.author": "Av {name}", + "link_preview.more_from_author": "Mer frรฅn {name}", + "link_preview.shares": "{count, plural, one {{counter} inlรคgg} other {{counter} inlรคgg}}", "lists.account.add": "Lรคgg till i lista", "lists.account.remove": "Ta bort frรฅn lista", "lists.delete": "Radera lista", @@ -393,9 +434,15 @@ "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.duration": "Varaktighet", - "mute_modal.hide_notifications": "Dรถlj aviseringar frรฅn denna anvรคndare?", - "mute_modal.indefinite": "Obestรคmt", + "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.", + "mute_modal.title": "Tysta anvรคndare?", + "mute_modal.you_wont_see_mentions": "Du kommer inte att se inlรคgg som nรคmner dem.", + "mute_modal.you_wont_see_posts": "De kan fortfarande se dina inlรคgg, men du kan inte se deras.", "navigation_bar.about": "Om", "navigation_bar.advanced_interface": "ร–ppna i avancerat webbgrรคnssnitt", "navigation_bar.blocks": "Blockerade anvรคndare", @@ -428,11 +475,29 @@ "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": "Du har fรฅtt en moderationsvarning", + "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_none": "Ditt konto har mottagit en modereringsvarning.", + "notification.moderation_warning.action_sensitive": "Dina inlรคgg kommer markeras som kรคnsliga frรฅn och med nu.", + "notification.moderation_warning.action_silence": "Ditt konto har begrรคnsats.", + "notification.moderation_warning.action_suspend": "Ditt konto har stรคngts av.", "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", + "notification_requests.dismiss": "Avfรคrda", + "notification_requests.notifications_from": "Aviseringar frรฅn {name}", + "notification_requests.title": "Filtrerade meddelanden", "notifications.clear": "Rensa aviseringar", "notifications.clear_confirmation": "ร„r du sรคker pรฅ att du vill rensa alla dina aviseringar permanent?", "notifications.column_settings.admin.report": "Nya rapporter:", @@ -441,7 +506,6 @@ "notifications.column_settings.favourite": "Favoriter:", "notifications.column_settings.filter_bar.advanced": "Visa alla kategorier", "notifications.column_settings.filter_bar.category": "Snabbfilter", - "notifications.column_settings.filter_bar.show_bar": "Visa filterfรคlt", "notifications.column_settings.follow": "Nya fรถljare:", "notifications.column_settings.follow_request": "Ny fรถlj-fรถrfrรฅgan:", "notifications.column_settings.mention": "Omnรคmningar:", @@ -467,6 +531,15 @@ "notifications.permission_denied": "Skrivbordsaviseringar รคr otillgรคngliga pรฅ grund av tidigare nekade fรถrfrรฅgningar om behรถrighet i webblรคsaren", "notifications.permission_denied_alert": "Skrivbordsaviseringar kan inte aktiveras, eftersom att webblรคsarens behรถrighet har nekats innan", "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", "notifications_permission_banner.how_to_control": "Fรถr att ta emot aviseringar nรคr Mastodon inte รคr รถppet, aktivera skrivbordsaviseringar. Nรคr de รคr aktiverade kan du styra exakt vilka typer av interaktioner som aviseras via {icon} -knappen ovan.", "notifications_permission_banner.title": "Missa aldrig nรฅgot", @@ -486,7 +559,9 @@ "onboarding.profile.note": "Bio", "onboarding.profile.note_hint": "Du kan @nรคmna andra personer eller #hashtagsโ€ฆ", "onboarding.profile.save_and_continue": "Spara och fortsรคtt", + "onboarding.profile.title": "Konfiguration av profil", "onboarding.profile.upload_avatar": "Ladda upp profilbild", + "onboarding.profile.upload_header": "Ladda upp profilbanner", "onboarding.share.lead": "Lรฅt folk veta hur de kan hitta dig pรฅ Mastodon!", "onboarding.share.message": "Jag รคr {username} pรฅ #Mastodon! Fรถlj mig pรฅ {url}", "onboarding.share.next_steps": "Mรถjliga nรคsta steg:", @@ -521,10 +596,14 @@ "poll_button.remove_poll": "Ta bort omrรถstning", "privacy.change": "ร„ndra inlรคggsintegritet", "privacy.direct.long": "Alla som nรคmns i inlรคgget", + "privacy.direct.short": "Sรคrskilda personer", "privacy.private.long": "Endast dina fรถljare", "privacy.private.short": "Fรถljare", "privacy.public.long": "Alla pรฅ och utanfรถr Mastodon", - "privacy.public.short": "Publik", + "privacy.public.short": "Offentlig", + "privacy.unlisted.additional": "Detta fungerar precis som offentlig, fรถrutom att inlรคgget inte visas i liveflรถden eller hashtaggar, utforska eller Mastodon-sรถkning, รคven om du har valt detta fรถr hela kontot.", + "privacy.unlisted.long": "Mindre beaktat av algoritmen", + "privacy.unlisted.short": "Offentlig (begrรคnsad)", "privacy_policy.last_updated": "Senast uppdaterad {date}", "privacy_policy.title": "Integritetspolicy", "recommended": "Rekommenderas", @@ -617,13 +696,10 @@ "server_banner.about_active_users": "Personer som anvรคnt denna server de senaste 30 dagarna (mรฅnatligt aktiva anvรคndare)", "server_banner.active_users": "aktiva anvรคndare", "server_banner.administered_by": "Administrerad av:", - "server_banner.introduction": "{domain} รคr en del av det decentraliserade sociala nรคtverket som drivs av {mastodon}.", - "server_banner.learn_more": "Lรคr dig mer", "server_banner.server_stats": "Serverstatistik:", "sign_in_banner.create_account": "Skapa konto", "sign_in_banner.sign_in": "Logga in", "sign_in_banner.sso_redirect": "Logga in eller registrera dig", - "sign_in_banner.text": "Logga in fรถr att fรถlja profiler eller hashtaggar, favoritmarkera, dela och svara pรฅ inlรคgg. Du kan ocksรฅ interagera med ditt konto pรฅ en annan server.", "status.admin_account": "ร–ppet modereringsgrรคnssnitt fรถr @{name}", "status.admin_domain": "ร–ppet modereringsgrรคnssnitt fรถr @{domain}", "status.admin_status": "ร–ppna detta inlรคgg i modereringsgrรคnssnittet", @@ -637,10 +713,11 @@ "status.direct": "Nรคmn @{name} privat", "status.direct_indicator": "Privat nรคmning", "status.edit": "Redigera", - "status.edited": "ร„ndrad {date}", + "status.edited": "Senast รคndrad {date}", "status.edited_x_times": "Redigerad {count, plural, one {{count} gรฅng} other {{count} gรฅnger}}", "status.embed": "Bรคdda in", "status.favourite": "Favoritmarkera", + "status.favourites": "{count, plural, one {favorit} other {favoriter}}", "status.filter": "Filtrera detta inlรคgg", "status.filtered": "Filtrerat", "status.hide": "Dรถlj inlรคgg", @@ -661,6 +738,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/szl.json b/app/javascript/mastodon/locales/szl.json index 42164f656b..43cfc78d5b 100644 --- a/app/javascript/mastodon/locales/szl.json +++ b/app/javascript/mastodon/locales/szl.json @@ -34,7 +34,6 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmations.delete.message": "Are you sure you want to delete this status?", - "confirmations.domain_block.confirm": "Hide entire domain", "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.", "embed.instructions": "Embed this status on your website by copying the code below.", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 6210c3d0b1..ac0984293a 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -126,22 +126,17 @@ "compose_form.spoiler.marked": "เฎŽเฎšเฏเฎšเฎฐเฎฟเฎ•เฏเฎ•เฏˆเฎฏเฎฟเฎฉเฏ เฎชเฎฟเฎฉเฏเฎฉเฎพเฎฒเฏ เฎชเฎคเฎฟเฎตเฏ เฎฎเฎฑเฏˆเฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฏเฎŸเฏเฎณเฏเฎณเฎคเฏ", "compose_form.spoiler.unmarked": "เฎชเฎคเฎฟเฎตเฏ เฎฎเฎฑเฏˆเฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฎตเฎฟเฎฒเฏเฎฒเฏˆ", "confirmation_modal.cancel": "เฎฐเฎคเฏเฎคเฏ", - "confirmations.block.block_and_report": "เฎคเฎŸเฏเฎคเฏเฎคเฏเฎชเฏ เฎชเฏเฎ•เฎพเฎฐเฎณเฎฟ", "confirmations.block.confirm": "เฎคเฎŸเฏ", - "confirmations.block.message": "{name}-เฎ เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ•เฎคเฏ เฎคเฎŸเฏเฎ•เฏเฎ• เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "confirmations.delete.confirm": "เฎจเฏ€เฎ•เฏเฎ•เฏ", "confirmations.delete.message": "เฎ‡เฎชเฏเฎชเฎคเฎฟเฎตเฏˆ เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ• เฎจเฏ€เฎ•เฏเฎ• เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "confirmations.delete_list.confirm": "เฎจเฏ€เฎ•เฏเฎ•เฏ", "confirmations.delete_list.message": "เฎ‡เฎชเฏเฎชเฎŸเฏเฎŸเฎฟเฎฏเฎฒเฏˆ เฎจเฎฟเฎฐเฎจเฏเฎคเฎฐเฎฎเฎพเฎ• เฎจเฏ€เฎ•เฏเฎ• เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฏ เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "confirmations.discard_edit_media.confirm": "เฎจเฎฟเฎฐเฎพเฎ•เฎฐเฎฟ", "confirmations.discard_edit_media.message": "เฎšเฏ‡เฎฎเฎฟเฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฎพเฎค เฎฎเฎพเฎฑเฏเฎฑเฎ™เฏเฎ•เฎณเฏ เฎŠเฎŸเฎ• เฎตเฎฟเฎณเฎ•เฏเฎ•เฎฎเฏ เฎ…เฎฒเฏเฎฒเฎคเฏ เฎฎเฏเฎฉเฏเฎฉเฏ‹เฎŸเฏเฎŸเฎคเฏเฎคเฎฟเฎฒเฏ เฎ‰เฎณเฏเฎณเฎคเฏ. เฎ…เฎตเฎฑเฏเฎฑเฏˆ เฎจเฎฟเฎฐเฎพเฎ•เฎฐเฎฟเฎ•เฏเฎ•เฎตเฎพ?", - "confirmations.domain_block.confirm": "เฎฎเฏเฎดเฏ เฎ•เฎณเฎคเฏเฎคเฏˆเฎฏเฏเฎฎเฏ เฎฎเฎฑเฏˆ", "confirmations.domain_block.message": "เฎจเฏ€เฎ™เฏเฎ•เฎณเฏ เฎฎเฏเฎดเฏ {domain} เฎ•เฎณเฎคเฏเฎคเฏˆเฎฏเฏเฎฎเฏ เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ•, เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ•เฎคเฏ เฎคเฎŸเฏเฎ•เฏเฎ• เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ? เฎชเฏ†เฎฐเฏเฎฎเฏเฎชเฎพเฎฒเฏเฎฎเฏ เฎšเฎฟเฎฒ เฎ•เฏเฎฑเฎฟเฎชเฏเฎชเฎฟเฎŸเฏเฎŸ เฎชเฎฏเฎฉเฎฐเฏเฎ•เฎณเฏˆเฎคเฏ เฎคเฎŸเฏเฎชเฏเฎชเฎคเฏ‡ เฎชเฏ‹เฎคเฏเฎฎเฎพเฎฉเฎคเฏ. เฎฎเฏเฎดเฏ เฎ•เฎณเฎคเฏเฎคเฏˆเฎฏเฏเฎฎเฏ เฎคเฎŸเฏเฎคเฏเฎคเฎพเฎฒเฏ, เฎ…เฎคเฎฟเฎฒเฎฟเฎฐเฏเฎจเฏเฎคเฏ เฎตเฎฐเฏเฎฎเฏ เฎŽเฎจเฏเฎคเฎชเฏ เฎชเฎคเฎฟเฎตเฏˆเฎฏเฏเฎฎเฏ เฎ‰เฎ™เฏเฎ•เฎณเฎพเฎฒเฏ เฎ•เฎพเฎฃ เฎฎเฏเฎŸเฎฟเฎฏเฎพเฎคเฏ, เฎฎเฏ‡เฎฒเฏเฎฎเฏ เฎ…เฎชเฏเฎชเฎคเฎฟเฎตเฏเฎ•เฎณเฏ เฎ•เฏเฎฑเฎฟเฎคเฏเฎค เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏเฎฎเฏ เฎ‰เฎ™เฏเฎ•เฎณเฏเฎ•เฏเฎ•เฏ เฎตเฎฐเฎพเฎคเฏ. เฎ…เฎจเฏเฎคเฎ•เฏ เฎ•เฎณเฎคเฏเฎคเฎฟเฎฒเฏ เฎ‡เฎฐเฏเฎ•เฏเฎ•เฏเฎฎเฏ เฎชเฎฟเฎฉเฏเฎคเฏŠเฎŸเฎฐเฏเฎชเฎตเฎฐเฏเฎ•เฎณเฏ เฎ‰เฎ™เฏเฎ•เฎณเฏ เฎชเฎ•เฏเฎ•เฎคเฏเฎคเฎฟเฎฒเฎฟเฎฐเฏเฎจเฏเฎคเฏ เฎจเฏ€เฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฏเฎตเฎพเฎฐเฏเฎ•เฎณเฏ.", "confirmations.logout.confirm": "เฎตเฏ†เฎณเฎฟเฎฏเฏ‡เฎฑเฏ", "confirmations.logout.message": "เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ• เฎจเฏ€เฎ™เฏเฎ•เฎณเฏ เฎตเฏ†เฎณเฎฟเฎฏเฏ‡เฎฑ เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "confirmations.mute.confirm": "เฎ…เฎฎเฏˆเฎคเฎฟเฎฏเฎพเฎ•เฏเฎ•เฏ", - "confirmations.mute.explanation": "เฎ‡เฎจเฏเฎคเฎคเฏ เฎคเฏ‡เฎฐเฏเฎตเฏ เฎ…เฎตเฎฐเฏเฎ•เฎณเฎฟเฎฉเฏ เฎชเฎคเฎฟเฎตเฏเฎ•เฎณเฏˆเฎฏเฏเฎฎเฏ, เฎ…เฎตเฎฐเฏเฎ•เฎณเฏˆเฎ•เฏ เฎ•เฏเฎฑเฎฟเฎชเฏเฎชเฎฟเฎŸเฏเฎฎเฏ เฎชเฎคเฎฟเฎตเฏเฎ•เฎณเฏˆเฎฏเฏเฎฎเฏ เฎฎเฎฑเฏˆเฎคเฏเฎคเฏเฎตเฎฟเฎŸเฏเฎฎเฏ. เฎ†เฎฉเฎพเฎฒเฏ, เฎ…เฎตเฎฐเฏเฎ•เฎณเฎพเฎฒเฏ เฎ‰เฎ™เฏเฎ•เฎณเฏˆเฎชเฏ เฎชเฎฟเฎฉเฏเฎคเฏŠเฎŸเฎฐเฏเฎจเฏเฎคเฏ เฎ‰เฎ™เฏเฎ•เฎณเฏ เฎชเฎคเฎฟเฎตเฏเฎ•เฎณเฏˆเฎ•เฏ เฎ•เฎพเฎฃ เฎฎเฏเฎŸเฎฟเฎฏเฏเฎฎเฏ.", - "confirmations.mute.message": "{name}-เฎ เฎจเฎฟเฎšเฏเฎšเฎฏเฎฎเฎพเฎ• เฎจเฏ€เฎ™เฏเฎ•เฎณเฏ เฎ…เฎฎเฏˆเฎคเฎฟเฎฏเฎพเฎ•เฏเฎ• เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "confirmations.redraft.confirm": "เฎชเฎคเฎฟเฎตเฏˆ เฎจเฏ€เฎ•เฏเฎ•เฎฟ เฎฎเฎฑเฏเฎตเฎฐเฏˆเฎตเฏ เฎšเฏ†เฎฏเฏ", "confirmations.reply.confirm": "เฎฎเฎฑเฏเฎฎเฏŠเฎดเฎฟ", "confirmations.reply.message": "เฎเฎฑเฏเฎ•เฎฉเฎตเฏ‡ เฎ’เฎฐเฏ เฎชเฎคเฎฟเฎตเฏ เฎŽเฎดเฏเฎคเฎชเฏเฎชเฎŸเฏเฎŸเฏเฎ•เฏเฎ•เฏŠเฎฃเฏเฎŸเฎฟเฎฐเฏเฎ•เฏเฎ•เฎฟเฎฑเฎคเฏ. เฎ‡เฎชเฏเฎชเฏŠเฎดเฏเฎคเฏ เฎชเฎคเฎฟเฎฒเฏ เฎŽเฎดเฏเฎค เฎฎเฏเฎฉเฏˆเฎจเฏเฎคเฎพเฎฒเฏ เฎ…เฎคเฏ เฎ…เฎดเฎฟเฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฏเฎฎเฏ. เฎชเฎฐเฎตเฎพเฎฏเฎฟเฎฒเฏเฎฒเฏˆเฎฏเฎพ?", @@ -211,7 +206,6 @@ "hashtag.column_settings.tag_mode.any": "เฎ‡เฎตเฎฑเฏเฎฑเฎฟเฎฒเฏ เฎŽเฎตเฏˆเฎฏเฏ‡เฎฉเฏเฎฎเฏ", "hashtag.column_settings.tag_mode.none": "เฎ‡เฎตเฎฑเฏเฎฑเฎฟเฎฒเฏ เฎเฎคเฏเฎฎเฎฟเฎฒเฏเฎฒเฏˆ", "hashtag.column_settings.tag_toggle": "เฎ‡เฎจเฏเฎค เฎจเฏ†เฎŸเฏเฎตเฎฐเฎฟเฎšเฏˆเฎฏเฎฟเฎฒเฏ เฎ•เฏ‚เฎŸเฏเฎคเฎฒเฏ เฎšเฎฟเฎŸเฏเฎŸเฏˆเฎ•เฎณเฏˆเฎšเฏ เฎšเฏ‡เฎฐเฏเฎ•เฏเฎ•เฎตเฏเฎฎเฏ", - "home.column_settings.basic": "เฎ…เฎŸเฎฟเฎชเฏเฎชเฎŸเฏˆเฎฏเฎพเฎฉเฎตเฏˆ", "home.column_settings.show_reblogs": "เฎชเฎ•เฎฟเฎฐเฏเฎตเฏเฎ•เฎณเฏˆเฎ•เฏ เฎ•เฎพเฎฃเฏเฎชเฎฟ", "home.column_settings.show_replies": "เฎฎเฎฑเฏเฎฎเฏŠเฎดเฎฟเฎ•เฎณเฏˆเฎ•เฏ เฎ•เฎพเฎฃเฏเฎชเฎฟ", "home.hide_announcements": "เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏˆ เฎฎเฎฑเฏˆ", @@ -265,7 +259,6 @@ "lists.subheading": "เฎ‰เฎ™เฏเฎ•เฎณเฏ เฎชเฎŸเฏเฎŸเฎฟเฎฏเฎฒเฏเฎ•เฎณเฏ", "load_pending": "{count, plural,one {# เฎชเฏเฎคเฎฟเฎฏเฎคเฏ}other {# เฎชเฏเฎคเฎฟเฎฏเฎตเฏˆ}}", "media_gallery.toggle_visible": "เฎจเฎฟเฎฒเฏˆเฎฎเฎพเฎฑเฏเฎฑเฏ เฎคเฏ†เฎฐเฎฟเฎฏเฏเฎฎเฏ", - "mute_modal.hide_notifications": "เฎ‡เฎจเฏเฎค เฎชเฎฏเฎฉเฎฐเฎฟเฎฉเฏ เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏˆ เฎฎเฎฑเฏˆเฎ•เฏเฎ•เฎตเฎพ?", "navigation_bar.blocks": "เฎคเฎŸเฏเฎ•เฏเฎ•เฎชเฏเฎชเฎŸเฏเฎŸ เฎชเฎฏเฎฉเฎฐเฏเฎ•เฎณเฏ", "navigation_bar.bookmarks": "เฎ…เฎŸเฏˆเฎฏเฎพเฎณเฎ•เฏเฎ•เฏเฎฑเฎฟเฎ•เฎณเฏ", "navigation_bar.community_timeline": "เฎ‰เฎณเฏเฎณเฏ‚เฎฐเฏ เฎ•เฎพเฎฒเฎ•เฏเฎ•เฏ†เฎŸเฏ", @@ -293,8 +286,6 @@ "notifications.clear": "เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏˆ เฎ…เฎดเฎฟเฎ•เฏเฎ•เฎตเฏเฎฎเฏ", "notifications.clear_confirmation": "เฎ‰เฎ™เฏเฎ•เฎณเฏ เฎŽเฎฒเฏเฎฒเฎพ เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏˆเฎฏเฏเฎฎเฏ เฎจเฎฟเฎฐเฎจเฏเฎคเฎฐเฎฎเฎพเฎ• เฎ…เฎดเฎฟเฎ•เฏเฎ• เฎตเฎฟเฎฐเฏเฎฎเฏเฎชเฏเฎ•เฎฟเฎฑเฏ€เฎฐเฏเฎ•เฎณเฎพ?", "notifications.column_settings.alert": "เฎŸเฏ†เฎธเฏเฎ•เฏเฎŸเฎพเฎชเฏ เฎ…เฎฑเฎฟเฎตเฎฟเฎชเฏเฎชเฏเฎ•เฎณเฏ", - "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/tai.json b/app/javascript/mastodon/locales/tai.json index b1a242c751..825cfb93bd 100644 --- a/app/javascript/mastodon/locales/tai.json +++ b/app/javascript/mastodon/locales/tai.json @@ -2,25 +2,24 @@ "about.blocks": "Siลซ kuรกn-tsรจ รช su-hฤu-khรฌ", "about.contact": "Liรขn-loฬk:", "about.disclaimer": "Ling-khรญ-tshiลซnn sฤซ tsiฬt-รช khai-guรขn nล„g-thรฉ๏ผŒi รช siong-phiau sฤซ Mastodon gGmbH.", - "account.badges.bot": "Bot", - "account.cancel_follow_request": "Withdraw follow request", + "account.badges.bot": "Tsลซ-tลng-รช", + "account.cancel_follow_request": "Mร i-koh tui-tsong", "account.media": "Mรปi-thรฉ", "account.mention": "Thรช-khรญ @{name}", - "account.posts": "Toots", - "account.posts_with_replies": "Toots and replies", - "account.requested": "Awaiting approval", - "account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}", - "account_note.placeholder": "Click to add a note", - "column.pins": "Pinned toot", - "community.column_settings.media_only": "Media only", - "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", - "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", - "compose_form.placeholder": "What is on your mind?", - "compose_form.publish_form": "Publish", - "compose_form.spoiler.marked": "Text is hidden behind warning", - "compose_form.spoiler.unmarked": "Text is not hidden", - "confirmations.delete.message": "Are you sure you want to delete this status?", - "confirmations.domain_block.confirm": "Hide entire domain", + "account.posts": "Huah-siann", + "account.posts_with_replies": "Huah-siann kah huรช-รฌng", + "account.requested": "Tรกn-thฤi phue-tsรบn", + "account.statuses_counter": "{count, plural, one {{counter} Huah-siann} other {{counter} Huah-siann}}", + "account_note.placeholder": "Tiรกm tsiฬt-ฤ“ ka-thiam pฤซ-tsรน", + "column.pins": "Tah thรขu-tsรฎng รช huah-siann", + "community.column_settings.media_only": "Kan-na muรฎ-thรฉ", + "compose_form.encryption_warning": "Tฤซ Mastodon tah huah-siann mฬ„-sฤซ tuan-tuรฌ-tuan ka-pรฌ รช. Mฬ„-thang tฤซ Mastodon hun-hiรณng jฤซm-hรด bรญn-kรกm รช tsลซ-sรฌn.", + "compose_form.hashtag_warning": "Tsit-รช huah-siann in-uฤซ mฬ„-sฤซ kong-khai รช, sรณo-รญ buฤ“ tฤซ jฤซm-hรด tsรบ-tรช piau-tshiam hiรกn-sฤซ. Kan-na kong-khai รช huah-siann ฤ“-tร ng hลo tsรบ-tรช piau-tshiam tshรข-tshuฤ“.", + "compose_form.placeholder": "Lรญ teh siลซnn siรกnn?", + "compose_form.publish_form": "Huah--tshut-khรฌ", + "compose_form.spoiler.marked": "รŽ-tรป luฤ“-iรดng kรญng-kรฒ", + "compose_form.spoiler.unmarked": "Tsing-ka luฤ“-iรดng kรญng-kรฒ", + "confirmations.delete.message": "Lรญ kรกm bueh thรขi-tiฤu tsiฬt-ฤ“ huah-siann?", "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.", "embed.instructions": "Embed this status on your website by copying the code below.", @@ -46,7 +45,7 @@ "keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.notifications": "to open notifications column", - "keyboard_shortcuts.open_media": "to open media", + "keyboard_shortcuts.open_media": "Khui muรฎ-thรฉ", "keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.reply": "to reply", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index 24a67247c0..284102c381 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -70,15 +70,12 @@ "compose_form.spoiler.unmarked": "เฐชเฐพเฐ เฑเฐฏเฐ‚ เฐฆเฐพเฐšเฐฌเฐกเฐฒเฑ‡เฐฆเฑ", "confirmation_modal.cancel": "เฐฐเฐฆเฑเฐฆเฑ เฐšเฑ†เฐฏเฑเฐฏเฐฟ", "confirmations.block.confirm": "เฐฌเฑเฐฒเฐพเฐ•เฑ เฐšเฑ‡เฐฏเฐฟ", - "confirmations.block.message": "เฐฎเฑ€เฐฐเฑ เฐ–เฐšเฑเฐšเฐฟเฐคเฐ‚เฐ—เฐพ {name}เฐจเฐฟ เฐฌเฑเฐฒเฐพเฐ•เฑ เฐšเฑ‡เฐฏเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", "confirmations.delete.confirm": "เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฑ", "confirmations.delete.message": "เฐฎเฑ€เฐฐเฑ เฐ–เฐšเฑเฐšเฐฟเฐคเฐ‚เฐ—เฐพ เฐˆ เฐธเฑเฐŸเฑ‡เฐŸเฐธเฑ เฐจเฐฟ เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", "confirmations.delete_list.confirm": "เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฑ", "confirmations.delete_list.message": "เฐฎเฑ€เฐฐเฑ เฐ–เฐšเฑเฐšเฐฟเฐคเฐ‚เฐ—เฐพ เฐˆ เฐœเฐพเฐฌเฐฟเฐคเฐพเฐจเฑ เฐถเฐพเฐถเฑเฐตเฐคเฐ‚เฐ—เฐพ เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", - "confirmations.domain_block.confirm": "เฐฎเฑŠเฐคเฑเฐคเฐ‚ เฐกเฑŠเฐฎเฑˆเฐจเฑเฐจเฑ เฐฆเฐพเฐšเฑ", "confirmations.domain_block.message": "เฐฎเฑ€เฐฐเฑ เฐจเฐฟเฐœเฐ‚เฐ—เฐพ เฐจเฐฟเฐœเฐ‚เฐ—เฐพ เฐฎเฑŠเฐคเฑเฐคเฐ‚ {domain} เฐจเฐฟ เฐฌเฑเฐฒเฐพเฐ•เฑ เฐšเฑ‡เฐฏเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ? เฐšเฐพเฐฒเฐพ เฐธเฐ‚เฐฆเฐฐเฑเฐญเฐพเฐฒเฐฒเฑ‹ เฐ•เฑŠเฐจเฑเฐจเฐฟ เฐฒเฐ•เฑเฐทเฑเฐฏเฐ‚เฐ—เฐพ เฐ‰เฐจเฑเฐจ เฐฌเฑเฐฒเฐพเฐ•เฑเฐธเฑ เฐฒเฑ‡เฐฆเฐพ เฐฎเฑเฐฏเฑ‚เฐŸเฑเฐธเฑ เฐธเฐฐเฐฟเฐชเฑ‹เฐคเฐพเฐฏเฐฟ เฐฎเฐฐเฐฟเฐฏเฑ เฐ‰เฐคเฑเฐคเฐฎเฐฎเฑˆเฐจเฐตเฐฟ. เฐฎเฑ€เฐฐเฑ เฐ† เฐกเฑŠเฐฎเฑˆเฐจเฑ เฐจเฑเฐ‚เฐกเฐฟ เฐ•เฐ‚เฐŸเฑ†เฐ‚เฐŸเฑเฐจเฑ เฐ เฐชเฑเฐฐเฐœเฐพ เฐ•เฐพเฐฒเฐ•เฑเฐฐเฐฎเฐพเฐฒเฐฒเฑ‹ เฐฒเฑ‡เฐฆเฐพ เฐฎเฑ€ เฐจเฑ‹เฐŸเฐฟเฐซเฐฟเฐ•เฑ‡เฐทเฐจเฑเฐฒเฐฒเฑ‹ เฐšเฑ‚เฐกเฐฒเฑ‡เฐฐเฑ. เฐ† เฐกเฑŠเฐฎเฑˆเฐจเฑ เฐจเฑเฐ‚เฐกเฐฟ เฐฎเฑ€ เฐ…เฐจเฑเฐšเฐฐเฑเฐฒเฑ เฐคเฑ€เฐธเฐฟเฐตเฑ‡เฐฏเฐฌเฐกเฐคเฐพเฐฐเฑ.", "confirmations.mute.confirm": "เฐฎเฑเฐฏเฑ‚เฐŸเฑ เฐšเฑ‡เฐฏเฐฟ", - "confirmations.mute.message": "{name}เฐจเฑ เฐฎเฑ€เฐฐเฑ เฐ–เฐšเฑเฐšเฐฟเฐคเฐ‚เฐ—เฐพ เฐฎเฑเฐฏเฑ‚เฐŸเฑ เฐšเฑ‡เฐฏเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", "confirmations.redraft.confirm": "เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฑ & เฐคเฐฟเฐฐเฐ—เฐฐเฐพเฐฏเฑ", "confirmations.reply.confirm": "เฐชเฑเฐฐเฐคเฑเฐฏเฑเฐคเฑเฐคเฐฐเฐฎเฐฟเฐตเฑเฐตเฑ", "confirmations.reply.message": "เฐ‡เฐชเฑเฐชเฑเฐกเฑ‡ เฐชเฑเฐฐเฐคเฑเฐฏเฑเฐคเฑเฐคเฐฐเฐ‚ เฐ‡เฐธเฑเฐคเฑ‡ เฐฎเฑ€เฐฐเฑ เฐชเฑเฐฐเฐธเฑเฐคเฑเฐคเฐ‚ เฐตเฑเฐฐเฐพเฐธเฑเฐคเฑเฐจเฑเฐจ เฐธเฐ‚เฐฆเฑ‡เฐถเฐ‚ เฐคเฐฟเฐฐเฐ—เฐฐเฐพเฐฏเฐฌเฐกเฑเฐคเฑเฐ‚เฐฆเฐฟ. เฐฎเฑ€เฐฐเฑ เฐ–เฐšเฑเฐšเฐฟเฐคเฐ‚เฐ—เฐพ เฐ•เฑŠเฐจเฐธเฐพเฐ—เฐฟเฐ‚เฐšเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", @@ -127,7 +124,6 @@ "hashtag.column_settings.tag_mode.any": "เฐตเฑ€เฐŸเฐฟเฐฒเฑ‹ เฐเฐตเฑˆเฐจเฐพ", "hashtag.column_settings.tag_mode.none": "เฐ‡เฐตเฑ‡เฐตเฑ€ เฐ•เฐพเฐตเฑ", "hashtag.column_settings.tag_toggle": "เฐˆ เฐจเฐฟเฐฒเฑเฐตเฑ เฐตเฐฐเฑเฐธเฐฒเฑ‹ เฐฎเฐฐเฐฟเฐ•เฑŠเฐจเฑเฐจเฐฟ เฐŸเฑเฐฏเฐพเฐ—เฑเฐฒเฐจเฑ เฐšเฑ‡เฐฐเฑเฐšเฐ‚เฐกเฐฟ", - "home.column_settings.basic": "เฐชเฑเฐฐเฐพเฐฅเฐฎเฐฟเฐ•", "home.column_settings.show_reblogs": "เฐฌเฑ‚เฐธเฑเฐŸเฑ เฐฒเฐจเฑ เฐšเฑ‚เฐชเฐฟเฐ‚เฐšเฑ", "home.column_settings.show_replies": "เฐชเฑเฐฐเฐคเฑเฐฏเฑเฐคเฑเฐคเฐฐเฐพเฐฒเฐจเฑ เฐšเฑ‚เฐชเฐฟเฐ‚เฐšเฑ", "keyboard_shortcuts.back": "เฐตเฑ†เฐจเฐ•เฑเฐ•เฐฟ เฐคเฐฟเฐฐเฐฟเฐ—เฐฟ เฐตเฑ†เฐณเฑเฐณเฐกเฐพเฐจเฐฟเฐ•เฐฟ", @@ -174,7 +170,6 @@ "lists.search": "เฐฎเฑ€เฐฐเฑ เฐ…เฐจเฑเฐธเฐฐเฐฟเฐ‚เฐšเฑ‡ เฐตเฑเฐฏเฐ•เฑเฐคเฑเฐฒเฐฒเฑ‹ เฐถเฑ‹เฐงเฐฟเฐ‚เฐšเฐ‚เฐกเฐฟ", "lists.subheading": "เฐฎเฑ€ เฐœเฐพเฐฌเฐฟเฐคเฐพเฐฒเฑ", "media_gallery.toggle_visible": "เฐฆเฑƒเฐถเฑเฐฏเฐฎเฐพเฐจเฐคเฐจเฑ เฐŸเฑ‹เฐ—เฑเฐฒเฑ เฐšเฑ‡เฐฏเฐ‚เฐกเฐฟ", - "mute_modal.hide_notifications": "เฐˆ เฐตเฐฟเฐจเฐฟเฐฏเฑ‹เฐ—เฐฆเฐพเฐฐเฑ เฐจเฑเฐ‚เฐกเฐฟ เฐจเฑ‹เฐŸเฐฟเฐซเฐฟเฐ•เฑ‡เฐทเฐจเฑเฐฒเฐจเฑ เฐฆเฐพเฐšเฐพเฐฒเฐพ?", "navigation_bar.blocks": "เฐฌเฑเฐฒเฐพเฐ•เฑ เฐšเฑ‡เฐฏเฐฌเฐกเฐฟเฐจ เฐตเฐฟเฐจเฐฟเฐฏเฑ‹เฐ—เฐฆเฐพเฐฐเฑเฐฒเฑ", "navigation_bar.community_timeline": "เฐธเฑเฐฅเฐพเฐจเฐฟเฐ• เฐ•เฐพเฐฒเฐ•เฑเฐฐเฐฎเฐ‚", "navigation_bar.compose": "เฐ•เฑŠเฐคเฑเฐค เฐŸเฑ‚เฐŸเฑเฐจเฑ เฐฐเฐพเฐฏเฐ‚เฐกเฐฟ", @@ -198,8 +193,6 @@ "notifications.clear": "เฐชเฑเฐฐเฐ•เฐŸเฐจเฐฒเฐจเฑ เฐคเฑเฐกเฐฟเฐšเฐฟเฐตเฑ‡เฐฏเฑ", "notifications.clear_confirmation": "เฐฎเฑ€เฐฐเฑ เฐฎเฑ€ เฐ…เฐจเฑเฐจเฐฟ เฐจเฑ‹เฐŸเฐฟเฐซเฐฟเฐ•เฑ‡เฐทเฐจเฑเฐฒเฐจเฑ เฐถเฐพเฐถเฑเฐตเฐคเฐ‚เฐ—เฐพ เฐคเฑŠเฐฒเฐ—เฐฟเฐ‚เฐšเฐพเฐฒเฐจเฑเฐ•เฑเฐ‚เฐŸเฑเฐจเฑเฐจเฐพเฐฐเฐพ?", "notifications.column_settings.alert": "เฐกเฑ†เฐธเฑเฐ•เฑเฐŸเฐพเฐชเฑ เฐจเฑ‹เฐŸเฐฟเฐซเฐฟเฐ•เฑ‡เฐทเฐจเฑเฐฒเฑ", - "notifications.column_settings.filter_bar.advanced": "เฐ…เฐจเฑเฐจเฐฟ เฐตเฐฟเฐญเฐพเฐ—เฐพเฐฒเฐจเฑ เฐšเฑ‚เฐชเฐฟเฐ‚เฐšเฑ", - "notifications.column_settings.filter_bar.category": "เฐ•เฑเฐตเฐฟเฐ•เฑ เฐซเฐฟเฐฒเฑเฐŸเฐฐเฑ เฐฌเฐพเฐฐเฑ", "notifications.column_settings.follow": "เฐ•เฑเฐฐเฑŠเฐคเฑเฐค เฐ…เฐจเฑเฐšเฐฐเฑเฐฒเฑ:", "notifications.column_settings.mention": "เฐชเฑเฐฐเฐธเฑเฐคเฐพเฐตเฐจเฐฒเฑ:", "notifications.column_settings.poll": "เฐŽเฐจเฑเฐจเฐฟเฐ• เฐซเฐฒเฐฟเฐคเฐพเฐฒเฑ:", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index e0aa072a77..64abb394bf 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -1,5 +1,5 @@ { - "about.blocks": "เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธ—เธตเนˆเธกเธตเธเธฒเธฃเธ„เธงเธšเธ„เธธเธก", + "about.blocks": "เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธ—เธตเนˆเธกเธตเธเธฒเธฃเธเธฅเธฑเนˆเธ™เธเธฃเธญเธ‡", "about.contact": "เธ•เธดเธ”เธ•เนˆเธญ:", "about.disclaimer": "Mastodon เน€เธ›เน‡เธ™เธ‹เธญเธŸเธ•เนŒเนเธงเธฃเนŒเน€เธชเธฃเธต เน‚เธญเน€เธžเธ™เธ‹เธญเธฃเนŒเธช เนเธฅเธฐเน€เธ„เธฃเธทเนˆเธญเธ‡เธซเธกเธฒเธขเธเธฒเธฃเธ„เน‰เธฒเธ‚เธญเธ‡ Mastodon gGmbH", "about.domain_blocks.no_reason_available": "เน€เธซเธ•เธธเธœเธฅเน„เธกเนˆเธžเธฃเน‰เธญเธกเนƒเธŠเน‰เธ‡เธฒเธ™", @@ -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": "เน„เธกเนˆเธชเธฒเธกเธฒเธฃเธ–เนเธชเธ”เธ‡เธœเธฅเธซเธ™เน‰เธฒเธ—เธตเนˆเธ‚เธญ เธ‚เน‰เธญเธœเธดเธ”เธžเธฅเธฒเธ”เธญเธฒเธˆเน€เธ›เน‡เธ™เน€เธžเธฃเธฒเธฐเธ‚เน‰เธญเธšเธเธžเธฃเนˆเธญเธ‡เนƒเธ™เน‚เธ„เน‰เธ”เธ‚เธญเธ‡เน€เธฃเธฒ เธซเธฃเธทเธญเธ›เธฑเธเธซเธฒเธ„เธงเธฒเธกเน€เธ‚เน‰เธฒเธเธฑเธ™เน„เธ”เน‰เธ‚เธญเธ‡เน€เธšเธฃเธฒเธงเนŒเน€เธ‹เธญเธฃเนŒ", @@ -150,7 +158,7 @@ "compose_form.poll.option_placeholder": "เธ•เธฑเธงเน€เธฅเธทเธญเธ {number}", "compose_form.poll.single": "เน€เธฅเธทเธญเธเธญเธขเนˆเธฒเธ‡เนƒเธ”เธญเธขเนˆเธฒเธ‡เธซเธ™เธถเนˆเธ‡", "compose_form.poll.switch_to_multiple": "เน€เธ›เธฅเธตเนˆเธขเธ™เธเธฒเธฃเธชเธณเธฃเธงเธˆเธ„เธงเธฒเธกเธ„เธดเธ”เน€เธซเน‡เธ™เน€เธ›เน‡เธ™เธญเธ™เธธเธเธฒเธ•เธซเธฅเธฒเธขเธ•เธฑเธงเน€เธฅเธทเธญเธ", - "compose_form.poll.switch_to_single": "เน€เธ›เธฅเธตเนˆเธขเธ™เธเธฒเธฃเธชเธณเธฃเธงเธˆเธ„เธงเธฒเธกเธ„เธดเธ”เน€เธซเน‡เธ™เน€เธ›เน‡เธ™เธญเธ™เธธเธเธฒเธ•เธ•เธฑเธงเน€เธฅเธทเธญเธเน€เธ”เธตเนˆเธขเธง", + "compose_form.poll.switch_to_single": "เน€เธ›เธฅเธตเนˆเธขเธ™เธเธฒเธฃเธชเธณเธฃเธงเธˆเธ„เธงเธฒเธกเธ„เธดเธ”เน€เธซเน‡เธ™เน€เธ›เน‡เธ™เธญเธ™เธธเธเธฒเธ•เธ•เธฑเธงเน€เธฅเธทเธญเธเน€เธ”เธตเธขเธง", "compose_form.poll.type": "เธฅเธฑเธเธฉเธ“เธฐ", "compose_form.publish": "เน‚เธžเธชเธ•เนŒ", "compose_form.publish_form": "เน‚เธžเธชเธ•เนŒเนƒเธซเธกเนˆ", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "เน€เธžเธดเนˆเธกเธ„เธณเน€เธ•เธทเธญเธ™เน€เธ™เธทเน‰เธญเธซเธฒ", "compose_form.spoiler_placeholder": "เธ„เธณเน€เธ•เธทเธญเธ™เน€เธ™เธทเน‰เธญเธซเธฒ (เน„เธกเนˆเธˆเธณเน€เธ›เน‡เธ™)", "confirmation_modal.cancel": "เธขเธเน€เธฅเธดเธ", - "confirmations.block.block_and_report": "เธ›เธดเธ”เธเธฑเน‰เธ™เนเธฅเน‰เธงเธฃเธฒเธขเธ‡เธฒเธ™", "confirmations.block.confirm": "เธ›เธดเธ”เธเธฑเน‰เธ™", - "confirmations.block.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธ›เธดเธ”เธเธฑเน‰เธ™ {name}?", "confirmations.cancel_follow_request.confirm": "เธ–เธญเธ™เธ„เธณเธ‚เธญ", "confirmations.cancel_follow_request.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธ–เธญเธ™เธ„เธณเธ‚เธญเน€เธžเธทเนˆเธญเธ•เธดเธ”เธ•เธฒเธก {name} เธ‚เธญเธ‡เธ„เธธเธ“?", "confirmations.delete.confirm": "เธฅเธš", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธฅเธšเธฃเธฒเธขเธเธฒเธฃเธ™เธตเน‰เธญเธขเนˆเธฒเธ‡เธ–เธฒเธงเธฃ?", "confirmations.discard_edit_media.confirm": "เธฅเธฐเธ—เธดเน‰เธ‡", "confirmations.discard_edit_media.message": "เธ„เธธเธ“เธกเธตเธเธฒเธฃเน€เธ›เธฅเธตเนˆเธขเธ™เนเธ›เธฅเธ‡เธ„เธณเธญเธ˜เธดเธšเธฒเธขเธซเธฃเธทเธญเธ•เธฑเธงเธญเธขเนˆเธฒเธ‡เธชเธทเนˆเธญเธ—เธตเนˆเธขเธฑเธ‡เน„เธกเนˆเน„เธ”เน‰เธšเธฑเธ™เธ—เธถเธ เธฅเธฐเธ—เธดเน‰เธ‡เธเธฒเธฃเน€เธ›เธฅเธตเนˆเธขเธ™เนเธ›เธฅเธ‡เน€เธซเธฅเนˆเธฒเธ™เธฑเน‰เธ™เธ•เนˆเธญเน„เธ›?", - "confirmations.domain_block.confirm": "เธ›เธดเธ”เธเธฑเน‰เธ™เธ—เธฑเน‰เธ‡เน‚เธ”เน€เธกเธ™", + "confirmations.domain_block.confirm": "เธ›เธดเธ”เธเธฑเน‰เธ™เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒ", "confirmations.domain_block.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธˆเธฃเธดเธ‡ เน† เธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธ›เธดเธ”เธเธฑเน‰เธ™เธ—เธฑเน‰เธ‡ {domain}? เนƒเธ™เธเธฃเธ“เธตเธชเนˆเธงเธ™เนƒเธซเธเนˆ เธเธฒเธฃเธ›เธดเธ”เธเธฑเน‰เธ™เธซเธฃเธทเธญเธเธฒเธฃเธ‹เนˆเธญเธ™เนเธšเธšเธเธณเธซเธ™เธ”เน€เธ›เน‰เธฒเธซเธกเธฒเธขเน„เธกเนˆเธเธตเนˆเธฃเธฒเธขเธเธฒเธฃเธ™เธฑเน‰เธ™เน€เธžเธตเธขเธ‡เธžเธญเนเธฅเธฐเน€เธ›เน‡เธ™เธ—เธตเนˆเธ™เธดเธขเธก เธ„เธธเธ“เธˆเธฐเน„เธกเนˆเน€เธซเน‡เธ™เน€เธ™เธทเน‰เธญเธซเธฒเธˆเธฒเธเน‚เธ”เน€เธกเธ™เธ™เธฑเน‰เธ™เนƒเธ™เน€เธชเน‰เธ™เน€เธงเธฅเธฒเธชเธฒเธ˜เธฒเธฃเธ“เธฐเนƒเธ” เน† เธซเธฃเธทเธญเธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธ‚เธญเธ‡เธ„เธธเธ“ เธˆเธฐเน€เธญเธฒเธœเธนเน‰เธ•เธดเธ”เธ•เธฒเธกเธ‚เธญเธ‡เธ„เธธเธ“เธˆเธฒเธเน‚เธ”เน€เธกเธ™เธ™เธฑเน‰เธ™เธญเธญเธ", "confirmations.edit.confirm": "เนเธเน‰เน„เธ‚", "confirmations.edit.message": "เธเธฒเธฃเนเธเน‰เน„เธ‚เนƒเธ™เธ•เธญเธ™เธ™เธตเน‰เธˆเธฐเน€เธ‚เธตเธขเธ™เธ—เธฑเธšเธ‚เน‰เธญเธ„เธงเธฒเธกเธ—เธตเนˆเธ„เธธเธ“เธเธณเธฅเธฑเธ‡เน€เธ‚เธตเธขเธ™เนƒเธ™เธ›เธฑเธˆเธˆเธธเธšเธฑเธ™ เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธ”เธณเน€เธ™เธดเธ™เธเธฒเธฃเธ•เนˆเธญ?", "confirmations.logout.confirm": "เธญเธญเธเธˆเธฒเธเธฃเธฐเธšเธš", "confirmations.logout.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธญเธญเธเธˆเธฒเธเธฃเธฐเธšเธš?", "confirmations.mute.confirm": "เธ‹เนˆเธญเธ™", - "confirmations.mute.explanation": "เธ™เธตเนˆเธˆเธฐเธ‹เนˆเธญเธ™เน‚เธžเธชเธ•เนŒเธˆเธฒเธเน€เธ‚เธฒเนเธฅเธฐเน‚เธžเธชเธ•เนŒเธ—เธตเนˆเธเธฅเนˆเธฒเธงเธ–เธถเธ‡เน€เธ‚เธฒ เนเธ•เนˆเธˆเธฐเธขเธฑเธ‡เธ„เธ‡เธญเธ™เธธเธเธฒเธ•เนƒเธซเน‰เน€เธ‚เธฒเน€เธซเน‡เธ™เน‚เธžเธชเธ•เนŒเธ‚เธญเธ‡เธ„เธธเธ“เนเธฅเธฐเธ•เธดเธ”เธ•เธฒเธกเธ„เธธเธ“", - "confirmations.mute.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธ‹เนˆเธญเธ™ {name}?", "confirmations.redraft.confirm": "เธฅเธšเนเธฅเน‰เธงเธฃเนˆเธฒเธ‡เนƒเธซเธกเนˆ", "confirmations.redraft.message": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธฅเธšเน‚เธžเธชเธ•เนŒเธ™เธตเน‰เนเธฅเน‰เธงเธฃเนˆเธฒเธ‡เน‚เธžเธชเธ•เนŒเนƒเธซเธกเนˆ? เธฃเธฒเธขเธเธฒเธฃเน‚เธ›เธฃเธ”เนเธฅเธฐเธเธฒเธฃเธ”เธฑเธ™เธˆเธฐเธชเธนเธเธซเธฒเธข เนเธฅเธฐเธเธฒเธฃเธ•เธญเธšเธเธฅเธฑเธšเน‚เธžเธชเธ•เนŒเธ”เธฑเน‰เธ‡เน€เธ”เธดเธกเธˆเธฐเน„เธกเนˆเธกเธตเธ„เธงเธฒเธกเน€เธเธตเนˆเธขเธงเธžเธฑเธ™", "confirmations.reply.confirm": "เธ•เธญเธšเธเธฅเธฑเธš", @@ -205,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": "เธเธดเธˆเธเธฃเธฃเธก", @@ -241,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": "เน€เธ™เธทเนˆเธญเธ‡เธˆเธฒเธเธ‚เน‰เธญเธšเธเธžเธฃเนˆเธญเธ‡เนƒเธ™เน‚เธ„เน‰เธ”เธ‚เธญเธ‡เน€เธฃเธฒเธซเธฃเธทเธญเธ›เธฑเธเธซเธฒเธ„เธงเธฒเธกเน€เธ‚เน‰เธฒเธเธฑเธ™เน„เธ”เน‰เธ‚เธญเธ‡เน€เธšเธฃเธฒเธงเนŒเน€เธ‹เธญเธฃเนŒ เธˆเธถเธ‡เน„เธกเนˆเธชเธฒเธกเธฒเธฃเธ–เนเธชเธ”เธ‡เธซเธ™เน‰เธฒเธ™เธตเน‰เน„เธ”เน‰เธญเธขเนˆเธฒเธ‡เธ–เธนเธเธ•เน‰เธญเธ‡", @@ -271,16 +297,28 @@ "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": "เธ—เธฑเน‰เธ‡เธซเธกเธ”", "firehose.local": "เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธ™เธตเน‰", "firehose.remote": "เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธญเธทเนˆเธ™ เน†", "follow_request.authorize": "เธญเธ™เธธเธเธฒเธ•", "follow_request.reject": "เธ›เธเธดเน€เธชเธ˜", "follow_requests.unlocked_explanation": "เนเธกเน‰เธงเนˆเธฒเน„เธกเนˆเธกเธตเธเธฒเธฃเธฅเน‡เธญเธ„เธšเธฑเธเธŠเธตเธ‚เธญเธ‡เธ„เธธเธ“ เธžเธ™เธฑเธเธ‡เธฒเธ™เธ‚เธญเธ‡ {domain} เธ„เธดเธ”เธงเนˆเธฒเธ„เธธเธ“เธญเธฒเธˆเธ•เน‰เธญเธ‡เธเธฒเธฃเธ•เธฃเธงเธˆเธ—เธฒเธ™เธ„เธณเธ‚เธญเธ•เธดเธ”เธ•เธฒเธกเธˆเธฒเธเธšเธฑเธเธŠเธตเน€เธซเธฅเนˆเธฒเธ™เธตเน‰เธ”เน‰เธงเธขเธ•เธ™เน€เธญเธ‡", - "follow_suggestions.curated_suggestion": "เธ„เธฑเธ”เธชเธฃเธฃเน‚เธ”เธขเธšเธฃเธฃเธ“เธฒเธ˜เธดเธเธฒเธฃ", + "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}", + "follow_suggestions.hints.most_interactions": "เน‚เธ›เธฃเน„เธŸเธฅเนŒเธ™เธตเน‰เน€เธžเธดเนˆเธ‡เน„เธ”เน‰เธฃเธฑเธšเธ„เธงเธฒเธกเธชเธ™เนƒเธˆเธญเธขเนˆเธฒเธ‡เธกเธฒเธเนƒเธ™ {domain}", + "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": "เนเธฎเธŠเนเธ—เน‡เธเธ—เธตเนˆเธ•เธดเธ”เธ•เธฒเธก", @@ -309,7 +347,6 @@ "hashtag.follow": "เธ•เธดเธ”เธ•เธฒเธกเนเธฎเธŠเนเธ—เน‡เธ", "hashtag.unfollow": "เน€เธฅเธดเธเธ•เธดเธ”เธ•เธฒเธกเนเธฎเธŠเนเธ—เน‡เธ", "hashtags.and_other": "โ€ฆเนเธฅเธฐเธญเธตเธ {count, plural, other {# เน€เธžเธดเนˆเธกเน€เธ•เธดเธก}}", - "home.column_settings.basic": "เธžเธทเน‰เธ™เธเธฒเธ™", "home.column_settings.show_reblogs": "เนเธชเธ”เธ‡เธเธฒเธฃเธ”เธฑเธ™", "home.column_settings.show_replies": "เนเธชเธ”เธ‡เธเธฒเธฃเธ•เธญเธšเธเธฅเธฑเธš", "home.hide_announcements": "เธ‹เนˆเธญเธ™เธ›เธฃเธฐเธเธฒเธจ", @@ -375,8 +412,10 @@ "lightbox.next": "เธ–เธฑเธ”เน„เธ›", "lightbox.previous": "เธเนˆเธญเธ™เธซเธ™เน‰เธฒ", "limited_account_hint.action": "เนเธชเธ”เธ‡เน‚เธ›เธฃเน„เธŸเธฅเนŒเธ•เนˆเธญเน„เธ›", - "limited_account_hint.title": "เธกเธตเธเธฒเธฃเธ‹เนˆเธญเธ™เน‚เธ›เธฃเน„เธŸเธฅเนŒเธ™เธตเน‰เน‚เธ”เธขเธœเธนเน‰เธ„เธงเธšเธ„เธธเธกเธ‚เธญเธ‡ {domain}", + "limited_account_hint.title": "เธกเธตเธเธฒเธฃเธ‹เนˆเธญเธ™เน‚เธ›เธฃเน„เธŸเธฅเนŒเธ™เธตเน‰เน‚เธ”เธขเธœเธนเน‰เธเธฅเธฑเนˆเธ™เธเธฃเธญเธ‡เธ‚เธญเธ‡ {domain}", "link_preview.author": "เน‚เธ”เธข {name}", + "link_preview.more_from_author": "เน€เธžเธดเนˆเธกเน€เธ•เธดเธกเธˆเธฒเธ {name}", + "link_preview.shares": "{count, plural, other {{counter} เน‚เธžเธชเธ•เนŒ}}", "lists.account.add": "เน€เธžเธดเนˆเธกเน„เธ›เธขเธฑเธ‡เธฃเธฒเธขเธเธฒเธฃ", "lists.account.remove": "เน€เธญเธฒเธญเธญเธเธˆเธฒเธเธฃเธฒเธขเธเธฒเธฃ", "lists.delete": "เธฅเธšเธฃเธฒเธขเธเธฒเธฃ", @@ -395,9 +434,15 @@ "loading_indicator.label": "เธเธณเธฅเธฑเธ‡เน‚เธซเธฅเธ”โ€ฆ", "media_gallery.toggle_visible": "{number, plural, other {เธ‹เนˆเธญเธ™เธ เธฒเธž}}", "moved_to_account_banner.text": "เธกเธตเธเธฒเธฃเธ›เธดเธ”เนƒเธŠเน‰เธ‡เธฒเธ™เธšเธฑเธเธŠเธตเธ‚เธญเธ‡เธ„เธธเธ“ {disabledAccount} เนƒเธ™เธ›เธฑเธˆเธˆเธธเธšเธฑเธ™เน€เธ™เธทเนˆเธญเธ‡เธˆเธฒเธเธ„เธธเธ“เน„เธ”เน‰เธขเน‰เธฒเธขเน„เธ›เธขเธฑเธ‡ {movedToAccount}", - "mute_modal.duration": "เธฃเธฐเธขเธฐเน€เธงเธฅเธฒ", - "mute_modal.hide_notifications": "เธ‹เนˆเธญเธ™เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธˆเธฒเธเธœเธนเน‰เนƒเธŠเน‰เธ™เธตเน‰?", - "mute_modal.indefinite": "เน„เธกเนˆเธกเธตเธเธณเธซเธ™เธ”", + "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": "เธœเธนเน‰เนƒเธŠเน‰เธ—เธตเนˆเธ›เธดเธ”เธเธฑเน‰เธ™เธญเธขเธนเนˆ", @@ -430,11 +475,29 @@ "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.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": "เธขเธญเธกเธฃเธฑเธš", + "notification_requests.dismiss": "เธ›เธดเธ”", + "notification_requests.notifications_from": "เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธˆเธฒเธ {name}", + "notification_requests.title": "เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธ—เธตเนˆเธเธฃเธญเธ‡เธญเธขเธนเนˆ", "notifications.clear": "เธฅเน‰เธฒเธ‡เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™", "notifications.clear_confirmation": "เธ„เธธเธ“เนเธ™เนˆเนƒเธˆเธซเธฃเธทเธญเน„เธกเนˆเธงเนˆเธฒเธ•เน‰เธญเธ‡เธเธฒเธฃเธฅเน‰เธฒเธ‡เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธ—เธฑเน‰เธ‡เธซเธกเธ”เธ‚เธญเธ‡เธ„เธธเธ“เธญเธขเนˆเธฒเธ‡เธ–เธฒเธงเธฃ?", "notifications.column_settings.admin.report": "เธฃเธฒเธขเธ‡เธฒเธ™เนƒเธซเธกเนˆ:", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "เธฃเธฒเธขเธเธฒเธฃเน‚เธ›เธฃเธ”:", "notifications.column_settings.filter_bar.advanced": "เนเธชเธ”เธ‡เธซเธกเธงเธ”เธซเธกเธนเนˆเธ—เธฑเน‰เธ‡เธซเธกเธ”", "notifications.column_settings.filter_bar.category": "เนเธ–เธšเธ•เธฑเธงเธเธฃเธญเธ‡เธ”เนˆเธงเธ™", - "notifications.column_settings.filter_bar.show_bar": "เนเธชเธ”เธ‡เนเธ–เธšเธ•เธฑเธงเธเธฃเธญเธ‡", "notifications.column_settings.follow": "เธœเธนเน‰เธ•เธดเธ”เธ•เธฒเธกเนƒเธซเธกเนˆ:", "notifications.column_settings.follow_request": "เธ„เธณเธ‚เธญเธ•เธดเธ”เธ•เธฒเธกเนƒเธซเธกเนˆ:", "notifications.column_settings.mention": "เธเธฒเธฃเธเธฅเนˆเธฒเธงเธ–เธถเธ‡:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ›เน„เธกเนˆเธžเธฃเน‰เธญเธกเนƒเธŠเน‰เธ‡เธฒเธ™เน€เธ™เธทเนˆเธญเธ‡เธˆเธฒเธเธกเธตเธเธฒเธฃเธ›เธเธดเน€เธชเธ˜เธ„เธณเธ‚เธญเธชเธดเธ—เธ˜เธดเธญเธ™เธธเธเธฒเธ•เน€เธšเธฃเธฒเธงเนŒเน€เธ‹เธญเธฃเนŒเธเนˆเธญเธ™เธซเธ™เน‰เธฒเธ™เธตเน‰", "notifications.permission_denied_alert": "เน„เธกเนˆเธชเธฒเธกเธฒเธฃเธ–เน€เธ›เธดเธ”เนƒเธŠเน‰เธ‡เธฒเธ™เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ› เน€เธ™เธทเนˆเธญเธ‡เธˆเธฒเธเธกเธตเธเธฒเธฃเธ›เธเธดเน€เธชเธ˜เธชเธดเธ—เธ˜เธดเธญเธ™เธธเธเธฒเธ•เน€เธšเธฃเธฒเธงเนŒเน€เธ‹เธญเธฃเนŒเธเนˆเธญเธ™เธซเธ™เน‰เธฒเธ™เธตเน‰", "notifications.permission_required": "เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ›เน„เธกเนˆเธžเธฃเน‰เธญเธกเนƒเธŠเน‰เธ‡เธฒเธ™เน€เธ™เธทเนˆเธญเธ‡เธˆเธฒเธเน„เธกเนˆเน„เธ”เน‰เนƒเธซเน‰เธชเธดเธ—เธ˜เธดเธญเธ™เธธเธเธฒเธ•เธ—เธตเนˆเธˆเธณเน€เธ›เน‡เธ™", + "notifications.policy.filter_new_accounts.hint": "เธชเธฃเน‰เธฒเธ‡เธ‚เธถเน‰เธ™เธ เธฒเธขเนƒเธ™ {days, plural, other {# เธงเธฑเธ™}}เธ—เธตเนˆเธœเนˆเธฒเธ™เธกเธฒ", + "notifications.policy.filter_new_accounts_title": "เธšเธฑเธเธŠเธตเนƒเธซเธกเนˆ", + "notifications.policy.filter_not_followers_hint": "เธฃเธงเธกเธ–เธถเธ‡เธœเธนเน‰เธ„เธ™เธ—เธตเนˆเน„เธ”เน‰เธ•เธดเธ”เธ•เธฒเธกเธ„เธธเธ“เธ™เน‰เธญเธขเธเธงเนˆเธฒ {days, plural, other {# เธงเธฑเธ™}}", + "notifications.policy.filter_not_followers_title": "เธœเธนเน‰เธ„เธ™เธ—เธตเนˆเน„เธกเนˆเน„เธ”เน‰เธ•เธดเธ”เธ•เธฒเธกเธ„เธธเธ“", + "notifications.policy.filter_not_following_hint": "เธˆเธ™เธเธงเนˆเธฒเธ„เธธเธ“เธˆเธฐเธญเธ™เธธเธกเธฑเธ•เธดเน€เธ‚เธฒเธ”เน‰เธงเธขเธ•เธ™เน€เธญเธ‡", + "notifications.policy.filter_not_following_title": "เธœเธนเน‰เธ„เธ™เธ—เธตเนˆเธ„เธธเธ“เน„เธกเนˆเน„เธ”เน‰เธ•เธดเธ”เธ•เธฒเธก", + "notifications.policy.filter_private_mentions_hint": "เธเธฃเธญเธ‡เน„เธงเน‰เน€เธงเน‰เธ™เนเธ•เนˆเธเธฒเธฃเธเธฅเนˆเธฒเธงเธ–เธถเธ‡เนเธšเธšเธชเนˆเธงเธ™เธ•เธฑเธงเธญเธขเธนเนˆเนƒเธ™เธเธฒเธฃเธ•เธญเธšเธเธฅเธฑเธšเธเธฒเธฃเธเธฅเนˆเธฒเธงเธ–เธถเธ‡เธ‚เธญเธ‡เธ„เธธเธ“เน€เธญเธ‡เธซเธฃเธทเธญเธซเธฒเธเธ„เธธเธ“เธ•เธดเธ”เธ•เธฒเธกเธœเธนเน‰เธชเนˆเธ‡", + "notifications.policy.filter_private_mentions_title": "เธเธฒเธฃเธเธฅเนˆเธฒเธงเธ–เธถเธ‡เนเธšเธšเธชเนˆเธงเธ™เธ•เธฑเธงเธ—เธตเนˆเน„เธกเนˆเธžเธถเธ‡เธ›เธฃเธฐเธชเธ‡เธ„เนŒ", + "notifications.policy.title": "เธเธฃเธญเธ‡เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธˆเธฒเธโ€ฆ", "notifications_permission_banner.enable": "เน€เธ›เธดเธ”เนƒเธŠเน‰เธ‡เธฒเธ™เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ›", "notifications_permission_banner.how_to_control": "เน€เธžเธทเนˆเธญเธฃเธฑเธšเธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เน€เธกเธทเนˆเธญ Mastodon เน„เธกเนˆเน„เธ”เน‰เน€เธ›เธดเธ” เน€เธ›เธดเธ”เนƒเธŠเน‰เธ‡เธฒเธ™เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ› เธ„เธธเธ“เธชเธฒเธกเธฒเธฃเธ–เธ„เธงเธšเธ„เธธเธกเธŠเธ™เธดเธ”เธ‚เธญเธ‡เธเธฒเธฃเน‚เธ•เน‰เธ•เธญเธšเธ—เธตเนˆเธชเธฃเน‰เธฒเธ‡เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™เธšเธ™เน€เธ”เธชเธเนŒเธ—เน‡เธญเธ›เน„เธ”เน‰เธญเธขเนˆเธฒเธ‡เนเธกเนˆเธ™เธขเธณเธœเนˆเธฒเธ™เธ›เธธเนˆเธก {icon} เธ”เน‰เธฒเธ™เธšเธ™เน€เธกเธทเนˆเธญเน€เธ›เธดเธ”เนƒเธŠเน‰เธ‡เธฒเธ™เธเธฒเธฃเนเธˆเน‰เธ‡เน€เธ•เธทเธญเธ™", "notifications_permission_banner.title": "เน„เธกเนˆเธžเธฅเธฒเธ”เธชเธดเนˆเธ‡เนƒเธ”", @@ -625,16 +696,16 @@ "server_banner.about_active_users": "เธœเธนเน‰เธ„เธ™เธ—เธตเนˆเนƒเธŠเน‰เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธ™เธตเน‰เนƒเธ™เธฃเธฐเธซเธงเนˆเธฒเธ‡ 30 เธงเธฑเธ™เธ—เธตเนˆเธœเนˆเธฒเธ™เธกเธฒ (เธœเธนเน‰เนƒเธŠเน‰เธ—เธตเนˆเนƒเธŠเน‰เธ‡เธฒเธ™เธญเธขเธนเนˆเธฃเธฒเธขเน€เธ”เธทเธญเธ™)", "server_banner.active_users": "เธœเธนเน‰เนƒเธŠเน‰เธ—เธตเนˆเนƒเธŠเน‰เธ‡เธฒเธ™เธญเธขเธนเนˆ", "server_banner.administered_by": "เธ”เธนเนเธฅเน‚เธ”เธข:", - "server_banner.introduction": "{domain} เน€เธ›เน‡เธ™เธชเนˆเธงเธ™เธซเธ™เธถเนˆเธ‡เธ‚เธญเธ‡เน€เธ„เธฃเธทเธญเธ‚เนˆเธฒเธขเธชเธฑเธ‡เธ„เธกเนเธšเธšเธเธฃเธฐเธˆเธฒเธขเธจเธนเธ™เธขเนŒเธ—เธตเนˆเธ‚เธฑเธšเน€เธ„เธฅเธทเนˆเธญเธ™เน‚เธ”เธข {mastodon}", - "server_banner.learn_more": "เน€เธฃเธตเธขเธ™เธฃเธนเน‰เน€เธžเธดเนˆเธกเน€เธ•เธดเธก", + "server_banner.is_one_of_many": "{domain} เน€เธ›เน‡เธ™เธซเธ™เธถเนˆเธ‡เนƒเธ™เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒ Mastodon เธญเธดเธชเธฃเธฐเธˆเธณเธ™เธงเธ™เธกเธฒเธเธ—เธตเนˆเธ„เธธเธ“เธชเธฒเธกเธฒเธฃเธ–เนƒเธŠเน‰เน€เธžเธทเนˆเธญเธกเธตเธชเนˆเธงเธ™เธฃเนˆเธงเธกเนƒเธ™เธˆเธฑเธเธฃเธงเธฒเธฅเธชเธซเธžเธฑเธ™เธ˜เนŒ", "server_banner.server_stats": "เธชเธ–เธดเธ•เธดเน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒ:", "sign_in_banner.create_account": "เธชเธฃเน‰เธฒเธ‡เธšเธฑเธเธŠเธต", + "sign_in_banner.follow_anyone": "เธ•เธดเธ”เธ•เธฒเธกเนƒเธ„เธฃเธเน‡เธ•เธฒเธกเธ—เธฑเนˆเธงเธ—เธฑเน‰เธ‡เธˆเธฑเธเธฃเธงเธฒเธฅเธชเธซเธžเธฑเธ™เธ˜เนŒเนเธฅเธฐเธ”เธนเธˆเธฑเธเธฃเธงเธฒเธฅเธชเธซเธžเธฑเธ™เธ˜เนŒเธ—เธฑเน‰เธ‡เธซเธกเธ”เธ•เธฒเธกเธฅเธณเธ”เธฑเธšเน€เธงเธฅเธฒ เน„เธกเนˆเธกเธตเธญเธฑเธฅเธเธญเธฃเธดเธ—เธถเธก, เน‚เธ†เธฉเธ“เธฒ เธซเธฃเธทเธญเธ„เธฅเธดเธเน€เธšเธ•เธญเธขเธนเนˆเนƒเธ™เธชเธฒเธขเธ•เธฒ", + "sign_in_banner.mastodon_is": "Mastodon เน€เธ›เน‡เธ™เธงเธดเธ˜เธตเธ—เธตเนˆเธ”เธตเธ—เธตเนˆเธชเธธเธ”เธ—เธตเนˆเธˆเธฐเธ•เธดเธ”เธ•เธฒเธกเธชเธดเนˆเธ‡เธ—เธตเนˆเธเธณเธฅเธฑเธ‡เน€เธเธดเธ”เธ‚เธถเน‰เธ™", "sign_in_banner.sign_in": "เน€เธ‚เน‰เธฒเธชเธนเนˆเธฃเธฐเธšเธš", "sign_in_banner.sso_redirect": "เน€เธ‚เน‰เธฒเธชเธนเนˆเธฃเธฐเธšเธšเธซเธฃเธทเธญเธฅเธ‡เธ—เธฐเน€เธšเธตเธขเธ™", - "sign_in_banner.text": "เน€เธ‚เน‰เธฒเธชเธนเนˆเธฃเธฐเธšเธšเน€เธžเธทเนˆเธญเธ•เธดเธ”เธ•เธฒเธกเน‚เธ›เธฃเน„เธŸเธฅเนŒเธซเธฃเธทเธญเนเธฎเธŠเนเธ—เน‡เธ เธŠเธทเนˆเธ™เธŠเธญเธš เนเธŠเธฃเนŒ เนเธฅเธฐเธ•เธญเธšเธเธฅเธฑเธšเน‚เธžเธชเธ•เนŒ เธ„เธธเธ“เธขเธฑเธ‡เธชเธฒเธกเธฒเธฃเธ–เน‚เธ•เน‰เธ•เธญเธšเธˆเธฒเธเธšเธฑเธเธŠเธตเธ‚เธญเธ‡เธ„เธธเธ“เนƒเธ™เน€เธ‹เธดเธฃเนŒเธŸเน€เธงเธญเธฃเนŒเธญเธทเนˆเธ™", - "status.admin_account": "เน€เธ›เธดเธ”เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธ„เธงเธšเธ„เธธเธกเธชเธณเธซเธฃเธฑเธš @{name}", - "status.admin_domain": "เน€เธ›เธดเธ”เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธ„เธงเธšเธ„เธธเธกเธชเธณเธซเธฃเธฑเธš {domain}", - "status.admin_status": "เน€เธ›เธดเธ”เน‚เธžเธชเธ•เนŒเธ™เธตเน‰เนƒเธ™เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธ„เธงเธšเธ„เธธเธก", + "status.admin_account": "เน€เธ›เธดเธ”เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธเธฅเธฑเนˆเธ™เธเธฃเธญเธ‡เธชเธณเธซเธฃเธฑเธš @{name}", + "status.admin_domain": "เน€เธ›เธดเธ”เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธเธฅเธฑเนˆเธ™เธเธฃเธญเธ‡เธชเธณเธซเธฃเธฑเธš {domain}", + "status.admin_status": "เน€เธ›เธดเธ”เน‚เธžเธชเธ•เนŒเธ™เธตเน‰เนƒเธ™เธชเนˆเธงเธ™เธ•เธดเธ”เธ•เนˆเธญเธเธฒเธฃเธเธฅเธฑเนˆเธ™เธเธฃเธญเธ‡", "status.block": "เธ›เธดเธ”เธเธฑเน‰เธ™ @{name}", "status.bookmark": "เน€เธžเธดเนˆเธกเธ—เธตเนˆเธ„เธฑเนˆเธ™เธซเธ™เน‰เธฒ", "status.cancel_reblog_private": "เน€เธฅเธดเธเธ”เธฑเธ™", @@ -645,10 +716,11 @@ "status.direct": "เธเธฅเนˆเธฒเธงเธ–เธถเธ‡ @{name} เนเธšเธšเธชเนˆเธงเธ™เธ•เธฑเธง", "status.direct_indicator": "เธเธฒเธฃเธเธฅเนˆเธฒเธงเธ–เธถเธ‡เนเธšเธšเธชเนˆเธงเธ™เธ•เธฑเธง", "status.edit": "เนเธเน‰เน„เธ‚", - "status.edited": "เนเธเน‰เน„เธ‚เน€เธกเธทเนˆเธญ {date}", + "status.edited": "เนเธเน‰เน„เธ‚เธฅเนˆเธฒเธชเธธเธ”เน€เธกเธทเนˆเธญ {date}", "status.edited_x_times": "เนเธเน‰เน„เธ‚ {count, plural, other {{count} เธ„เธฃเธฑเน‰เธ‡}}", "status.embed": "เธเธฑเธ‡", "status.favourite": "เธŠเธทเนˆเธ™เธŠเธญเธš", + "status.favourites": "{count, plural, other {เธฃเธฒเธขเธเธฒเธฃเน‚เธ›เธฃเธ”}}", "status.filter": "เธเธฃเธญเธ‡เน‚เธžเธชเธ•เนŒเธ™เธตเน‰", "status.filtered": "เธเธฃเธญเธ‡เธญเธขเธนเนˆ", "status.hide": "เธ‹เนˆเธญเธ™เน‚เธžเธชเธ•เนŒ", @@ -669,6 +741,7 @@ "status.reblog": "เธ”เธฑเธ™", "status.reblog_private": "เธ”เธฑเธ™เธ”เน‰เธงเธขเธเธฒเธฃเธกเธญเธ‡เน€เธซเน‡เธ™เธ”เธฑเน‰เธ‡เน€เธ”เธดเธก", "status.reblogged_by": "{name} เน„เธ”เน‰เธ”เธฑเธ™", + "status.reblogs": "{count, plural, other {เธเธฒเธฃเธ”เธฑเธ™}}", "status.reblogs.empty": "เธขเธฑเธ‡เน„เธกเนˆเธกเธตเนƒเธ„เธฃเธ”เธฑเธ™เน‚เธžเธชเธ•เนŒเธ™เธตเน‰ เน€เธกเธทเนˆเธญเนƒเธ„เธฃเธชเธฑเธเธ„เธ™เธ”เธฑเธ™ เน€เธ‚เธฒเธˆเธฐเธ›เธฃเธฒเธเธเธ—เธตเนˆเธ™เธตเนˆ", "status.redraft": "เธฅเธšเนเธฅเน‰เธงเธฃเนˆเธฒเธ‡เนƒเธซเธกเนˆ", "status.remove_bookmark": "เน€เธญเธฒเธ—เธตเนˆเธ„เธฑเนˆเธ™เธซเธ™เน‰เธฒเธญเธญเธ", diff --git a/app/javascript/mastodon/locales/tok.json b/app/javascript/mastodon/locales/tok.json index 4d2cc3d1dc..80d412a20b 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", @@ -120,7 +130,6 @@ "compose_form.spoiler.marked": "o weka e toki pi ijo ike ken", "confirmation_modal.cancel": "o pini", "confirmations.block.confirm": "o weka", - "confirmations.block.message": "sina o wile ala wile weka e jan {name}?", "confirmations.cancel_follow_request.confirm": "o weka e wile sina", "confirmations.cancel_follow_request.message": "sina awen ala awen wile weka e wile kute sina lon {name}?", "confirmations.delete.confirm": "o weka", @@ -129,23 +138,24 @@ "confirmations.delete_list.message": "sina wile ala wile weka e lipu ni?", "confirmations.discard_edit_media.confirm": "o weka", "confirmations.discard_edit_media.message": "toki sitelen anu lukin lili sitelen la ante pi awen ala li lon. sina wile weka e ante ni?", - "confirmations.domain_block.confirm": "o weka.", "confirmations.domain_block.message": "sina wile ala a wile a len e ma {domain} ๊ž ken suli la len jan taso li pona ๊ž len pi ma ni la sina ken ala lukin e ijo pi ma ni lon lipu toki ale anu lukin toki ๊ž len ni la jan kute sina pi ma ni li weka", "confirmations.edit.confirm": "o ante", + "confirmations.edit.message": "sina ante e toki sina la toki pali sina li weka. sina wile ala wile e ni?", "confirmations.logout.confirm": "o weka", "confirmations.logout.message": "sina wile ala wile weka", "confirmations.mute.confirm": "o len", - "confirmations.mute.message": "sina awen ala awen wile kute ala e {name}?", "confirmations.redraft.confirm": "o weka o pali sin e toki", "confirmations.redraft.message": "pali sin e toki ni la sina wile ala wile weka e ona? sina ni la suli pi toki ni en wawa pi toki ni li weka. kin la toki lon toki ni li jo e mama ala.", "confirmations.reply.confirm": "toki lon toki ni", - "confirmations.reply.message": "toki tawa ona li weka e toki pali sina ๊ž sina wile ala wile ni", + "confirmations.reply.message": "sina toki lon toki ni la toki pali sina li weka. sina wile ala wile e ni?", "confirmations.unfollow.confirm": "o pini kute", "confirmations.unfollow.message": "sina o wile ala wile pini kute e jan {name}?", "conversation.delete": "o weka e toki ni", "conversation.mark_as_read": "ni o sin ala", "conversation.open": "o lukin e toki", "conversation.with": "lon {names}", + "copy_icon_button.copied": "toki li awen lon ilo sina", + "copypaste.copy_to_clipboard": "o awen lon ilo sina", "directory.local": "tan {domain} taso", "directory.new_arrivals": "jan pi kama sin", "directory.recently_active": "jan lon tenpo poka", @@ -154,6 +164,12 @@ "dismissable_banner.community_timeline": "ni li toki pi tenpo poka tawa ale tan jan lon ma lawa pi nimi {domain}.", "dismissable_banner.dismiss": "o weka", "dismissable_banner.explore_links": "ni li toki pi ijo sin ๊ž jan mute li pana e ni lon tenpo suno ni ๊ž sin la jan mute li pana la ni li kama suli", + "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", @@ -171,15 +187,25 @@ "empty_column.account_timeline": "toki ala li lon!", "empty_column.account_unavailable": "ken ala lukin e lipu jan", "empty_column.blocks": "jan ala li weka tawa sina.", + "empty_column.direct": "jan ala li toki len e sina. jan li toki len e sina la sina ken lukin e ni lon ni.", + "empty_column.domain_blocks": "ma ala li weka tawa sina.", + "empty_column.favourited_statuses": "sina suli ala e toki. sina suli e toki la sina ken lukin e toki ni lon ni.", + "empty_column.favourites": "jan ala li suli e toki ni. jan li suli e toki ni la sina ken lukin e ona lon ni.", + "empty_column.follow_requests": "jan ala li toki pi wile kute tawa sina. jan li toki pi wile kute tawa sina la sina ken lukin e toki ni lon ni.", "empty_column.followed_tags": "sina alasa ala e toki ๊ž sina alasa e toki la toki li lon ni", "empty_column.hashtag": "ala li lon toki ni", + "empty_column.home": "ala a li lon lipu open sina! sina wile lon e ijo lon ni la o kute e jan pi toki suli.", + "empty_column.list": "ala li lon kulupu lipu ni. jan pi kulupu lipu ni li toki sin la toki ni li lon ni.", + "empty_column.lists": "sina jo ala e kulupu lipu. sina pali sin e kulupu lipu la ona li lon ni.", "empty_column.mutes": "jan ala li len tawa sina.", + "error.unexpected_crash.explanation": "ilo li ken ala pana e lipu ni. ni li ken tan pakala mi tan pakala pi ilo sina.", "errors.unexpected_crash.report_issue": "o toki e pakala tawa lawa", "explore.search_results": "ijo pi alasa ni", "explore.suggested_follows": "jan", "explore.title": "o alasa", "explore.trending_links": "sin", "explore.trending_statuses": "toki", + "filter_modal.added.settings_link": "lipu lawa", "filter_modal.select_filter.expired": "tenpo pini", "filter_modal.select_filter.search": "o alasa anu pali", "firehose.all": "ale", @@ -187,6 +213,10 @@ "firehose.remote": "kulupu ante", "follow_request.authorize": "o ken", "follow_request.reject": "o ala", + "follow_suggestions.hints.friends_of_friends": "jan kute sina li lukin mute e toki pi jan ni.", + "follow_suggestions.hints.most_followed": "jan mute lon ma {domain} li kute e jan ni.", + "follow_suggestions.hints.most_interactions": "tenpo poka la jan mute pi ma {domain} li lukin mute e toki pi jan ni.", + "follow_suggestions.hints.similar_to_recently_followed": "sina kute e jan lon tenpo poka la jan ni li sama ona.", "follow_suggestions.view_all": "o lukin e ale", "follow_suggestions.who_to_follow": "sina o kute e ni", "footer.about": "sona", @@ -203,16 +233,19 @@ "hashtag.column_settings.tag_mode.any": "wan ni", "hashtag.column_settings.tag_mode.none": "ala ni", "home.pending_critical_update.link": "o lukin e ijo ilo sin", + "interaction_modal.login.action": "o lon tomo", "interaction_modal.on_another_server": "lon ma ante", "interaction_modal.on_this_server": "lon ma ni", "interaction_modal.title.favourite": "o suli e toki {name}", "interaction_modal.title.follow": "o kute e {name}", "interaction_modal.title.reblog": "o wawa e toki {name}", + "interaction_modal.title.reply": "o toki lon toki pi jan {name}", + "intervals.full.days": "{number, plural, other {suni #}}", "keyboard_shortcuts.blocked": "o lukin e lipu sina pi jan weka", "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", @@ -241,37 +274,54 @@ "load_pending": "{count, plural, other {ijo sin #}}", "loading_indicator.label": "ni li kamaโ€ฆ", "media_gallery.toggle_visible": "{number, plural, other {o len e sitelen}}", - "mute_modal.duration": "tenpo", - "mute_modal.indefinite": "tenpo ale", "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", "navigation_bar.pins": "toki sewi", "navigation_bar.preferences": "wile sina", "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", + "notification.poll": "sina pana lon pana la pana ni li pini", "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", + "onboarding.share.lead": "o toki lon nasin Masoton pi alasa sina tawa jan", + "onboarding.share.message": "ilo #Mastodon la mi jan {username} a! o kute e mi lon ni: {url}", "onboarding.start.title": "sina o kama pona a!", + "onboarding.tips.migration": "sina sona ala sona e ni? tenpo kama la sina pilin ike tawa ma {domain} la, sina ken tawa ma ante lon ilo Masoton. jan li kute e sina la jan ni li awen kute e sina. kin la sina ken lawa e ma pi sina taso a!", "poll.total_people": "{count, plural, other {jan #}}", + "poll.total_votes": "{count, plural, other {pana #}}", + "poll.vote": "o pana", + "poll.voted": "sina pana e ni", + "poll.votes": "{votes, plural, other {pana #}}", + "privacy.direct.long": "jan ale lon toki", "privacy.public.short": "tawa ale", "relative_time.full.just_now": "tenpo ni", "relative_time.just_now": "tenpo ni", "relative_time.today": "tenpo suno ni", "report.block": "o weka e jan", "report.block_explanation": "sina kama lukin ala e toki ona. ona li kama ala ken lukin e toki sina li kama ala ken kute e sina. ona li ken sona e kama ni.", + "report.categories.other": "ante", + "report.categories.spam": "ike tan toki mute", "report.category.title": "ike seme li lon {type} ni", "report.category.title_account": "lipu", "report.category.title_status": "toki", @@ -297,9 +347,8 @@ "status.cancel_reblog_private": "o pini e pana", "status.delete": "o weka", "status.edit": "o ante", - "status.edited": "ni li ante lon {date}", "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 7ab370b8bc..0bb2a0e4a6 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -89,6 +89,14 @@ "announcement.announcement": "Duyuru", "attachments_list.unprocessed": "(iลŸlenmemiลŸ)", "audio.hide": "Sesi gizle", + "block_modal.remote_users_caveat": "{domain} sunucusundan kararฤฑnฤฑza saygฤฑ duymasฤฑnฤฑ isteyeceฤŸiz. Ancak, Uymalarฤฑ garanti deฤŸildir รงรผnkรผ bazฤฑ sunucular engellemeyi farklฤฑ ลŸekilde yapฤฑyorlar. Herkese aรงฤฑk gรถnderiler giriลŸ yapmamฤฑลŸ kullanฤฑcฤฑlara gรถrรผntรผlenmeye devam edebilir.", + "block_modal.show_less": "Daha az gรถster", + "block_modal.show_more": "Daha fazla gรถster", + "block_modal.they_cant_mention": "Sizden bahsedemez veya sizi takip edemezler.", + "block_modal.they_cant_see_posts": "Onlar sizin gรถnderilerinizi gรถrmeye devam edebilir, ancak siz onlarฤฑnkini gรถremezsiniz.", + "block_modal.they_will_know": "Engellendiklerini gรถrebiliyorlar.", + "block_modal.title": "Kullanฤฑcฤฑyฤฑ engelle?", + "block_modal.you_wont_see_mentions": "Onlardan bahseden gรถnderiler gรถremezsiniz.", "boost_modal.combo": "Bir daha ki sefere {combo} tuลŸuna basabilirsin", "bundle_column_error.copy_stacktrace": "Hata raporunu kopyala", "bundle_column_error.error.body": "ฤฐstenen sayfa gรถsterilemiyor. Bu durum kodumuzdaki bir hatadan veya tarayฤฑcฤฑ uyum sorunundan kaynaklanฤฑyor olabilir.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Metin gizli deฤŸil", "compose_form.spoiler_placeholder": "ฤฐรงerik uyarฤฑsฤฑ (isteฤŸe baฤŸlฤฑ)", "confirmation_modal.cancel": "ฤฐptal", - "confirmations.block.block_and_report": "Engelle ve Bildir", "confirmations.block.confirm": "Engelle", - "confirmations.block.message": "{name} adlฤฑ kullanฤฑcฤฑyฤฑ engellemek istediฤŸinden emin misin?", "confirmations.cancel_follow_request.confirm": "ฤฐsteฤŸi geri รงek", "confirmations.cancel_follow_request.message": "{name} kiลŸisini takip etme isteฤŸini geri รงekmek istediฤŸinden emin misin?", "confirmations.delete.confirm": "Sil", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Bu listeyi kalฤฑcฤฑ olarak silmek istediฤŸinden emin misin?", "confirmations.discard_edit_media.confirm": "Vazgeรง", "confirmations.discard_edit_media.message": "Medya aรงฤฑklamasฤฑ veya รถn izlemede kaydedilmemiลŸ deฤŸiลŸiklikleriniz var, yine de vazgeรงmek istiyor musunuz?", - "confirmations.domain_block.confirm": "Alanฤฑn tamamฤฑnฤฑ engelle", + "confirmations.domain_block.confirm": "Sunucuyu engelle", "confirmations.domain_block.message": "{domain} alanฤฑnฤฑn tamamฤฑnฤฑ engellemek istediฤŸinden gerรงekten emin misin? Genellikle hedeflenen birkaรง engelleme veya sessize alma yeterlidir ve tercih edilir. Bu alan adฤฑndan gelen iรงeriฤŸi herhangi bir genel zaman รงizelgesinde veya bildirimlerinde gรถrmezsin. Bu alan adฤฑndaki takipรงilerin kaldฤฑrฤฑlฤฑr.", "confirmations.edit.confirm": "Dรผzenle", "confirmations.edit.message": "ลžimdi dรผzenlersen ลŸu an oluลŸturduฤŸun iletinin รผzerine yazฤฑlฤฑr. Devam etmek istediฤŸine emin misin?", "confirmations.logout.confirm": "Oturumu kapat", "confirmations.logout.message": "Oturumu kapatmak istediฤŸinden emin misin?", "confirmations.mute.confirm": "Sessize al", - "confirmations.mute.explanation": "Bu, onlardan gelen ve bahseden gรถnderileri gizler. Ancak yine de gรถnderilerini gรถrmelerine ve seni takip etmelerine izin verilir.", - "confirmations.mute.message": "{name} kullanฤฑcฤฑsฤฑnฤฑ sessize almak istediฤŸinden emin misin?", "confirmations.redraft.confirm": "Sil Dรผzenle ve yeniden paylaลŸ", "confirmations.redraft.message": "Bu gรถnderiyi silip taslak haline getirmek istediฤŸinize emin misiniz? Mevcut favoriler ve boostlar silinecek ve gรถnderiye verilen yanฤฑtlar baลŸฤฑboลŸ kalacak.", "confirmations.reply.confirm": "Yanฤฑtla", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "Bunlar, sosyal aฤŸ genelinde bugรผn ilgi gรถren gรถnderiler. Daha รงok yinelenen ve favorilenen yeni gรถnderiler daha รผst sฤฑralarda yer alฤฑr.", "dismissable_banner.explore_tags": "Bu etiketler, merkeziyetsiz aฤŸda bulunan bu ve diฤŸer sunuculardaki insanlarฤฑn ลŸimdilerde ilgisini รงekiyor.", "dismissable_banner.public_timeline": "Bunlar, {domain} รผzerindeki insanlarฤฑn, sosyal aฤŸ da takip ettiฤŸi insanlarca gรถnderilen en son ve herkese aรงฤฑk gรถnderilerdir.", + "domain_block_modal.block": "Sunucuyu engelle", + "domain_block_modal.block_account_instead": "Bunun yerine {name} hesabฤฑnฤฑ engelle", + "domain_block_modal.they_can_interact_with_old_posts": "Bu sunucudan kiลŸiler eski gรถnderilerinizle etkileลŸebilirler.", + "domain_block_modal.they_cant_follow": "Bu sunucudan hiรง kimse sizi takip edemez.", + "domain_block_modal.they_wont_know": "Engellendiklerini bilmeyecekler.", + "domain_block_modal.title": "Alan adฤฑnฤฑ engelle?", + "domain_block_modal.you_will_lose_followers": "Bu sunucudaki tรผm takipรงileriniz kaldฤฑrฤฑlacaktฤฑr.", + "domain_block_modal.you_wont_see_posts": "Bu sunucudaki kullanฤฑcฤฑlardan gelen gรถnderileri veya bildirimleri gรถremezsiniz.", + "domain_pill.activitypub_lets_connect": "Sadece Mastodon รผzerindeki deฤŸil, diฤŸer sosyal uygulamalardaki kiลŸilerle de baฤŸlantฤฑ kurmanฤฑza ve etkileลŸmenize olanak saฤŸlar.", + "domain_pill.activitypub_like_language": "ActivityPub, Mastodon'un diฤŸer sosyal aฤŸlarla konuลŸmak iรงin kullandฤฑฤŸฤฑ dil gibidir.", + "domain_pill.server": "Sunucu", + "domain_pill.their_handle": "Tanฤฑtฤฑcฤฑlarฤฑ:", + "domain_pill.their_server": "Dijital evleri, tรผm gรถnderilerinin yaลŸadฤฑฤŸฤฑ yerdir.", + "domain_pill.their_username": "Sunucularฤฑndaki tekil tanฤฑmlayฤฑcฤฑlarฤฑ. Farklฤฑ sunucularda aynฤฑ kullanฤฑcฤฑ adฤฑna sahip kullanฤฑcฤฑlarฤฑ bulmak mรผmkรผndรผr.", + "domain_pill.username": "Kullanฤฑcฤฑ adฤฑ", + "domain_pill.whats_in_a_handle": "Tanฤฑtฤฑcฤฑ nedir?", + "domain_pill.who_they_are": "Tanฤฑtฤฑcฤฑlar bir kiลŸinin kim olduฤŸunu ve nerede olduฤŸunu sรถylediฤŸi iรงin, sosyal aฤŸฤฑndaki insanlarla etkileลŸime geรงebilirsiniz.", + "domain_pill.who_you_are": "Tanฤฑtฤฑcฤฑnฤฑz kim olduฤŸunuzu ve nerede olduฤŸunuzu sรถylediฤŸi iรงin, sosyal aฤŸฤฑndaki insanlar sizinle etkileลŸime geรงebilir.", + "domain_pill.your_handle": "Tanฤฑtฤฑcฤฑnฤฑz:", + "domain_pill.your_server": "Dijital anasayfanฤฑz, tรผm gรถnderilerinizin yaลŸadฤฑฤŸฤฑ yerdir. Bunu beฤŸenmediniz mi? ฤฐstediฤŸiniz zaman sunucularฤฑnฤฑzฤฑ deฤŸiลŸtirin ve takipรงilerinizi de getirin.", + "domain_pill.your_username": "Bu sunucudaki tekil tanฤฑmlayฤฑcฤฑnฤฑz. Farklฤฑ sunucularda aynฤฑ kullanฤฑcฤฑ adฤฑna sahip kullanฤฑcฤฑlarฤฑ bulmak mรผmkรผndรผr.", "embed.instructions": "AลŸaฤŸฤฑdaki kodu kopyalayarak bu durumu sitenize gรถmรผn.", "embed.preview": "ฤฐลŸte nasฤฑl gรถrรผneceฤŸi:", "emoji_button.activity": "Aktivite", @@ -214,7 +239,7 @@ "emoji_button.food": "Yiyecek ve ฤฐรงecek", "emoji_button.label": "ฤฐfade ekle", "emoji_button.nature": "DoฤŸa", - "emoji_button.not_found": "ฤฐfade yok!! (โ•ฏยฐโ–กยฐ๏ผ‰โ•ฏ๏ธต โ”ปโ”โ”ป", + "emoji_button.not_found": "EลŸleลŸen emoji yok", "emoji_button.objects": "Nesneler", "emoji_button.people": "Kullanฤฑcฤฑlar", "emoji_button.recent": "Sฤฑk kullanฤฑlan", @@ -241,6 +266,7 @@ "empty_column.list": "Henรผz bu listede bir ลŸey yok. Bu listenin รผyeleri bir ลŸey paylaลŸฤฑฤŸฤฑnda burada gรถzรผkecek.", "empty_column.lists": "Henรผz listen yok. Liste oluลŸturduฤŸunda burada gรถrรผnรผr.", "empty_column.mutes": "Henรผz bir kullanฤฑcฤฑyฤฑ sessize almadฤฑnฤฑz.", + "empty_column.notification_requests": "Hepsi tamam! Burada yeni bir ลŸey yok. Yeni bildirim aldฤฑฤŸฤฑnฤฑzda, ayarlarฤฑnฤฑza gรถre burada gรถrรผntรผlenecekler.", "empty_column.notifications": "Henรผz bildiriminiz yok. Sohbete baลŸlamak iรงin baลŸkalarฤฑyla etkileลŸim kurun.", "empty_column.public": "Burada hiรงbir ลŸey yok! Herkese aรงฤฑk bir ลŸeyler yazฤฑn veya burayฤฑ doldurmak iรงin diฤŸer sunuculardaki kullanฤฑcฤฑlarฤฑ takip edin", "error.unexpected_crash.explanation": "Bizim kodumuzdaki bir hatadan ya da tarayฤฑcฤฑ uyumluluk sorunundan dolayฤฑ, bu sayfa dรผzgรผn gรถrรผntรผlenemedi.", @@ -271,16 +297,28 @@ "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รผ", "firehose.local": "Bu sunucu", "firehose.remote": "DiฤŸer sunucular", "follow_request.authorize": "ฤฐzin Ver", "follow_request.reject": "Reddet", "follow_requests.unlocked_explanation": "Hesabฤฑnฤฑz kilitli olmasa da, {domain} personeli bu hesaplardan gelen takip isteklerini gรถzden geรงirmek isteyebileceฤŸinizi dรผลŸรผndรผ.", - "follow_suggestions.curated_suggestion": "Editรถrรผn Seรงimi", + "follow_suggestions.curated_suggestion": "ร‡alฤฑลŸanlarฤฑn seรงtikleri", "follow_suggestions.dismiss": "Tekrar gรถsterme", + "follow_suggestions.featured_longer": "{domain} takฤฑmฤฑ tarafฤฑndan elle seรงildi", + "follow_suggestions.friends_of_friends_longer": "Takip ettiฤŸiniz kiลŸiler arasฤฑnda popรผler", + "follow_suggestions.hints.featured": "Bu profil {domain} ekibi tarafฤฑndan elle seรงilmiลŸtir.", + "follow_suggestions.hints.friends_of_friends": "Bu profil takip ettiฤŸiniz insanlar arasฤฑnda popรผlerdir.", + "follow_suggestions.hints.most_followed": "Bu, {domain} sunucusunda en fazla izlenen profildir.", + "follow_suggestions.hints.most_interactions": "Bu, {domain} sunucusunda son zamanlarda oldukรงa fazla dikkat รงeken bir profildir.", + "follow_suggestions.hints.similar_to_recently_followed": "Bu profil, son zamanlarda takip ettiฤŸiniz profillere benziyor.", "follow_suggestions.personalized_suggestion": "KiลŸiselleลŸmiลŸ รถneriler", "follow_suggestions.popular_suggestion": "Popรผler รถneriler", + "follow_suggestions.popular_suggestion_longer": "{domain} รผzerinde popรผler", + "follow_suggestions.similar_to_recently_followed_longer": "Yakฤฑn zamanda takip ettiฤŸiniz hesaplara benziyor", "follow_suggestions.view_all": "Tรผmรผnรผ gรถr", "follow_suggestions.who_to_follow": "Takip edebileceklerin", "followed_tags": "Takip edilen etiketler", @@ -309,7 +347,6 @@ "hashtag.follow": "Etiketi takip et", "hashtag.unfollow": "Etiketi takibi bฤฑrak", "hashtags.and_other": "โ€ฆve {count, plural, one {}other {# fazlasฤฑ}}", - "home.column_settings.basic": "Temel", "home.column_settings.show_reblogs": "Yeniden paylaลŸฤฑmlarฤฑ gรถster", "home.column_settings.show_replies": "Yanฤฑtlarฤฑ gรถster", "home.hide_announcements": "Duyurularฤฑ gizle", @@ -343,7 +380,7 @@ "keyboard_shortcuts.description": "Aรงฤฑklama", "keyboard_shortcuts.direct": "รถzel deฤŸinmeler sรผtununu aรงmak iรงin", "keyboard_shortcuts.down": "Listede aลŸaฤŸฤฑya inmek iรงin", - "keyboard_shortcuts.enter": "gรถnderiyi aรง", + "keyboard_shortcuts.enter": "Gรถnderiyi aรงฤฑnฤฑz", "keyboard_shortcuts.favourite": "Gรถnderiyi favorilerine ekle", "keyboard_shortcuts.favourites": "Gรถzde listeni aรง", "keyboard_shortcuts.federated": "Federe akฤฑลŸฤฑ aรง", @@ -352,7 +389,7 @@ "keyboard_shortcuts.hotkey": "Kฤฑsayol tuลŸu", "keyboard_shortcuts.legend": "Bu efsaneyi gรถrรผntรผlemek iรงin", "keyboard_shortcuts.local": "Yerel akฤฑลŸฤฑ aรง", - "keyboard_shortcuts.mention": "Yazandan bahsetmek iรงin", + "keyboard_shortcuts.mention": "Yazana deฤŸinmek iรงin", "keyboard_shortcuts.muted": "Sessize alฤฑnmฤฑลŸ kullanฤฑcฤฑ listesini aรงmak iรงin", "keyboard_shortcuts.my_profile": "Profilinizi aรงmak iรงin", "keyboard_shortcuts.notifications": "Bildirimler sรผtununu aรงmak iรงin", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Yine de profili gรถster", "limited_account_hint.title": "Bu profil {domain} moderatรถrleri tarafฤฑndan gizlendi.", "link_preview.author": "Yazar: {name}", + "link_preview.more_from_author": "{name} kiลŸisinden daha fazlasฤฑ", + "link_preview.shares": "{count, plural, one {{counter} gรถnderi} other {{counter} gรถnderi}}", "lists.account.add": "Listeye ekle", "lists.account.remove": "Listeden kaldฤฑr", "lists.delete": "Listeyi sil", @@ -395,9 +434,15 @@ "loading_indicator.label": "Yรผkleniyorโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {Resmi} other {Resimleri}} gizle", "moved_to_account_banner.text": "{disabledAccount} hesabฤฑnฤฑz, {movedToAccount} hesabฤฑna taลŸฤฑdฤฑฤŸฤฑnฤฑz iรงin ลŸu an devre dฤฑลŸฤฑ.", - "mute_modal.duration": "Sรผre", - "mute_modal.hide_notifications": "Bu kullanฤฑcฤฑdan bildirimler gizlensin mฤฑ?", - "mute_modal.indefinite": "Belirsiz", + "mute_modal.hide_from_notifications": "Bildirimlerde gizle", + "mute_modal.hide_options": "Seรงenekleri gizle", + "mute_modal.indefinite": "Ben sessizliklerini kaldฤฑrana kadar", + "mute_modal.show_options": "Seรงenekleri gรถster", + "mute_modal.they_can_mention_and_follow": "Sizden bahsedebilir ve sizi takip edebilirler, ancak siz onlarฤฑ gรถremezsiniz.", + "mute_modal.they_wont_know": "Susturulduklarฤฑnฤฑ bilmeyecekler.", + "mute_modal.title": "Kullanฤฑcฤฑyฤฑ sustur?", + "mute_modal.you_wont_see_mentions": "Onlardan bahseden gรถnderiler gรถremezsiniz.", + "mute_modal.you_wont_see_posts": "Onlar sizin gรถnderilerinizi gรถrmeye devam edebilir, ancak siz onlarฤฑnkini gรถremezsiniz.", "navigation_bar.about": "Hakkฤฑnda", "navigation_bar.advanced_interface": "GeliลŸmiลŸ web arayรผzรผnde aรง", "navigation_bar.blocks": "Engellenen kullanฤฑcฤฑlar", @@ -430,11 +475,29 @@ "notification.follow": "{name} seni takip etti", "notification.follow_request": "{name} size takip isteฤŸi gรถnderdi", "notification.mention": "{name} senden bahsetti", + "notification.moderation-warning.learn_more": "Daha fazlasฤฑ", + "notification.moderation_warning": "Hesabฤฑnฤฑz bir denetim uyarฤฑsฤฑ aldฤฑ", + "notification.moderation_warning.action_delete_statuses": "Bazฤฑ gรถnderileriniz kaldฤฑrฤฑldฤฑ.", + "notification.moderation_warning.action_disable": "Hesabฤฑnฤฑz devre dฤฑลŸฤฑ bฤฑrakฤฑldฤฑ.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Bazฤฑ gรถnderileriniz hassas olarak iลŸaretlendi.", + "notification.moderation_warning.action_none": "Hesabฤฑnฤฑz bir denetim uyarฤฑsฤฑ aldฤฑ.", + "notification.moderation_warning.action_sensitive": "Gรถnderileriniz artฤฑk hassas olarak iลŸaretlenecek.", + "notification.moderation_warning.action_silence": "Hesabฤฑnฤฑz sฤฑnฤฑrlandฤฑrฤฑldฤฑ.", + "notification.moderation_warning.action_suspend": "Hesabฤฑnฤฑz askฤฑya alฤฑndฤฑ.", "notification.own_poll": "Anketiniz sona erdi", "notification.poll": "Oy verdiฤŸiniz bir anket sona erdi", "notification.reblog": "{name} gรถnderini yeniden paylaลŸtฤฑ", + "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", + "notification_requests.dismiss": "Yoksay", + "notification_requests.notifications_from": "{name} bildirimleri", + "notification_requests.title": "FiltrelenmiลŸ bildirimler", "notifications.clear": "Bildirimleri temizle", "notifications.clear_confirmation": "Tรผm bildirimlerinizi kalฤฑcฤฑ olarak temizlemek ister misiniz?", "notifications.column_settings.admin.report": "Yeni bildirimler:", @@ -442,11 +505,10 @@ "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ฤฑ sรผzgeรง รงubuฤŸu", - "notifications.column_settings.filter_bar.show_bar": "Sรผzgeรง รงubuฤŸunu gรถster", + "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:", @@ -460,7 +522,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.", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Daha รถnce reddedilen tarayฤฑcฤฑ izinleri isteฤŸi nedeniyle masaรผstรผ bildirimleri kullanฤฑlamฤฑyor", "notifications.permission_denied_alert": "Tarayฤฑcฤฑ izni daha รถnce reddedildiฤŸinden, masaรผstรผ bildirimleri etkinleลŸtirilemez", "notifications.permission_required": "Masaรผstรผ bildirimleri, gereksinim duyulan izin verilmediฤŸi iรงin mevcut deฤŸil.", + "notifications.policy.filter_new_accounts.hint": "Son {days, plural, one {bir gรผn} other {# gรผn}}de oluลŸturuldu", + "notifications.policy.filter_new_accounts_title": "Yeni hesaplar", + "notifications.policy.filter_not_followers_hint": "Sizi {days, plural, one {bir gรผn} other {# gรผn}}den azdฤฑr takip eden kiลŸileri de iรงeriyor", + "notifications.policy.filter_not_followers_title": "Seni takip etmeyen kullanฤฑcฤฑlar", + "notifications.policy.filter_not_following_hint": "Onlarฤฑ manuel olarak onaylayana kadar", + "notifications.policy.filter_not_following_title": "Takip etmediฤŸin kullanฤฑcฤฑlar", + "notifications.policy.filter_private_mentions_hint": "Kendi deฤŸinmenize yanฤฑt veya takip ettiฤŸiniz kullanฤฑcฤฑdan deฤŸilse filtrelenir", + "notifications.policy.filter_private_mentions_title": "ฤฐstenmeyen รถzel deฤŸinmeler", + "notifications.policy.title": "ลžundan bildirimleri filtreleโ€ฆ", "notifications_permission_banner.enable": "Masaรผstรผ bildirimlerini etkinleลŸtir", "notifications_permission_banner.how_to_control": "Mastodon aรงฤฑk olmadฤฑฤŸฤฑnda bildirim almak iรงin masaรผstรผ bildirimlerini etkinleลŸtirin. EtkinleลŸtirildikten sonra yukarฤฑdaki {icon} dรผฤŸmesini kullanarak hangi etkileลŸim tรผrlerinin masaรผstรผ bildirimleri oluลŸturduฤŸunu tam olarak kontrol edebilirsiniz.", "notifications_permission_banner.title": "Hiรงbir ลŸeyi kaรงฤฑrmayฤฑn", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Bu sunucuyu son 30 gรผnde kullanan insanlar (Aylฤฑk Etkin Kullanฤฑcฤฑlar)", "server_banner.active_users": "etkin kullanฤฑcฤฑlar", "server_banner.administered_by": "Yรถnetici:", - "server_banner.introduction": "{domain}, {mastodon} destekli merkeziyetsiz sosyal aฤŸฤฑn bir parรงasฤฑdฤฑr.", - "server_banner.learn_more": "Daha fazlasฤฑnฤฑ รถฤŸrenin", + "server_banner.is_one_of_many": "{domain} fediverse katฤฑlฤฑmฤฑ iรงin kullanabileceฤŸiniz birรงok baฤŸฤฑmsฤฑz Mastodon sunucusundan biridir.", "server_banner.server_stats": "Sunucu istatistikleri:", "sign_in_banner.create_account": "Hesap oluลŸtur", + "sign_in_banner.follow_anyone": "Fediverse รงapฤฑnda herhangi bir kimseyi takip edin ve tรผmรผnรผ kronolojik sฤฑrada gรถrรผntรผleyin. Algoritma, reklam veya tฤฑklama tuzaฤŸฤฑ yok.", + "sign_in_banner.mastodon_is": "Neler olup bittiฤŸini izlemenin en iyi aracฤฑ Mastodon'dur.", "sign_in_banner.sign_in": "GiriลŸ yap", "sign_in_banner.sso_redirect": "GiriลŸ yap veya kaydol", - "sign_in_banner.text": "Profilleri ve hashtagleri takip etmek, gรถnderileri favorilerine eklemek, paylaลŸmak ve yanฤฑtlamak iรงin giriลŸ yap. Farklฤฑ bir sunucudaki hesabฤฑnla da etkileลŸimde bulunabilirsin.", "status.admin_account": "@{name} iรงin denetim arayรผzรผnรผ aรงฤฑn", "status.admin_domain": "{domain} iรงin denetim arayรผzรผnรผ aรงฤฑn", "status.admin_status": "Denetim arayรผzรผnde bu gรถnderiyi aรงฤฑn", @@ -645,10 +716,11 @@ "status.direct": "@{name} kullanฤฑcฤฑsฤฑna รถzelden deฤŸin", "status.direct_indicator": "ร–zel deฤŸinme", "status.edit": "Dรผzenle", - "status.edited": "{date} tarihinde dรผzenlenmiลŸ", + "status.edited": "Son dรผzenleme {date}", "status.edited_x_times": "{count, plural, one {{count} kez} other {{count} kez}} dรผzenlendi", "status.embed": "Gรถmรผlรผ", "status.favourite": "Favori", + "status.favourites": "{count, plural, one {beฤŸeni} other {beฤŸeni}}", "status.filter": "Bu gรถnderiyi sรผzgeรงle", "status.filtered": "SรผzgeรงlenmiลŸ", "status.hide": "Gรถnderiyi gizle", @@ -669,6 +741,7 @@ "status.reblog": "Yeniden paylaลŸ", "status.reblog_private": "ร–zgรผn gรถrรผnรผrlรผk ile yeniden paylaลŸ", "status.reblogged_by": "{name} yeniden paylaลŸtฤฑ", + "status.reblogs": "{count, plural, one {yeniden paylaลŸฤฑm} other {yeniden paylaลŸฤฑm}}", "status.reblogs.empty": "Henรผz hiรง kimse bu Gรถnderiyi Yeniden PaylaลŸmadฤฑ. Herhangi bir kullanฤฑcฤฑ yeniden paylaลŸtฤฑฤŸฤฑnda burada gรถrรผntรผlenecek.", "status.redraft": "Sil,Dรผzenle ve Yeniden paylaลŸ", "status.remove_bookmark": "Yer iลŸaretini kaldฤฑr", @@ -719,10 +792,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 17de9884e7..273c1a6de7 100644 --- a/app/javascript/mastodon/locales/tt.json +++ b/app/javascript/mastodon/locales/tt.json @@ -134,9 +134,7 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmation_modal.cancel": "ะ‘ะฐัˆ ั‚ะฐั€ั‚ัƒ", - "confirmations.block.block_and_report": "ะ‘ะปะพะบะปะฐัƒ าปำ™ะผ ัˆะธะบะฐัั‚ัŒ ะธั‚าฏ", "confirmations.block.confirm": "ะ‘ะปะพะบะปะฐัƒ", - "confirmations.block.message": "ะกะตะท {name} ะบัƒะปะปะฐะฝัƒั‡ั‹ะฝั‹ ะฑะปะพะบะปะฐั€ะณะฐ ั‚ะตะปะธัะตะทะผะต?", "confirmations.cancel_follow_request.confirm": "ะกะพั€ะฐัƒะฝั‹ ะฑะฐัˆ ั‚ะฐั€ั‚ัƒ", "confirmations.cancel_follow_request.message": "ะกะตะท ะฐะฑะพะฝะตะผะตะฝั‚ ัะพั€ะฐะฒั‹ะณั‹ะทะฝั‹ ะบะธั€ะต ะบะฐะนั‚ะฐั€ั‹ั€ะณะฐ ั‚ะตะปะธัะตะท {name}?", "confirmations.delete.confirm": "ะ‘ะตั‚ะตั€าฏ", @@ -145,14 +143,11 @@ "confirmations.delete_list.message": "ะกะตะท ะฑัƒ ะธัะตะผะปะตะบะฝะต ะผำ™าฃะณะตะณำ™ ะฑะตั‚ะตั€ะตั€ะณำ™ ั‚ะตะปะธัะตะทะผะต?", "confirmations.discard_edit_media.confirm": "ะ‘ะฐัˆ ั‚ะฐั€ั‚ัƒ", "confirmations.discard_edit_media.message": "ะกะตะทะฝะตาฃ ะผะตะดะธะฐ ั‚ะฐัะฒะธั€ะปะฐะผะฐัั‹ะฝะดะฐ ัะบะธ ะฐะปะดะฐะฝ ะบะฐั€ะฐัƒ ำฉั‡ะตะฝ ัะฐะบะปะฐะฝะผะฐะณะฐะฝ าฏะทะณำ™ั€ะตัˆะปำ™ั€ ะฑะฐั€ะผั‹? ", - "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.message": "ะกะตะท ั‡ั‹ะฝะฝะฐะฝ ะดะฐ ะฑะฐั€ั‹ัั‹ะฝ ะดะฐ ะฑะปะพะบะปะฐั€ะณะฐ ั‚ะตะปะธัะตะท {domain}? ะšาฏะฟั‡ะตะปะตะบ ะพั‡ั€ะฐะบั‚ะฐ ะฑะตั€ะฝะธั‡ำ™ ะผะฐะบัะฐั‚ะปั‹ ะฑะปะพะบะปะฐั€ ัะบะธ ั‚ะฐะฒั‹ัˆัั‹ะทะปะฐั€ า—ะธั‚ำ™ั€ะปะตะบ าปำ™ะผ ำฉัั‚ะตะฝะปะตะบะปะต. ะกะตะท ะฑัƒ ะดะพะผะตะฝะฝะฐะฝ ัั‡ั‚ำ™ะปะตะบะฝะต า—ำ™ะผำ™ะณะฐั‚ัŒ ัั€ะพะบะปะฐั€ั‹ะฝะดะฐ ัะบะธ ั…ำ™ะฑำ™ั€ะปำ™ั€ะตะณะตะทะดำ™ ะบาฏั€ะผำ™ัั‡ำ™ะบัะตะท. ะ‘ัƒ ะดะพะผะตะฝะฝะฐะฝ ัะตะทะฝะตาฃ ัˆำ™ะบะตั€ั‚ะปำ™ั€ ะฑะตั‚ะตั€ะตะปำ™ั‡ำ™ะบ.", "confirmations.edit.confirm": "าฎะทะณำ™ั€ั‚าฏ", "confirmations.logout.confirm": "ะงั‹ะณัƒ", "confirmations.logout.message": "ะกะตะท ั‡ั‹ะณะฐั€ะณะฐ ั‚ะตะปะธัะตะทะผะต?", "confirmations.mute.confirm": "ะขะฐะฒั‹ัˆัั‹ะท", - "confirmations.mute.explanation": "ะ‘ัƒ ะฐะปะฐั€ะดะฐะฝ ัƒั€ะฐะทะฐ ั‚ะพั‚ัƒะฝั‹ าปำ™ะผ ะฐะปะฐั€ ั‚ัƒั€ั‹ะฝะดะฐ ะธัะบำ™ ะฐะปัƒะฝั‹ ััˆะตั€ำ™ั‡ำ™ะบ, ะปำ™ะบะธะฝ ะฑัƒ ะฐะปะฐั€ะณะฐ ัƒั€ะฐะทะฐะปะฐั€ั‹ะณั‹ะทะฝั‹ ะบาฏั€ะตั€ะณำ™ าปำ™ะผ ัะทั‹ะปั‹ั€ะณะฐ ะผำฉะผะบะธะฝะปะตะบ ะฑะธั€ำ™ั‡ำ™ะบ.", - "confirmations.mute.message": "ะกะตะท ั‚ะฐะฒั‹ัˆะฝั‹ ัาฏะฝะดะตั€ะตั€ะณำ™ ั‚ะตะปะธัะตะท {name}?", "confirmations.redraft.confirm": "ะ‘ะตั‚ะตั€าฏ & ััˆะบำ™ั€ั‚าฏ", "confirmations.reply.confirm": "า–ะฐะฒะฐะฟ ะฑะธั€าฏ", "confirmations.reply.message": "ะขาปะตะฐะฒะฐะฟ ั…ำ™ะทะตั€ ัะตะท ััะฐะณะฐะฝ ั…ำ™ะฑำ™ั€ะฝะต ัาฃะฐะดะฐะฝ ัะทัƒะณะฐ ะบะธั‚ะตั€ำ™ั‡ำ™ะบ. ะกะตะท ะดำ™ะฒะฐะผ ะธั‚ำ™ัะตะณะตะท ะบะธะปำ™ะผะต?", @@ -236,7 +231,6 @@ "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.follow": "ะฅััˆั‚ะตะณะบะฐ ัะทั‹ะปัƒ", "hashtag.unfollow": "ะฅััˆั‚ะตะณะบะฐ ัะทั‹ะปัƒ ัŽะบ", - "home.column_settings.basic": "ะขำฉะฟ", "home.column_settings.show_reblogs": "ะขะฐะฑั‹ัˆะผะฐะบะปะฐัƒ", "home.column_settings.show_replies": "า–ะฐะฒะฐะฟะปะฐั€ ะบาฏั€ัำ™ั‚าฏ", "home.hide_announcements": "ะ˜ะณัŠะปะฐะฝะฝะฐั€ะฝั‹ ััˆะตั€าฏ", @@ -302,8 +296,6 @@ "lists.replies_policy.none": "าบะธั‡ะบะตะผ", "lists.subheading": "ะ˜ัะตะผะปะตะณะตะณะตะณะตะทะปำ™ั€", "load_pending": "{count, plural, one {# ัาฃะฐ ัะปะตะผะตะฝั‚} other {# ัาฃะฐ ัะปะตะผะตะฝั‚}}", - "mute_modal.duration": "ะ”ำ™ะฒะฐะผะปั‹ะบ", - "mute_modal.indefinite": "ะ‘ะธะปะณะตัะตะท", "navigation_bar.about": "ะŸั€ะพะตะบั‚ ั‚ัƒั€ั‹ะฝะดะฐ", "navigation_bar.blocks": "ะ‘ะปะพะบะปะฐะฝะณะฐะฝ ะบัƒะปะปะฐะฝัƒั‡ั‹ะปะฐั€", "navigation_bar.bookmarks": "ะšั‹ัั‚ั‹ั€ะณั‹ั‡ะปะฐั€", @@ -415,7 +407,6 @@ "search_results.statuses": "ะฏะทะผะฐะปะฐั€", "search_results.title": "{q} ำฉั‡ะตะฝ ัะทะปำ™าฏ", "server_banner.administered_by": "ะ˜ะดะฐั€ำ™ ะธั‚าฏั‡ะต:", - "server_banner.learn_more": "ะšาฏะฑั€ำ™ะบ ะฑะตะปาฏ", "server_banner.server_stats": "ะกะตั€ะฒะตั€ ัั‚ะฐั‚ะธัั‚ะธะบะฐัั‹:", "sign_in_banner.create_account": "ะะบะบะฐัƒะฝั‚ะฝั‹ ััะฐัƒ", "sign_in_banner.sign_in": "ะšะตั€าฏ", @@ -426,7 +417,6 @@ "status.delete": "ะ‘ะตั‚ะตั€าฏ", "status.direct_indicator": "ะฅะพััƒัั‹ะน ะธัะบำ™ ะฐะปัƒ", "status.edit": "าฎะทะณำ™ั€ั‚าฏ", - "status.edited": "{date} ะบำฉะฝะฝะต ั‚ำฉะทำ™ั‚ั‚ะต", "status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}", "status.embed": "ะ’ะตะฑ-ะฑะธั‚ะบำ™ ะบะตั€ั‚าฏ", "status.filtered": "ะกำฉะทะตะปะณำ™ะฝ", @@ -458,9 +448,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/ug.json b/app/javascript/mastodon/locales/ug.json index 9dc3b5c1f9..4120d4483b 100644 --- a/app/javascript/mastodon/locales/ug.json +++ b/app/javascript/mastodon/locales/ug.json @@ -17,7 +17,6 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmations.delete.message": "Are you sure you want to delete this status?", - "confirmations.domain_block.confirm": "Hide entire domain", "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.", "embed.instructions": "Embed this status on your website by copying the code below.", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 0504ec60d8..22cd15bd23 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.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": "ะะตะผะพะถะปะธะฒะพ ะฟะพะบะฐะทะฐั‚ะธ ะทะฐะฟะธั‚ะฐะฝัƒ ัั‚ะพั€ั–ะฝะบัƒ. ะฆะต ะผะพะถะต ะฑัƒั‚ะธ ัะฟั€ะธั‡ะธะฝะตะฝะพ ะฟะพะผะธะปะบะพัŽ ัƒ ะฝะฐัˆะพะผัƒ ะบะพะดั–, ะฐะฑะพ ั‡ะตั€ะตะท ะฟั€ะพะฑะปะตะผัƒ ััƒะผั–ัะฝะพัั‚ั– ะท ะฑั€ะฐัƒะทะตั€ะพะผ.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ะ”ะพะดะฐั‚ะธ ะฟะพะฟะตั€ะตะดะถะตะฝะฝั ะฟั€ะพ ะฒะผั–ัั‚", "compose_form.spoiler_placeholder": "ะŸะพะฟะตั€ะตะดะถะตะฝะฝั ะฟั€ะพ ะฒะผั–ัั‚ (ะฝะตะพะฑะพะฒ'ัะทะบะพะฒะพ)", "confirmation_modal.cancel": "ะกะบะฐััƒะฒะฐั‚ะธ", - "confirmations.block.block_and_report": "ะ—ะฐะฑะปะพะบัƒะฒะฐั‚ะธ ั‚ะฐ ะฟะพัะบะฐั€ะถะธั‚ะธัั", "confirmations.block.confirm": "ะ—ะฐะฑะปะพะบัƒะฒะฐั‚ะธ", - "confirmations.block.message": "ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะทะฐะฑะปะพะบัƒะฒะฐั‚ะธ {name}?", "confirmations.cancel_follow_request.confirm": "ะ’ั–ะดะบะปะธะบะฐั‚ะธ ะทะฐะฟะธั‚", "confirmations.cancel_follow_request.message": "ะ’ะธ ะดั–ะนัะฝะพ ะฑะฐะถะฐั”ั‚ะต ะฒั–ะดะบะปะธะบะฐั‚ะธ ะทะฐะฟะธั‚ ะฝะฐ ัั‚ะตะถะตะฝะฝั ะทะฐ {name}?", "confirmations.delete.confirm": "ะ’ะธะดะฐะปะธั‚ะธ", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะฒะธะดะฐะปะธั‚ะธ ั†ะตะน ัะฟะธัะพะบ ะฝะฐะทะฐะฒะถะดะธ?", "confirmations.discard_edit_media.confirm": "ะ’ั–ะดะบะธะฝัƒั‚ะธ", "confirmations.discard_edit_media.message": "ะฃ ะฒะฐั ั” ะฝะตะทะฑะตั€ะตะถะตะฝั– ะทะผั–ะฝะธ ะฒ ะพะฟะธัั– ะผะตะดั–ะฐ ะฐะฑะพ ะฟะพะฟะตั€ะตะดะฝัŒะพะณะพ ะฟะตั€ะตะณะปัะดัƒ, ะฒัะต ะพะดะฝะพ ะฒั–ะดะบะธะฝัƒั‚ะธ ั—ั…?", - "confirmations.domain_block.confirm": "ะ—ะฐะฑะปะพะบัƒะฒะฐั‚ะธ ะฒะตััŒ ะดะพะผะตะฝ", + "confirmations.domain_block.confirm": "ะ‘ะปะพะบัƒะฒะฐั‚ะธ ัะตั€ะฒะตั€", "confirmations.domain_block.message": "ะ’ะธ ั‚ะพั‡ะฝะพ, ั‚ะพั‡ะฝะพ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะทะฐะฑะปะพะบัƒะฒะฐั‚ะธ ะฒะตััŒ ะดะพะผะตะฝ {domain}? ะฃ ะฑั–ะปัŒัˆะพัั‚ั– ะฒะธะฟะฐะดะบั–ะฒ ะดะปั ะฝะพั€ะผะฐะปัŒะฝะพั— ั€ะพะฑะพั‚ะธ ะบั€ะฐั‰ะต ะทะฐะฑะปะพะบัƒะฒะฐั‚ะธ ะฐะฑะพ ะฟั€ะธั…ะพะฒะฐั‚ะธ ะปะธัˆะต ะดะตัะบะธั… ะบะพั€ะธัั‚ัƒะฒะฐั‡ั–ะฒ. ะ’ะธ ะฝะต ะทะผะพะถะตั‚ะต ะฑะฐั‡ะธั‚ะธ ะบะพะฝั‚ะตะฝั‚ ะท ั†ัŒะพะณะพ ะดะพะผะตะฝัƒ ัƒ ะฑัƒะดัŒ-ัะบะธั… ัั‚ั€ั–ั‡ะบะฐั… ะฐะฑะพ ะฒะฐัˆะธั… ัะฟะพะฒั–ั‰ะตะฝะฝัั…. ะ’ะฐัˆั– ะฟั–ะดะฟะธัะฝะธะบะธ ะท ั†ัŒะพะณะพ ะดะพะผะตะฝัƒ ะฑัƒะดัƒั‚ัŒ ะฒั–ะดะฟะธัะฐะฝั– ะฒั–ะด ะฒะฐั.", "confirmations.edit.confirm": "ะ—ะผั–ะฝะธั‚ะธ", "confirmations.edit.message": "ะ ะตะดะฐะณัƒะฒะฐะฝะฝั ะฟะตั€ะตะทะฐะฟะธัˆะต ะฟะพะฒั–ะดะพะผะปะตะฝะฝั, ัะบะต ะฒะธ ะทะฐั€ะฐะท ะฟะธัˆะตั‚ะต. ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะฟั€ะพะดะพะฒะถะธั‚ะธ?", "confirmations.logout.confirm": "ะ’ะธะนั‚ะธ", "confirmations.logout.message": "ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะฒะธะนั‚ะธ?", "confirmations.mute.confirm": "ะŸั€ะธั…ะพะฒะฐั‚ะธ", - "confirmations.mute.explanation": "ะฆะต ัั…ะพะฒะฐั” ะดะพะฟะธัะธ ะฒั–ะด ะฝะธั… ั– ะดะพะฟะธัะธ ะทั– ะทะณะฐะดะบะฐะผะธ ะฟั€ะพ ะฝะธั…, ะฟั€ะพั‚ะต ะฒะพะฝะธ ะฒัะต ะพะดะฝะพ ะผะฐั‚ะธะผัƒั‚ัŒ ะทะผะพะณัƒ ะฑะฐั‡ะธั‚ะธ ะฒะฐัˆั– ะดะพะฟะธัะธ ะน ะฟั–ะดะฟะธััƒะฒะฐั‚ะธัั ะฝะฐ ะฒะฐั.", - "confirmations.mute.message": "ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะฟั€ะธั…ะพะฒะฐั‚ะธ {name}?", "confirmations.redraft.confirm": "ะ’ะธะดะฐะปะธั‚ะธ ั‚ะฐ ะฒะธะฟั€ะฐะฒะธั‚ะธ", "confirmations.redraft.message": "ะ’ะธ ะฒะฟะตะฒะฝะตะฝั–, ั‰ะพ ั…ะพั‡ะตั‚ะต ะฒะธะดะฐะปะธั‚ะธ ั†ะตะน ะดะพะฟะธั ั‚ะฐ ะฟะตั€ะตะฟะธัะฐั‚ะธ ะนะพะณะพ? ะ”ะพะดะฐะฒะฐะฝะฝั ัƒ ะฒะธะฑั€ะฐะฝะต ั‚ะฐ ะฟะพัˆะธั€ะตะฝะฝั ะฑัƒะดะต ะฒั‚ั€ะฐั‡ะตะฝะพ, ะฐ ะฒั–ะดะฟะพะฒั–ะดั– ะฝะฐ ะพั€ะธะณั–ะฝะฐะปัŒะฝะธะน ะดะพะฟะธั ะทะฐะปะธัˆะฐั‚ัŒัั ะฑะตะท ะฟะตั€ัˆะพะดะถะตั€ะตะปะฐ.", "confirmations.reply.confirm": "ะ’ั–ะดะฟะพะฒั–ัั‚ะธ", @@ -205,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 - ั†ะต ัะบ ะผะพะฒะฐ, ัะบะพัŽ ะœะฐัั‚ะพะดะพะฝั‚ ั€ะพะทะผะพะฒะปัั” ะท ั–ะฝัˆะธะผะธ ัะพั†ั–ะฐะปัŒะฝะธะผะธ ะผะตั€ะตะถะฐะผะธ.", + "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": "ะ”ั–ัะปัŒะฝั–ัั‚ัŒ", @@ -241,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": "ะงะตั€ะตะท ะฟะพะผะธะปะบัƒ ัƒ ะฝะฐัˆะพะผัƒ ะบะพะดั– ะฐะฑะพ ะฝะตััƒะผั–ัะฝั–ัั‚ัŒ ะฑั€ะฐัƒะทะตั€ะฐ, ั†ั ัั‚ะพั€ั–ะฝะบะฐ ะฝะต ะผะพะถะต ะฑัƒั‚ะธ ะทะพะฑั€ะฐะถะตะฝะฐ ะบะพั€ะตะบั‚ะฝะพ.", @@ -271,16 +297,28 @@ "filter_modal.select_filter.subtitle": "ะ’ะธะบะพั€ะธัั‚ะฐั‚ะธ ะฝะฐัะฒะฝัƒ ะบะฐั‚ะตะณะพั€ั–ัŽ ะฐะฑะพ ัั‚ะฒะพั€ะธั‚ะธ ะฝะพะฒัƒ", "filter_modal.select_filter.title": "ะคั–ะปัŒั‚ั€ัƒะฒะฐั‚ะธ ั†ะตะน ะดะพะฟะธั", "filter_modal.title.status": "ะคั–ะปัŒั‚ั€ัƒะฒะฐั‚ะธ ะดะพะฟะธั", + "filtered_notifications_banner.mentions": "{count, plural, one {mention} other {mentions}}", + "filtered_notifications_banner.pending_requests": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ะฒั–ะด {count, plural, =0 {ะถะพะดะฝะพั— ะพัะพะฑะธ} one {ะพะดะฝั–ั”ั— ะพัะพะฑะธ} few {# ะพัั–ะฑ} many {# ะพัั–ะฑ} 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.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}.", + "follow_suggestions.hints.most_interactions": "ะะตั‰ะพะดะฐะฒะฝะพ ั†ะตะน ะฟั€ะพั„ั–ะปัŒ ะพั‚ั€ะธะผะฐะฒ ะฑะฐะณะฐั‚ะพ ัƒะฒะฐะณะธ ะฝะฐ {domain}.", + "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": "ะ’ั–ะดัั‚ะตะถัƒะฒะฐะฝั– ั…ะตัˆั‚ะตา‘ะธ", @@ -309,7 +347,6 @@ "hashtag.follow": "ะกั‚ะตะถะธั‚ะธ ะทะฐ ั…ะตัˆั‚ะตะณะพะผ", "hashtag.unfollow": "ะะต ัั‚ะตะถะธั‚ะธ ะทะฐ ั…ะตัˆั‚ะตะณะพะผ", "hashtags.and_other": "โ€ฆั– {count, plural, other {ั‰ะต #}}", - "home.column_settings.basic": "ะžัะฝะพะฒะฝั–", "home.column_settings.show_reblogs": "ะŸะพะบะฐะทัƒะฒะฐั‚ะธ ะฟะพัˆะธั€ะตะฝะฝั", "home.column_settings.show_replies": "ะŸะพะบะฐะทัƒะฒะฐั‚ะธ ะฒั–ะดะฟะพะฒั–ะดั–", "home.hide_announcements": "ะŸั€ะธั…ะพะฒะฐั‚ะธ ะพะณะพะปะพัˆะตะฝะฝั", @@ -377,6 +414,7 @@ "limited_account_hint.action": "ะฃัะต ะพะดะฝะพ ะฟะพะบะฐะทะฐั‚ะธ ะฟั€ะพั„ั–ะปัŒ", "limited_account_hint.title": "ะฆะตะน ะฟั€ะพั„ั–ะปัŒ ัั…ะพะฒะฐะปะธ ะผะพะดะตั€ะฐั‚ะพั€ะธ {domain}.", "link_preview.author": "ะ’ั–ะด {name}", + "link_preview.more_from_author": "ะ‘ั–ะปัŒัˆะต ะฒั–ะด {name}", "lists.account.add": "ะ”ะพะดะฐั‚ะธ ะดะพ ัะฟะธัะบัƒ", "lists.account.remove": "ะ’ะธะปัƒั‡ะธั‚ะธ ะทั– ัะฟะธัะบัƒ", "lists.delete": "ะ’ะธะดะฐะปะธั‚ะธ ัะฟะธัะพะบ", @@ -395,9 +433,15 @@ "loading_indicator.label": "ะ—ะฐะฒะฐะฝั‚ะฐะถะตะฝะฝัโ€ฆ", "media_gallery.toggle_visible": "{number, plural, one {ะŸั€ะธั…ะพะฒะฐั‚ะธ ะทะพะฑั€ะฐะถะตะฝะฝั} other {ะŸั€ะธั…ะพะฒะฐั‚ะธ ะทะพะฑั€ะฐะถะตะฝะฝั}}", "moved_to_account_banner.text": "ะ’ะฐัˆ ะพะฑะปั–ะบะพะฒะธะน ะทะฐะฟะธั {disabledAccount} ะฝะฐั€ะฐะทั– ะฒะธะผะบะฝะตะฝะธะน, ะพัะบั–ะปัŒะบะธ ะฒะฐั ะฟะตั€ะตะฝะตัะตะฝะพ ะดะพ {movedToAccount}.", - "mute_modal.duration": "ะขั€ะธะฒะฐะปั–ัั‚ัŒ", - "mute_modal.hide_notifications": "ะกั…ะพะฒะฐั‚ะธ ัะฟะพะฒั–ั‰ะตะฝะฝั ั†ัŒะพะณะพ ะบะพั€ะธัั‚ัƒะฒะฐั‡ะฐ?", - "mute_modal.indefinite": "ะะตะฒะธะทะฝะฐั‡ะตะฝะธะน ัั‚ั€ะพะบ", + "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": "ะ—ะฐะฑะปะพะบะพะฒะฐะฝั– ะบะพั€ะธัั‚ัƒะฒะฐั‡ั–", @@ -430,11 +474,29 @@ "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.relationships_severance_event": "ะ’ั‚ั€ะฐั‡ะตะฝะพ ะท'ั”ะดะฝะฐะฝะฝั ะท {name}", + "notification.relationships_severance_event.account_suspension": "ะะดะผั–ะฝั–ัั‚ั€ะฐั‚ะพั€ ะท {from} ะฟั€ะธะทัƒะฟะธะฝะธะฒ {target}, ั‰ะพ ะพะทะฝะฐั‡ะฐั”, ั‰ะพ ะฒะธ ะฑั–ะปัŒัˆะต ะฝะต ะผะพะถะตั‚ะต ะพั‚ั€ะธะผัƒะฒะฐั‚ะธ ะพะฝะพะฒะปะตะฝะฝั ะฒั–ะด ะฝะธั… ะฐะฑะพ ะฒะทะฐั”ะผะพะดั–ัั‚ะธ ะท ะฝะธะผะธ.", + "notification.relationships_severance_event.domain_block": "ะะดะผั–ะฝั–ัั‚ั€ะฐั‚ะพั€ ะท {from} ะทะฐะฑะปะพะบัƒะฒะฐะฒ {target}, ะฒะบะปัŽั‡ะฐัŽั‡ะธ {followersCount} ะฒะฐัˆะธั… ะฟั–ะดะฟะธัะฝะธะบั–ะฒ ั– {{followingCount, plural, one {# account} other {# accounts}}, ะฝะฐ ัะบั– ะฒะธ ะฟั–ะดะฟะธัะฐะฝั–.", + "notification.relationships_severance_event.learn_more": "ะ”ั–ะทะฝะฐั‚ะธัั ะฑั–ะปัŒัˆะต", + "notification.relationships_severance_event.user_domain_block": "ะ’ะธ ะทะฐะฑะปะพะบัƒะฒะฐะปะธ {target}, ะฒะธะดะฐะปะธะฒัˆะธ {followersCount} ะฒะฐัˆะธั… ะฟั–ะดะฟะธัะฝะธะบั–ะฒ ั– {followingCount, plural, one {# account} other {# accounts}}, ะทะฐ ัะบะธะผะธ ะฒะธ ัั‚ะตะถะธั‚ะต.", "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": "ะะพะฒั– ัะบะฐั€ะณะธ:", @@ -442,8 +504,7 @@ "notifications.column_settings.alert": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ัั‚ั–ะปัŒะฝะธั†ั–", "notifications.column_settings.favourite": "ะฃะฟะพะดะพะฑะฐะฝะต:", "notifications.column_settings.filter_bar.advanced": "ะŸะพะบะฐะทะฐั‚ะธ ะฒัั– ะบะฐั‚ะตะณะพั€ั–ั—", - "notifications.column_settings.filter_bar.category": "ะŸะฐะฝะตะปัŒ ัˆะฒะธะดะบะพะณะพ ั„ั–ะปัŒั‚ั€ัƒ", - "notifications.column_settings.filter_bar.show_bar": "ะŸะพะบะฐะทะฐั‚ะธ ะฟะฐะฝะตะปัŒ ั„ั–ะปัŒั‚ั€ะฐ", + "notifications.column_settings.filter_bar.category": "ะŸะฐะฝะตะปัŒ ัˆะฒะธะดะบะพะณะพ ั„ั–ะปัŒั‚ั€ะฐ", "notifications.column_settings.follow": "ะะพะฒั– ะฟั–ะดะฟะธัะฝะธะบะธ:", "notifications.column_settings.follow_request": "ะะพะฒั– ะทะฐะฟะธั‚ะธ ะฝะฐ ะฟั–ะดะฟะธัะบัƒ:", "notifications.column_settings.mention": "ะ—ะณะฐะดะบะธ:", @@ -469,6 +530,15 @@ "notifications.permission_denied": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ัั‚ั–ะปัŒะฝะธั†ั– ะฝะตะดะพัั‚ัƒะฟะฝั– ั‡ะตั€ะตะท ั€ะฐะฝั–ัˆะต ะฒั–ะดั…ะธะปะตะฝะธะน ะทะฐะฟะธั‚ ะดะพะทะฒะพะปั–ะฒ ะดะปั ะฑั€ะฐัƒะทะตั€ะฐ", "notifications.permission_denied_alert": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ะฝะต ะผะพะถะฝะฐ ะฒะฒั–ะผะบะฝัƒั‚ะธ ะพัะบั–ะปัŒะบะธ ัƒ ะดะพะทะฒะพะปั– ะฒะถะต ะฑัƒะปะพ ะฒั–ะดะผะพะฒะปะตะฝะพ ั€ะฐะฝั–ัˆะต", "notifications.permission_required": "ะกะฟะพะฒั–ั‰ะตะฝะฝั ะฝะฐ ัั‚ั–ะปัŒะฝะธั†ั– ะฝะต ะดะพัั‚ัƒะฟะฝั–, ะพัะบั–ะปัŒะบะธ ะฝะตะพะฑั…ั–ะดะฝะธะน ะดะพะทะฒั–ะป ะฝะต ะฝะฐะดะฐะฝะพ.", + "notifications.policy.filter_new_accounts.hint": "ะกั‚ะฒะพั€ะตะฝะพ ะฒะฟั€ะพะดะพะฒะถ {days, plural, one {ะพะดะฝะพะณะพ} few {# ะดะฝั–ะฒ} many {# ะดะฝั–ะฒ} other {# ะดะฝั}}", + "notifications.policy.filter_new_accounts_title": "ะะพะฒั– ะพะฑะปั–ะบะพะฒั– ะทะฐะฟะธัะธ", + "notifications.policy.filter_not_followers_hint": "ะ’ะบะปัŽั‡ะฐัŽั‡ะธ ะปัŽะดะตะน, ัะบั– ัั‚ะตะถะฐั‚ัŒ ะทะฐ ะฒะฐะผะธ ะผะตะฝัˆะต {days, plural, one {one day} other {# days}}", + "notifications.policy.filter_not_followers_title": "ะ›ัŽะดะธ ะฝะต ะฟั–ะดะฟะธัะฐะฝั– ะฝะฐ ะฒะฐั", + "notifications.policy.filter_not_following_hint": "ะ”ะพะบะธ ะฒะธ ะฝะต ัั…ะฒะฐะปัŽั”ั‚ะต ั—ั… ะฒั€ัƒั‡ะฝัƒ", + "notifications.policy.filter_not_following_title": "ะ›ัŽะดะธ, ะฝะฐ ัะบะธั… ะฒะธ ะฝะต ะฟั–ะดะฟะธัะฐะฝั–", + "notifications.policy.filter_private_mentions_hint": "ะ’ั–ะดั„ั–ะปัŒั‚ั€ะพะฒัƒั”ั‚ัŒัั, ัะบั‰ะพ ั†ะต ะฝะต ะฒั–ะดะฟะพะฒั–ะดัŒ ะฝะฐ ะฒะฐัˆัƒ ะฒะปะฐัะฝัƒ ะทะณะฐะดะบัƒ ะฐะฑะพ ัะบั‰ะพ ะฒะธ ะฒั–ะดัั‚ะตะถัƒั”ั‚ะต ะฒั–ะดะฟั€ะฐะฒะฝะธะบะฐ", + "notifications.policy.filter_private_mentions_title": "ะะตะฑะฐะถะฐะฝั– ะฟั€ะธะฒะฐั‚ะฝั– ะทะณะฐะดะบะธ", + "notifications.policy.title": "ะ’ั–ะดั„ั–ะปัŒั‚ั€ัƒะฒะฐั‚ะธ ัะฟะพะฒั–ั‰ะตะฝะฝั ะฒั–ะดโ€ฆ", "notifications_permission_banner.enable": "ะฃะฒั–ะผะบะฝัƒั‚ะธ ัะฟะพะฒั–ั‰ะตะฝะฝั ัั‚ั–ะปัŒะฝะธั†ั–", "notifications_permission_banner.how_to_control": "ะฉะพะฑ ะพั‚ั€ะธะผัƒะฒะฐั‚ะธ ัะฟะพะฒั–ั‰ะตะฝะฝั, ะบะพะปะธ Mastodon ะฝะต ะฒั–ะดะบั€ะธั‚ะพ, ัƒะฒั–ะผะบะฝั–ั‚ัŒ ัะฟะพะฒั–ั‰ะตะฝะฝั ัั‚ั–ะปัŒะฝะธั†ั–. ะ’ะธ ะผะพะถะตั‚ะต ะบะพะฝั‚ั€ะพะปัŽะฒะฐั‚ะธ, ัะบั– ั‚ะธะฟะธ ะฒะทะฐั”ะผะพะดั–ะน ัั‚ะฒะพั€ัŽัŽั‚ัŒ ัะฟะพะฒั–ั‰ะตะฝะฝั ั‡ะตั€ะตะท ะบะฝะพะฟะบัƒ {icon} ะฒะณะพั€ั– ะฟั–ัะปั ั—ั…ะฝัŒะพะณะพ ัƒะฒั–ะผะบะฝะตะฝะฝั.", "notifications_permission_banner.title": "ะะต ะฟั€ะพา‘ะฐะฒั‚ะต ะฝั–ั‡ะพะณะพ", @@ -625,13 +695,12 @@ "server_banner.about_active_users": "ะ›ัŽะดะธ, ัะบั– ะฒะธะบะพั€ะธัั‚ะพะฒัƒัŽั‚ัŒ ั†ะตะน ัะตั€ะฒะตั€ ะฟั€ะพั‚ัะณะพะผ ะพัั‚ะฐะฝะฝั–ั… 30 ะดะฝั–ะฒ (ะฉะพะผั–ััั‡ะฝั– ะะบั‚ะธะฒะฝั– ะšะพั€ะธัั‚ัƒะฒะฐั‡ั–)", "server_banner.active_users": "ะฐะบั‚ะธะฒะฝั– ะบะพั€ะธัั‚ัƒะฒะฐั‡ั–", "server_banner.administered_by": "ะะดะผั–ะฝั–ัั‚ั€ะฐั‚ะพั€:", - "server_banner.introduction": "{domain} ั” ั‡ะฐัั‚ะธะฝะพัŽ ะดะตั†ะตะฝั‚ั€ะฐะปั–ะทะพะฒะฐะฝะพั— ัะพั†ั–ะฐะปัŒะฝะพั— ะผะตั€ะตะถั– ะฒั–ะด {mastodon}.", - "server_banner.learn_more": "ะ”ั–ะทะฝะฐะนั‚ะตััŒ ะฑั–ะปัŒัˆะต", + "server_banner.is_one_of_many": "{domain} - ะพะดะธะฝ ะท ะฑะฐะณะฐั‚ัŒะพั… ะฝะตะทะฐะปะตะถะฝะธั… ัะตั€ะฒะตั€ั–ะฒ Mastodon, ัะบั– ะฒะธ ะผะพะถะตั‚ะต ะฒะธะบะพั€ะธัั‚ะฐั‚ะธ, ั‰ะพะฑ ะฑั€ะฐั‚ะธ ัƒั‡ะฐัั‚ัŒ ัƒ ั„ะตะดั–ะฒะตั€ั–.", "server_banner.server_stats": "ะกั‚ะฐั‚ะธัั‚ะธะบะฐ ัะตั€ะฒะตั€ะฐ:", "sign_in_banner.create_account": "ะกั‚ะฒะพั€ะธั‚ะธ ะพะฑะปั–ะบะพะฒะธะน ะทะฐะฟะธั", + "sign_in_banner.mastodon_is": "ะœะฐัั‚ะพะดะพะฝ - ะฝะฐะนะบั€ะฐั‰ะธะน ัะฟะพัั–ะฑ ะฟั€ะพะดะพะฒะถัƒะฒะฐั‚ะธ ัะฒะพัŽ ัะฟั€ะฐะฒัƒ.", "sign_in_banner.sign_in": "ะฃะฒั–ะนั‚ะธ", "sign_in_banner.sso_redirect": "ะฃะฒั–ะนะดั–ั‚ัŒ ะฐะฑะพ ะทะฐั€ะตั”ัั‚ั€ัƒะนั‚ะตััŒ", - "sign_in_banner.text": "ะฃะฒั–ะนะดั–ั‚ัŒ, ั‰ะพะฑ ัะปั–ะดะบัƒะฒะฐั‚ะธ ะทะฐ ะฟั€ะพั„ั–ะปัะผะธ ะฐะฑะพ ั…ะตัˆั‚ะตะณะฐะผะธ, ะฒะฟะพะดะพะฑะฐะฝะธะผะธ, ะดั–ะปะธั‚ะธัั ั– ะฒั–ะดะฟะพะฒั–ะดะฐั‚ะธ ะฝะฐ ะดะพะฟะธัะธ. ะ’ะธ ั‚ะฐะบะพะถ ะผะพะถะตั‚ะต ะฒะทะฐั”ะผะพะดั–ัั‚ะธ ะท ะฒะฐัˆะพะณะพ ะพะฑะปั–ะบะพะฒะพะณะพ ะทะฐะฟะธััƒ ะฝะฐ ั–ะฝัˆะพะผัƒ ัะตั€ะฒะตั€ั–.", "status.admin_account": "ะ’ั–ะดะบั€ะธั‚ะธ ั–ะฝั‚ะตั€ั„ะตะนั ะผะพะดะตั€ะฐั†ั–ั— ะดะปั @{name}", "status.admin_domain": "ะ’ั–ะดะบั€ะธั‚ะธ ั–ะฝั‚ะตั€ั„ะตะนั ะผะพะดะตั€ะฐั†ั–ั— ะดะปั {domain}", "status.admin_status": "ะ’ั–ะดะบั€ะธั‚ะธ ั†ะตะน ะดะพะฟะธั ะฒ ั–ะฝั‚ะตั€ั„ะตะนัั– ะผะพะดะตั€ะฐั†ั–ั—", @@ -645,10 +714,11 @@ "status.direct": "ะžัะพะฑะธัั‚ะฐ ะทะณะฐะดะบะฐ @{name}", "status.direct_indicator": "ะžัะพะฑะธัั‚ะฐ ะทะณะฐะดะบะฐ", "status.edit": "ะ ะตะดะฐะณัƒะฒะฐั‚ะธ", - "status.edited": "ะ’ั–ะดั€ะตะดะฐะณะพะฒะฐะฝะพ {date}", + "status.edited": "ะ’ะพัั‚ะฐะฝะฝั” ะทะผั–ะฝะตะฝะพ {date}", "status.edited_x_times": "ะ’ั–ะดั€ะตะดะฐะณะพะฒะฐะฝะพ {count, plural, one {{count} ั€ะฐะท} few {{count} ั€ะฐะทะธ} many {{counter} ั€ะฐะทั–ะฒ} other {{counter} ั€ะฐะทั–ะฒ}}", "status.embed": "ะ’ะฑัƒะดัƒะฒะฐั‚ะธ", "status.favourite": "ะฃะฟะพะดะพะฑะฐะฝะต", + "status.favourites": "{count, plural, one {ะฒะฟะพะดะพะฑะฐะฝะฝั} few {ะฒะฟะพะดะพะฑะฐะฝะฝั} many {ะฒะฟะพะดะพะฑะฐะฝัŒ} other {ะฒะฟะพะดะพะฑะฐะฝะฝั}}", "status.filter": "ะคั–ะปัŒั‚ั€ัƒะฒะฐั‚ะธ ั†ะตะน ะดะพะฟะธั", "status.filtered": "ะ’ั–ะดั„ั–ะปัŒั‚ั€ะพะฒะฐะฝะพ", "status.hide": "ะกั…ะพะฒะฐั‚ะธ ะดะพะฟะธั", @@ -669,6 +739,7 @@ "status.reblog": "ะŸะพัˆะธั€ะธั‚ะธ", "status.reblog_private": "ะŸะพัˆะธั€ะธั‚ะธ ะดะปั ะฟะพั‡ะฐั‚ะบะพะฒะพั— ะฐัƒะดะธั‚ะพั€ั–ั—", "status.reblogged_by": "{name} ะฟะพัˆะธั€ัŽั”", + "status.reblogs": "{count, plural, one {ะฟะพัˆะธั€ะตะฝะฝั} few {ะฟะพัˆะธั€ะตะฝะฝั} many {ะฟะพัˆะธั€ะตะฝัŒ} other {ะฟะพัˆะธั€ะตะฝะฝั}}", "status.reblogs.empty": "ะั–ั…ั‚ะพ ั‰ะต ะฝะต ะฟะพัˆะธั€ะธะฒ ั†ะตะน ะดะพะฟะธั. ะšะพะปะธ ั…ั‚ะพััŒ ั†ะต ะทั€ะพะฑะปัั‚ัŒ, ะฒะพะฝะธ ะฑัƒะดัƒั‚ัŒ ะทะพะฑั€ะฐะถะตะฝั– ั‚ัƒั‚.", "status.redraft": "ะ’ะธะดะฐะปะธั‚ะธ ั‚ะฐ ะฒะธะฟั€ะฐะฒะธั‚ะธ", "status.remove_bookmark": "ะ’ะธะดะฐะปะธั‚ะธ ะทะฐะบะปะฐะดะบัƒ", diff --git a/app/javascript/mastodon/locales/ur.json b/app/javascript/mastodon/locales/ur.json index fee2cc3a98..1b9f8d9691 100644 --- a/app/javascript/mastodon/locales/ur.json +++ b/app/javascript/mastodon/locales/ur.json @@ -26,8 +26,9 @@ "account.featured_tags.last_status_never": "ฺฉูˆุฆŒ ู…ุฑุงุณู„ ู†Œฺบ", "account.featured_tags.title": "{name} ฺฉ’ ู†ู…ุงŒุงฺบ Œุด ูนŒฺฏุฒ", "account.follow": "ูพŒุฑูˆŒ ฺฉุฑŒฺบ", + "account.follow_back": "ุงฺฉุงุคู†ูน ฺฉูˆ ูุงู„ูˆ ุจŒฺฉ ", "account.followers": "ูพŒุฑูˆฺฉุงุฑ", - "account.followers.empty": "\"ู†ูˆุฒ ุงุณ ุตุงุฑู ฺฉŒ ฺฉูˆุฆŒ ูพŒุฑูˆŒ ู†Œฺบ ฺฉุฑุชุง\".", + "account.followers.empty": "ู†ูˆุฒ ุงุณ ุตุงุฑู ฺฉŒ ฺฉูˆุฆŒ ูพŒุฑูˆŒ ู†Œฺบ ฺฉุฑุชุง.", "account.followers_counter": "{count, plural,one {{counter} ูพŒุฑูˆฺฉุงุฑ} other {{counter} ูพŒุฑูˆฺฉุงุฑ}}", "account.following": "ูุงู„ูˆ ฺฉุฑ ุฑ’ Œฺบ", "account.following_counter": "{count, plural, one {{counter} ูพŒุฑูˆŒ ฺฉุฑ ุฑ’ Œฺบ} other {{counter} ูพŒุฑูˆŒ ฺฉุฑ ุฑ’ Œฺบ}}", @@ -46,6 +47,7 @@ "account.mute_notifications_short": "ู†ูˆูนŒูŒฺฉŒุดู†ุฒ ฺฉูˆ ุฎุงู…ูˆุด ฺฉุฑŒฺบ", "account.mute_short": "ุฎุงู…ูˆุด", "account.muted": "ุฎุงู…ูˆุด ฺฉุฑุฏ", + "account.mutual": "ู…Œูˆฺ†ูˆู„ ุงฺฉุงุคู†ูน", "account.no_bio": "ฺฉูˆุฆŒ ุชูุตŒู„ ู†Œฺบ ุฏŒ ฺฏุฆŒ”", "account.open_original_page": "ุงุตู„ ุตูุญ ฺฉฺพูˆู„Œฺบ", "account.posts": "ูนูˆูน", @@ -64,7 +66,8 @@ "account.unmute": "@{name} ฺฉูˆ ุจุง ุขูˆุงุฒ ฺฉุฑŒฺบ", "account.unmute_notifications_short": "ู†ูˆูนŒูŒฺฉŒุดู†ุฒ ฺฉูˆ ุฎุงู…ูˆุด ู† ฺฉุฑŒฺบ", "account.unmute_short": "ฺฉูˆ ุฎุงู…ูˆุด ู† ฺฉุฑŒฺบ", - "account_note.placeholder": "Click to add a note", + "admin.dashboard.daily_retention": "ุงŒฺˆู…ู† ฺˆŒุด ุจูˆุฑฺˆ ฺฉูˆ ฺˆŒู„Œ ฺ†Œฺฉ ุงู† ฺฉุฑŒฺบ", + "admin.dashboard.monthly_retention": "ุงŒฺˆู…ู† ฺฉŒุด ุจูˆุฑฺˆ ฺฉูˆ ู…ู†ุชฺพู„Œ ฺ†Œฺฉ ุงู† ฺฉุฑŒฺบ", "admin.dashboard.retention.average": "ุงูˆุณุท", "admin.dashboard.retention.cohort_size": "ู†ุฆ’ Œุณุฑุฒ", "alert.rate_limited.message": "\"{retry_time, time, medium} ฺฉ’ ุจุนุฏ ฺฉูˆุดุด ฺฉุฑŒฺบ\".", @@ -121,20 +124,15 @@ "compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.unmarked": "Text is not hidden", "confirmation_modal.cancel": "ู…ู†ุณูˆุฎ", - "confirmations.block.block_and_report": "ุดฺฉุงŒุช ฺฉุฑŒฺบ ุงูˆุฑ ุจู„ุงฺฉ ฺฉุฑŒฺบ", "confirmations.block.confirm": "ุจู„ุงฺฉ", - "confirmations.block.message": "ฺฉŒุง ูˆุงู‚ุนŒ ุงู“ูพ {name} ฺฉูˆ ุจู„ุงฺฉ ฺฉุฑู†ุง ฺ†ุงุช’ ŒฺบุŸ", "confirmations.delete.confirm": "ฺˆŒู„Œูน", "confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete_list.confirm": "ฺˆŒู„Œูน", "confirmations.delete_list.message": "ฺฉŒุง ุขูพ ูˆุงู‚ุนŒ ุงุณ ูุฑุณุช ฺฉูˆ ู…ุณุชู‚ู„ ุทูˆุฑ ูพุฑ ฺˆŒู„Œูน ฺฉุฑู†ุง ฺ†ุงุช’ ŒฺบุŸ", - "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.message": "ฺฉŒุง ุขูพ ูˆุงู‚ุนŒุŒ ูˆุงู‚ุนŒ Œู‚Œู† ุฑฺฉฺพุช’ Œฺบ ฺฉ ุขูพ ูพูˆุฑ’ {domain} ฺฉูˆ ุจู„ุงฺฉ ฺฉุฑู†ุง ฺ†ุงุช’ ŒฺบุŸ ุฒŒุงุฏ ุชุฑ ู…ุนุงู…ู„ุงุช ู…Œฺบ ฺ†ู†ุฏ ูนุงุฑฺฏูนŒฺˆ ุจู„ุงฺฉุณ Œุง ุฎุงู…ูˆุด ฺฉุฑู†ุง ฺฉุงูŒ ุงูˆุฑ ุงูุถู„ Œฺบ” ุขูพ ุงุณ ฺˆูˆู…Œู† ฺฉุง ู…ูˆุงุฏ ฺฉุณŒ ุจฺพŒ ุนูˆุงู…Œ ูนุงุฆู… ู„ุงุฆู†ุฒ Œุง ุงูพู†Œ ุงุทู„ุงุนุงุช ู…Œฺบ ู†Œฺบ ุฏŒฺฉฺพŒฺบ ฺฏ’” ุงุณ ฺˆูˆู…Œู† ุณ’ ุขูพ ฺฉ’ ูพŒุฑูˆฺฉุงุฑูˆฺบ ฺฉูˆ ูนุง ุฏŒุง ุฌุงุฆ’ ฺฏุง”", "confirmations.logout.confirm": "ู„ุงฺฏ ุงู“ุคูน", "confirmations.logout.message": "ฺฉŒุง ูˆุงู‚ุนŒ ุงู“ูพ ู„ุงฺฏ ุงู“ุคูน ูˆู†ุง ฺ†ุงุช’ ŒฺบุŸ", "confirmations.mute.confirm": "ุฎุงู…ูˆุด", - "confirmations.mute.explanation": "Œ ุงู† ุณ’ ูพูˆุณูนุณ ุงูˆุฑ ุงู† ฺฉุง ุชุฐฺฉุฑ ฺฉุฑู†’ ูˆุงู„Œ ูพูˆุณูนุณ ฺฉูˆ ฺ†ฺพูพุงุฆ’ ฺฏุงุŒ ู„Œฺฉู† Œ ูพฺพุฑ ุจฺพŒ ุงู†Œฺบ ุขูพ ฺฉŒ ูพูˆุณูนุณ ุฏŒฺฉฺพู†’ ุงูˆุฑ ุขูพ ฺฉŒ ูพŒุฑูˆŒ ฺฉุฑู†’ ฺฉŒ ุงุฌุงุฒุช ุฏ’ ฺฏุง”", - "confirmations.mute.message": "ฺฉŒุง ูˆุงู‚ุนŒ ุงู“ูพ {name} ฺฉูˆ ุฎุงู…ูˆุด ฺฉุฑู†ุง ฺ†ุงุช’ ŒฺบุŸ", "confirmations.redraft.confirm": "ฺˆŒู„Œูน ฺฉุฑŒฺบ ุงูˆุฑ ุฏูˆุจุงุฑ ฺˆุฑุงููน ฺฉุฑŒฺบ", "confirmations.reply.confirm": "ุฌูˆุงุจ ุฏŒฺบ", "confirmations.reply.message": "ุงุจฺพŒ ุฌูˆุงุจ ุฏŒู†’ ุณ’ ูˆ ูพŒุบุงู… ุงูˆูˆุฑ ุฑุงุฆูน ูˆ ุฌุงุฆ’ ฺฏุง ุฌูˆ ุขูพ ูŒ ุงู„ุญุงู„ ู„ฺฉฺพ ุฑ’ Œฺบ” ฺฉŒุง ุขูพ ูˆุงู‚ุนŒ ุขฺฏ’ ุจฺ‘ฺพู†ุง ฺ†ุงุช’ ŒฺบุŸ", @@ -189,7 +187,6 @@ "hashtag.column_settings.tag_mode.any": "ุงู† ู…Œฺบ ุณ’ ฺฉูˆุฆŒ", "hashtag.column_settings.tag_mode.none": "ุงู† ู…Œฺบ ุณ’ ฺฉูˆุฆŒ ุจฺพŒ ู†Œฺบ", "hashtag.column_settings.tag_toggle": "ุงุณ ฺฉุงู„ู… ฺฉ’ ู„ุฆ’ ู…ุฒŒุฏ ูนŒฺฏุฒ ุดุงู…ู„ ฺฉุฑŒฺบ", - "home.column_settings.basic": "ุจู†ŒุงุฏŒ", "home.column_settings.show_reblogs": "ุงูุฒุงุฆุดุงุช ุฏฺฉฺพุงุฆŒฺบ", "home.column_settings.show_replies": "ุฌูˆุงุจุงุช ุฏฺฉฺพุงุฆŒฺบ", "intervals.full.days": "{number, plural, one {# ุฑูˆุฒ} other {# ุฑูˆุฒ}}", @@ -224,7 +221,6 @@ "keyboard_shortcuts.toot": "to start a brand new toot", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", - "mute_modal.indefinite": "ุบŒุฑ ู…ุนŒู†", "navigation_bar.blocks": "ู…ุณุฏูˆุฏ ุตุงุฑูŒู†", "navigation_bar.bookmarks": "ุจูฺฉ ู…ุงุฑฺฉุณ", "navigation_bar.community_timeline": "ู…ู‚ุงู…Œ ูนุงุฆู… ู„ุงุฆู†", @@ -253,7 +249,6 @@ "notifications.clear": "ุงุทู„ุงุนุงุช ูนุงุฆŒฺบ", "notifications.clear_confirmation": "ฺฉŒุง ุขูพ ูˆุงู‚ุนŒ ุงูพู†Œ ุชู…ุงู… ุงุทู„ุงุนุงุช ฺฉูˆ ุตุงู ฺฉุฑู†ุง ฺ†ุงุช’ ŒฺบุŸ", "notifications.column_settings.alert": "ฺˆŒุณฺฉ ูนุงูพ ุงุทู„ุงุนุงุช", - "notifications.column_settings.filter_bar.advanced": "ุชู…ุงู… ุฒู…ุฑ’ ุฏฺฉฺพุงุฆŒฺบ", "notifications.column_settings.status": "New toots:", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", diff --git a/app/javascript/mastodon/locales/uz.json b/app/javascript/mastodon/locales/uz.json index 8f231c8c77..77892914a4 100644 --- a/app/javascript/mastodon/locales/uz.json +++ b/app/javascript/mastodon/locales/uz.json @@ -132,9 +132,7 @@ "compose_form.spoiler.marked": "Kontent ogohlantirishini olib tashlang", "compose_form.spoiler.unmarked": "Kontent haqida ogohlantirish qo'shing", "confirmation_modal.cancel": "Bekor qilish", - "confirmations.block.block_and_report": "Bloklash va hisobot berish", "confirmations.block.confirm": "Bloklash", - "confirmations.block.message": "Haqiqatan ham {name}ni bloklamoqchimisiz?", "confirmations.cancel_follow_request.confirm": "Bekor qilish", "confirmations.cancel_follow_request.message": "Haqiqatan ham {name}ga obuna boสปlish soสปrovingizni qaytarib olmoqchimisiz?", "confirmations.delete.confirm": "Oสปchirish", @@ -143,13 +141,10 @@ "confirmations.delete_list.message": "Haqiqatan ham bu roสปyxatni butunlay oสปchirib tashlamoqchimisiz?", "confirmations.discard_edit_media.confirm": "Bekor qilish", "confirmations.discard_edit_media.message": "Sizda media tavsifi yoki oldindan koโ€˜rishda saqlanmagan oโ€˜zgarishlar bor, ular baribir bekor qilinsinmi?", - "confirmations.domain_block.confirm": "Butun domenni bloklash", "confirmations.domain_block.message": "Haqiqatan ham, {domain} ni butunlay bloklamoqchimisiz? Ko'pgina hollarda bir nechta maqsadli bloklar yoki ovozni o'chirish etarli va afzaldir. Siz oสปsha domendagi kontentni hech qanday umumiy vaqt jadvallarida yoki bildirishnomalaringizda koสปrmaysiz. Bu domendagi obunachilaringiz olib tashlanadi.", "confirmations.logout.confirm": "Chiqish", "confirmations.logout.message": "Chiqishingizga aminmisiz?", "confirmations.mute.confirm": "Ovozsiz", - "confirmations.mute.explanation": "Bu ulardagi postlar va ular haqida eslatib o'tilgan postlarni yashiradi, ammo bu ularga sizning postlaringizni ko'rish va sizni kuzatish imkonini beradi.", - "confirmations.mute.message": "Haqiqatan ham {name} ovozini oโ€˜chirib qoโ€˜ymoqchimisiz?", "confirmations.redraft.confirm": "O'chirish va qayta loyihalash", "confirmations.reply.confirm": "Javob berish", "confirmations.reply.message": "Hozir javob bersangiz, hozir yozayotgan xabaringiz ustidan yoziladi. Davom etishni xohlaysizmi?", @@ -255,7 +250,6 @@ "hashtag.column_settings.tag_toggle": "Ushbu ustun uchun qo'shimcha teglarni qo'shing", "hashtag.follow": "Hashtagni kuzatish", "hashtag.unfollow": "Hashtagni kuzatishni to'xtatish", - "home.column_settings.basic": "Asos", "home.column_settings.show_reblogs": "Boostlarni ko'rish", "home.column_settings.show_replies": "Javoblarni ko'rish", "home.hide_announcements": "E'lonlarni yashirish", @@ -315,9 +309,6 @@ "load_pending": "{count, plural, one {# yangi element} other {# yangi elementlar}}", "media_gallery.toggle_visible": "{number, plural, one {Rasmni yashirish} other {Rasmlarni yashirish}}", "moved_to_account_banner.text": "{movedToAccount} hisobiga koสปchganingiz uchun {disabledAccount} hisobingiz hozirda oสปchirib qoสปyilgan.", - "mute_modal.duration": "Davomiyligi", - "mute_modal.hide_notifications": "Bu foydalanuvchidan bildirishnomalar berkitilsinmi?", - "mute_modal.indefinite": "Cheksiz", "navigation_bar.about": "Haqida", "navigation_bar.blocks": "Bloklangan foydalanuvchilar", "navigation_bar.bookmarks": "Xatchoโ€˜plar", diff --git a/app/javascript/mastodon/locales/vi.json b/app/javascript/mastodon/locales/vi.json index 626f40783c..18f0fec3c5 100644 --- a/app/javascript/mastodon/locales/vi.json +++ b/app/javascript/mastodon/locales/vi.json @@ -89,6 +89,14 @@ "announcement.announcement": "Cรณ gรฌ mแป›i?", "attachments_list.unprocessed": "(chฦฐa xแปญ lรญ)", "audio.hide": "แบจn รขm thanh", + "block_modal.remote_users_caveat": "Chรบng tรดi sแบฝ yรชu cแบงu {domain} tรดn trแปng quyแบฟt ฤ‘แป‹nh cแปงa bแบกn. Tuy nhiรชn, viแป‡c tuรขn thแปง khรดng ฤ‘ฦฐแปฃc ฤ‘แบฃm bแบฃo vรฌ mแป™t sแป‘ mรกy chแปง cรณ thแปƒ xแปญ lรฝ viแป‡c chแบทn theo cรกch khรกc nhau. Cรกc tรบt cรดng khai vแบซn cรณ thแปƒ hiแปƒn thแป‹ ฤ‘แป‘i vแป›i ngฦฐแปi dรนng chฦฐa ฤ‘ฤƒng nhแบญp.", + "block_modal.show_less": "Thu gแปn", + "block_modal.show_more": "Hiแป‡n thรชm", + "block_modal.they_cant_mention": "Hแป khรดng thแปƒ nhแบฏc ฤ‘แบฟn hay theo dรตi bแบกn.", + "block_modal.they_cant_see_posts": "Bแบกn vร  hแป sแบฝ khรดng nhรฌn thแบฅy tรบt cแปงa nhau.", + "block_modal.they_will_know": "Hแป sแบฝ biแบฟt ฤ‘รฃ bแป‹ bแบกn chแบทn.", + "block_modal.title": "Chแบทn ngฦฐแปi nร y?", + "block_modal.you_wont_see_mentions": "Bแบกn sแบฝ khรดng nhรฌn thแบฅy tรบt cรณ nhแบฏc ฤ‘แบฟn hแป.", "boost_modal.combo": "Nhแบฅn {combo} ฤ‘แปƒ bแป qua bฦฐแป›c nร y", "bundle_column_error.copy_stacktrace": "Sao chรฉp bรกo lแป—i", "bundle_column_error.error.body": "Khรดng thแปƒ hiแป‡n trang nร y. ฤรขy cรณ thแปƒ lร  mแป™t lแป—i trong mรฃ lแบญp trรฌnh cแปงa chรบng tรดi, hoแบทc lร  vแบฅn ฤ‘แป tฦฐฦกng thรญch cแปงa trรฌnh duyแป‡t.", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "Tแบกo nแป™i dung แบฉn", "compose_form.spoiler_placeholder": "Nแป™i dung แบฉn (tรนy chแปn)", "confirmation_modal.cancel": "Hแปงy bแป", - "confirmations.block.block_and_report": "Chแบทn & Bรกo cรกo", "confirmations.block.confirm": "Chแบทn", - "confirmations.block.message": "Bแบกn cรณ thแบญt sแปฑ muแป‘n chแบทn {name}?", "confirmations.cancel_follow_request.confirm": "Thu hแป“i yรชu cแบงu", "confirmations.cancel_follow_request.message": "Bแบกn cรณ chแบฏc muแป‘n thu hแป“i yรชu cแบงu theo dรตi cแปงa bแบกn vแป›i {name}?", "confirmations.delete.confirm": "Xรณa bแป", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "Bแบกn thแบญt sแปฑ muแป‘n xรณa vฤฉnh viแป…n danh sรกch nร y?", "confirmations.discard_edit_media.confirm": "Bแป qua", "confirmations.discard_edit_media.message": "Bแบกn chฦฐa lฦฐu thay ฤ‘แป•i ฤ‘แป‘i vแป›i phแบงn mรด tแบฃ hoแบทc bแบฃn xem trฦฐแป›c cแปงa media, vแบซn bแป luรดn?", - "confirmations.domain_block.confirm": "แบจn toร n bแป™ mรกy chแปง", + "confirmations.domain_block.confirm": "Chแบทn mรกy chแปง", "confirmations.domain_block.message": "Bแบกn thแบญt sแปฑ muแป‘n แบฉn toร n bแป™ nแป™i dung tแปซ {domain}? Sแบฝ hแปฃp lรฝ hฦกn nแบฟu bแบกn chแป‰ chแบทn hoแบทc แบฉn mแป™t vร i tร i khoแบฃn cแปฅ thแปƒ. แบจn toร n bแป™ nแป™i dung tแปซ mรกy chแปง sแบฝ khiแบฟn bแบกn khรดng cรฒn thแบฅy nแป™i dung tแปซ mรกy chแปง ฤ‘รณ แปŸ bแบฅt kแปณ nฦกi nร o, kแปƒ cแบฃ thรดng bรกo. Ngฦฐแปi quan tรขm bแบกn tแปซ mรกy chแปง ฤ‘รณ cลฉng sแบฝ bแป‹ xรณa luรดn.", "confirmations.edit.confirm": "Sแปญa", "confirmations.edit.message": "Nแป™i dung tรบt cลฉ sแบฝ bแป‹ ghi ฤ‘รจ, bแบกn cรณ tiแบฟp tแปฅc?", "confirmations.logout.confirm": "ฤฤƒng xuแบฅt", "confirmations.logout.message": "Bแบกn cรณ thแบญt sแปฑ muแป‘n thoรกt?", "confirmations.mute.confirm": "แบจn", - "confirmations.mute.explanation": "ฤiแปu nร y sแบฝ khiแบฟn tรบt cแปงa hแป vร  nhแปฏng tรบt cรณ nhแบฏc ฤ‘แบฟn hแป bแป‹ แบฉn, tuy nhiรชn hแป vแบซn cรณ thแปƒ xem tรบt cแปงa bแบกn vร  theo dรตi bแบกn.", - "confirmations.mute.message": "Bแบกn thแบญt sแปฑ muแป‘n แบฉn {name}?", "confirmations.redraft.confirm": "Xรณa & viแบฟt lแบกi", "confirmations.redraft.message": "Bแบกn thแบญt sแปฑ muแป‘n xรณa tรบt vร  viแบฟt lแบกi? ฤiแปu nร y sแบฝ xรณa mแบฅt nhแปฏng lฦฐแปฃt thรญch vร  ฤ‘ฤƒng lแบกi cแปงa tรบt, cลฉng nhฦฐ nhแปฏng trแบฃ lแปi sแบฝ khรดng cรฒn nแป™i dung gแป‘c.", "confirmations.reply.confirm": "Trแบฃ lแปi", @@ -205,6 +209,27 @@ "dismissable_banner.explore_statuses": "ฤรขy lร  nhแปฏng tรบt ฤ‘ang phแป• biแบฟn trong mแบกng liรชn hแปฃp cแปงa mรกy chแปง nร y.", "dismissable_banner.explore_tags": "ฤรขy lร  nhแปฏng hashtag ฤ‘ang ฤ‘ฦฐแปฃc sแปญ dแปฅng nhiแปu trong mแบกng liรชn hแปฃp cแปงa mรกy chแปง nร y.", "dismissable_banner.public_timeline": "ฤรขy lร  nhแปฏng tรบt cรดng khai gแบงn ฤ‘รขy trong mแบกng liรชn hแปฃp cแปงa mรกy chแปง {domain}.", + "domain_block_modal.block": "Chแบทn mรกy chแปง", + "domain_block_modal.block_account_instead": "Chแป‰ chแบทn {name}", + "domain_block_modal.they_can_interact_with_old_posts": "Thร nh viรชn mรกy chแปง nร y cรณ thแปƒ tฦฐฦกng tรกc vแป›i cรกc tรบt cลฉ cแปงa bแบกn.", + "domain_block_modal.they_cant_follow": "Khรดng ai trรชn mรกy chแปง nร y cรณ thแปƒ theo dรตi bแบกn.", + "domain_block_modal.they_wont_know": "Hแป sแบฝ khรดng biแบฟt ฤ‘รฃ bแป‹ bแบกn chแบทn.", + "domain_block_modal.title": "Chแบทn mรกy chแปง?", + "domain_block_modal.you_will_lose_followers": "Nhแปฏng ngฦฐแปi theo dรตi bแบกn แปŸ mรกy chแปง nร y sแบฝ bแป‹ xรณa.", + "domain_block_modal.you_wont_see_posts": "Bแบกn sแบฝ khรดng thแบฅy tรบt hoแบทc thรดng bรกo tแปซ thร nh viรชn mรกy chแปง nร y.", + "domain_pill.activitypub_lets_connect": "Nรณ cho phรฉp bแบกn kแบฟt nแป‘i vร  tฦฐฦกng tรกc vแป›i mแปi ngฦฐแปi khรดng chแป‰ trรชn Mastodon mร  cรฒn trรชn cรกc แปฉng dแปฅng xรฃ hแป™i khรกc.", + "domain_pill.activitypub_like_language": "ActivityPub giแป‘ng nhฦฐ ngรดn ngแปฏ Mastodon giao tiแบฟp vแป›i cรกc mแบกng xรฃ hแป™i khรกc.", + "domain_pill.server": "Mรกy chแปง", + "domain_pill.their_handle": "ฤแป‹a chแป‰ Mastodon:", + "domain_pill.their_server": "Ngรดi nhร  kแปน thuแบญt sแป‘, nฦกi lฦฐu giแปฏ tรบt cแปงa ai ฤ‘รณ.", + "domain_pill.their_username": "Danh tรญnh duy nhแบฅt cแปงa hแป trรชn mรกy chแปง nร y. Cรณ thแปƒ cรณ tรชn ngฦฐแปi dรนng giแป‘ng nhau trรชn cรกc mรกy chแปง khรกc.", + "domain_pill.username": "Tรชn ngฦฐแปi dรนng", + "domain_pill.whats_in_a_handle": "ฤแป‹a chแป‰ Mastodon lร  gรฌ?", + "domain_pill.who_they_are": "Vรฌ ฤ‘แป‹a chแป‰ Mastodon cho biแบฟt mแป™t ngฦฐแปi lร  ai vร  hแป แปŸ ฤ‘รขu, nรชn bแบกn cรณ thแปƒ tฦฐฦกng tรกc vแป›i mแปi ngฦฐแปi trรชn cรกc nแปn tแบฃng cรณ .", + "domain_pill.who_you_are": "Vรฌ ฤ‘แป‹a chแป‰ Mastodon cho biแบฟt bแบกn lร  ai vร  bแบกn แปŸ ฤ‘รขu, nรชn bแบกn cรณ thแปƒ tฦฐฦกng tรกc vแป›i mแปi ngฦฐแปi trรชn cรกc nแปn tแบฃng cรณ .", + "domain_pill.your_handle": "ฤแป‹a chแป‰ Mastodon cแปงa bแบกn:", + "domain_pill.your_server": "Ngรดi nhร  kแปน thuแบญt sแป‘, nฦกi lฦฐu giแปฏ tรบt cแปงa bแบกn. Khรดng thรญch แปŸ ฤ‘รขy? Chuyแปƒn sang mรกy chแปง khรกc vร  mang theo ngฦฐแปi theo dรตi cแปงa bแบกn.", + "domain_pill.your_username": "Danh tรญnh duy nhแบฅt cแปงa bแบกn trรชn mรกy chแปง nร y. Cรณ thแปƒ cรณ tรชn ngฦฐแปi dรนng giแป‘ng bแบกn trรชn cรกc mรกy chแปง khรกc.", "embed.instructions": "Sao chรฉp ฤ‘oแบกn mรฃ dฦฐแป›i ฤ‘รขy vร  chรจn vร o trang web cแปงa bแบกn.", "embed.preview": "Nรณ sแบฝ hiแปƒn thแป‹ nhฦฐ vแบงy:", "emoji_button.activity": "Hoแบกt ฤ‘แป™ng", @@ -241,6 +266,7 @@ "empty_column.list": "Chฦฐa cรณ tรบt. Khi nhแปฏng ngฦฐแปi trong danh sรกch nร y ฤ‘ฤƒng tรบt mแป›i, chรบng sแบฝ xuแบฅt hiแป‡n แปŸ ฤ‘รขy.", "empty_column.lists": "Bแบกn chฦฐa tแบกo danh sรกch nร o.", "empty_column.mutes": "Bแบกn chฦฐa แบฉn bแบฅt kแปณ ai.", + "empty_column.notification_requests": "Sแบกch sแบฝ! Khรดng cรฒn gรฌ แปŸ ฤ‘รขy. Khi bแบกn nhแบญn ฤ‘ฦฐแปฃc thรดng bรกo mแป›i, chรบng sแบฝ xuแบฅt hiแป‡n แปŸ ฤ‘รขy theo cร i ฤ‘แบทt cแปงa bแบกn.", "empty_column.notifications": "Bแบกn chฦฐa cรณ thรดng bรกo nร o. Hรฃy thแปญ theo dรตi hoแบทc nhแบฏn riรชng cho ai ฤ‘รณ.", "empty_column.public": "Trแป‘ng trฦกn! Bแบกn hรฃy viแบฟt gรฌ ฤ‘รณ hoแบทc bแบฏt ฤ‘แบงu theo dรตi nhแปฏng ngฦฐแปi khรกc", "error.unexpected_crash.explanation": "Trang nร y cรณ thแปƒ khรดng hiแปƒn thแป‹ chรญnh xรกc do lแป—i lแบญp trรฌnh Mastodon hoแบทc vแบฅn ฤ‘แป tฦฐฦกng thรญch trรฌnh duyแป‡t.", @@ -271,16 +297,28 @@ "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แป™", "firehose.local": "Mรกy chแปง nร y", "firehose.remote": "Mรกy chแปง khรกc", - "follow_request.authorize": "Cho phรฉp", + "follow_request.authorize": "Chแบฅp nhแบญn", "follow_request.reject": "Tแปซ chแป‘i", "follow_requests.unlocked_explanation": "Mแบทc dรน tร i khoแบฃn cแปงa bแบกn ฤ‘ang แปŸ chแบฟ ฤ‘แป™ cรดng khai, quแบฃn trแป‹ viรชn cแปงa {domain} vแบซn tin rแบฑng bแบกn sแบฝ muแป‘n xem lแบกi yรชu cแบงu theo dรตi tแปซ nhแปฏng ngฦฐแปi khรกc.", - "follow_suggestions.curated_suggestion": "Lแปฑa chแปn cแปงa mรกy chแปง", + "follow_suggestions.curated_suggestion": "Gแปฃi รฝ tแปซ mรกy chแปง", "follow_suggestions.dismiss": "Khรดng hiแป‡n lแบกi", + "follow_suggestions.featured_longer": "Tuyแปƒn chแปn bแปŸi {domain}", + "follow_suggestions.friends_of_friends_longer": "Nแป•i tiแบฟng vแป›i nhแปฏng ngฦฐแปi mร  bแบกn theo dรตi", + "follow_suggestions.hints.featured": "Ngฦฐแปi nร y ฤ‘ฦฐแปฃc ฤ‘แป™i ngลฉ {domain} ฤ‘แป xuแบฅt.", + "follow_suggestions.hints.friends_of_friends": "Ngฦฐแปi nร y nแป•i tiแบฟng vแป›i nhแปฏng ngฦฐแปi bแบกn theo dรตi.", + "follow_suggestions.hints.most_followed": "Ngฦฐแปi nร y ฤ‘ฦฐแปฃc theo dรตi nhiแปu nhแบฅt trรชn {domain}.", + "follow_suggestions.hints.most_interactions": "Ngฦฐแปi nร y ฤ‘ang thu hรบt sแปฑ chรบ รฝ trรชn {domain}.", + "follow_suggestions.hints.similar_to_recently_followed": "Ngฦฐแปi nร y cรณ nรฉt giแป‘ng nhแปฏng ngฦฐแปi mร  bแบกn theo dรตi gแบงn ฤ‘รขy.", "follow_suggestions.personalized_suggestion": "Gแปฃi รฝ cรก nhรขn hรณa", "follow_suggestions.popular_suggestion": "Nhแปฏng ngฦฐแปi nแป•i tiแบฟng", + "follow_suggestions.popular_suggestion_longer": "Nแป•i tiแบฟng trรชn {domain}", + "follow_suggestions.similar_to_recently_followed_longer": "Tฦฐฦกng tแปฑ nhแปฏng ngฦฐแปi mร  bแบกn theo dรตi gแบงn ฤ‘รขy", "follow_suggestions.view_all": "Xem tแบฅt cแบฃ", "follow_suggestions.who_to_follow": "Gแปฃi รฝ theo dรตi", "followed_tags": "Hashtag theo dรตi", @@ -309,7 +347,6 @@ "hashtag.follow": "Theo dรตi hashtag", "hashtag.unfollow": "Bแป theo dรตi hashtag", "hashtags.and_other": "โ€ฆvร  {count, plural, other {# nแปฏa}}", - "home.column_settings.basic": "Tรนy chแป‰nh", "home.column_settings.show_reblogs": "Hiแป‡n nhแปฏng lฦฐแปฃt ฤ‘ฤƒng lแบกi", "home.column_settings.show_replies": "Hiแป‡n nhแปฏng tรบt dแบกng trแบฃ lแปi", "home.hide_announcements": "แบจn thรดng bรกo mรกy chแปง", @@ -357,7 +394,7 @@ "keyboard_shortcuts.my_profile": "mแปŸ hแป“ sฦก cแปงa bแบกn", "keyboard_shortcuts.notifications": "mแปŸ thรดng bรกo", "keyboard_shortcuts.open_media": "mแปŸ แบฃnh hoแบทc video", - "keyboard_shortcuts.pinned": "Open pinned posts list", + "keyboard_shortcuts.pinned": "mแปŸ nhแปฏng tรบt ฤ‘รฃ ghim", "keyboard_shortcuts.profile": "mแปŸ trang cแปงa ngฦฐแปi ฤ‘ฤƒng tรบt", "keyboard_shortcuts.reply": "trแบฃ lแปi", "keyboard_shortcuts.requests": "mแปŸ danh sรกch yรชu cแบงu theo dรตi", @@ -377,6 +414,8 @@ "limited_account_hint.action": "Vแบซn cแปฉ xem", "limited_account_hint.title": "Ngฦฐแปi nร y ฤ‘รฃ bแป‹ แบฉn bแปŸi quแบฃn trแป‹ viรชn cแปงa {domain}.", "link_preview.author": "BแปŸi {name}", + "link_preview.more_from_author": "Thรชm tแปซ {name}", + "link_preview.shares": "{count, plural, other {{counter} lฦฐแปฃt chia sแบป}}", "lists.account.add": "Thรชm vร o danh sรกch", "lists.account.remove": "Xรณa khแปi danh sรกch", "lists.delete": "Xรณa danh sรกch", @@ -395,9 +434,15 @@ "loading_indicator.label": "ฤang tแบฃiโ€ฆ", "media_gallery.toggle_visible": "{number, plural, other {แบจn hรฌnh แบฃnh}}", "moved_to_account_banner.text": "Tร i khoแบฃn {disabledAccount} cแปงa bแบกn hiแป‡n khรดng khแบฃ dแปฅng vรฌ bแบกn ฤ‘รฃ chuyแปƒn sang {movedToAccount}.", - "mute_modal.duration": "Thแปi hแบกn", - "mute_modal.hide_notifications": "แบจn thรดng bรกo tแปซ ngฦฐแปi nร y?", - "mute_modal.indefinite": "Vฤฉnh viแป…n", + "mute_modal.hide_from_notifications": "แบจn thรดng bรกo", + "mute_modal.hide_options": "Tรนy chแปn แบฉn", + "mute_modal.indefinite": "Cho tแป›i khi bแป แบฉn", + "mute_modal.show_options": "Hiแปƒn thแป‹ tรนy chแปn", + "mute_modal.they_can_mention_and_follow": "Hแป cรณ thแปƒ nhแบฏc ฤ‘แบฟn vร  theo dรตi bแบกn, nhฦฐng bแบกn khรดng thแบฅy hแป.", + "mute_modal.they_wont_know": "Hแป sแบฝ khรดng biแบฟt ฤ‘รฃ bแป‹ bแบกn แบฉn.", + "mute_modal.title": "แบจn ngฦฐแปi nร y?", + "mute_modal.you_wont_see_mentions": "Bแบกn sแบฝ khรดng nhรฌn thแบฅy tรบt cรณ nhแบฏc ฤ‘แบฟn hแป.", + "mute_modal.you_wont_see_posts": "Bแบกn sแบฝ khรดng nhรฌn thแบฅy tรบt cแปงa hแป.", "navigation_bar.about": "Giแป›i thiแป‡u", "navigation_bar.advanced_interface": "Dรนng bแป‘ cแปฅc nhiแปu cแป™t", "navigation_bar.blocks": "Ngฦฐแปi ฤ‘รฃ chแบทn", @@ -430,11 +475,29 @@ "notification.follow": "{name} theo dรตi bแบกn", "notification.follow_request": "{name} yรชu cแบงu theo dรตi bแบกn", "notification.mention": "{name} nhแบฏc ฤ‘แบฟn bแบกn", + "notification.moderation-warning.learn_more": "Tรฌm hiแปƒu", + "notification.moderation_warning": "Bแบกn vแปซa nhแบญn mแป™t cแบฃnh bรกo kiแปƒm duyแป‡t", + "notification.moderation_warning.action_delete_statuses": "Mแป™t vร i tรบt cแปงa bแบกn bแป‹ gแปก.", + "notification.moderation_warning.action_disable": "Tร i khoแบฃn cแปงa bแบกn ฤ‘รฃ bแป‹ vรด hiแป‡u hรณa.", + "notification.moderation_warning.action_mark_statuses_as_sensitive": "Vร i tรบt bแบกn bแป‹ ฤ‘รกnh dแบฅu nhแบกy cแบฃm.", + "notification.moderation_warning.action_none": "Bแบกn ฤ‘รฃ nhแบญn mแป™t cแบฃnh bรกo kiแปƒm duyแป‡t.", + "notification.moderation_warning.action_sensitive": "Tรบt cแปงa bแบกn sแบฝ bแป‹ ฤ‘รกnh dแบฅu nhแบกy cแบฃm kแปƒ tแปซ bรขy giแป.", + "notification.moderation_warning.action_silence": "Tร i khoแบฃn cแปงa bแบกn ฤ‘รฃ bแป‹ hแบกn chแบฟ.", + "notification.moderation_warning.action_suspend": "Tร i khoแบฃn cแปงa bแบกn ฤ‘รฃ bแป‹ vรด hiแป‡u hรณa.", "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.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", + "notification_requests.dismiss": "Bแป qua", + "notification_requests.notifications_from": "Thรดng bรกo tแปซ {name}", + "notification_requests.title": "Thรดng bรกo ฤ‘รฃ lแปc", "notifications.clear": "Xรณa hแบฟt thรดng bรกo", "notifications.clear_confirmation": "Bแบกn thแบญt sแปฑ muแป‘n xรณa vฤฉnh viแป…n tแบฅt cแบฃ thรดng bรกo cแปงa mรฌnh?", "notifications.column_settings.admin.report": "Bรกo cรกo mแป›i:", @@ -442,8 +505,7 @@ "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": "Phรขn loแบกi", - "notifications.column_settings.filter_bar.show_bar": "Hiแป‡n bแป™ lแปc", + "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:", @@ -469,6 +531,15 @@ "notifications.permission_denied": "Trรฌnh duyแป‡t khรดng cho phรฉp hiแปƒn thแป‹ thรดng bรกo trรชn mร n hรฌnh.", "notifications.permission_denied_alert": "Khรดng thแปƒ bแบญt thรดng bรกo trรชn mร n hรฌnh bแปŸi vรฌ trรฌnh duyแป‡t ฤ‘รฃ cแบฅm trฦฐแป›c ฤ‘รณ", "notifications.permission_required": "Khรดng hiแป‡n thรดng bรกo trรชn mร n hรฌnh bแปŸi vรฌ chฦฐa cho phรฉp.", + "notifications.policy.filter_new_accounts.hint": "ฤรฃ tแบกo trong vรฒng {days, plural, other {# ngร y}}", + "notifications.policy.filter_new_accounts_title": "Tร i khoแบฃn mแป›i", + "notifications.policy.filter_not_followers_hint": "Bao gแป“m nhแปฏng ngฦฐแปi ฤ‘รฃ theo dรตi bแบกn รญt hฦกn {days, plural, other {# ngร y}}", + "notifications.policy.filter_not_followers_title": "Nhแปฏng ngฦฐแปi khรดng theo dรตi bแบกn", + "notifications.policy.filter_not_following_hint": "Cho tแป›i khi bแบกn duyแป‡t hแป", + "notifications.policy.filter_not_following_title": "Nhแปฏng ngฦฐแปi bแบกn khรดng theo dรตi", + "notifications.policy.filter_private_mentions_hint": "ฤฦฐแปฃc lแปc trแปซ khi nรณ trแบฃ lแปi lฦฐแปฃt nhแบฏc tแปซ bแบกn hoแบทc nแบฟu bแบกn theo dรตi ngฦฐแปi gแปญi", + "notifications.policy.filter_private_mentions_title": "Lฦฐแปฃt nhแบฏc riรชng tฦฐ khรดng ฤ‘ฦฐแปฃc yรชu cแบงu", + "notifications.policy.title": "Lแปc ra thรดng bรกo tแปซโ€ฆ", "notifications_permission_banner.enable": "Cho phรฉp thรดng bรกo trรชn mร n hรฌnh", "notifications_permission_banner.how_to_control": "Hรฃy bแบญt thรดng bรกo trรชn mร n hรฌnh ฤ‘แปƒ khรดng bแป lแปก nhแปฏng thรดng bรกo tแปซ Mastodon. Mแป™t khi ฤ‘รฃ bแบญt, bแบกn cรณ thแปƒ lแปฑa chแปn tแปซng loแบกi thรดng bรกo khรกc nhau thรดng qua {icon} nรบt bรชn dฦฐแป›i.", "notifications_permission_banner.title": "Khรดng bแป lแปก ฤ‘iแปu thรบ vแป‹ nร o", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "Nhแปฏng ngฦฐแปi แปŸ mรกy chแปง nร y trong 30 ngร y qua (MAU)", "server_banner.active_users": "ngฦฐแปi hoแบกt ฤ‘แป™ng", "server_banner.administered_by": "Vแบญn hร nh:", - "server_banner.introduction": "{domain} lร  mแป™t phแบงn cแปงa mแบกng xรฃ hแป™i liรชn hแปฃp {mastodon}.", - "server_banner.learn_more": "Tรฌm hiแปƒu", + "server_banner.is_one_of_many": "{domain} lร  mแป™t trong nhiแปu mรกy chแปง Mastodon ฤ‘แป™c lแบญp mร  bแบกn cรณ thแปƒ sแปญ dแปฅng ฤ‘แปƒ tham gia vร o Fediverse.", "server_banner.server_stats": "Thแป‘ng kรช:", "sign_in_banner.create_account": "ฤฤƒng kรฝ", + "sign_in_banner.follow_anyone": "Theo dรตi bแบฅt kแปณ ai trรชn Fediverse vร  ฤ‘แปc tรบt theo thแปฉ tแปฑ thแปi gian. Khรดng thuแบญt toรกn, quแบฃng cรกo hoแบทc clickbait.", + "sign_in_banner.mastodon_is": "Mastodon lร  cรกch tแป‘t nhแบฅt ฤ‘แปƒ nแบฏm bแบฏt nhแปฏng gรฌ ฤ‘ang xแบฃy ra.", "sign_in_banner.sign_in": "ฤฤƒng nhแบญp", "sign_in_banner.sso_redirect": "ฤฤƒng nhแบญp", - "sign_in_banner.text": "ฤฤƒng nhแบญp ฤ‘แปƒ theo dรตi ngฦฐแปi hoแบทc hashtag, thรญch, chia sแบป vร  trแบฃ lแปi tรบt. Bแบกn cลฉng cรณ thแปƒ tฦฐฦกng tรกc tแปซ tร i khoแบฃn cแปงa mรฌnh trรชn mแป™t mรกy chแปง khรกc.", "status.admin_account": "MแปŸ giao diแป‡n quแบฃn trแป‹ @{name}", "status.admin_domain": "MแปŸ giao diแป‡n quแบฃn trแป‹ @{domain}", "status.admin_status": "MแปŸ tรบt nร y trong giao diแป‡n quแบฃn trแป‹", @@ -645,10 +716,11 @@ "status.direct": "Nhแบฏn riรชng @{name}", "status.direct_indicator": "Nhแบฏn riรชng", "status.edit": "Sแปญa", - "status.edited": "ฤรฃ sแปญa {date}", + "status.edited": "Sแปญa lแบงn cuแป‘i {date}", "status.edited_x_times": "ฤรฃ sแปญa {count, plural, other {{count} lแบงn}}", "status.embed": "Nhรบng", "status.favourite": "Thรญch", + "status.favourites": "{count, plural, other {lฦฐแปฃt thรญch}}", "status.filter": "Lแปc tรบt nร y", "status.filtered": "Bแป™ lแปc", "status.hide": "แบจn tรบt", @@ -669,6 +741,7 @@ "status.reblog": "ฤฤƒng lแบกi", "status.reblog_private": "ฤฤƒng lแบกi (Riรชng tฦฐ)", "status.reblogged_by": "{name} ฤ‘ฤƒng lแบกi", + "status.reblogs": "{count, plural, other {ฤ‘ฤƒng lแบกi}}", "status.reblogs.empty": "Tรบt nร y chฦฐa cรณ ai ฤ‘ฤƒng lแบกi. Nแบฟu cรณ, nรณ sแบฝ hiแปƒn thแป‹ แปŸ ฤ‘รขy.", "status.redraft": "Xรณa vร  viแบฟt lแบกi", "status.remove_bookmark": "Bแป lฦฐu", diff --git a/app/javascript/mastodon/locales/zgh.json b/app/javascript/mastodon/locales/zgh.json index a585838cd2..1d3a22108c 100644 --- a/app/javascript/mastodon/locales/zgh.json +++ b/app/javascript/mastodon/locales/zgh.json @@ -48,11 +48,9 @@ "compose_form.spoiler.unmarked": "Text is not hidden", "confirmation_modal.cancel": "โต™โต”", "confirmations.block.confirm": "โดณโดทโต", - "confirmations.block.message": "โต‰โต™ โตโต‰โตœ โตœโต…โต™โดท โดฐโดท โตœโดณโดทโตโดท {name}?", "confirmations.delete.confirm": "โดฝโดฝโต™", "confirmations.delete.message": "โต‰โต™ โตโต‰โตœ โตœโต…โต™โดท โดฐโดท โตœโดฝโดฝโต™โดท โตœโดฐโตฅโต•โต‰โดณโตœ โดฐ?", "confirmations.delete_list.confirm": "โดฝโดฝโต™", - "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.logout.confirm": "โดผโดผโต–", "confirmations.logout.message": "โต‰โต™ โตโต‰โตœ โตœโต…โต™โดท โดฐโดท โตœโดผโดผโต–โดท?", "confirmations.mute.confirm": "โตฅโตฅโต‰โตฅโต", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 9d0da95c81..3456f99d25 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -21,7 +21,7 @@ "account.blocked": "ๅทฒๅฑ่”ฝ", "account.browse_more_on_origin_server": "ๅœจๅŽŸๅง‹ไธชไบบ่ต„ๆ–™้กต้ขไธŠๆต่งˆ่ฏฆๆƒ…", "account.cancel_follow_request": "ๆ’คๅ›žๅ…ณๆณจ่ฏทๆฑ‚", - "account.copy": "ๅคๅˆถ่ต„ๆ–™ๅก้“พๆŽฅ", + "account.copy": "ๅคๅˆถไธชไบบ่ต„ๆ–™้“พๆŽฅ", "account.direct": "็งไธ‹ๆๅŠ @{name}", "account.disable_notifications": "ๅฝ“ @{name} ๅ‘ๅธƒๅ˜Ÿๆ–‡ๆ—ถไธ่ฆ้€š็Ÿฅๆˆ‘", "account.domain_blocked": "ๅŸŸๅๅทฒๅฑ่”ฝ", @@ -53,7 +53,7 @@ "account.mute_notifications_short": "ๅ…ณ้—ญ้€š็Ÿฅ", "account.mute_short": "้š่—", "account.muted": "ๅทฒ้š่—", - "account.mutual": "ไบ’็ฒ‰ๅฅฝๅ‹", + "account.mutual": "ไบ’็›ธๅ…ณๆณจ", "account.no_bio": "ๆœชๆไพ›ๆ่ฟฐใ€‚", "account.open_original_page": "ๆ‰“ๅผ€ๅŽŸๅง‹้กต้ข", "account.posts": "ๅ˜Ÿๆ–‡", @@ -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": "่ฏทๆฑ‚็š„้กต้ขๆ— ๆณ•ๆธฒๆŸ“๏ผŒๅฏ่ƒฝๆ˜ฏไปฃ็ ๅ‡บ็Žฐ้”™่ฏฏๆˆ–ๆต่งˆๅ™จๅญ˜ๅœจๅ…ผๅฎนๆ€ง้—ฎ้ข˜ใ€‚", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ๆทปๅŠ ๅ†…ๅฎน่ญฆๅ‘Š", "compose_form.spoiler_placeholder": "ๅ†…ๅฎน่ญฆๅ‘Š (ๅฏ้€‰)", "confirmation_modal.cancel": "ๅ–ๆถˆ", - "confirmations.block.block_and_report": "ๅฑ่”ฝไธŽไธพๆŠฅ", "confirmations.block.confirm": "ๅฑ่”ฝ", - "confirmations.block.message": "็กฎๅฎš่ฆๅฑ่”ฝ {name} ๅ—๏ผŸ", "confirmations.cancel_follow_request.confirm": "ๆ’คๅ›ž่ฏทๆฑ‚", "confirmations.cancel_follow_request.message": "็กฎๅฎšๆ’คๅ›žๅ…ณๆณจ {name} ็š„่ฏทๆฑ‚ๅ—๏ผŸ", "confirmations.delete.confirm": "ๅˆ ้™ค", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "็กฎๅฎšๆฐธไน…ๅˆ ้™ค่ฟ™ไธชๅˆ—่กจๅ—๏ผŸ", "confirmations.discard_edit_media.confirm": "ไธขๅผƒ", "confirmations.discard_edit_media.message": "ๆ‚จ่ฟ˜ๆœ‰ๆœชไฟๅญ˜็š„ๅช’ไฝ“ๆ่ฟฐๆˆ–้ข„่งˆไฟฎๆ”น๏ผŒไป่ฆไธขๅผƒๅ—๏ผŸ", - "confirmations.domain_block.confirm": "ๅฑ่”ฝๆ•ดไธชๅŸŸๅ", + "confirmations.domain_block.confirm": "ๅฑ่”ฝๆœๅŠกๅ™จ", "confirmations.domain_block.message": "ไฝ ็œŸ็š„็กฎๅฎš่ฆๅฑ่”ฝๆ‰€ๆœ‰ๆฅ่‡ช {domain} ็š„ๅ†…ๅฎนๅ—๏ผŸๅคšๆ•ฐๆƒ…ๅ†ตไธ‹๏ผŒๅฏนๅ‡ ไธช็‰นๅฎš็š„็”จๆˆท่ฟ›่กŒๅฑ่”ฝๆˆ–็ฆ็”จๅฏนไป–ไปฌ็š„ๆถˆๆฏๆ้†’ๅฐฑ่ถณๅคŸไบ†ใ€‚ๅฑ่”ฝๅŽ๏ผŒๆฅ่‡ช่ฏฅๅŸŸๅ็š„ๅ†…ๅฎนๅฐ†ไธๅ†ๅ‡บ็Žฐๅœจไฝ ไปปไฝ•็š„ๅ…ฌๅ…ฑๆ—ถ้—ด่ฝดๆˆ–้€š็Ÿฅๅˆ—่กจ้‡Œ๏ผŒไฝ ๆฅ่‡ช่ฏฅๅŸŸๅไธ‹็š„ๅ…ณๆณจ่€…ไนŸๅฐ†่ขซ็งป้™คใ€‚", "confirmations.edit.confirm": "็ผ–่พ‘", "confirmations.edit.message": "็ผ–่พ‘ๆญคๆถˆๆฏๅฐ†ไผš่ฆ†็›–ๅฝ“ๅ‰ๆญฃๅœจๆ’ฐๅ†™็š„ไฟกๆฏใ€‚ไป่ฆ็ปง็ปญๅ—๏ผŸ", "confirmations.logout.confirm": "้€€ๅ‡บ็™ปๅฝ•", "confirmations.logout.message": "็กฎๅฎš่ฆ้€€ๅ‡บ็™ปๅฝ•ๅ—๏ผŸ", "confirmations.mute.confirm": "้š่—", - "confirmations.mute.explanation": "ไป–ไปฌ็š„ๅ˜Ÿๆ–‡ไปฅๅŠๆๅˆฐไป–ไปฌ็š„ๅ˜Ÿๆ–‡้ƒฝไผš้š่—๏ผŒไฝ†ไป–ไปฌไป็„ถๅฏไปฅ็œ‹ๅˆฐไฝ ็š„ๅ˜Ÿๆ–‡๏ผŒไนŸๅฏไปฅๅ…ณๆณจไฝ ใ€‚", - "confirmations.mute.message": "ไฝ ็กฎๅฎš่ฆ้š่— {name} ๅ—๏ผŸ", "confirmations.redraft.confirm": "ๅˆ ้™คๅนถ้‡ๆ–ฐ็ผ–่พ‘", "confirmations.redraft.message": "็กฎๅฎšๅˆ ้™ค่ฟ™ๆกๅ˜Ÿๆ–‡ๅนถ้‡ๅ†™ๅ—๏ผŸๆ‰€ๆœ‰็›ธๅ…ณ็š„ๅ–œๆฌขๅ’Œ่ฝฌๅ˜Ÿ้ƒฝๅฐ†ไธขๅคฑ๏ผŒๅ˜Ÿๆ–‡็š„ๅ›žๅคไนŸไผšๅคฑๅŽปๅ…ณ่”ใ€‚", "confirmations.reply.confirm": "ๅ›žๅค", @@ -205,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": "ๆดปๅŠจ", @@ -241,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": "ๆญค้กต้ขๆ— ๆณ•ๆญฃ็กฎๆ˜พ็คบ๏ผŒ่ฟ™ๅฏ่ƒฝๆ˜ฏๅ› ไธบๆˆ‘ไปฌ็š„ไปฃ็ ไธญๆœ‰้”™่ฏฏ๏ผŒไนŸๅฏ่ƒฝๆ˜ฏๅ› ไธบๆต่งˆๅ™จๅ…ผๅฎน้—ฎ้ข˜ใ€‚", @@ -271,16 +297,28 @@ "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": "ๅ…จ้ƒจ", "firehose.local": "ๆญคๆœๅŠกๅ™จ", "firehose.remote": "ๅ…ถไป–ๆœๅŠกๅ™จ", "follow_request.authorize": "ๅŒๆ„", "follow_request.reject": "ๆ‹’็ป", "follow_requests.unlocked_explanation": "ๅฐฝ็ฎกไฝ ๆฒกๆœ‰้”ๅ˜Ÿ๏ผŒไฝ†ๆ˜ฏ {domain} ็š„ๅทฅไฝœไบบๅ‘˜่ฎคไธบไฝ ไนŸ่ฎธไผšๆƒณๆ‰‹ๅŠจๅฎกๆ ธๅฎกๆ ธ่ฟ™ไบ›่ดฆๅท็š„ๅ…ณๆณจ่ฏทๆฑ‚ใ€‚", - "follow_suggestions.curated_suggestion": "ไธป็ผ–ๆŽจ่", + "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} ไธŠๅ…ณๆณจๅบฆๆœ€้ซ˜็š„็”จๆˆทไน‹ไธ€ใ€‚", + "follow_suggestions.hints.most_interactions": "่ฏฅ็”จๆˆทๆœ€่ฟ‘ๅœจ {domain} ไธŠ่Žทๅพ—ไบ†ๅพˆๅคšๅ…ณๆณจใ€‚", + "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": "ๅ…ณๆณจ็š„่ฏ้ข˜ๆ ‡็ญพ", @@ -309,7 +347,6 @@ "hashtag.follow": "ๅ…ณๆณจ่ฏ้ข˜ๆ ‡็ญพ", "hashtag.unfollow": "ๅ–ๆถˆๅ…ณๆณจ่ฏ้ข˜ๆ ‡็ญพ", "hashtags.and_other": "โ€ฆ ๅ’Œๅฆๅค– {count, plural, other {# ไธช่ฏ้ข˜}}", - "home.column_settings.basic": "ๅŸบๆœฌ่ฎพ็ฝฎ", "home.column_settings.show_reblogs": "ๆ˜พ็คบ่ฝฌๅ˜Ÿ", "home.column_settings.show_replies": "ๆ˜พ็คบๅ›žๅค", "home.hide_announcements": "้š่—ๅ…ฌๅ‘Š", @@ -377,6 +414,8 @@ "limited_account_hint.action": "ไป่ฆๆ˜พ็คบไธชไบบ่ต„ๆ–™", "limited_account_hint.title": "ๆญค่ดฆๅท่ต„ๆ–™ๅทฒ่ขซ {domain} ็ฎก็†ๅ‘˜้š่—ใ€‚", "link_preview.author": "็”ฑ {name}", + "link_preview.more_from_author": "ๆŸฅ็œ‹ {name} ็š„ๆ›ดๅคšๅ†…ๅฎน", + "link_preview.shares": "{count, plural, other {{counter} ๆกๅ˜Ÿๆ–‡}}", "lists.account.add": "ๆทปๅŠ ๅˆฐๅˆ—่กจ", "lists.account.remove": "ไปŽๅˆ—่กจไธญ็งป้™ค", "lists.delete": "ๅˆ ้™คๅˆ—่กจ", @@ -395,9 +434,15 @@ "loading_indicator.label": "ๅŠ ่ฝฝไธญโ€ฆ", "media_gallery.toggle_visible": "{number, plural, other {้š่—ๅ›พๅƒ}}", "moved_to_account_banner.text": "ๆ‚จ็š„่ดฆๅท {disabledAccount} ๅทฒ็ฆ็”จ๏ผŒๅ› ไธบๆ‚จๅทฒ่ฟ็งปๅˆฐ {movedToAccount}ใ€‚", - "mute_modal.duration": "ๆŒ็ปญๆ—ถ้•ฟ", - "mute_modal.hide_notifications": "ๅŒๆ—ถ้š่—ๆฅ่‡ช่ฟ™ไธช็”จๆˆท็š„้€š็Ÿฅ๏ผŸ", - "mute_modal.indefinite": "ๆ— ๆœŸ้™", + "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": "ๅทฒๅฑ่”ฝ็š„็”จๆˆท", @@ -430,11 +475,29 @@ "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.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": "ๆŽฅๅ—", + "notification_requests.dismiss": "ๆ‹’็ป", + "notification_requests.notifications_from": "ๆฅ่‡ช {name} ็š„้€š็Ÿฅ", + "notification_requests.title": "้€š็Ÿฅ๏ผˆๅทฒ่ฟ‡ๆปค๏ผ‰", "notifications.clear": "ๆธ…็ฉบ้€š็Ÿฅๅˆ—่กจ", "notifications.clear_confirmation": "ไฝ ็กฎๅฎš่ฆๆฐธไน…ๆธ…็ฉบ้€š็Ÿฅๅˆ—่กจๅ—๏ผŸ", "notifications.column_settings.admin.report": "ๆ–ฐไธพๆŠฅ๏ผš", @@ -442,8 +505,7 @@ "notifications.column_settings.alert": "ๆกŒ้ข้€š็Ÿฅ", "notifications.column_settings.favourite": "ๅ–œๆฌข๏ผš", "notifications.column_settings.filter_bar.advanced": "ๆ˜พ็คบๆ‰€ๆœ‰็ฑปๅˆซ", - "notifications.column_settings.filter_bar.category": "ๅฟซ้€Ÿ่ฟ‡ๆปคๆ ", - "notifications.column_settings.filter_bar.show_bar": "ๆ˜พ็คบ่ฟ‡ๆปคๆ ", + "notifications.column_settings.filter_bar.category": "ๅฟซ้€Ÿ็ญ›้€‰ๆ ", "notifications.column_settings.follow": "ๆ–ฐ็ฒ‰ไธ๏ผš", "notifications.column_settings.follow_request": "ๆ–ฐๅ…ณๆณจ่ฏทๆฑ‚๏ผš", "notifications.column_settings.mention": "ๆๅŠ๏ผš", @@ -469,6 +531,15 @@ "notifications.permission_denied": "็”ฑไบŽๆƒ้™่ขซๆ‹’็ป๏ผŒๆ— ๆณ•ๅฏ็”จๆกŒ้ข้€š็Ÿฅใ€‚", "notifications.permission_denied_alert": "็”ฑไบŽๅœจๆญคไน‹ๅ‰ๆต่งˆๅ™จๆƒ้™่ฏทๆฑ‚ๅฐฑๅทฒ่ขซๆ‹’็ป๏ผŒๆ‰€ไปฅๅฏ็”จๆกŒ้ข้€š็Ÿฅๅคฑ่ดฅ", "notifications.permission_required": "ๆ‰€้œ€ๆƒ้™ๆœช่ขซๆŽˆไบˆ๏ผŒๆ‰€ไปฅๆกŒ้ข้€š็Ÿฅไธๅฏ็”จ", + "notifications.policy.filter_new_accounts.hint": "ๅœจ {days, plural, other {# ๅคฉ}}ๅ†…ๅˆ›ๅปบ็š„่ดฆๆˆท", + "notifications.policy.filter_new_accounts_title": "ๆ–ฐ่ดฆๆˆท", + "notifications.policy.filter_not_followers_hint": "ๅŒ…ๆ‹ฌๅ…ณๆณจไฝ ๅฐ‘ไบŽ {days, plural, other {# ๅคฉ}}็š„ไบบ", + "notifications.policy.filter_not_followers_title": "ๆœชๅ…ณๆณจไฝ ็š„ไบบ", + "notifications.policy.filter_not_following_hint": "็›ดๅˆฐไฝ ๆ‰‹ๅŠจๆ‰นๅ‡†", + "notifications.policy.filter_not_following_title": "ไฝ ๆฒกๆœ‰ๅ…ณๆณจ็š„ไบบ", + "notifications.policy.filter_private_mentions_hint": "่ฟ‡ๆปค้€š็Ÿฅ๏ผŒ้™ค้ž้€š็Ÿฅๆ˜ฏๅœจๅ›žๅคๆๅŠไฝ ่‡ชๅทฑ็š„ๅ†…ๅฎน๏ผŒๆˆ–ๅ‘้€่€…ๆ˜ฏไฝ ๅ…ณๆณจ็š„ไบบ", + "notifications.policy.filter_private_mentions_title": "ไธ่ฏท่‡ชๆฅ็š„ๆๅŠ", + "notifications.policy.title": "้€š็Ÿฅ่ฟ‡ๆปค่Œƒๅ›ด", "notifications_permission_banner.enable": "ๅฏ็”จๆกŒ้ข้€š็Ÿฅ", "notifications_permission_banner.how_to_control": "ๅฏ็”จๆกŒ้ข้€š็Ÿฅไปฅๅœจ Mastodon ๆœชๆ‰“ๅผ€ๆ—ถๆŽฅๆ”ถ้€š็Ÿฅใ€‚ไฝ ๅฏไปฅ้€š่ฟ‡ไบคไบ’้€š่ฟ‡ไธŠ้ข็š„ {icon} ๆŒ‰้’ฎๆฅ็ฒพ็ป†ๆŽงๅˆถๅฏไปฅๅ‘้€ๆกŒ้ข้€š็Ÿฅ็š„ไบคไบ’็ฑปๅž‹ใ€‚", "notifications_permission_banner.title": "็ฒพๅฝฉไธๅฎน้”™่ฟ‡", @@ -528,7 +599,7 @@ "privacy.direct.short": "ๅ…ทไฝ“็š„ไบบ", "privacy.private.long": "ไป…้™ๆ‚จ็š„ๅ…ณๆณจ่€…", "privacy.private.short": "ๅ…ณๆณจ่€…", - "privacy.public.long": "ๆ‰€ๆœ‰Mastodonๅ†…ๅค–็š„ไบบ", + "privacy.public.long": "ๆ‰€ๆœ‰ Mastodon ๅ†…ๅค–็š„ไบบ", "privacy.public.short": "ๅ…ฌๅผ€", "privacy.unlisted.additional": "่ฏฅๆจกๅผ็š„่กŒไธบไธŽโ€œๅ…ฌๅผ€โ€ๅฎŒๅ…จ็›ธๅŒ๏ผŒๅชๆ˜ฏๅธ–ๅญไธไผšๅ‡บ็Žฐๅœจๅฎžๆ—ถๅŠจๆ€ใ€่ฏ้ข˜ๆ ‡็ญพใ€ๆŽข็ดขๆˆ– Mastodon ๆœ็ดขไธญ๏ผŒๅณไฝฟไฝ ๅทฒๅœจ่ดฆๆˆท็บง่ฎพ็ฝฎไธญ้€‰ๆ‹ฉๅŠ ๅ…ฅใ€‚", "privacy.unlisted.long": "ๅ‡ๅฐ‘็ฎ—ๆณ•ๅฝฑๅ“", @@ -625,13 +696,12 @@ "server_banner.about_active_users": "่ฟ‡ๅŽป 30 ๅคฉๅ†…ไฝฟ็”จๆญคๆœๅŠกๅ™จ็š„ไบบ(ๆฏๆœˆๆดป่ทƒ็”จๆˆท)", "server_banner.active_users": "ๆดป่ทƒ็”จๆˆท", "server_banner.administered_by": "ๆœฌ็ซ™็ฎก็†ๅ‘˜๏ผš", - "server_banner.introduction": "{domain} ๆ˜ฏ็”ฑ {mastodon} ้ฉฑๅŠจ็š„ๅŽปไธญๅฟƒๅŒ–็คพไบค็ฝ‘็ปœ็š„ไธ€้ƒจๅˆ†ใ€‚", - "server_banner.learn_more": "่ฏฆ็ป†ไบ†่งฃ", + "server_banner.is_one_of_many": "{domain} ๆ˜ฏๅฏ็”จไบŽๅ‚ไธŽ่”้‚ฆๅฎ‡ๅฎ™็š„ไผ—ๅคš็‹ฌ็ซ‹ Mastodon ๆœๅŠกๅ™จไน‹ไธ€ใ€‚", "server_banner.server_stats": "ๆœๅŠกๅ™จ็ปŸ่ฎกๆ•ฐๆฎ๏ผš", "sign_in_banner.create_account": "ๅˆ›ๅปบ่ดฆๆˆท", + "sign_in_banner.mastodon_is": "Mastodon ๆ˜ฏไบ†่งฃๆœ€ๆ–ฐๅŠจๆ€็š„ๆœ€ไฝณ้€”ๅพ„ใ€‚", "sign_in_banner.sign_in": "็™ปๅฝ•", "sign_in_banner.sso_redirect": "็™ปๅฝ•ๆˆ–ๆณจๅ†Œ", - "sign_in_banner.text": "็™ปๅฝ•ๅ…ณๆณจ็”จๆˆทๅ’Œ่ฏ้ข˜ๆ ‡็ญพ๏ผŒๅ–œๆฌขใ€ๅˆ†ไบซๅ’Œๅ›žๅคๅ˜Ÿๆ–‡ใ€‚ๆ‚จ่ฟ˜ๅฏไปฅไธŽๅ…ถไป–ๆœๅŠกๅ™จไธŠ็š„็”จๆˆท่ฟ›่กŒไบ’ๅŠจใ€‚", "status.admin_account": "ๆ‰“ๅผ€ @{name} ็š„็ฎก็†็•Œ้ข", "status.admin_domain": "ๆ‰“ๅผ€ {domain} ็š„็ฎก็†็•Œ้ข", "status.admin_status": "ๆ‰“ๅผ€ๆญคๅธ–็š„็ฎก็†็•Œ้ข", @@ -645,10 +715,11 @@ "status.direct": "็งไธ‹ๆๅŠ @{name}", "status.direct_indicator": "็งไธ‹ๆๅŠ", "status.edit": "็ผ–่พ‘", - "status.edited": "็ผ–่พ‘ไบŽ {date}", + "status.edited": "ๆœ€่ฟ‘็ผ–่พ‘ไบŽ {date}", "status.edited_x_times": "ๅ…ฑ็ผ–่พ‘ {count, plural, one {{count} ๆฌก} other {{count} ๆฌก}}", "status.embed": "ๅตŒๅ…ฅ", "status.favourite": "ๅ–œๆฌข", + "status.favourites": "{count, plural, other {ๆฌกๅ–œๆฌข}}", "status.filter": "่ฟ‡ๆปคๆญคๅ˜Ÿๆ–‡", "status.filtered": "ๅทฒ่ฟ‡ๆปค", "status.hide": "้š่—ๅ˜Ÿๆ–‡", @@ -669,6 +740,7 @@ "status.reblog": "่ฝฌๅ˜Ÿ", "status.reblog_private": "่ฝฌๅ˜Ÿ๏ผˆๅฏ่ง่€…ไธๅ˜๏ผ‰", "status.reblogged_by": "{name} ่ฝฌๅ˜Ÿไบ†", + "status.reblogs": "{count, plural, other {ๆฌก่ฝฌๅ˜Ÿ}}", "status.reblogs.empty": "ๆฒกๆœ‰ไบบ่ฝฌๅ˜Ÿ่ฟ‡ๆญคๆกๅ˜Ÿๆ–‡ใ€‚ๅฆ‚ๆžœๆœ‰ไบบ่ฝฌๅ˜Ÿไบ†๏ผŒๅฐฑไผšๆ˜พ็คบๅœจ่ฟ™้‡Œใ€‚", "status.redraft": "ๅˆ ้™คๅนถ้‡ๆ–ฐ็ผ–่พ‘", "status.remove_bookmark": "็งป้™คไนฆ็ญพ", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index c1a69591ff..5dff466201 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.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": "็„กๆณ•ๆไพ›่ซ‹ๆฑ‚็š„้ ้ขใ€‚้€™ๅฏ่ƒฝๆ˜ฏๅ› ็‚บไปฃ็ขผๅ‡บ็พ้Œฏ่ชคๆˆ–็€่ฆฝๅ™จๅ‡บ็พๅ…ผๅฎนๅ•้กŒใ€‚", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ๆ–‡ๅญ—ๆฒ’ๆœ‰่ขซ้šฑ่—", "compose_form.spoiler_placeholder": "ๅ…งๅฎน่ญฆๅ‘Š (้ธ็”จ)", "confirmation_modal.cancel": "ๅ–ๆถˆ", - "confirmations.block.block_and_report": "ๅฐ้Ž–ไธฆๆชข่ˆ‰", "confirmations.block.confirm": "ๅฐ้Ž–", - "confirmations.block.message": "ไฝ ็ขบๅฎš่ฆๅฐ้Ž–{name}ๅ—Ž๏ผŸ", "confirmations.cancel_follow_request.confirm": "ๆ’คๅ›ž่ซ‹ๆฑ‚", "confirmations.cancel_follow_request.message": "ๆ‚จ็ขบๅฎš่ฆๆ’คๅ›ž่ฟฝ่นค {name} ็š„่ซ‹ๆฑ‚ๅ—Ž๏ผŸ", "confirmations.delete.confirm": "ๅˆช้™ค", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ไฝ ็ขบๅฎš่ฆๆฐธไน…ๅˆช้™ค้€™ๅˆ—่กจๅ—Ž๏ผŸ", "confirmations.discard_edit_media.confirm": "ๆจๆฃ„", "confirmations.discard_edit_media.message": "ๆ‚จๅœจๅช’้ซ”ๆ่ฟฐๆˆ–้ ่ฆฝๆœ‰ๅฐšๆœชๅ„ฒๅญ˜็š„่ฎŠๆ›ดใ€‚็ขบๅฎš่ฆๆจๆฃ„ๅฎƒๅ€‘ๅ—Ž๏ผŸ", - "confirmations.domain_block.confirm": "ๅฐ้Ž–ๆ•ดๅ€‹็ถฒ็ซ™", + "confirmations.domain_block.confirm": "ๅฐ้Ž–ไผบๆœๅ™จ", "confirmations.domain_block.message": "ไฝ ็œŸ็š„็œŸ็š„็ขบๅฎš่ฆๅฐ้Ž–ๆ•ดๅ€‹ {domain} ๏ผŸๅคšๆ•ธๆƒ…ๆณไธ‹๏ผŒๅฐ้Ž–ๆˆ–้œ้Ÿณๅนพๅ€‹็‰นๅฎš็›ฎๆจ™ๅฐฑๅทฒ็ถ“ๆœ‰ๆ•ˆ๏ผŒไนŸๆ˜ฏๆฏ”่ผƒๅปบ่ญฐ็š„ๅšๆณ•ใ€‚่‹ฅ็„ถๅฐ้Ž–ๅ…จ็ซ™๏ผŒไฝ ๅฐ‡ไธๆœƒๅ†ๅœจ้€™่ฃ็œ‹ๅˆฐ่ฉฒ็ซ™็š„ๅ…งๅฎนๅ’Œ้€š็Ÿฅใ€‚ไพ†่‡ช่ฉฒ็ซ™็š„้—œๆณจ่€…ไบฆๆœƒ่ขซ็งป้™คใ€‚", "confirmations.edit.confirm": "็ทจ่ผฏ", "confirmations.edit.message": "็พๅœจ็ทจ่ผฏๅฐ‡ๆœƒ่ฆ†่“‹ไฝ ็›ฎๅ‰ๆญฃๅœจๆ’ฐๅฏซ็š„่จŠๆฏใ€‚ไฝ ็ขบๅฎš่ฆ็นผ็บŒๅ—Ž๏ผŸ", "confirmations.logout.confirm": "็™ปๅ‡บ", "confirmations.logout.message": "็ขบๅฎš่ฆ็™ปๅ‡บๅ—Ž๏ผŸ", "confirmations.mute.confirm": "้œ้Ÿณ", - "confirmations.mute.explanation": "้€™ๅฐ‡ๆœƒ้šฑ่—ไพ†่‡ชไป–ๅ€‘็š„่ฒผๆ–‡่ˆ‡้€š็Ÿฅ๏ผŒไฝ†ๆ˜ฏไป–ๅ€‘้‚„ๆ˜ฏๅฏไปฅๆŸฅ้–ฑไฝ ็š„่ฒผๆ–‡่ˆ‡้—œๆณจไฝ ใ€‚", - "confirmations.mute.message": "ไฝ ็ขบๅฎš่ฆๅฐ‡{name}้œ้Ÿณๅ—Ž๏ผŸ", "confirmations.redraft.confirm": "ๅˆช้™คไธฆ็ทจ่ผฏ", "confirmations.redraft.message": "ไฝ ็ขบๅฎš่ฆ็งป้™คไธฆ้‡ๆ–ฐ่ตท่‰้€™็ฏ‡ๅธ–ๆ–‡ๅ—Ž๏ผŸไฝ ๅฐ‡ๆœƒๅคฑๅŽปๆœ€ๆ„›ๅ’Œ่ฝ‰ๆŽจ๏ผŒ่€Œๅ›ž่ฆ†ไนŸๆœƒ่ˆ‡ๅŽŸๅง‹ๅธ–ๆ–‡ๆ–ท้–‹้€ฃๆŽฅใ€‚", "confirmations.reply.confirm": "ๅ›ž่ฆ†", @@ -205,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": "ๆดปๅ‹•", @@ -241,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": "็”ฑๆ–ผ็™ผ็”Ÿ็ณป็ตฑๆ•…้šœๆˆ–็€่ฆฝๅ™จ็›ธๅฎนๆ€งๅ•้กŒ๏ผŒๆ•…็„กๆณ•ๆญฃๅธธ้กฏ็คบ้ ้ขใ€‚", @@ -271,16 +297,28 @@ "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": "ๅ…จ้ƒจ", "firehose.local": "ๆœฌไผบๆœๅ™จ", "firehose.remote": "ๅ…ถไป–ไผบๆœๅ™จ", "follow_request.authorize": "ๆ‰นๅ‡†", "follow_request.reject": "ๆ‹’็ต•", "follow_requests.unlocked_explanation": "ๅณไฝฟๆ‚จ็š„ๅธณ่™ŸๆœชไธŠ้Ž–๏ผŒ{domain} ็š„ๅทฅไฝœไบบๅ“ก่ช็‚บๆ‚จๅฏ่ƒฝๆœƒๆƒณๆ‰‹ๅ‹•ๅฏฉๆ ธไพ†่‡ช้€™ไบ›ๅธณ่™Ÿ็š„่ฟฝ่นค่ซ‹ๆฑ‚ใ€‚", - "follow_suggestions.curated_suggestion": "็ทจ่ผฏๆŽจ่–ฆ", + "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} ไธŠๆœ€ๅคš่ฟฝ่นคไน‹ไธ€ใ€‚", + "follow_suggestions.hints.most_interactions": "้€™ๅ€‹ไบบๆช”ๆกˆๆœ€่ฟ‘ๅœจ {domain} ไธŠๅ‚™ๅ—้—œๆณจใ€‚", + "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": "ๅทฒ่ฟฝ่นคๆจ™็ฑค", @@ -309,7 +347,6 @@ "hashtag.follow": "่ฟฝ่นคไธป้กŒๆจ™็ฑค", "hashtag.unfollow": "ๅ–ๆถˆ่ฟฝ่นคไธป้กŒๆจ™็ฑค", "hashtags.and_other": "โ€ฆๅŠ{count, plural, other {ๅ…ถไป– # ๅ€‹}}", - "home.column_settings.basic": "ๅŸบๆœฌ", "home.column_settings.show_reblogs": "้กฏ็คบ่ขซ่ฝ‰ๆŽจ็š„ๆ–‡็ซ ", "home.column_settings.show_replies": "้กฏ็คบๅ›žๆ‡‰ๆ–‡็ซ ", "home.hide_announcements": "้šฑ่—ๅ…ฌๅ‘Š", @@ -395,9 +432,15 @@ "loading_indicator.label": "่ผ‰ๅ…ฅไธญโ€ฆ", "media_gallery.toggle_visible": "้šฑ่—ๅœ–็‰‡", "moved_to_account_banner.text": "ๆ‚จ็š„ๅธณ่™Ÿ {disabledAccount} ็›ฎๅ‰ๅทฒๅœ็”จ๏ผŒๅ› ็‚บๆ‚จๅทฒๆฌๅฎถ่‡ณ {movedToAccount}ใ€‚", - "mute_modal.duration": "ๆ™‚้–“", - "mute_modal.hide_notifications": "้œ€่ฆ้šฑ่—้€™ไฝฟ็”จ่€…็š„้€š็Ÿฅๅ—Ž๏ผŸ", - "mute_modal.indefinite": "ๆฒ’ๆœŸ้™", + "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": "ๅฐ้Ž–ๅๅ–ฎ", @@ -430,11 +473,28 @@ "notification.follow": "{name} ้–‹ๅง‹่ฟฝ่นคไฝ ", "notification.follow_request": "{name} ่ฆๆฑ‚่ฟฝ่นคไฝ ", "notification.mention": "{name} ๆๅŠไฝ ", + "notification.moderation-warning.learn_more": "ไบ†่งฃๆ›ดๅคš", + "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.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": "ๆŽฅๅ—", + "notification_requests.dismiss": "ๅฟฝ็•ฅ", + "notification_requests.notifications_from": "ไพ†่‡ช {name} ็š„้€š็Ÿฅ", + "notification_requests.title": "ๅทฒ้Žๆฟพไน‹้€š็Ÿฅ", "notifications.clear": "ๆธ…็ฉบ้€š็Ÿฅ็ด€้Œ„", "notifications.clear_confirmation": "ไฝ ็ขบๅฎš่ฆๆธ…็ฉบ้€š็Ÿฅ็ด€้Œ„ๅ—Ž๏ผŸ", "notifications.column_settings.admin.report": "ๆ–ฐ่ˆ‰ๅ ฑ๏ผš", @@ -442,8 +502,7 @@ "notifications.column_settings.alert": "้กฏ็คบๆกŒ้ข้€š็Ÿฅ", "notifications.column_settings.favourite": "ๆœ€ๆ„›๏ผš", "notifications.column_settings.filter_bar.advanced": "้กฏ็คบๆ‰€ๆœ‰ๅˆ†้กž", - "notifications.column_settings.filter_bar.category": "ๅฟซ้€Ÿ้Žๆฟพๆฌ„", - "notifications.column_settings.filter_bar.show_bar": "้กฏ็คบ็ฏฉ้ธๆฌ„", + "notifications.column_settings.filter_bar.category": "ๅฟซ้€Ÿ็ฏฉ้ธๆฌ„", "notifications.column_settings.follow": "ๆ–ฐ่ฟฝ่นค่€…๏ผš", "notifications.column_settings.follow_request": "ๆ–ฐ็š„่ฟฝ่นค่ซ‹ๆฑ‚๏ผš", "notifications.column_settings.mention": "ๆๅŠไฝ ๏ผš", @@ -469,6 +528,15 @@ "notifications.permission_denied": "ๆœฌ็ซ™ไธ่ƒฝ็™ผ้€ๆกŒ้ข้€š็Ÿฅ๏ผŒๅ› ็‚บ็€่ฆฝๅ™จๅ…ˆๅ‰ๆ‹’็ต•ไบ†ๆœฌ็ซ™็š„ๆกŒ้ข้€š็ŸฅๆฌŠ้™่ซ‹ๆฑ‚", "notifications.permission_denied_alert": "็„กๆณ•ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ๏ผŒๅ› ็‚บ็€่ฆฝๅ™จๅ…ˆๅ‰ๆ‹’็ต•ไบ†ๆœฌ็ซ™็š„ๆกŒ้ข้€š็ŸฅๆฌŠ้™่ซ‹ๆฑ‚", "notifications.permission_required": "็”ฑๆ–ผ็€่ฆฝๅ™จๆœชๆœ‰ๆŽˆไบˆๆกŒ้ข้€š็ŸฅๆฌŠ้™๏ผŒๆœฌ็ซ™ๆšซๆœช่ƒฝ็™ผ้€ๆกŒ้ข้€š็Ÿฅใ€‚", + "notifications.policy.filter_new_accounts.hint": "ๅœจ้ŽๅŽป {days, plural, other {# ๅคฉ}}ๅ…งๅปบ็ซ‹", + "notifications.policy.filter_new_accounts_title": "ๆ–ฐๅธณ่™Ÿ", + "notifications.policy.filter_not_followers_hint": "ๅŒ…ๆ‹ฌ่ฟฝ่นคไฝ ไธๅˆฐ {days, plural, other {# ๅคฉ}}็š„ไบบ", + "notifications.policy.filter_not_followers_title": "ๆœช่ฟฝ่นคไฝ ็š„ไบบ", + "notifications.policy.filter_not_following_hint": "็›ด่‡ณไฝ ๆ‰‹ๅ‹•ๆ ธๅ‡†ไป–ๅ€‘", + "notifications.policy.filter_not_following_title": "ไฝ ๆœช่ฟฝ่นค็š„ไบบ", + "notifications.policy.filter_private_mentions_hint": "้™ค้žๅ›ž่ฆ†ไฝ ็š„ๆๅŠๆˆ–ไพ†่‡ชไฝ ่ฟฝ่นค็š„ไบบ๏ผŒๅฆๅ‰‡ๅฐ‡่ขซ้Žๆฟพ", + "notifications.policy.filter_private_mentions_title": "ๆœช็ถ“่ซ‹ๆฑ‚็š„็งไบบๆๅŠ", + "notifications.policy.title": "้Žๆฟพไพ†่‡ชไปฅไธ‹็š„้€š็Ÿฅโ€ฆ", "notifications_permission_banner.enable": "ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ", "notifications_permission_banner.how_to_control": "ๅช่ฆๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ๏ผŒไพฟๅฏๅœจ Mastodon ็ถฒ็ซ™ๆฒ’ๆœ‰ๆ‰“้–‹ๆ™‚ๆ”ถๅˆฐ้€š็Ÿฅใ€‚ๅœจๅทฒ็ถ“ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ็š„ๆ™‚ๅ€™๏ผŒไฝ ๅฏไปฅ้€้ŽไธŠ้ข็š„ {icon} ๆŒ‰้ˆ•ๆบ–็ขบๆŽงๅˆถๅ“ชไบ›้กžๅž‹็š„ไบ’ๅ‹•ๆœƒ็”ข็”ŸๆกŒ้ข้€š็Ÿฅใ€‚", "notifications_permission_banner.title": "ไธๆ”พ้Žไปปไฝ•ไบ‹ๆƒ…", @@ -625,13 +693,10 @@ "server_banner.about_active_users": "ๅœจๆœ€่ฟ‘ 30 ๅคฉๅ…งๅ…งไฝฟ็”จๆญคไผบๆœๅ™จ็š„ไบบ (ๆœˆๆดป่บ็”จๆˆถ)", "server_banner.active_users": "ๆดป่บ็”จๆˆถ", "server_banner.administered_by": "็ฎก็†่€…๏ผš", - "server_banner.introduction": "{domain} ๆ˜ฏ็”ฑ {mastodon} ๆไพ›ไน‹ๅŽปไธญๅฟƒๅŒ–็คพไบค็ถฒ็ตก็š„ไธ€้ƒจไปฝใ€‚", - "server_banner.learn_more": "ไบ†่งฃๆ›ดๅคš", "server_banner.server_stats": "ไผบๆœๅ™จ็ตฑ่จˆ๏ผš", "sign_in_banner.create_account": "ๅปบ็ซ‹ๅธณ่™Ÿ", "sign_in_banner.sign_in": "็™ปๅ…ฅ", "sign_in_banner.sso_redirect": "็™ปๅ…ฅๆˆ–่จปๅ†Š", - "sign_in_banner.text": "็™ปๅ…ฅไปฅ่ฟฝ่นคๅ€‹ไบบๆช”ๆกˆใ€ไธป้กŒๆจ™็ฑค๏ผŒๆˆ–ๆœ€ๆ„›ใ€ๅˆ†ไบซๅ’Œๅ›ž่ฆ†ๅธ–ๆ–‡ใ€‚ไฝ ไนŸๅฏไปฅๅพžๅ…ถไป–ไผบๆœๅ™จไธŠ็š„ๅธณ่™Ÿ้€ฒ่กŒไบ’ๅ‹•ใ€‚", "status.admin_account": "้–‹ๅ•Ÿ @{name} ็š„็ฎก็†ไป‹้ข", "status.admin_domain": "ๆ‰“้–‹ {domain} ็ฎก็†ไป‹้ข", "status.admin_status": "ๅœจ็ฎก็†ไป‹้ข้–‹ๅ•Ÿ้€™็ฏ‡ๆ–‡็ซ ", @@ -645,10 +710,11 @@ "status.direct": "็งไธ‹ๆๅŠ @{name}", "status.direct_indicator": "็งไบบๆๅŠ", "status.edit": "็ทจ่ผฏ", - "status.edited": "็ทจ่ผฏๆ–ผ {date}", + "status.edited": "ๆœ€ๅพŒ็ทจ่ผฏๆ–ผ {date}", "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": "้šฑ่—ๅธ–ๆ–‡", @@ -669,6 +735,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 d83b523d1e..e6cd62162b 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -6,7 +6,7 @@ "about.domain_blocks.preamble": "Mastodon ๅŸบๆœฌไธŠๅ…่จฑๆ‚จ็€่ฆฝ่ฏ้‚ฆๅฎ‡ๅฎ™ไธญไปปไฝ•ไผบๆœๅ™จ็š„ๅ…งๅฎนไธฆ่ˆ‡ไฝฟ็”จ่€…ไบ’ๅ‹•ใ€‚ไปฅไธ‹ๆ˜ฏๅœจๆœฌไผบๆœๅ™จไธŠ่จญๅฎš็š„ไพ‹ๅค–ใ€‚", "about.domain_blocks.silenced.explanation": "ไธ€่ˆฌไพ†่ชชๆ‚จไธๆœƒ็œ‹ๅˆฐไพ†่‡ช้€™ๅ€‹ไผบๆœๅ™จ็š„ๅ€‹ไบบๆช”ๆกˆๅ’Œๅ…งๅฎน๏ผŒ้™ค้žๆ‚จๆ˜Ž็ขบๆœๅฐ‹ๆˆ–ไธปๅ‹•่ทŸ้šจๅฐๆ–นใ€‚", "about.domain_blocks.silenced.title": "ๅทฒๅ—้™", - "about.domain_blocks.suspended.explanation": "ไพ†่‡ชๆญคไผบๆœๅ™จ็š„่ณ‡ๆ–™้ƒฝไธๆœƒ่ขซ่™•็†ใ€ๅ„ฒๅญ˜ๆˆ–ไบคๆ›๏ผŒไนŸ็„กๆณ•่ˆ‡ๆญคไผบๆœๅ™จไธŠ็š„ไฝฟ็”จ่€…ไบ’ๅ‹•ๆˆ–ไบคๆตใ€‚", + "about.domain_blocks.suspended.explanation": "ไพ†่‡ชๆญคไผบๆœๅ™จ็š„่ณ‡ๆ–™้ƒฝไธๆœƒ่ขซ่™•็†ใ€ๅ„ฒๅญ˜ๆˆ–ไบคๆ›๏ผŒไนŸ็„กๆณ•ๅ’Œๆญคไผบๆœๅ™จไธŠ็š„ไฝฟ็”จ่€…ไบ’ๅ‹•่ˆ‡ไบคๆตใ€‚", "about.domain_blocks.suspended.title": "ๅทฒๅœๆฌŠ", "about.not_available": "็„กๆณ•ๆ–ผๆœฌไผบๆœๅ™จไธŠไฝฟ็”จๆญค่ณ‡่จŠใ€‚", "about.powered_by": "็”ฑ {mastodon} ๆไพ›็š„ๅŽปไธญๅฟƒๅŒ–็คพ็พคๅช’้ซ”", @@ -70,7 +70,7 @@ "account.unendorse": "ๅ–ๆถˆๆ–ผๅ€‹ไบบๆช”ๆกˆๆŽจ่–ฆๅฐๆ–น", "account.unfollow": "ๅ–ๆถˆ่ทŸ้šจ", "account.unmute": "่งฃ้™ค้œ้Ÿณ @{name}", - "account.unmute_notifications_short": "ๅ–ๆถˆ้œ้ŸณๆŽจๆ’ญ้€š็Ÿฅ", + "account.unmute_notifications_short": "่งฃ้™ค้œ้ŸณๆŽจๆ’ญ้€š็Ÿฅ", "account.unmute_short": "่งฃ้™ค้œ้Ÿณ", "account_note.placeholder": "ๆŒ‰ๆญคๆ–ฐๅขžๅ‚™่จป", "admin.dashboard.daily_retention": "่จปๅ†ŠๅพŒไฝฟ็”จ่€…ๅญ˜็•™็Ž‡๏ผˆๆ—ฅ๏ผ‰", @@ -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": "็„กๆณ•็นช่ฃฝ่ซ‹ๆฑ‚็š„้ ้ขใ€‚้€™ๅฏ่ƒฝๆ˜ฏๅ› ็‚บๆˆ‘ๅ€‘็จ‹ๅผ็ขผไธญ็š„่‡ญ่Ÿฒๆˆ–ๆ˜ฏ็€่ฆฝๅ™จ็š„็›ธๅฎนๅ•้กŒใ€‚", @@ -160,9 +168,7 @@ "compose_form.spoiler.unmarked": "ๆ–ฐๅขžๅ…งๅฎน่ญฆๅ‘Š", "compose_form.spoiler_placeholder": "ๅ…งๅฎน่ญฆๅ‘Š (ๅฏ้ธ็š„)", "confirmation_modal.cancel": "ๅ–ๆถˆ", - "confirmations.block.block_and_report": "ๅฐ้Ž–ไธฆๆชข่ˆ‰", "confirmations.block.confirm": "ๅฐ้Ž–", - "confirmations.block.message": "ๆ‚จ็ขบๅฎš่ฆๅฐ้Ž– {name} ๅ—Ž๏ผŸ", "confirmations.cancel_follow_request.confirm": "ๆ”ถๅ›ž่ทŸ้šจ่ซ‹ๆฑ‚", "confirmations.cancel_follow_request.message": "ๆ‚จ็ขบๅฎš่ฆๆ”ถๅ›ž่ทŸ้šจ {name} ็š„่ซ‹ๆฑ‚ๅ—Ž๏ผŸ", "confirmations.delete.confirm": "ๅˆช้™ค", @@ -171,15 +177,13 @@ "confirmations.delete_list.message": "ๆ‚จ็ขบๅฎš่ฆๆฐธไน…ๅˆช้™คๆญคๅˆ—่กจๅ—Ž๏ผŸ", "confirmations.discard_edit_media.confirm": "ๆจๆฃ„", "confirmations.discard_edit_media.message": "ๆ‚จๆ–ผๅช’้ซ”ๆ่ฟฐๆˆ–้ ่ฆฝๅ€ๅกŠๆœ‰ๆœชๅ„ฒๅญ˜็š„่ฎŠๆ›ดใ€‚ๆ˜ฏๅฆ่ฆๆจๆฃ„้€™ไบ›่ฎŠๆ›ด๏ผŸ", - "confirmations.domain_block.confirm": "ๅฐ้Ž–ๆ•ดๅ€‹็ถฒๅŸŸ", + "confirmations.domain_block.confirm": "ๅฐ้Ž–ไผบๆœๅ™จ", "confirmations.domain_block.message": "ๆ‚จ็œŸ็š„้žๅธธ็ขบๅฎš่ฆๅฐ้Ž–ๆ•ดๅ€‹ {domain} ็ถฒๅŸŸๅ—Ž๏ผŸๅคง้ƒจๅˆ†ๆƒ…ๆณไธ‹๏ผŒๅฐ้Ž–ๆˆ–้œ้Ÿณๅฐ‘ๆ•ธ็‰นๅฎš็š„ๅธณ่™Ÿๅฐฑ่ƒฝๆปฟ่ถณ้œ€ๆฑ‚ไบ†ใ€‚ๆ‚จๅฐ‡ไธ่ƒฝๅœจไปปไฝ•ๅ…ฌ้–‹็š„ๆ™‚้–“่ปธๅŠ้€š็Ÿฅไธญ็œ‹ๅˆฐไพ†่‡ชๆญค็ถฒๅŸŸ็š„ๅ…งๅฎนใ€‚ๆ‚จไพ†่‡ช่ฉฒ็ถฒๅŸŸ็š„่ทŸ้šจ่€…ไนŸๅฐ‡่ขซ็งป้™คใ€‚", "confirmations.edit.confirm": "็ทจ่ผฏ", "confirmations.edit.message": "็ทจ่ผฏๅ˜Ÿๆ–‡ๅฐ‡่ฆ†่“‹ๆŽ‰ๆ‚จ็›ฎๅ‰ๆญฃๅœจๆ’ฐๅฏซไน‹ๅ˜Ÿๆ–‡ๅ…งๅฎนใ€‚ๆ‚จๆ˜ฏๅฆไป่ฆ็นผ็บŒ๏ผŸ", "confirmations.logout.confirm": "็™ปๅ‡บ", "confirmations.logout.message": "ๆ‚จ็ขบๅฎš่ฆ็™ปๅ‡บๅ—Ž๏ผŸ", "confirmations.mute.confirm": "้œ้Ÿณ", - "confirmations.mute.explanation": "ๆญคๆ“ไฝœๅฐ‡้šฑ่—ไพ†่‡ชไป–ๅ€‘็š„ๅ˜Ÿๆ–‡่ˆ‡้€š็Ÿฅ๏ผŒไฝ†ๆ˜ฏไป–ๅ€‘้‚„ๆ˜ฏๅฏไปฅๆŸฅ้–ฑๆ‚จ็š„ๅ˜Ÿๆ–‡่ˆ‡่ทŸ้šจๆ‚จใ€‚", - "confirmations.mute.message": "ๆ‚จ็ขบๅฎš่ฆ้œ้Ÿณ {name} ๅ—Ž๏ผŸ", "confirmations.redraft.confirm": "ๅˆช้™คไธฆ้‡ๆ–ฐ็ทจ่ผฏ", "confirmations.redraft.message": "ๆ‚จ็ขบๅฎš่ฆๅˆช้™ค้€™ๅ‰‡ๅ˜Ÿๆ–‡ไธฆ้‡ๆ–ฐ็ทจ่ผฏๅ—Ž๏ผŸๆ‚จๅฐ‡ๅคฑๅŽป้€™ๅ‰‡ๅ˜Ÿๆ–‡ไน‹่ฝ‰ๅ˜ŸๅŠๆœ€ๆ„›๏ผŒไธ”ๅฐๆญคๅ˜Ÿๆ–‡ไน‹ๅ›ž่ฆ†ๆœƒ่ฎŠๆˆ็จ็ซ‹็š„ๅ˜Ÿๆ–‡ใ€‚", "confirmations.reply.confirm": "ๅ›ž่ฆ†", @@ -205,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": "ไป€้บผๆ˜ฏๅธณ่™Ÿ (@handle) ๏ผŸ", + "domain_pill.who_they_are": "็”ฑๆ–ผๅธณ่™Ÿ (@handle) ่ƒฝ่ชชๆ˜ŽๆŸไบบๆ˜ฏ่ชฐไปฅๅŠไป–ๅ€‘ไพ†่‡ชไฝ•ๆ–น๏ผŒๆ‚จ่ƒฝๆ–ผ ไน‹็คพ็พค็ถฒ่ทฏไธŠ่ˆ‡ไบบๅ€‘ไบ’ๅ‹•ใ€‚", + "domain_pill.who_you_are": "็”ฑๆ–ผๅธณ่™Ÿ (@handle) ่ƒฝ่ชชๆ˜Žๆ‚จๆ˜ฏ่ชฐไปฅๅŠๆ‚จไพ†่‡ชไฝ•ๆ–น๏ผŒไบบๅ€‘่ƒฝๆ–ผ ไน‹็คพ็พค็ถฒ่ทฏไธŠ่ˆ‡ๆ‚จไบ’ๅ‹•ใ€‚", + "domain_pill.your_handle": "ๆ‚จ็š„ๅธณ่™Ÿ๏ผš", + "domain_pill.your_server": "ๆ‚จๆ•ธไฝไธ–็•Œ็š„ๅฎถ๏ผŒๆ‚จๆ‰€ๆœ‰็š„ๅ˜Ÿๆ–‡้ƒฝๅœจ้€™่ฃกใ€‚ไธๅ–œๆญก้€™ๅฐไผบๆœๅ™จๅ—Ž๏ผŸๆ‚จ่ƒฝ้šจๆ™‚ๆฌๅฎถ่‡ณๅ…ถไป–ไผบๆœๅ™จไธฆไธ”ไปไฟๆœ‰ๆ‚จ็š„่ทŸ้šจ่€…ใ€‚", + "domain_pill.your_username": "ๆ‚จๆ–ผๆ‚จ็š„ไผบๆœๅ™จไธญ็จไธ€็„กไบŒ็š„่ญ˜ๅˆฅใ€‚ๆ–ผไธๅŒ็š„ไผบๆœๅ™จไธŠๅฏ่ƒฝๆ‰พๅˆฐๅ…ทๆœ‰็›ธๅŒๅธณ่™Ÿ็š„ไฝฟ็”จ่€…ใ€‚", "embed.instructions": "่‹ฅๆ‚จๆฌฒๆ–ผๆ‚จ็š„็ถฒ็ซ™ๅตŒๅ…ฅๆญคๅ˜Ÿๆ–‡๏ผŒ่ซ‹่ค‡่ฃฝไปฅไธ‹็จ‹ๅผ็ขผใ€‚", "embed.preview": "ๅฎƒๅฐ‡้กฏ็คบๆˆ้€™ๆจฃ๏ผš", "emoji_button.activity": "ๆดปๅ‹•", @@ -212,7 +237,7 @@ "emoji_button.custom": "่‡ช่จ‚", "emoji_button.flags": "ๆ——ๅนŸ", "emoji_button.food": "้ฃŸ็‰ฉ & ้ฃฒๆ–™", - "emoji_button.label": "ๆ’ๅ…ฅ่กจๆƒ…็ฌฆ่™Ÿ", + "emoji_button.label": "ๆ’ๅ…ฅ emoji ่กจๆƒ…็ฌฆ่™Ÿ", "emoji_button.nature": "่‡ช็„ถ", "emoji_button.not_found": "ๅ•Šๅฐฑๆฒ’้€™่กจๆƒ…็ฌฆ่™Ÿๅผ๏ผ๏ผ (โ•ฏยฐโ–กยฐ๏ผ‰โ•ฏ๏ธต โ”ปโ”โ”ป", "emoji_button.objects": "็‰ฉไปถ", @@ -227,7 +252,7 @@ "empty_column.account_timeline": "้€™่ฃก้‚„ๆฒ’ๆœ‰ๅ˜Ÿๆ–‡๏ผ", "empty_column.account_unavailable": "็„กๆณ•ๅ–ๅพ—ๅ€‹ไบบๆช”ๆกˆ", "empty_column.blocks": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๅฐ้Ž–ไปปไฝ•ไฝฟ็”จ่€…ใ€‚", - "empty_column.bookmarked_statuses": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๅปบ็ซ‹ไปปไฝ•ๆ›ธ็ฑคใ€‚็•ถๆ‚จๅปบ็ซ‹ๆ›ธ็ฑคๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", + "empty_column.bookmarked_statuses": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๆ–ฐๅขžไปปไฝ•ๆ›ธ็ฑคใ€‚็•ถๆ‚จๆ–ฐๅขžๆ›ธ็ฑคๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", "empty_column.community": "ๆœฌ็ซ™ๆ™‚้–“่ปธๆ˜ฏ็ฉบ็š„ใ€‚ๅฟซๅ…ฌ้–‹ๅ˜Ÿไบ›ๆ–‡ๆถ้ ญ้ฆ™ๅ•Š๏ผ", "empty_column.direct": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๆ”ถๅˆฐไปปไฝ•็ง่จŠใ€‚็•ถๆ‚จ็ง่จŠๅˆฅไบบๆˆ–ๆ”ถๅˆฐ็ง่จŠๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", "empty_column.domain_blocks": "ๅฐšๆœชๅฐ้Ž–ไปปไฝ•็ถฒๅŸŸใ€‚", @@ -239,8 +264,9 @@ "empty_column.hashtag": "้€™ๅ€‹ไธป้กŒๆจ™็ฑคไธ‹ไป€้บผไนŸๆฒ’ๆœ‰ใ€‚", "empty_column.home": "ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธๆ˜ฏ็ฉบ็š„๏ผ่ทŸ้šจๆ›ดๅคšไบบไพ†ๅฐ‡ๅฎƒๅกซๆปฟๅง๏ผ", "empty_column.list": "้€™ไปฝๅˆ—่กจไธ‹ไป€้บผไนŸๆฒ’ๆœ‰ใ€‚็•ถๆญคๅˆ—่กจ็š„ๆˆๅ“กๅ˜Ÿๅ‡บๆ–ฐ็š„ๅ˜Ÿๆ–‡ๆ™‚๏ผŒๅฎƒๅ€‘ๅฐ‡้กฏ็คบๆ–ผๆญคใ€‚", - "empty_column.lists": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๅปบ็ซ‹ไปปไฝ•ๅˆ—่กจใ€‚็•ถๆ‚จๅปบ็ซ‹ๅˆ—่กจๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", + "empty_column.lists": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๆ–ฐๅขžไปปไฝ•ๅˆ—่กจใ€‚็•ถๆ‚จๆ–ฐๅขžๅˆ—่กจๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", "empty_column.mutes": "ๆ‚จๅฐšๆœช้œ้Ÿณไปปไฝ•ไฝฟ็”จ่€…ใ€‚", + "empty_column.notification_requests": "ๆธ…็ฉบๅ•ฆ๏ผๅทฒ็ถ“ๆฒ’ๆœ‰ไปปไฝ•้€š็Ÿฅใ€‚็•ถๆ‚จๆ”ถๅˆฐๆ–ฐ้€š็Ÿฅๆ™‚๏ผŒๅฎƒๅ€‘ๅฐ‡ไพ็…งๆ‚จ็š„่จญๅฎšๆ–ผๆญค้กฏ็คบใ€‚", "empty_column.notifications": "ๆ‚จ้‚„ๆฒ’ๆœ‰ๆ”ถๅˆฐไปปไฝ•้€š็Ÿฅ๏ผŒ็•ถๆ‚จ่ˆ‡ๅˆฅไบบ้–‹ๅง‹ไบ’ๅ‹•ๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", "empty_column.public": "้€™่ฃกไป€้บผ้ƒฝๆฒ’ๆœ‰๏ผๅ˜—่ฉฆๅฏซไบ›ๅ…ฌ้–‹็š„ๅ˜Ÿๆ–‡๏ผŒๆˆ–่€…่ทŸ้šจๅ…ถไป–ไผบๆœๅ™จ็š„ไฝฟ็”จ่€…ๅพŒ๏ผŒๅฐฑๆœƒๆœ‰ๅ˜Ÿๆ–‡ๅ‡บ็พไบ†", "error.unexpected_crash.explanation": "็”ฑๆ–ผ็™ผ็”Ÿ็ณป็ตฑๆ•…้šœๆˆ–็€่ฆฝๅ™จ็›ธๅฎนๆ€งๅ•้กŒ๏ผŒ็„กๆณ•ๆญฃๅธธ้กฏ็คบๆญค้ ้ขใ€‚", @@ -271,6 +297,9 @@ "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": "ๅ…จ้ƒจ", "firehose.local": "ๆœฌ็ซ™", "firehose.remote": "่ฏ้‚ฆๅฎ‡ๅฎ™", @@ -279,8 +308,17 @@ "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} ไธญๆœ€ๅ—ๆญก่ฟŽ็š„ๅธณ่™Ÿไน‹ไธ€ใ€‚", + "follow_suggestions.hints.most_interactions": "้€™ๅ€‹ๅ€‹ไบบๆช”ๆกˆๆœ€่ฟ‘ๆ–ผ {domain} ๅ—ๅˆฐ้žๅธธๅคš้—œๆณจใ€‚", + "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": "ๅทฒ่ทŸ้šจไธป้กŒๆจ™็ฑค", @@ -309,7 +347,6 @@ "hashtag.follow": "่ทŸ้šจไธป้กŒๆจ™็ฑค", "hashtag.unfollow": "ๅ–ๆถˆ่ทŸ้šจไธป้กŒๆจ™็ฑค", "hashtags.and_other": "โ€ฆๅŠๅ…ถไป– {count, plural, other {# ๅ€‹}}", - "home.column_settings.basic": "ๅŸบๆœฌ่จญๅฎš", "home.column_settings.show_reblogs": "้กฏ็คบ่ฝ‰ๅ˜Ÿ", "home.column_settings.show_replies": "้กฏ็คบๅ›ž่ฆ†", "home.hide_announcements": "้šฑ่—ๅ…ฌๅ‘Š", @@ -317,10 +354,10 @@ "home.pending_critical_update.link": "ๆชข่ฆ–ๆ›ดๆ–ฐๅ…งๅฎน", "home.pending_critical_update.title": "ๆœ‰ๅฏๅ–ๅพ—็š„้‡่ฆๅฎ‰ๅ…จๆ€งๆ›ดๆ–ฐ๏ผ", "home.show_announcements": "้กฏ็คบๅ…ฌๅ‘Š", - "interaction_modal.description.favourite": "ๅœจ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ็š„่ฉฑ๏ผŒๆ‚จๅฏไปฅๅฐ‡ๆญคๅ˜Ÿๆ–‡ๅŠ ๅ…ฅๆœ€ๆ„›ไปฅ่ฎ“ไฝœ่€…็Ÿฅ้“ๆ‚จๆฌฃ่ณžๅฎƒไธ”ๅฐ‡ๅฎƒๅ„ฒๅญ˜ไธ‹ไพ†ใ€‚", - "interaction_modal.description.follow": "ๅœจ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ็š„่ฉฑ๏ผŒๆ‚จๅฏไปฅ่ทŸ้šจ {name} ไปฅๆ–ผ้ฆ–้ ๆ™‚้–“่ปธๆŽฅๆ”ถไป–ๅ€‘็š„ๅ˜Ÿๆ–‡ใ€‚", - "interaction_modal.description.reblog": "ๅœจ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ็š„่ฉฑ๏ผŒๆ‚จๅฏไปฅ่ฝ‰ๅ˜Ÿๆญคๅ˜Ÿๆ–‡ไปฅๅˆ†ไบซ็ตฆๆ‚จ็š„่ทŸ้šจ่€…ๅ€‘ใ€‚", - "interaction_modal.description.reply": "ๅœจ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ็š„่ฉฑ๏ผŒๆ‚จๅฏไปฅๅ›ž่ฆ†ๆญคๅ˜Ÿๆ–‡ใ€‚", + "interaction_modal.description.favourite": "่‹ฅๆ–ผ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ๏ผŒๆ‚จๅฏไปฅๅฐ‡ๆญคๅ˜Ÿๆ–‡ๅŠ ๅ…ฅๆœ€ๆ„›ไฝฟไฝœ่€…็Ÿฅ้“ๆ‚จๆฌฃ่ณžๅฎƒไธ”ๅฐ‡ๅฎƒๅ„ฒๅญ˜ไธ‹ไพ†ใ€‚", + "interaction_modal.description.follow": "่‹ฅๆ–ผ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ๏ผŒๆ‚จๅฏไปฅ่ทŸ้šจ {name} ไปฅๆ–ผ้ฆ–้ ๆ™‚้–“่ปธๆŽฅๆ”ถไป–ๅ€‘็š„ๅ˜Ÿๆ–‡ใ€‚", + "interaction_modal.description.reblog": "่‹ฅๆ–ผ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ๏ผŒๆ‚จๅฏไปฅ่ฝ‰ๅ˜Ÿๆญคๅ˜Ÿๆ–‡ไปฅๅˆ†ไบซ็ตฆๆ‚จ็š„่ทŸ้šจ่€…ๅ€‘ใ€‚", + "interaction_modal.description.reply": "่‹ฅๆ–ผ Mastodon ไธŠๆœ‰ๅ€‹ๅธณ่™Ÿ๏ผŒๆ‚จๅฏไปฅๅ›ž่ฆ†ๆญคๅ˜Ÿๆ–‡ใ€‚", "interaction_modal.login.action": "่ฟ”ๅ›ž้ฆ–้ ", "interaction_modal.login.prompt": "ๆ‚จๅธณ่™Ÿๆ‰€ๅฑฌไผบๆœๅ™จไน‹็ถฒๅŸŸ๏ผŒไพ‹ๅฆ‚๏ผšmastodon.social", "interaction_modal.no_account_yet": "้‚„ๆฒ’ๆœ‰ Mastodon ๅธณ่™Ÿๅ—Ž๏ผŸ", @@ -342,7 +379,7 @@ "keyboard_shortcuts.compose": "ๅฐ‡ๆธธๆจ™็งป่‡ณๆ–‡ๅญ—ๆ’ฐๅฏซๅ€ๅกŠ", "keyboard_shortcuts.description": "่ชชๆ˜Ž", "keyboard_shortcuts.direct": "้–‹ๅ•Ÿ็ง่จŠๅฐ่ฉฑๆฌ„", - "keyboard_shortcuts.down": "ๅพ€ไธ‹็งปๅ‹•", + "keyboard_shortcuts.down": "ๅ‘ไธ‹็งปๅ‹•", "keyboard_shortcuts.enter": "ๆชข่ฆ–ๅ˜Ÿๆ–‡", "keyboard_shortcuts.favourite": "ๅŠ ๅˆฐๆœ€ๆ„›", "keyboard_shortcuts.favourites": "้–‹ๅ•Ÿๆœ€ๆ„›ๅˆ—่กจ", @@ -368,7 +405,7 @@ "keyboard_shortcuts.toggle_sensitivity": "้กฏ็คบๆˆ–้šฑ่—ๅช’้ซ”", "keyboard_shortcuts.toot": "็™ผๅ€‹ๆ–ฐๅ˜Ÿๆ–‡", "keyboard_shortcuts.unfocus": "่ทณ้›ขๆ–‡ๅญ—ๆ’ฐๅฏซๅ€ๅกŠๆˆ–ๆœๅฐ‹ๆก†", - "keyboard_shortcuts.up": "ๅพ€ไธŠ็งปๅ‹•", + "keyboard_shortcuts.up": "ๅ‘ไธŠ็งปๅ‹•", "lightbox.close": "้—œ้–‰", "lightbox.compress": "ๆŠ˜็–Šๅœ–็‰‡ๆชข่ฆ–ๆก†", "lightbox.expand": "ๅฑ•้–‹ๅœ–็‰‡ๆชข่ฆ–ๆก†", @@ -377,6 +414,8 @@ "limited_account_hint.action": "ไธ€ๅพ‹้กฏ็คบๅ€‹ไบบๆช”ๆกˆ", "limited_account_hint.title": "ๆญคๅ€‹ไบบๆช”ๆกˆๅทฒ่ขซ {domain} ็š„็ฎก็†ๅ“ก้šฑ่—ใ€‚", "link_preview.author": "ไพ†่‡ช {name}", + "link_preview.more_from_author": "ไพ†่‡ช {name} ไน‹ๆ›ดๅคšๅ…งๅฎน", + "link_preview.shares": "{count, plural, other {{count} ๅ‰‡ๅ˜Ÿๆ–‡}}", "lists.account.add": "ๆ–ฐๅขž่‡ณๅˆ—่กจ", "lists.account.remove": "่‡ชๅˆ—่กจไธญ็งป้™ค", "lists.delete": "ๅˆช้™คๅˆ—่กจ", @@ -389,15 +428,21 @@ "lists.replies_policy.list": "ๅˆ—่กจๆˆๅ“ก", "lists.replies_policy.none": "ๆฒ’ๆœ‰ไบบ", "lists.replies_policy.title": "้กฏ็คบๅ›ž่ฆ†๏ผš", - "lists.search": "ๆœๅฐ‹ๆ‚จ่ทŸ้šจ็š„ไฝฟ็”จ่€…", + "lists.search": "ๆœๅฐ‹ๆ‚จ่ทŸ้šจไน‹ไฝฟ็”จ่€…", "lists.subheading": "ๆ‚จ็š„ๅˆ—่กจ", "load_pending": "{count, plural, one {# ๅ€‹ๆ–ฐ้ …็›ฎ} other {# ๅ€‹ๆ–ฐ้ …็›ฎ}}", "loading_indicator.label": "ๆญฃๅœจ่ผ‰ๅ…ฅ...", "media_gallery.toggle_visible": "ๅˆ‡ๆ›ๅฏ่ฆ‹ๆ€ง", "moved_to_account_banner.text": "ๆ‚จ็š„ๅธณ่™Ÿ {disabledAccount} ็›ฎๅ‰ๅทฒๅœ็”จ๏ผŒๅ› ็‚บๆ‚จๅทฒๆฌๅฎถ่‡ณ {movedToAccount}ใ€‚", - "mute_modal.duration": "ๆŒ็บŒๆ™‚้–“", - "mute_modal.hide_notifications": "ๆ˜ฏๅฆ้šฑ่—ไพ†่‡ช้€™ไฝไฝฟ็”จ่€…็š„้€š็Ÿฅ๏ผŸ", - "mute_modal.indefinite": "็„กๆœŸ้™", + "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": "ๅทฒๅฐ้Ž–็š„ไฝฟ็”จ่€…", @@ -430,11 +475,29 @@ "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.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": "ๆŽฅๅ—", + "notification_requests.dismiss": "้—œ้–‰", + "notification_requests.notifications_from": "ไพ†่‡ช {name} ไน‹้€š็Ÿฅ", + "notification_requests.title": "ๅทฒ้Žๆฟพไน‹้€š็Ÿฅ", "notifications.clear": "ๆธ…้™ค้€š็Ÿฅ", "notifications.clear_confirmation": "ๆ‚จ็ขบๅฎš่ฆๆฐธไน…ๆธ…้™คๆ‚จ็š„้€š็Ÿฅๅ—Ž๏ผŸ", "notifications.column_settings.admin.report": "ๆ–ฐๆชข่ˆ‰ๅ ฑๅ‘Š๏ผš", @@ -443,7 +506,6 @@ "notifications.column_settings.favourite": "ๆœ€ๆ„›๏ผš", "notifications.column_settings.filter_bar.advanced": "้กฏ็คบๆ‰€ๆœ‰ๅˆ†้กž", "notifications.column_settings.filter_bar.category": "ๅฟซ้€Ÿ้Žๆฟพๅ™จ", - "notifications.column_settings.filter_bar.show_bar": "้กฏ็คบ้Žๆฟพๅ™จ", "notifications.column_settings.follow": "ๆ–ฐ็š„่ทŸ้šจ่€…๏ผš", "notifications.column_settings.follow_request": "ๆ–ฐ็š„่ทŸ้šจ่ซ‹ๆฑ‚๏ผš", "notifications.column_settings.mention": "ๆๅŠ๏ผš", @@ -469,6 +531,15 @@ "notifications.permission_denied": "็”ฑๆ–ผไน‹ๅ‰ๅทฒๆ‹’็ต•็€่ฆฝๅ™จ่ซ‹ๆฑ‚๏ผŒๅ› ๆญค็„กๆณ•ไฝฟ็”จๆกŒ้ข้€š็Ÿฅ", "notifications.permission_denied_alert": "็”ฑๆ–ผไน‹ๅ‰็€่ฆฝๅ™จๆฌŠ้™่ขซๆ‹’็ต•๏ผŒ็„กๆณ•ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ", "notifications.permission_required": "็”ฑๆ–ผๅฐšๆœชๆŽˆไบˆๆ‰€้œ€็š„ๆฌŠ้™๏ผŒๅ› ๆญค็„กๆณ•ไฝฟ็”จๆกŒ้ข้€š็Ÿฅใ€‚", + "notifications.policy.filter_new_accounts.hint": "ๆ–ฐๅขžๆ–ผ้ŽๅŽป {days, plural, other {# ๆ—ฅ}}", + "notifications.policy.filter_new_accounts_title": "ๆ–ฐๅธณ่™Ÿ", + "notifications.policy.filter_not_followers_hint": "ๅŒ…ๅซๆœ€่ฟ‘ {days, plural, other {# ๆ—ฅ}} ๅ…ง่ทŸ้šจๆ‚จไน‹ไฝฟ็”จ่€…", + "notifications.policy.filter_not_followers_title": "ๆœช่ทŸ้šจๆ‚จไน‹ไฝฟ็”จ่€…", + "notifications.policy.filter_not_following_hint": "็›ด่‡ณๆ‚จๆ‰‹ๅ‹•ๆ ธๅ‡†ไป–ๅ€‘", + "notifications.policy.filter_not_following_title": "ๆ‚จๆœช่ทŸ้šจไน‹ไฝฟ็”จ่€…", + "notifications.policy.filter_private_mentions_hint": "้Žๆฟพ้€š็Ÿฅ๏ผŒ้™ค้žๅ˜Ÿๆ–‡ๅŒ…ๅซๆ–ผๆ‚จ็š„ๆๅŠ๏ผŒๆˆ–ๆ‚จ่ทŸ้šจ่ฉฒ็™ผๅ˜Ÿๅธณ่™Ÿ", + "notifications.policy.filter_private_mentions_title": "ไธ่ซ‹่‡ชไพ†็š„็ง่จŠ", + "notifications.policy.title": "้Žๆฟพ้€š็Ÿฅไพ†่‡ช...", "notifications_permission_banner.enable": "ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅ", "notifications_permission_banner.how_to_control": "ๅ•Ÿ็”จๆกŒ้ข้€š็Ÿฅไปฅๆ–ผ Mastodon ๆฒ’ๆœ‰้–‹ๅ•Ÿ็š„ๆ™‚ๅ€™ๆŽฅๆ”ถ้€š็Ÿฅใ€‚ๅ•Ÿ็”จๆกŒ้ข้€š็ŸฅๅพŒ๏ผŒๆ‚จๅฏไปฅ้€้ŽไธŠ้ข็š„ {icon} ๆŒ‰้ˆ•ๆบ–็ขบ็š„ๆŽงๅˆถๅ“ชไบ›้กžๅž‹็š„ไบ’ๅ‹•ๆœƒ็”ข็”ŸๆกŒ้ข้€š็Ÿฅใ€‚", "notifications_permission_banner.title": "ไธ่ฆ้Œฏ้Žไปปไฝ•ๆฑ่ฅฟ๏ผ", @@ -478,10 +549,10 @@ "onboarding.actions.go_to_home": "ๅ‰ๅพ€ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธ", "onboarding.compose.template": "ๅ“ˆๅ›‰ #Mastodon๏ผ", "onboarding.follows.empty": "ๅพˆ้บๆ†พ๏ผŒ็›ฎๅ‰ๆœช่ƒฝ้กฏ็คบไปปไฝ•็ตๆžœใ€‚ๆ‚จๅฏไปฅๅ˜—่ฉฆไฝฟ็”จๆœๅฐ‹ใ€็€่ฆฝๆŽข็ดข้ ้ขไปฅๆ‰พๅฐ‹ไบบๅ€‘่ทŸ้šจใ€ๆˆ–็จๅ€™ๅ†่ฉฆใ€‚", - "onboarding.follows.lead": "ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธๆ˜ฏ Mastodon ็š„ๆ ธๅฟƒ้ซ”้ฉ—ใ€‚่‹ฅๆ‚จ่ทŸ้šจๆ›ดๅคšไบบ็š„่ฉฑ๏ผŒๅฎƒๅฐ‡ๆœƒ่ฎŠๅพ—ๆ›ดๆดป่บๆœ‰่ถฃใ€‚้€™ไบ›ๅ€‹ไบบๆช”ๆกˆไนŸ่จฑๆ˜ฏๅ€‹ๅฅฝ่ตท้ปž๏ผŒๆ‚จๅฏไปฅ้šจๆ™‚ๅ–ๆถˆ่ทŸ้šจไป–ๅ€‘๏ผ", + "onboarding.follows.lead": "ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธๆ˜ฏ Mastodon ็š„ๆ ธๅฟƒ้ซ”้ฉ—ใ€‚่‹ฅๆ‚จ่ทŸ้šจๆ›ดๅคšไบบ๏ผŒๅฎƒๅฐ‡ๆœƒ่ฎŠๅพ—ๆ›ดๆดป่บๆœ‰่ถฃใ€‚้€™ไบ›ๅ€‹ไบบๆช”ๆกˆไนŸ่จฑๆ˜ฏๅ€‹ๅฅฝ่ตท้ปž๏ผŒๆ‚จๅฏไปฅ้šจๆ™‚ๅ–ๆถˆ่ทŸ้šจไป–ๅ€‘๏ผ", "onboarding.follows.title": "ๅฎข่ฃฝๅŒ–ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธ", "onboarding.profile.discoverable": "ไฝฟๆˆ‘็š„ๅ€‹ไบบๆช”ๆกˆๅฏไปฅ่ขซๆ‰พๅˆฐ", - "onboarding.profile.discoverable_hint": "็•ถๆ‚จๆ–ผ Mastodon ไธŠ้ธๆ“‡ๅŠ ๅ…ฅๅฏ็™ผ็พๆ€งๆ™‚๏ผŒๆ‚จ็š„ๅ˜Ÿๆ–‡ๅฏ่ƒฝๆœƒๅ‡บ็พๆ–ผๆœๅฐ‹็ตๆžœ่ˆ‡่ถจๅ‹ขไธญใ€‚ๆ‚จ็š„ๅ€‹ไบบๆช”ๆกˆๅฏ่ƒฝๆœƒ่ขซๆŽจ่–ฆ็ตฆ่ˆ‡ๆ‚จๅฟ—่ถฃ็›ธๆŠ•็š„ไบบใ€‚", + "onboarding.profile.discoverable_hint": "็•ถๆ‚จๆ–ผ Mastodon ไธŠ้ธๆ“‡ๅŠ ๅ…ฅๅฏ็™ผ็พๆ€งๆ™‚๏ผŒๆ‚จ็š„ๅ˜Ÿๆ–‡ๅฏ่ƒฝๆœƒ้กฏ็คบๆ–ผๆœๅฐ‹็ตๆžœ่ˆ‡่ถจๅ‹ขไธญใ€‚ๆ‚จ็š„ๅ€‹ไบบๆช”ๆกˆๅฏ่ƒฝๆœƒ่ขซๆŽจ่–ฆ็ตฆ่ˆ‡ๆ‚จๅฟ—่ถฃ็›ธๆŠ•็š„ไบบใ€‚", "onboarding.profile.display_name": "้กฏ็คบๅ็จฑ", "onboarding.profile.display_name_hint": "ๅฎŒๆ•ดๅ็จฑๆˆ–ๆšฑ็จฑ...", "onboarding.profile.lead": "ๆ‚จ้šจๆ™‚ๅฏไปฅ็จๅ€™ๆ–ผ่จญๅฎšไธญๅฎŒๆˆๆญคๆ“ไฝœ๏ผŒๅฐ‡ๆœ‰ๆ›ดๅคš่‡ช่จ‚้ธ้ …ๅฏไฝฟ็”จใ€‚", @@ -500,7 +571,7 @@ "onboarding.start.title": "ๅ™นๅ™น๏ผๅฎŒๆˆๅ•ฆ๏ผ", "onboarding.steps.follow_people.body": "Mastodon ็š„่ถฃๅ‘ณๅฐฑๆ˜ฏ่ทŸ้šจไบ›ๆœ‰่ถฃ็š„ไบบๅ€‘๏ผ", "onboarding.steps.follow_people.title": "ๅฎข่ฃฝๅŒ–ๆ‚จ็š„้ฆ–้ ๆ™‚้–“่ปธ", - "onboarding.steps.publish_status.body": "ๅ‘ๆ–ฐไธ–็•Œๆ‰“่ฒๆ‹›ๅ‘ผๅงใ€‚", + "onboarding.steps.publish_status.body": "้€้Žๆ–‡ๅญ—ใ€็…ง็‰‡ใ€ๅฝฑ็‰‡ๆˆ–ๆŠ•็ฅจ {emoji} ๅ‘ๆ–ฐไธ–็•Œๆ‰“่ฒๆ‹›ๅ‘ผๅงใ€‚", "onboarding.steps.publish_status.title": "ๆ’ฐๅฏซๆ‚จ็ฌฌไธ€ๅ‰‡ๅ˜Ÿๆ–‡", "onboarding.steps.setup_profile.body": "่‹ฅๆ‚จๅฎŒๆ•ดๅกซๅฏซๅ€‹ไบบๆช”ๆกˆ๏ผŒๅ…ถไป–ไบบๆฏ”่ผƒ้ก˜ๆ„่ˆ‡ๆ‚จไบ’ๅ‹•ใ€‚", "onboarding.steps.setup_profile.title": "ๅฎข่ฃฝๅŒ–ๆ‚จ็š„ๅ€‹ไบบๆช”ๆกˆ", @@ -521,12 +592,12 @@ "poll.vote": "ๆŠ•็ฅจ", "poll.voted": "ๆ‚จๅทฒๅฐๆญคๅ•้กŒๆŠ•็ฅจ", "poll.votes": "{votes, plural, one {# ๅผต็ฅจ} other {# ๅผต็ฅจ}}", - "poll_button.add_poll": "ๅปบ็ซ‹ๆŠ•็ฅจ", + "poll_button.add_poll": "ๆ–ฐๅขžๆŠ•็ฅจ", "poll_button.remove_poll": "็งป้™คๆŠ•็ฅจ", "privacy.change": "่ชฟๆ•ดๅ˜Ÿๆ–‡้šฑ็ง็‹€ๆ…‹", "privacy.direct.long": "ๆญคๅ˜Ÿๆ–‡ๆๅŠไน‹ๆ‰€ๆœ‰ไบบ", "privacy.direct.short": "ๆŒ‡ๅฎšไฝฟ็”จ่€…", - "privacy.private.long": "ๅชๆœ‰่ทŸ้šจๆ‚จ็š„ไบบ่ƒฝ็œ‹ๅˆฐ", + "privacy.private.long": "ๅชๆœ‰่ทŸ้šจๆ‚จไน‹ไฝฟ็”จ่€…่ƒฝ็œ‹ๅˆฐ", "privacy.private.short": "่ทŸ้šจ่€…", "privacy.public.long": "ๆ‰€ๆœ‰ไบบ (็„ก่ซ–ๅœจ Mastodon ไธŠ่ˆ‡ๅฆ)", "privacy.public.short": "ๅ…ฌ้–‹", @@ -625,13 +696,13 @@ "server_banner.about_active_users": "ๆœ€่ฟ‘ไธ‰ๅๆ—ฅๅ…งไฝฟ็”จๆญคไผบๆœๅ™จ็š„ไบบ๏ผˆๆœˆๆดป่บไฝฟ็”จ่€…๏ผ‰", "server_banner.active_users": "ๆดป่บไฝฟ็”จ่€…", "server_banner.administered_by": "็ฎก็†่€…๏ผš", - "server_banner.introduction": "{domain} ๆ˜ฏ็”ฑ {mastodon} ๆไพ›ไน‹ๅŽปไธญๅฟƒๅŒ–็คพ็พค็ถฒ่ทฏไธ€้ƒจๅˆ†ใ€‚", - "server_banner.learn_more": "ไบ†่งฃๆ›ดๅคš", + "server_banner.is_one_of_many": "{domain} ็‚บ่จฑๅคš็จ็ซ‹็š„ Mastodon ไผบๆœๅ™จไน‹ไธ€๏ผŒๆ‚จ่ƒฝ้€้Ž่ฉฒไผบๆœๅ™จๅƒ่ˆ‡่ฏ้‚ฆๅฎ‡ๅฎ™ใ€‚", "server_banner.server_stats": "ไผบๆœๅ™จ็ตฑ่จˆ๏ผš", "sign_in_banner.create_account": "ๆ–ฐๅขžๅธณ่™Ÿ", + "sign_in_banner.follow_anyone": "่ทŸ้šจ่ฏ้‚ฆๅฎ‡ๅฎ™ไธญ็š„ไปปไฝ•ไบบ๏ผŒไธฆไธ”ไปฅๆ™‚้–“้ †ๅบ็€่ฆฝๆ‰€ๆœ‰ๅ…งๅฎนใ€‚ๆฒ’ๆœ‰ๆผ”็ฎ—ๆณ•ใ€ๅปฃๅ‘Šใ€ๆˆ–้จ™้ปžๆ“Š้€ฃ็ตใ€‚", + "sign_in_banner.mastodon_is": "Mastodon ๆ˜ฏ่ทŸไธŠๆ™‚ไปฃๆฝฎๆต็š„ๆœ€ไฝณๅทฅๅ…ท๏ผ", "sign_in_banner.sign_in": "็™ปๅ…ฅ", "sign_in_banner.sso_redirect": "็™ปๅ…ฅๆˆ–่จปๅ†Š", - "sign_in_banner.text": "็™ปๅ…ฅไปฅ่ทŸ้šจๅ€‹ไบบๆช”ๆกˆ่ˆ‡ไธป้กŒๆจ™็ฑค๏ผŒๆˆ–ๆ”ถ่—ใ€ๅˆ†ไบซๅŠๅ›ž่ฆ†ๅ˜Ÿๆ–‡ใ€‚ๆ‚จไนŸๅฏไปฅไฝฟ็”จๆ‚จ็š„ๅธณ่™Ÿๆ–ผๅ…ถไป–ไผบๆœๅ™จ้€ฒ่กŒไบ’ๅ‹•ใ€‚", "status.admin_account": "้–‹ๅ•Ÿ @{name} ็š„็ฎก็†ไป‹้ข", "status.admin_domain": "้–‹ๅ•Ÿ {domain} ็š„็ฎก็†ไป‹้ข", "status.admin_status": "ๆ–ผ็ฎก็†ไป‹้ข้–‹ๅ•Ÿๆญคๅ˜Ÿๆ–‡", @@ -645,10 +716,11 @@ "status.direct": "็ง่จŠ @{name}", "status.direct_indicator": "็ง่จŠ", "status.edit": "็ทจ่ผฏ", - "status.edited": "็ทจ่ผฏๆ–ผ {date}", + "status.edited": "ไธŠๆฌก็ทจ่ผฏๆ–ผ {date}", "status.edited_x_times": "ๅทฒ็ทจ่ผฏ {count, plural, one {{count} ๆฌก} other {{count} ๆฌก}}", "status.embed": "ๅ…งๅตŒๅ˜Ÿๆ–‡", "status.favourite": "ๆœ€ๆ„›", + "status.favourites": "{count, plural, other {# ๅ‰‡ๆœ€ๆ„›}}", "status.filter": "้Žๆฟพๆญคๅ˜Ÿๆ–‡", "status.filtered": "ๅทฒ้Žๆฟพ", "status.hide": "้šฑ่—ๅ˜Ÿๆ–‡", @@ -663,16 +735,17 @@ "status.mute": "้œ้Ÿณ @{name}", "status.mute_conversation": "้œ้Ÿณๅฐ่ฉฑ", "status.open": "ๅฑ•้–‹ๆญคๅ˜Ÿๆ–‡", - "status.pin": "้‡˜้ธๅˆฐๅ€‹ไบบๆช”ๆกˆ้ ้ข", + "status.pin": "้‡˜้ธ่‡ณๅ€‹ไบบๆช”ๆกˆ้ ้ข", "status.pinned": "้‡˜้ธๅ˜Ÿๆ–‡", "status.read_more": "้–ฑ่ฎ€ๆ›ดๅคš", "status.reblog": "่ฝ‰ๅ˜Ÿ", "status.reblog_private": "ไพ็…งๅŽŸๅ˜Ÿๅฏ่ฆ‹ๆ€ง่ฝ‰ๅ˜Ÿ", "status.reblogged_by": "{name} ๅทฒ่ฝ‰ๅ˜Ÿ", + "status.reblogs": "{count, plural, other {# ๅ‰‡่ฝ‰ๅ˜Ÿ}}", "status.reblogs.empty": "้‚„ๆฒ’ๆœ‰ไบบ่ฝ‰ๅ˜Ÿ้Ž้€™ๅ‰‡ๅ˜Ÿๆ–‡ใ€‚็•ถๆœ‰ไบบ่ฝ‰ๅ˜Ÿๆ™‚๏ผŒๅฎƒๅฐ‡ๆ–ผๆญค้กฏ็คบใ€‚", "status.redraft": "ๅˆช้™คไธฆ้‡ๆ–ฐ็ทจ่ผฏ", "status.remove_bookmark": "็งป้™คๆ›ธ็ฑค", - "status.replied_to": "ๅ›ž่ฆ†็ตฆ {name}", + "status.replied_to": "ๅ›ž่ฆ† {name}", "status.reply": "ๅ›ž่ฆ†", "status.replyAll": "ๅ›ž่ฆ†่จŽ่ซ–ไธฒ", "status.report": "ๆชข่ˆ‰ @{name}", @@ -711,7 +784,7 @@ "units.short.million": "{count}M", "units.short.thousand": "{count}K", "upload_area.title": "ๆ‹–ๆ”พไพ†ไธŠๅ‚ณ", - "upload_button.label": "ไธŠๅ‚ณๅœ–็‰‡ใ€ๅฝฑ็‰‡ใ€ๆˆ–่€…้Ÿณๆจ‚ๆช”ๆกˆ", + "upload_button.label": "ไธŠๅ‚ณๅœ–็‰‡ใ€ๅฝฑ็‰‡ใ€ๆˆ–่€…้Ÿณ่จŠๆช”ๆกˆ", "upload_error.limit": "ๅทฒ้”ๅˆฐๆช”ๆกˆไธŠๅ‚ณ้™ๅˆถใ€‚", "upload_error.poll": "ไธๅ…่จฑๆ–ผๆŠ•็ฅจๆ™‚ไธŠๅ‚ณๆช”ๆกˆใ€‚", "upload_form.audio_description": "็‚บ่ฝ้šœไบบๅฃซๅขžๅŠ ๆ–‡ๅญ—่ชชๆ˜Ž", diff --git a/app/javascript/mastodon/models/notification_policy.ts b/app/javascript/mastodon/models/notification_policy.ts new file mode 100644 index 0000000000..eb65403292 --- /dev/null +++ b/app/javascript/mastodon/models/notification_policy.ts @@ -0,0 +1,3 @@ +import type { NotificationPolicyJSON } from 'mastodon/api_types/notification_policies'; + +export type NotificationPolicy = NotificationPolicyJSON; // No changes from the API type diff --git a/app/javascript/mastodon/models/status.ts b/app/javascript/mastodon/models/status.ts new file mode 100644 index 0000000000..7907fc34f8 --- /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/blocks.js b/app/javascript/mastodon/reducers/blocks.js deleted file mode 100644 index 1b65071634..0000000000 --- a/app/javascript/mastodon/reducers/blocks.js +++ /dev/null @@ -1,22 +0,0 @@ -import Immutable from 'immutable'; - -import { - BLOCKS_INIT_MODAL, -} from '../actions/blocks'; - -const initialState = Immutable.Map({ - new: Immutable.Map({ - account_id: null, - }), -}); - -export default function mutes(state = initialState, action) { - switch (action.type) { - case BLOCKS_INIT_MODAL: - return state.withMutations((state) => { - state.setIn(['new', 'account_id'], action.account.get('id')); - }); - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/boosts.js b/app/javascript/mastodon/reducers/boosts.js deleted file mode 100644 index d0d825057c..0000000000 --- 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/compose.js b/app/javascript/mastodon/reducers/compose.js index f57bbb77b8..9f66c09631 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -1,5 +1,7 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; + import { COMPOSE_MOUNT, COMPOSE_UNMOUNT, @@ -45,12 +47,12 @@ import { INIT_MEDIA_EDIT_MODAL, COMPOSE_CHANGE_MEDIA_DESCRIPTION, COMPOSE_CHANGE_MEDIA_FOCUS, + COMPOSE_CHANGE_MEDIA_ORDER, COMPOSE_SET_STATUS, COMPOSE_FOCUS, } from '../actions/compose'; import { REDRAFT } from '../actions/statuses'; import { STORE_HYDRATE } from '../actions/store'; -import { TIMELINE_DELETE } from '../actions/timelines'; import { me } from '../initial_state'; import { unescapeHTML } from '../utils/html'; import { uuid } from '../uuid'; @@ -280,12 +282,12 @@ const updateSuggestionTags = (state, token) => { }); }; -const updatePoll = (state, index, value) => state.updateIn(['poll', 'options'], options => { +const updatePoll = (state, index, value, maxOptions) => state.updateIn(['poll', 'options'], options => { const tmp = options.set(index, value).filterNot(x => x.trim().length === 0); if (tmp.size === 0) { return tmp.push('').push(''); - } else if (tmp.size < 4) { + } else if (tmp.size < maxOptions) { return tmp.push(''); } @@ -315,8 +317,8 @@ export default function compose(state = initialState, action) { map.set('spoiler', !state.get('spoiler')); map.set('idempotencyKey', uuid()); - if (!state.get('sensitive') && state.get('media_attachments').size >= 1) { - map.set('sensitive', true); + if (state.get('media_attachments').size >= 1 && !state.get('default_sensitive')) { + map.set('sensitive', !state.get('spoiler')); } }); case COMPOSE_SPOILER_TEXT_CHANGE: @@ -445,10 +447,10 @@ export default function compose(state = initialState, action) { return updateSuggestionTags(state, action.token); case COMPOSE_TAG_HISTORY_UPDATE: return state.set('tagHistory', fromJS(action.tags)); - case TIMELINE_DELETE: - if (action.id === state.get('in_reply_to')) { + case timelineDelete.type: + if (action.payload.statusId === state.get('in_reply_to')) { return state.set('in_reply_to', null); - } else if (action.id === state.get('id')) { + } else if (action.payload.statusId === state.get('id')) { return state.set('id', null); } else { return state; @@ -529,13 +531,21 @@ export default function compose(state = initialState, action) { case COMPOSE_POLL_REMOVE: return state.set('poll', null); case COMPOSE_POLL_OPTION_CHANGE: - return updatePoll(state, action.index, action.title); + return updatePoll(state, action.index, action.title, action.maxOptions); case COMPOSE_POLL_SETTINGS_CHANGE: return state.update('poll', poll => poll.set('expires_in', action.expiresIn).set('multiple', action.isMultiple)); case COMPOSE_LANGUAGE_CHANGE: return state.set('language', action.language); case COMPOSE_FOCUS: return state.set('focusDate', new Date()).update('text', text => text.length > 0 ? text : action.defaultText); + case COMPOSE_CHANGE_MEDIA_ORDER: + return state.update('media_attachments', list => { + const indexA = list.findIndex(x => x.get('id') === action.a); + const moveItem = list.get(indexA); + const indexB = list.findIndex(x => x.get('id') === action.b); + + return list.splice(indexA, 1).splice(indexB, 0, moveItem); + }); default: return state; } diff --git a/app/javascript/mastodon/reducers/contexts.js b/app/javascript/mastodon/reducers/contexts.js index f7d7419a4e..b2c6f3f1ab 100644 --- a/app/javascript/mastodon/reducers/contexts.js +++ b/app/javascript/mastodon/reducers/contexts.js @@ -1,11 +1,13 @@ import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; + import { blockAccountSuccess, muteAccountSuccess, } from '../actions/accounts'; import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses'; -import { TIMELINE_DELETE, TIMELINE_UPDATE } from '../actions/timelines'; +import { TIMELINE_UPDATE } from '../actions/timelines'; import { compareId } from '../compare_id'; const initialState = ImmutableMap({ @@ -97,8 +99,8 @@ export default function replies(state = initialState, action) { return filterContexts(state, action.payload.relationship, action.payload.statuses); case CONTEXT_FETCH_SUCCESS: return normalizeContext(state, action.id, action.ancestors, action.descendants); - case TIMELINE_DELETE: - return deleteFromContexts(state, [action.id]); + case timelineDelete.type: + return deleteFromContexts(state, [action.payload.statusId]); case TIMELINE_UPDATE: return updateContext(state, action.status); default: diff --git a/app/javascript/mastodon/reducers/index.ts b/app/javascript/mastodon/reducers/index.ts index ecef633873..6296ef2026 100644 --- a/app/javascript/mastodon/reducers/index.ts +++ b/app/javascript/mastodon/reducers/index.ts @@ -7,8 +7,6 @@ import { accountsReducer } from './accounts'; import accounts_map from './accounts_map'; import alerts from './alerts'; import announcements from './announcements'; -import blocks from './blocks'; -import boosts from './boosts'; import compose from './compose'; import contexts from './contexts'; import conversations from './conversations'; @@ -22,13 +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 mutes from './mutes'; +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,9 +59,6 @@ const reducers = { relationships: relationshipsReducer, settings, push_notifications, - mutes, - blocks, - boosts, server, contexts, compose, @@ -79,11 +75,13 @@ const reducers = { suggestions, polls, trends, - markers, - picture_in_picture, + markers: markersReducer, + picture_in_picture: pictureInPictureReducer, history, tags, followed_tags, + notificationPolicy: notificationPolicyReducer, + notificationRequests: notificationRequestsReducer, }; // We want the root state to be an ImmutableRecord, which is an object with a defined list of keys, diff --git a/app/javascript/mastodon/reducers/markers.js b/app/javascript/mastodon/reducers/markers.js deleted file mode 100644 index c7c5d99f61..0000000000 --- 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 0000000000..ec85d0f173 --- /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/meta.js b/app/javascript/mastodon/reducers/meta.js index 96baf2f115..ddb7884592 100644 --- a/app/javascript/mastodon/reducers/meta.js +++ b/app/javascript/mastodon/reducers/meta.js @@ -6,7 +6,6 @@ import { layoutFromWindow } from 'mastodon/is_mobile'; const initialState = ImmutableMap({ streaming_api_base_url: null, - access_token: null, layout: layoutFromWindow(), permissions: '0', }); @@ -14,7 +13,8 @@ const initialState = ImmutableMap({ export default function meta(state = initialState, action) { switch(action.type) { case STORE_HYDRATE: - return state.merge(action.state.get('meta')).set('permissions', action.state.getIn(['role', 'permissions'])); + // we do not want `access_token` to be stored in the state + return state.merge(action.state.get('meta')).delete('access_token').set('permissions', action.state.getIn(['role', 'permissions'])); case changeLayout.type: return state.set('layout', action.payload.layout); default: diff --git a/app/javascript/mastodon/reducers/modal.ts b/app/javascript/mastodon/reducers/modal.ts index 368f26542c..ca85eb8c7f 100644 --- a/app/javascript/mastodon/reducers/modal.ts +++ b/app/javascript/mastodon/reducers/modal.ts @@ -1,10 +1,11 @@ import type { Reducer } from '@reduxjs/toolkit'; import { Record as ImmutableRecord, Stack } from 'immutable'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; + import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose'; import type { ModalType } from '../actions/modal'; import { openModal, closeModal } from '../actions/modal'; -import { TIMELINE_DELETE } from '../actions/timelines'; export type ModalProps = Record; interface Modal { @@ -72,10 +73,10 @@ export const modalReducer: Reducer = (state = initialState, action) => { // TODO: type those actions else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS) return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false }); - else if (action.type === TIMELINE_DELETE) + else if (timelineDelete.match(action)) return state.update('stack', (stack) => stack.filterNot( - (modal) => modal.get('modalProps').statusId === action.id, + (modal) => modal.get('modalProps').statusId === action.payload.statusId, ), ); else return state; diff --git a/app/javascript/mastodon/reducers/mutes.js b/app/javascript/mastodon/reducers/mutes.js deleted file mode 100644 index a9eb61ff83..0000000000 --- a/app/javascript/mastodon/reducers/mutes.js +++ /dev/null @@ -1,31 +0,0 @@ -import Immutable from 'immutable'; - -import { - MUTES_INIT_MODAL, - MUTES_TOGGLE_HIDE_NOTIFICATIONS, - MUTES_CHANGE_DURATION, -} from '../actions/mutes'; - -const initialState = Immutable.Map({ - new: Immutable.Map({ - account: null, - notifications: true, - duration: 0, - }), -}); - -export default function mutes(state = initialState, action) { - switch (action.type) { - case MUTES_INIT_MODAL: - return state.withMutations((state) => { - state.setIn(['new', 'account'], action.account); - state.setIn(['new', 'notifications'], true); - }); - case MUTES_TOGGLE_HIDE_NOTIFICATIONS: - return state.updateIn(['new', 'notifications'], (old) => !old); - case MUTES_CHANGE_DURATION: - return state.setIn(['new', 'duration'], Number(action.duration)); - default: - return state; - } -} diff --git a/app/javascript/mastodon/reducers/notification_policy.ts b/app/javascript/mastodon/reducers/notification_policy.ts new file mode 100644 index 0000000000..ab111066cc --- /dev/null +++ b/app/javascript/mastodon/reducers/notification_policy.ts @@ -0,0 +1,18 @@ +import { createReducer, isAnyOf } from '@reduxjs/toolkit'; + +import { + fetchNotificationPolicy, + updateNotificationsPolicy, +} from 'mastodon/actions/notification_policies'; +import type { NotificationPolicy } from 'mastodon/models/notification_policy'; + +export const notificationPolicyReducer = + createReducer(null, (builder) => { + builder.addMatcher( + isAnyOf( + fetchNotificationPolicy.fulfilled, + updateNotificationsPolicy.fulfilled, + ), + (_state, action) => action.payload, + ); + }); diff --git a/app/javascript/mastodon/reducers/notification_requests.js b/app/javascript/mastodon/reducers/notification_requests.js new file mode 100644 index 0000000000..4247062a58 --- /dev/null +++ b/app/javascript/mastodon/reducers/notification_requests.js @@ -0,0 +1,96 @@ +import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; + +import { + NOTIFICATION_REQUESTS_EXPAND_REQUEST, + NOTIFICATION_REQUESTS_EXPAND_SUCCESS, + NOTIFICATION_REQUESTS_EXPAND_FAIL, + NOTIFICATION_REQUESTS_FETCH_REQUEST, + NOTIFICATION_REQUESTS_FETCH_SUCCESS, + NOTIFICATION_REQUESTS_FETCH_FAIL, + NOTIFICATION_REQUEST_FETCH_REQUEST, + NOTIFICATION_REQUEST_FETCH_SUCCESS, + NOTIFICATION_REQUEST_FETCH_FAIL, + NOTIFICATION_REQUEST_ACCEPT_REQUEST, + NOTIFICATION_REQUEST_DISMISS_REQUEST, + NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST, + NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS, + NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL, + NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST, + NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS, + NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL, +} from 'mastodon/actions/notifications'; + +import { notificationToMap } from './notifications'; + +const initialState = ImmutableMap({ + items: ImmutableList(), + isLoading: false, + next: null, + current: ImmutableMap({ + isLoading: false, + item: null, + removed: false, + notifications: ImmutableMap({ + items: ImmutableList(), + isLoading: false, + next: null, + }), + }), +}); + +const normalizeRequest = request => fromJS({ + ...request, + account: request.account.id, +}); + +const removeRequest = (state, id) => { + if (state.getIn(['current', 'item', 'id']) === id) { + state = state.setIn(['current', 'removed'], true); + } + + return state.update('items', list => list.filterNot(item => item.get('id') === id)); +}; + +export const notificationRequestsReducer = (state = initialState, action) => { + switch(action.type) { + case NOTIFICATION_REQUESTS_FETCH_SUCCESS: + return state.withMutations(map => { + map.update('items', list => ImmutableList(action.requests.map(normalizeRequest)).concat(list)); + map.set('isLoading', false); + map.update('next', next => next ?? action.next); + }); + case NOTIFICATION_REQUESTS_EXPAND_SUCCESS: + return state.withMutations(map => { + map.update('items', list => list.concat(ImmutableList(action.requests.map(normalizeRequest)))); + map.set('isLoading', false); + map.set('next', action.next); + }); + case NOTIFICATION_REQUESTS_EXPAND_REQUEST: + case NOTIFICATION_REQUESTS_FETCH_REQUEST: + return state.set('isLoading', true); + case NOTIFICATION_REQUESTS_EXPAND_FAIL: + case NOTIFICATION_REQUESTS_FETCH_FAIL: + return state.set('isLoading', false); + case NOTIFICATION_REQUEST_ACCEPT_REQUEST: + case NOTIFICATION_REQUEST_DISMISS_REQUEST: + return removeRequest(state, action.id); + case NOTIFICATION_REQUEST_FETCH_REQUEST: + return state.set('current', initialState.get('current').set('isLoading', true)); + case NOTIFICATION_REQUEST_FETCH_SUCCESS: + return state.update('current', map => map.set('isLoading', false).set('item', normalizeRequest(action.request))); + case NOTIFICATION_REQUEST_FETCH_FAIL: + return state.update('current', map => map.set('isLoading', false)); + case NOTIFICATIONS_FOR_REQUEST_FETCH_REQUEST: + case NOTIFICATIONS_FOR_REQUEST_EXPAND_REQUEST: + return state.setIn(['current', 'notifications', 'isLoading'], true); + case NOTIFICATIONS_FOR_REQUEST_FETCH_SUCCESS: + return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => ImmutableList(action.notifications.map(notificationToMap)).concat(list)).update('next', next => next ?? action.next)); + case NOTIFICATIONS_FOR_REQUEST_EXPAND_SUCCESS: + return state.updateIn(['current', 'notifications'], map => map.set('isLoading', false).update('items', list => list.concat(ImmutableList(action.notifications.map(notificationToMap)))).set('next', action.next)); + case NOTIFICATIONS_FOR_REQUEST_FETCH_FAIL: + case NOTIFICATIONS_FOR_REQUEST_EXPAND_FAIL: + return state.setIn(['current', 'notifications', 'isLoading'], false); + default: + return state; + } +}; diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js index 2ca301b19a..79aa5651ff 100644 --- a/app/javascript/mastodon/reducers/notifications.js +++ b/app/javascript/mastodon/reducers/notifications.js @@ -1,6 +1,7 @@ import { fromJS, Map as ImmutableMap, List as ImmutableList } from 'immutable'; import { blockDomainSuccess } from 'mastodon/actions/domain_blocks'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; import { authorizeFollowRequestSuccess, @@ -13,7 +14,7 @@ import { unfocusApp, } from '../actions/app'; import { - MARKERS_FETCH_SUCCESS, + fetchMarkers, } from '../actions/markers'; import { notificationsUpdate, @@ -30,7 +31,7 @@ import { NOTIFICATIONS_SET_BROWSER_SUPPORT, NOTIFICATIONS_SET_BROWSER_PERMISSION, } from '../actions/notifications'; -import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines'; +import { disconnectTimeline } from '../actions/timelines'; import { compareId } from '../compare_id'; const initialState = ImmutableMap({ @@ -48,13 +49,15 @@ const initialState = ImmutableMap({ browserPermission: 'default', }); -const notificationToMap = notification => ImmutableMap({ +export const notificationToMap = notification => ImmutableMap({ id: notification.id, type: notification.type, account: notification.account.id, created_at: notification.created_at, 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) => { @@ -254,8 +257,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: @@ -289,11 +292,11 @@ export default function notifications(state = initialState, action) { return filterNotifications(state, [action.payload.id], 'follow_request'); case NOTIFICATIONS_CLEAR: return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false); - case TIMELINE_DELETE: - return deleteByStatus(state, action.id); - case TIMELINE_DISCONNECT: - return action.timeline === 'home' ? - state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) : + case timelineDelete.type: + return deleteByStatus(state, action.payload.statusId); + case disconnectTimeline.type: + return action.payload.timeline === 'home' ? + state.update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) : state; case NOTIFICATIONS_MARK_AS_READ: const lastNotification = state.get('items').find(item => item !== null); 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 6824ad9303..0000000000 --- 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 0000000000..10d4f1fae5 --- /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 { timelineDelete } from 'mastodon/actions/timelines_typed'; + +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 (timelineDelete.match(action)) + if (state.type && state.statusId === action.payload.statusId) + return initialState; + + return state; +}; diff --git a/app/javascript/mastodon/reducers/search.js b/app/javascript/mastodon/reducers/search.js index 72835eb917..7828d49eee 100644 --- a/app/javascript/mastodon/reducers/search.js +++ b/app/javascript/mastodon/reducers/search.js @@ -50,6 +50,7 @@ export default function search(state = initialState, action) { return state.set('hidden', true); case SEARCH_FETCH_REQUEST: return state.withMutations(map => { + map.set('results', ImmutableMap()); map.set('isLoading', true); map.set('submitted', true); map.set('type', action.searchType); diff --git a/app/javascript/mastodon/reducers/statuses.js b/app/javascript/mastodon/reducers/statuses.js index 683fe848f7..d92174f806 100644 --- a/app/javascript/mastodon/reducers/statuses.js +++ b/app/javascript/mastodon/reducers/statuses.js @@ -1,12 +1,10 @@ import { Map as ImmutableMap, fromJS } from 'immutable'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; + import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer'; import { normalizeStatusTranslation } from '../actions/importer/normalizer'; import { - REBLOG_REQUEST, - REBLOG_FAIL, - UNREBLOG_REQUEST, - UNREBLOG_FAIL, FAVOURITE_REQUEST, FAVOURITE_FAIL, UNFAVOURITE_REQUEST, @@ -16,6 +14,10 @@ import { UNBOOKMARK_REQUEST, UNBOOKMARK_FAIL, } from '../actions/interactions'; +import { + reblog, + unreblog, +} from '../actions/interactions_typed'; import { STATUS_MUTE_SUCCESS, STATUS_UNMUTE_SUCCESS, @@ -27,7 +29,6 @@ import { STATUS_FETCH_REQUEST, STATUS_FETCH_FAIL, } from '../actions/statuses'; -import { TIMELINE_DELETE } from '../actions/timelines'; const importStatus = (state, status) => state.set(status.id, fromJS(status)); @@ -65,6 +66,7 @@ const statusTranslateUndo = (state, id) => { const initialState = ImmutableMap(); +/** @type {import('@reduxjs/toolkit').Reducer} */ export default function statuses(state = initialState, action) { switch(action.type) { case STATUS_FETCH_REQUEST: @@ -91,14 +93,6 @@ export default function statuses(state = initialState, action) { return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], false); case UNBOOKMARK_FAIL: return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'bookmarked'], true); - case REBLOG_REQUEST: - return state.setIn([action.status.get('id'), 'reblogged'], true); - case REBLOG_FAIL: - return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], false); - case UNREBLOG_REQUEST: - return state.setIn([action.status.get('id'), 'reblogged'], false); - case UNREBLOG_FAIL: - return state.get(action.status.get('id')) === undefined ? state : state.setIn([action.status.get('id'), 'reblogged'], true); case STATUS_MUTE_SUCCESS: return state.setIn([action.id, 'muted'], true); case STATUS_UNMUTE_SUCCESS: @@ -121,13 +115,22 @@ export default function statuses(state = initialState, action) { }); case STATUS_COLLAPSE: return state.setIn([action.id, 'collapsed'], action.isCollapsed); - case TIMELINE_DELETE: - return deleteStatus(state, action.id, action.references); + case timelineDelete.type: + return deleteStatus(state, action.payload.statusId, action.payload.references); case STATUS_TRANSLATE_SUCCESS: return statusTranslateSuccess(state, action.id, action.translation); case STATUS_TRANSLATE_UNDO: return statusTranslateUndo(state, action.id); default: - return state; + if(reblog.pending.match(action)) + return state.setIn([action.meta.arg.statusId, 'reblogged'], true); + else if(reblog.rejected.match(action)) + return state.get(action.meta.arg.statusId) === undefined ? state : state.setIn([action.meta.arg.statusId, 'reblogged'], false); + else if(unreblog.pending.match(action)) + return state.setIn([action.meta.arg.statusId, 'reblogged'], false); + else if(unreblog.rejected.match(action)) + return state.get(action.meta.arg.statusId) === undefined ? state : state.setIn([action.meta.arg.statusId, 'reblogged'], true); + else + return state; } } diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 4c9ab98a82..b07281ab87 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -1,5 +1,7 @@ import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable'; +import { timelineDelete } from 'mastodon/actions/timelines_typed'; + import { blockAccountSuccess, muteAccountSuccess, @@ -7,19 +9,18 @@ import { } from '../actions/accounts'; import { TIMELINE_UPDATE, - TIMELINE_DELETE, TIMELINE_CLEAR, TIMELINE_EXPAND_SUCCESS, TIMELINE_EXPAND_REQUEST, TIMELINE_EXPAND_FAIL, TIMELINE_SCROLL_TOP, TIMELINE_CONNECT, - TIMELINE_DISCONNECT, TIMELINE_LOAD_PENDING, TIMELINE_MARK_AS_PARTIAL, TIMELINE_INSERT, TIMELINE_GAP, TIMELINE_SUGGESTIONS, + disconnectTimeline, } from '../actions/timelines'; import { compareId } from '../compare_id'; @@ -158,7 +159,7 @@ const filterTimelines = (state, relationship, statuses) => { return; } - references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => item.get('id')); + references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => item.get('id')).valueSeq().toJSON(); state = deleteStatus(state, status.get('id'), references, relationship.id); }); @@ -201,8 +202,8 @@ export default function timelines(state = initialState, action) { return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent, action.usePendingItems); case TIMELINE_UPDATE: return updateTimeline(state, action.timeline, fromJS(action.status), action.usePendingItems); - case TIMELINE_DELETE: - return deleteStatus(state, action.id, action.references, action.reblogOf); + case timelineDelete.type: + return deleteStatus(state, action.payload.statusId, action.payload.references, action.payload.reblogOf); case TIMELINE_CLEAR: return clearTimeline(state, action.timeline); case blockAccountSuccess.type: @@ -214,11 +215,11 @@ export default function timelines(state = initialState, action) { return updateTop(state, action.timeline, action.top); case TIMELINE_CONNECT: return state.update(action.timeline, initialTimeline, map => reconnectTimeline(map, action.usePendingItems)); - case TIMELINE_DISCONNECT: + case disconnectTimeline.type: return state.update( - action.timeline, + action.payload.timeline, initialTimeline, - map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items), + map => map.set('online', false).update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items), ); case TIMELINE_MARK_AS_PARTIAL: return state.update( diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index b1c60403e9..bd9b53919c 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 e11aa78178..e77cec34ed 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 51839f427a..91407b1ec0 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 = {}; @@ -73,8 +74,9 @@ export const soundsMiddleware = (): Middleware< if (isActionWithMetaSound(action)) { const sound = action.meta.sound; - if (sound && Object.hasOwn(soundCache, sound)) { - play(soundCache[sound]); + if (sound) { + const s = soundCache[sound]; + if (s) play(s); } } diff --git a/app/javascript/mastodon/store/typed_functions.ts b/app/javascript/mastodon/store/typed_functions.ts index 4859b82651..e5820149db 100644 --- a/app/javascript/mastodon/store/typed_functions.ts +++ b/app/javascript/mastodon/store/typed_functions.ts @@ -2,13 +2,212 @@ import { createAsyncThunk } from '@reduxjs/toolkit'; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { useDispatch, useSelector } from 'react-redux'; +import type { BaseThunkAPI } from '@reduxjs/toolkit/dist/createAsyncThunk'; + 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; +} + +interface AppMeta { + skipLoading?: boolean; +} + export const createAppAsyncThunk = createAsyncThunk.withTypes<{ state: RootState; dispatch: AppDispatch; - rejectValue: string; + rejectValue: AsyncThunkRejectValue; }>(); + +type AppThunkApi = Pick< + BaseThunkAPI< + RootState, + unknown, + AppDispatch, + AsyncThunkRejectValue, + AppMeta, + AppMeta + >, + 'getState' | 'dispatch' +>; + +interface AppThunkOptions { + skipLoading?: boolean; +} + +const createBaseAsyncThunk = createAsyncThunk.withTypes<{ + state: RootState; + dispatch: AppDispatch; + rejectValue: AsyncThunkRejectValue; + fulfilledMeta: AppMeta; + rejectedMeta: AppMeta; +}>(); + +export function createThunk( + name: string, + creator: (arg: Arg, api: AppThunkApi) => Returned | Promise, + options: AppThunkOptions = {}, +) { + return createBaseAsyncThunk( + name, + async ( + arg: Arg, + { getState, dispatch, fulfillWithValue, rejectWithValue }, + ) => { + try { + const result = await creator(arg, { dispatch, getState }); + + return fulfillWithValue(result, { + skipLoading: options.skipLoading, + }); + } catch (error) { + return rejectWithValue({ error }, { skipLoading: true }); + } + }, + { + getPendingMeta() { + if (options.skipLoading) return { skipLoading: true }; + return {}; + }, + }, + ); +} + +const discardLoadDataInPayload = Symbol('discardLoadDataInPayload'); +type DiscardLoadData = typeof discardLoadDataInPayload; + +type OnData = ( + data: LoadDataResult, + api: AppThunkApi & { + actionArg: ActionArg; + discardLoadData: DiscardLoadData; + }, +) => ReturnedData | DiscardLoadData | Promise; + +type LoadData = ( + args: Args, + api: AppThunkApi, +) => Promise; + +type ArgsType = Record | undefined; + +// Overload when there is no `onData` method, the payload is the `onData` result +export function createDataLoadingThunk( + name: string, + loadData: (args: Args) => Promise, + thunkOptions?: AppThunkOptions, +): ReturnType>; + +// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty +export function createDataLoadingThunk( + name: string, + loadData: LoadData, + onDataOrThunkOptions?: + | AppThunkOptions + | OnData, + thunkOptions?: AppThunkOptions, +): ReturnType>; + +// Overload when the `onData` method returns nothing, then the mayload is the `onData` result +export function createDataLoadingThunk( + name: string, + loadData: LoadData, + onDataOrThunkOptions?: AppThunkOptions | OnData, + thunkOptions?: AppThunkOptions, +): ReturnType>; + +// Overload when there is an `onData` method returning something +export function createDataLoadingThunk< + LoadDataResult, + Args extends ArgsType, + Returned, +>( + name: string, + loadData: LoadData, + onDataOrThunkOptions?: + | AppThunkOptions + | OnData, + thunkOptions?: AppThunkOptions, +): ReturnType>; + +/** + * This function creates a Redux Thunk that handles loading data asynchronously (usually from the API), dispatching `pending`, `fullfilled` and `rejected` actions. + * + * You can run a callback on the `onData` results to either dispatch side effects or modify the payload. + * + * It is a wrapper around RTK's [`createAsyncThunk`](https://redux-toolkit.js.org/api/createAsyncThunk) + * @param name Prefix for the actions types + * @param loadData Function that loads the data. It's (object) argument will become the thunk's argument + * @param onDataOrThunkOptions + * Callback called on the results from `loadData`. + * + * First argument will be the return from `loadData`. + * + * Second argument is an object with: `dispatch`, `getState` and `discardLoadData`. + * It can return: + * - `undefined` (or no explicit return), meaning that the `onData` results will be the payload + * - `discardLoadData` to discard the `onData` results and return an empty payload + * - anything else, which will be the payload + * + * You can also omit this parameter and pass `thunkOptions` directly + * @param maybeThunkOptions + * Additional Mastodon specific options for the thunk. Currently supports: + * - `skipLoading` to avoid showing the loading bar when the request is in progress + * @returns The created thunk + */ +export function createDataLoadingThunk< + LoadDataResult, + Args extends ArgsType, + Returned, +>( + name: string, + loadData: LoadData, + onDataOrThunkOptions?: + | AppThunkOptions + | OnData, + maybeThunkOptions?: AppThunkOptions, +) { + let onData: OnData | undefined; + let thunkOptions: AppThunkOptions | undefined; + + if (typeof onDataOrThunkOptions === 'function') onData = onDataOrThunkOptions; + else if (typeof onDataOrThunkOptions === 'object') + thunkOptions = onDataOrThunkOptions; + + if (maybeThunkOptions) { + thunkOptions = maybeThunkOptions; + } + + return createThunk( + name, + async (arg, { getState, dispatch }) => { + const data = await loadData(arg, { + dispatch, + getState, + }); + + if (!onData) return data as Returned; + + const result = await onData(data, { + dispatch, + getState, + discardLoadData: discardLoadDataInPayload, + actionArg: arg, + }); + + // if there is no return in `onData`, we return the `onData` result + if (typeof result === 'undefined') return data as Returned; + // the user explicitely asked to discard the payload + else if (result === discardLoadDataInPayload) + return undefined as Returned; + else return result; + }, + thunkOptions, + ); +} diff --git a/app/javascript/mastodon/stream.js b/app/javascript/mastodon/stream.js index ff3af5fd88..40d69136a8 100644 --- a/app/javascript/mastodon/stream.js +++ b/app/javascript/mastodon/stream.js @@ -2,6 +2,8 @@ import WebSocketClient from '@gamestdio/websocket'; +import { getAccessToken } from './initial_state'; + /** * @type {WebSocketClient | undefined} */ @@ -145,9 +147,11 @@ const channelNameWithInlineParams = (channelName, params) => { // @ts-expect-error export const connectStream = (channelName, params, callbacks) => (dispatch, getState) => { const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']); - const accessToken = getState().getIn(['meta', 'access_token']); + const accessToken = getAccessToken(); const { onConnect, onReceive, onDisconnect } = callbacks(dispatch, getState); + if(!accessToken) throw new Error("Trying to connect to the streaming server but no access token is available."); + // If we cannot use a websockets connection, we must fall back // to using individual connections for each channel if (!streamingAPIBaseURL.startsWith('ws')) { diff --git a/app/javascript/mastodon/test_helpers.tsx b/app/javascript/mastodon/test_helpers.tsx index 6895895569..93b5a8453a 100644 --- a/app/javascript/mastodon/test_helpers.tsx +++ b/app/javascript/mastodon/test_helpers.tsx @@ -1,7 +1,3 @@ -import PropTypes from 'prop-types'; -import type { PropsWithChildren } from 'react'; -import { Component } from 'react'; - import { IntlProvider } from 'react-intl'; import { MemoryRouter } from 'react-router'; @@ -9,44 +5,26 @@ import { MemoryRouter } from 'react-router'; // eslint-disable-next-line import/no-extraneous-dependencies import { render as rtlRender } from '@testing-library/react'; -class FakeIdentityWrapper extends Component< - PropsWithChildren<{ signedIn: boolean }> -> { - static childContextTypes = { - identity: PropTypes.shape({ - signedIn: PropTypes.bool.isRequired, - accountId: PropTypes.string, - disabledAccountId: PropTypes.string, - accessToken: PropTypes.string, - }).isRequired, - }; - - getChildContext() { - return { - identity: { - signedIn: this.props.signedIn, - accountId: '123', - accessToken: 'test-access-token', - }, - }; - } - - render() { - return this.props.children; - } -} +import { IdentityContext } from './identity_context'; function render( ui: React.ReactElement, { locale = 'en', signedIn = true, ...renderOptions } = {}, ) { - const Wrapper = (props: { children: React.ReactElement }) => { + const fakeIdentity = { + signedIn: signedIn, + accountId: '123', + disabledAccountId: undefined, + permissions: 0, + }; + + const Wrapper = (props: { children: React.ReactNode }) => { return ( - + {props.children} - + ); 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 d948cf4c5d..99bfdcb801 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 0000000000..d1d1444e8a --- /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/log_out.ts b/app/javascript/mastodon/utils/log_out.ts index 3a4cc8ecb1..b08a61a6a2 100644 --- a/app/javascript/mastodon/utils/log_out.ts +++ b/app/javascript/mastodon/utils/log_out.ts @@ -1,5 +1,3 @@ -import Rails from '@rails/ujs'; - export const logOut = () => { const form = document.createElement('form'); @@ -9,13 +7,18 @@ export const logOut = () => { methodInput.setAttribute('type', 'hidden'); form.appendChild(methodInput); - const csrfToken = Rails.csrfToken(); - const csrfParam = Rails.csrfParam(); + const csrfToken = document.querySelector( + 'meta[name=csrf-token]', + ); + + const csrfParam = document.querySelector( + 'meta[name=csrf-param]', + ); if (csrfParam && csrfToken) { const csrfInput = document.createElement('input'); - csrfInput.setAttribute('name', csrfParam); - csrfInput.setAttribute('value', csrfToken); + csrfInput.setAttribute('name', csrfParam.content); + csrfInput.setAttribute('value', csrfToken.content); csrfInput.setAttribute('type', 'hidden'); form.appendChild(csrfInput); } diff --git a/app/javascript/mastodon/utils/numbers.ts b/app/javascript/mastodon/utils/numbers.ts index 0a73061f69..0c11c268dd 100644 --- a/app/javascript/mastodon/utils/numbers.ts +++ b/app/javascript/mastodon/utils/numbers.ts @@ -69,3 +69,11 @@ export function pluralReady( export function roundTo10(num: number): number { return Math.round(num * 0.1) / 0.1; } + +export function toCappedNumber(num: number, max = 99): string { + if (num > max) { + return `${max}+`; + } else { + return num.toString(); + } +} diff --git a/app/javascript/mastodon/uuid.ts b/app/javascript/mastodon/uuid.ts index 4d0a8a8036..0b4d55beb6 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/material-icons/400-20px/bar_chart_4_bars-fill.svg b/app/javascript/material-icons/400-20px/bar_chart_4_bars-fill.svg new file mode 100644 index 0000000000..78ce147272 --- /dev/null +++ b/app/javascript/material-icons/400-20px/bar_chart_4_bars-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/bar_chart_4_bars.svg b/app/javascript/material-icons/400-20px/bar_chart_4_bars.svg new file mode 100644 index 0000000000..78ce147272 --- /dev/null +++ b/app/javascript/material-icons/400-20px/bar_chart_4_bars.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/close-fill.svg b/app/javascript/material-icons/400-20px/close-fill.svg new file mode 100644 index 0000000000..46d8afd7e1 --- /dev/null +++ b/app/javascript/material-icons/400-20px/close-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/close.svg b/app/javascript/material-icons/400-20px/close.svg new file mode 100644 index 0000000000..46d8afd7e1 --- /dev/null +++ b/app/javascript/material-icons/400-20px/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/mood-fill.svg b/app/javascript/material-icons/400-20px/mood-fill.svg new file mode 100644 index 0000000000..ef72aeef6e --- /dev/null +++ b/app/javascript/material-icons/400-20px/mood-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/mood.svg b/app/javascript/material-icons/400-20px/mood.svg new file mode 100644 index 0000000000..abb44c4663 --- /dev/null +++ b/app/javascript/material-icons/400-20px/mood.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/photo_library-fill.svg b/app/javascript/material-icons/400-20px/photo_library-fill.svg new file mode 100644 index 0000000000..5f5e39fbf9 --- /dev/null +++ b/app/javascript/material-icons/400-20px/photo_library-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/photo_library.svg b/app/javascript/material-icons/400-20px/photo_library.svg new file mode 100644 index 0000000000..5804edb01c --- /dev/null +++ b/app/javascript/material-icons/400-20px/photo_library.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/settings-fill.svg b/app/javascript/material-icons/400-20px/settings-fill.svg new file mode 100644 index 0000000000..f5de77821d --- /dev/null +++ b/app/javascript/material-icons/400-20px/settings-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/settings.svg b/app/javascript/material-icons/400-20px/settings.svg new file mode 100644 index 0000000000..472569ab6a --- /dev/null +++ b/app/javascript/material-icons/400-20px/settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/warning-fill.svg b/app/javascript/material-icons/400-20px/warning-fill.svg new file mode 100644 index 0000000000..85dd926d39 --- /dev/null +++ b/app/javascript/material-icons/400-20px/warning-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-20px/warning.svg b/app/javascript/material-icons/400-20px/warning.svg new file mode 100644 index 0000000000..d7d45a3211 --- /dev/null +++ b/app/javascript/material-icons/400-20px/warning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/badge-fill.svg b/app/javascript/material-icons/400-24px/badge-fill.svg new file mode 100644 index 0000000000..2f7175b7f1 --- /dev/null +++ b/app/javascript/material-icons/400-24px/badge-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/badge.svg b/app/javascript/material-icons/400-24px/badge.svg new file mode 100644 index 0000000000..d413363a4c --- /dev/null +++ b/app/javascript/material-icons/400-24px/badge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/domain_disabled-fill.svg b/app/javascript/material-icons/400-24px/domain_disabled-fill.svg new file mode 100644 index 0000000000..2f16593d38 --- /dev/null +++ b/app/javascript/material-icons/400-24px/domain_disabled-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/domain_disabled.svg b/app/javascript/material-icons/400-24px/domain_disabled.svg new file mode 100644 index 0000000000..2f16593d38 --- /dev/null +++ b/app/javascript/material-icons/400-24px/domain_disabled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/explore-fill.svg b/app/javascript/material-icons/400-24px/explore-fill.svg new file mode 100644 index 0000000000..febe0a63b4 --- /dev/null +++ b/app/javascript/material-icons/400-24px/explore-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/explore.svg b/app/javascript/material-icons/400-24px/explore.svg new file mode 100644 index 0000000000..547a999421 --- /dev/null +++ b/app/javascript/material-icons/400-24px/explore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/gavel-fill.svg b/app/javascript/material-icons/400-24px/gavel-fill.svg new file mode 100644 index 0000000000..9699b8480a --- /dev/null +++ b/app/javascript/material-icons/400-24px/gavel-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/gavel.svg b/app/javascript/material-icons/400-24px/gavel.svg new file mode 100644 index 0000000000..9699b8480a --- /dev/null +++ b/app/javascript/material-icons/400-24px/gavel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/globe-fill.svg b/app/javascript/material-icons/400-24px/globe-fill.svg new file mode 100644 index 0000000000..c931f53c74 --- /dev/null +++ b/app/javascript/material-icons/400-24px/globe-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/globe.svg b/app/javascript/material-icons/400-24px/globe.svg new file mode 100644 index 0000000000..c931f53c74 --- /dev/null +++ b/app/javascript/material-icons/400-24px/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/heart_broken-fill.svg b/app/javascript/material-icons/400-24px/heart_broken-fill.svg new file mode 100644 index 0000000000..75ff3932cd --- /dev/null +++ b/app/javascript/material-icons/400-24px/heart_broken-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/heart_broken.svg b/app/javascript/material-icons/400-24px/heart_broken.svg new file mode 100644 index 0000000000..2ce7de57f1 --- /dev/null +++ b/app/javascript/material-icons/400-24px/heart_broken.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/history-fill.svg b/app/javascript/material-icons/400-24px/history-fill.svg new file mode 100644 index 0000000000..2d8124b474 --- /dev/null +++ b/app/javascript/material-icons/400-24px/history-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/history.svg b/app/javascript/material-icons/400-24px/history.svg new file mode 100644 index 0000000000..2d8124b474 --- /dev/null +++ b/app/javascript/material-icons/400-24px/history.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/inventory_2-fill.svg b/app/javascript/material-icons/400-24px/inventory_2-fill.svg new file mode 100644 index 0000000000..10ec85da04 --- /dev/null +++ b/app/javascript/material-icons/400-24px/inventory_2-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/inventory_2.svg b/app/javascript/material-icons/400-24px/inventory_2.svg new file mode 100644 index 0000000000..d00fb1a632 --- /dev/null +++ b/app/javascript/material-icons/400-24px/inventory_2.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/link_off-fill.svg b/app/javascript/material-icons/400-24px/link_off-fill.svg new file mode 100644 index 0000000000..618e775347 --- /dev/null +++ b/app/javascript/material-icons/400-24px/link_off-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/link_off.svg b/app/javascript/material-icons/400-24px/link_off.svg new file mode 100644 index 0000000000..618e775347 --- /dev/null +++ b/app/javascript/material-icons/400-24px/link_off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mood-fill.svg b/app/javascript/material-icons/400-24px/mood-fill.svg deleted file mode 100644 index 9480d0fb92..0000000000 --- a/app/javascript/material-icons/400-24px/mood-fill.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/mood.svg b/app/javascript/material-icons/400-24px/mood.svg deleted file mode 100644 index 46cafa7680..0000000000 --- a/app/javascript/material-icons/400-24px/mood.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/person_remove-fill.svg b/app/javascript/material-icons/400-24px/person_remove-fill.svg new file mode 100644 index 0000000000..239c7a49dc --- /dev/null +++ b/app/javascript/material-icons/400-24px/person_remove-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/person_remove.svg b/app/javascript/material-icons/400-24px/person_remove.svg new file mode 100644 index 0000000000..725da3649b --- /dev/null +++ b/app/javascript/material-icons/400-24px/person_remove.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/star-fill.svg b/app/javascript/material-icons/400-24px/star-fill.svg index cb2231e634..84e8230ab7 100644 --- a/app/javascript/material-icons/400-24px/star-fill.svg +++ b/app/javascript/material-icons/400-24px/star-fill.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/material-icons/400-24px/star.svg b/app/javascript/material-icons/400-24px/star.svg index 1736e085d0..6a72ecc226 100644 --- a/app/javascript/material-icons/400-24px/star.svg +++ b/app/javascript/material-icons/400-24px/star.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/app/javascript/packs/admin.jsx b/app/javascript/packs/admin.jsx deleted file mode 100644 index d3bfc4ea90..0000000000 --- a/app/javascript/packs/admin.jsx +++ /dev/null @@ -1,248 +0,0 @@ -import './public-path'; -import React from 'react'; -import { createRoot } from 'react-dom/client'; - -import Rails from '@rails/ujs'; - -import ready from '../mastodon/ready'; - -const setAnnouncementEndsAttributes = (target) => { - const valid = target?.value && target?.validity?.valid; - const element = document.querySelector('input[type="datetime-local"]#announcement_ends_at'); - if (valid) { - element.classList.remove('optional'); - element.required = true; - element.min = target.value; - } else { - element.classList.add('optional'); - element.removeAttribute('required'); - element.removeAttribute('min'); - } -}; - -Rails.delegate(document, 'input[type="datetime-local"]#announcement_starts_at', 'change', ({ target }) => { - setAnnouncementEndsAttributes(target); -}); - -const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]'; - -const showSelectAll = () => { - const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); - selectAllMatchingElement.classList.add('active'); -}; - -const hideSelectAll = () => { - const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); - const hiddenField = document.querySelector('#select_all_matching'); - const selectedMsg = document.querySelector('.batch-table__select-all .selected'); - const notSelectedMsg = document.querySelector('.batch-table__select-all .not-selected'); - - selectAllMatchingElement.classList.remove('active'); - selectedMsg.classList.remove('active'); - notSelectedMsg.classList.add('active'); - hiddenField.value = '0'; -}; - -Rails.delegate(document, '#batch_checkbox_all', 'change', ({ target }) => { - const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); - - [].forEach.call(document.querySelectorAll(batchCheckboxClassName), (content) => { - content.checked = target.checked; - }); - - if (selectAllMatchingElement) { - if (target.checked) { - showSelectAll(); - } else { - hideSelectAll(); - } - } -}); - -Rails.delegate(document, '.batch-table__select-all button', 'click', () => { - const hiddenField = document.querySelector('#select_all_matching'); - const active = hiddenField.value === '1'; - const selectedMsg = document.querySelector('.batch-table__select-all .selected'); - const notSelectedMsg = document.querySelector('.batch-table__select-all .not-selected'); - - if (active) { - hiddenField.value = '0'; - selectedMsg.classList.remove('active'); - notSelectedMsg.classList.add('active'); - } else { - hiddenField.value = '1'; - notSelectedMsg.classList.remove('active'); - selectedMsg.classList.add('active'); - } -}); - -Rails.delegate(document, batchCheckboxClassName, 'change', () => { - const checkAllElement = document.querySelector('#batch_checkbox_all'); - const selectAllMatchingElement = document.querySelector('.batch-table__select-all'); - - if (checkAllElement) { - checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); - checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); - - if (selectAllMatchingElement) { - if (checkAllElement.checked) { - showSelectAll(); - } else { - hideSelectAll(); - } - } - } -}); - -Rails.delegate(document, '.media-spoiler-show-button', 'click', () => { - [].forEach.call(document.querySelectorAll('button.media-spoiler'), (element) => { - element.click(); - }); -}); - -Rails.delegate(document, '.media-spoiler-hide-button', 'click', () => { - [].forEach.call(document.querySelectorAll('.spoiler-button.spoiler-button--visible button'), (element) => { - element.click(); - }); -}); - -Rails.delegate(document, '.filter-subset--with-select select', 'change', ({ target }) => { - target.form.submit(); -}); - -const onDomainBlockSeverityChange = (target) => { - const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media'); - const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports'); - - if (rejectMediaDiv) { - rejectMediaDiv.style.display = (target.value === 'suspend') ? 'none' : 'block'; - } - - if (rejectReportsDiv) { - rejectReportsDiv.style.display = (target.value === 'suspend') ? 'none' : 'block'; - } -}; - -Rails.delegate(document, '#domain_block_severity', 'change', ({ target }) => onDomainBlockSeverityChange(target)); - -const onEnableBootstrapTimelineAccountsChange = (target) => { - const bootstrapTimelineAccountsField = document.querySelector('#form_admin_settings_bootstrap_timeline_accounts'); - - if (bootstrapTimelineAccountsField) { - bootstrapTimelineAccountsField.disabled = !target.checked; - if (target.checked) { - bootstrapTimelineAccountsField.parentElement.classList.remove('disabled'); - bootstrapTimelineAccountsField.parentElement.parentElement.classList.remove('disabled'); - } else { - bootstrapTimelineAccountsField.parentElement.classList.add('disabled'); - bootstrapTimelineAccountsField.parentElement.parentElement.classList.add('disabled'); - } - } -}; - -Rails.delegate(document, '#form_admin_settings_enable_bootstrap_timeline_accounts', 'change', ({ target }) => onEnableBootstrapTimelineAccountsChange(target)); - -const onChangeRegistrationMode = (target) => { - const enabled = target.value === 'approved'; - - [].forEach.call(document.querySelectorAll('#form_admin_settings_require_invite_text'), (input) => { - input.disabled = !enabled; - if (enabled) { - let element = input; - do { - element.classList.remove('disabled'); - element = element.parentElement; - } while (element && !element.classList.contains('fields-group')); - } else { - let element = input; - do { - element.classList.add('disabled'); - element = element.parentElement; - } while (element && !element.classList.contains('fields-group')); - } - }); -}; - -const convertUTCDateTimeToLocal = (value) => { - const date = new Date(value + 'Z'); - const twoChars = (x) => (x.toString().padStart(2, '0')); - return `${date.getFullYear()}-${twoChars(date.getMonth()+1)}-${twoChars(date.getDate())}T${twoChars(date.getHours())}:${twoChars(date.getMinutes())}`; -}; - -const convertLocalDatetimeToUTC = (value) => { - const re = /^([0-9]{4,})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2})/; - const match = re.exec(value); - const date = new Date(match[1], match[2] - 1, match[3], match[4], match[5]); - const fullISO8601 = date.toISOString(); - return fullISO8601.slice(0, fullISO8601.indexOf('T') + 6); -}; - -Rails.delegate(document, '#form_admin_settings_registrations_mode', 'change', ({ target }) => onChangeRegistrationMode(target)); - -ready(() => { - const domainBlockSeverityInput = document.getElementById('domain_block_severity'); - if (domainBlockSeverityInput) onDomainBlockSeverityChange(domainBlockSeverityInput); - - const enableBootstrapTimelineAccounts = document.getElementById('form_admin_settings_enable_bootstrap_timeline_accounts'); - if (enableBootstrapTimelineAccounts) onEnableBootstrapTimelineAccountsChange(enableBootstrapTimelineAccounts); - - const registrationMode = document.getElementById('form_admin_settings_registrations_mode'); - if (registrationMode) onChangeRegistrationMode(registrationMode); - - const checkAllElement = document.querySelector('#batch_checkbox_all'); - if (checkAllElement) { - checkAllElement.checked = [].every.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); - checkAllElement.indeterminate = !checkAllElement.checked && [].some.call(document.querySelectorAll(batchCheckboxClassName), (content) => content.checked); - } - - document.querySelector('a#add-instance-button')?.addEventListener('click', (e) => { - const domain = document.querySelector('input[type="text"]#by_domain')?.value; - - if (domain) { - const url = new URL(event.target.href); - url.searchParams.set('_domain', domain); - e.target.href = url; - } - }); - - [].forEach.call(document.querySelectorAll('input[type="datetime-local"]'), element => { - if (element.value) { - element.value = convertUTCDateTimeToLocal(element.value); - } - if (element.placeholder) { - element.placeholder = convertUTCDateTimeToLocal(element.placeholder); - } - }); - - Rails.delegate(document, 'form', 'submit', ({ target }) => { - [].forEach.call(target.querySelectorAll('input[type="datetime-local"]'), element => { - if (element.value && element.validity.valid) { - element.value = convertLocalDatetimeToUTC(element.value); - } - }); - }); - - const announcementStartsAt = document.querySelector('input[type="datetime-local"]#announcement_starts_at'); - if (announcementStartsAt) { - setAnnouncementEndsAttributes(announcementStartsAt); - } - - [].forEach.call(document.querySelectorAll('[data-admin-component]'), element => { - const componentName = element.getAttribute('data-admin-component'); - const componentProps = JSON.parse(element.getAttribute('data-props')); - - import('../mastodon/containers/admin_component').then(({ default: AdminComponent }) => { - return import('../mastodon/components/admin/' + componentName).then(({ default: Component }) => { - const root = createRoot(element); - - root.render ( - - - , - ); - }); - }).catch(error => { - console.error(error); - }); - }); -}); diff --git a/app/javascript/packs/public.jsx b/app/javascript/packs/public.jsx deleted file mode 100644 index 5edc355370..0000000000 --- a/app/javascript/packs/public.jsx +++ /dev/null @@ -1,286 +0,0 @@ -import { createRoot } from 'react-dom/client'; - -import './public-path'; - -import { IntlMessageFormat } from 'intl-messageformat'; -import { defineMessages } from 'react-intl'; - -import Rails from '@rails/ujs'; -import axios from 'axios'; -import { throttle } from 'lodash'; - -import { start } from '../mastodon/common'; -import { timeAgoString } from '../mastodon/components/relative_timestamp'; -import emojify from '../mastodon/features/emoji/emoji'; -import loadKeyboardExtensions from '../mastodon/load_keyboard_extensions'; -import { loadLocale, getLocale } from '../mastodon/locales'; -import { loadPolyfills } from '../mastodon/polyfills'; -import ready from '../mastodon/ready'; - -import 'cocoon-js-vanilla'; - -start(); - -const messages = defineMessages({ - usernameTaken: { id: 'username.taken', defaultMessage: 'That username is taken. Try another' }, - passwordExceedsLength: { id: 'password_confirmation.exceeds_maxlength', defaultMessage: 'Password confirmation exceeds the maximum password length' }, - passwordDoesNotMatch: { id: 'password_confirmation.mismatching', defaultMessage: 'Password confirmation does not match' }, -}); - -window.addEventListener('message', e => { - const data = e.data || {}; - - if (!window.parent || data.type !== 'setHeight') { - return; - } - - ready(() => { - window.parent.postMessage({ - type: 'setHeight', - id: data.id, - height: document.getElementsByTagName('html')[0].scrollHeight, - }, '*'); - }); -}); - -function loaded() { - const { messages: localeData } = getLocale(); - - const locale = document.documentElement.lang; - - const dateTimeFormat = new Intl.DateTimeFormat(locale, { - year: 'numeric', - month: 'long', - day: 'numeric', - hour: 'numeric', - minute: 'numeric', - }); - - const dateFormat = new Intl.DateTimeFormat(locale, { - year: 'numeric', - month: 'short', - day: 'numeric', - timeFormat: false, - }); - - const timeFormat = new Intl.DateTimeFormat(locale, { - timeStyle: 'short', - hour12: false, - }); - - const formatMessage = ({ id, defaultMessage }, values) => { - const messageFormat = new IntlMessageFormat(localeData[id] || defaultMessage, locale); - return messageFormat.format(values); - }; - - [].forEach.call(document.querySelectorAll('.emojify'), (content) => { - content.innerHTML = emojify(content.innerHTML); - }); - - [].forEach.call(document.querySelectorAll('time.formatted'), (content) => { - const datetime = new Date(content.getAttribute('datetime')); - const formattedDate = dateTimeFormat.format(datetime); - - content.title = formattedDate; - content.textContent = formattedDate; - }); - - const isToday = date => { - const today = new Date(); - - return date.getDate() === today.getDate() && - date.getMonth() === today.getMonth() && - date.getFullYear() === today.getFullYear(); - }; - const todayFormat = new IntlMessageFormat(localeData['relative_format.today'] || 'Today at {time}', locale); - - [].forEach.call(document.querySelectorAll('time.relative-formatted'), (content) => { - const datetime = new Date(content.getAttribute('datetime')); - - let formattedContent; - - if (isToday(datetime)) { - const formattedTime = timeFormat.format(datetime); - - formattedContent = todayFormat.format({ time: formattedTime }); - } else { - formattedContent = dateFormat.format(datetime); - } - - content.title = formattedContent; - content.textContent = formattedContent; - }); - - [].forEach.call(document.querySelectorAll('time.time-ago'), (content) => { - const datetime = new Date(content.getAttribute('datetime')); - const now = new Date(); - - const timeGiven = content.getAttribute('datetime').includes('T'); - content.title = timeGiven ? dateTimeFormat.format(datetime) : dateFormat.format(datetime); - content.textContent = timeAgoString({ - formatMessage, - formatDate: (date, options) => (new Intl.DateTimeFormat(locale, options)).format(date), - }, datetime, now, now.getFullYear(), timeGiven); - }); - - const reactComponents = document.querySelectorAll('[data-component]'); - - if (reactComponents.length > 0) { - import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container') - .then(({ default: MediaContainer }) => { - [].forEach.call(reactComponents, (component) => { - [].forEach.call(component.children, (child) => { - component.removeChild(child); - }); - }); - - const content = document.createElement('div'); - - const root = createRoot(content); - root.render(); - document.body.appendChild(content); - }) - .catch(error => { - console.error(error); - }); - } - - Rails.delegate(document, '#user_account_attributes_username', 'input', throttle(({ target }) => { - if (target.value && target.value.length > 0) { - axios.get('/api/v1/accounts/lookup', { params: { acct: target.value } }).then(() => { - target.setCustomValidity(formatMessage(messages.usernameTaken)); - }).catch(() => { - target.setCustomValidity(''); - }); - } else { - target.setCustomValidity(''); - } - }, 500, { leading: false, trailing: true })); - - Rails.delegate(document, '#user_password,#user_password_confirmation', 'input', () => { - const password = document.getElementById('user_password'); - const confirmation = document.getElementById('user_password_confirmation'); - if (!confirmation) return; - - if (confirmation.value && confirmation.value.length > password.maxLength) { - confirmation.setCustomValidity(formatMessage(messages.passwordExceedsLength)); - } else if (password.value && password.value !== confirmation.value) { - confirmation.setCustomValidity(formatMessage(messages.passwordDoesNotMatch)); - } else { - confirmation.setCustomValidity(''); - } - }); - - Rails.delegate(document, '.status__content__spoiler-link', 'click', function() { - const statusEl = this.parentNode.parentNode; - - if (statusEl.dataset.spoiler === 'expanded') { - statusEl.dataset.spoiler = 'folded'; - this.textContent = (new IntlMessageFormat(localeData['status.show_more'] || 'Show more', locale)).format(); - } else { - statusEl.dataset.spoiler = 'expanded'; - this.textContent = (new IntlMessageFormat(localeData['status.show_less'] || 'Show less', locale)).format(); - } - - return false; - }); - - [].forEach.call(document.querySelectorAll('.status__content__spoiler-link'), (spoilerLink) => { - const statusEl = spoilerLink.parentNode.parentNode; - const message = (statusEl.dataset.spoiler === 'expanded') ? (localeData['status.show_less'] || 'Show less') : (localeData['status.show_more'] || 'Show more'); - spoilerLink.textContent = (new IntlMessageFormat(message, locale)).format(); - }); -} - -Rails.delegate(document, '#edit_profile input[type=file]', 'change', ({ target }) => { - const avatar = document.getElementById(target.id + '-preview'); - const [file] = target.files || []; - const url = file ? URL.createObjectURL(file) : avatar.dataset.originalSrc; - - avatar.src = url; -}); - -Rails.delegate(document, '.input-copy input', 'click', ({ target }) => { - target.focus(); - target.select(); - target.setSelectionRange(0, target.value.length); -}); - -Rails.delegate(document, '.input-copy button', 'click', ({ target }) => { - const input = target.parentNode.querySelector('.input-copy__wrapper input'); - - const oldReadOnly = input.readonly; - - input.readonly = false; - input.focus(); - input.select(); - input.setSelectionRange(0, input.value.length); - - try { - if (document.execCommand('copy')) { - input.blur(); - target.parentNode.classList.add('copied'); - - setTimeout(() => { - target.parentNode.classList.remove('copied'); - }, 700); - } - } catch (err) { - console.error(err); - } - - input.readonly = oldReadOnly; -}); - -const toggleSidebar = () => { - const sidebar = document.querySelector('.sidebar ul'); - const toggleButton = document.querySelector('.sidebar__toggle__icon'); - - if (sidebar.classList.contains('visible')) { - document.body.style.overflow = null; - toggleButton.setAttribute('aria-expanded', 'false'); - } else { - document.body.style.overflow = 'hidden'; - toggleButton.setAttribute('aria-expanded', 'true'); - } - - toggleButton.classList.toggle('active'); - sidebar.classList.toggle('visible'); -}; - -Rails.delegate(document, '.sidebar__toggle__icon', 'click', () => { - toggleSidebar(); -}); - -Rails.delegate(document, '.sidebar__toggle__icon', 'keydown', e => { - if (e.key === ' ' || e.key === 'Enter') { - e.preventDefault(); - toggleSidebar(); - } -}); - -Rails.delegate(document, '.custom-emoji', 'mouseover', ({ target }) => target.src = target.getAttribute('data-original')); -Rails.delegate(document, '.custom-emoji', 'mouseout', ({ target }) => target.src = target.getAttribute('data-static')); - -// Empty the honeypot fields in JS in case something like an extension -// automatically filled them. -Rails.delegate(document, '#registration_new_user,#new_user', 'submit', () => { - ['user_website', 'user_confirm_password', 'registration_user_website', 'registration_user_confirm_password'].forEach(id => { - const field = document.getElementById(id); - if (field) { - field.value = ''; - } - }); -}); - -function main() { - ready(loaded); -} - -loadPolyfills() - .then(loadLocale) - .then(main) - .then(loadKeyboardExtensions) - .catch(error => { - console.error(error); - }); diff --git a/app/javascript/packs/sign_up.js b/app/javascript/packs/sign_up.js deleted file mode 100644 index cf9c837773..0000000000 --- a/app/javascript/packs/sign_up.js +++ /dev/null @@ -1,42 +0,0 @@ -import './public-path'; -import axios from 'axios'; - -import ready from '../mastodon/ready'; - -ready(() => { - setInterval(() => { - axios.get('/api/v1/emails/check_confirmation').then((response) => { - if (response.data) { - window.location = '/start'; - } - }).catch(error => { - console.error(error); - }); - }, 5000); - - document.querySelectorAll('.timer-button').forEach(button => { - let counter = 30; - - const container = document.createElement('span'); - - const updateCounter = () => { - container.innerText = ` (${counter})`; - }; - - updateCounter(); - - const countdown = setInterval(() => { - counter--; - - if (counter === 0) { - button.disabled = false; - button.removeChild(container); - clearInterval(countdown); - } else { - updateCounter(); - } - }, 1000); - - button.appendChild(container); - }); -}); diff --git a/app/javascript/packs/two_factor_authentication.js b/app/javascript/packs/two_factor_authentication.js deleted file mode 100644 index e77965c757..0000000000 --- a/app/javascript/packs/two_factor_authentication.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as WebAuthnJSON from '@github/webauthn-json'; -import axios from 'axios'; - -import ready from '../mastodon/ready'; -import 'regenerator-runtime/runtime'; - -function getCSRFToken() { - var CSRFSelector = document.querySelector('meta[name="csrf-token"]'); - if (CSRFSelector) { - return CSRFSelector.getAttribute('content'); - } else { - return null; - } -} - -function hideFlashMessages() { - Array.from(document.getElementsByClassName('flash-message')).forEach(function(flashMessage) { - flashMessage.classList.add('hidden'); - }); -} - -function callback(url, body) { - axios.post(url, JSON.stringify(body), { - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json', - 'X-CSRF-Token': getCSRFToken(), - }, - credentials: 'same-origin', - }).then(function(response) { - window.location.replace(response.data.redirect_path); - }).catch(function(error) { - if (error.response.status === 422) { - const errorMessage = document.getElementById('security-key-error-message'); - errorMessage.classList.remove('hidden'); - console.error(error.response.data.error); - } else { - console.error(error); - } - }); -} - -ready(() => { - if (!WebAuthnJSON.supported()) { - const unsupported_browser_message = document.getElementById('unsupported-browser-message'); - if (unsupported_browser_message) { - unsupported_browser_message.classList.remove('hidden'); - document.querySelector('.btn.js-webauthn').disabled = true; - } - } - - - const webAuthnCredentialRegistrationForm = document.getElementById('new_webauthn_credential'); - if (webAuthnCredentialRegistrationForm) { - webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => { - event.preventDefault(); - - var nickname = event.target.querySelector('input[name="new_webauthn_credential[nickname]"]'); - if (nickname.value) { - axios.get('/settings/security_keys/options') - .then((response) => { - const credentialOptions = response.data; - - WebAuthnJSON.create({ 'publicKey': credentialOptions }).then((credential) => { - var params = { 'credential': credential, 'nickname': nickname.value }; - callback('/settings/security_keys', params); - }).catch((error) => { - const errorMessage = document.getElementById('security-key-error-message'); - errorMessage.classList.remove('hidden'); - console.error(error); - }); - }).catch((error) => { - console.error(error.response.data.error); - }); - } else { - nickname.focus(); - } - }); - } - - const webAuthnCredentialAuthenticationForm = document.getElementById('webauthn-form'); - if (webAuthnCredentialAuthenticationForm) { - webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => { - event.preventDefault(); - - axios.get('sessions/security_key_options') - .then((response) => { - const credentialOptions = response.data; - - WebAuthnJSON.get({ 'publicKey': credentialOptions }).then((credential) => { - var params = { 'user': { 'credential': credential } }; - callback('sign_in', params); - }).catch((error) => { - const errorMessage = document.getElementById('security-key-error-message'); - errorMessage.classList.remove('hidden'); - console.error(error); - }); - }).catch((error) => { - console.error(error.response.data.error); - }); - }); - - const otpAuthenticationForm = document.getElementById('otp-authentication-form'); - - const linkToOtp = document.getElementById('link-to-otp'); - linkToOtp.addEventListener('click', () => { - webAuthnCredentialAuthenticationForm.classList.add('hidden'); - otpAuthenticationForm.classList.remove('hidden'); - hideFlashMessages(); - }); - - const linkToWebAuthn = document.getElementById('link-to-webauthn'); - linkToWebAuthn.addEventListener('click', () => { - otpAuthenticationForm.classList.add('hidden'); - webAuthnCredentialAuthenticationForm.classList.remove('hidden'); - hideFlashMessages(); - }); - } -}); diff --git a/app/javascript/styles/mailer.scss b/app/javascript/styles/mailer.scss index a2cbb494b4..e5d0c05f81 100644 --- a/app/javascript/styles/mailer.scss +++ b/app/javascript/styles/mailer.scss @@ -192,6 +192,18 @@ table + p { } } +.email-dir-rtl { + direction: rtl; + + [dir='rtl'] & { + direction: ltr; + } +} + +.email-dir-ltr { + direction: ltr; +} + .email-padding-24 { padding: 24px; } @@ -216,6 +228,30 @@ table + p { border-bottom: 1px solid #dfdee3; } +.email-desktop-flex { + font-size: 0; + max-width: 740px; + margin-left: auto; + margin-right: auto; + + &.email-dir-rtl > .email-desktop-column { + direction: ltr; + + [dir='rtl'] & { + direction: rtl; + } + } +} + +.email-desktop-column { + display: inline-block; + width: 100%; + max-width: none; + text-align: start; + vertical-align: top; + font-size: 16px; +} + // Header .email-header-td { padding: 16px 32px; @@ -312,6 +348,66 @@ table + p { } } +.email-header-card-table { + width: 100%; + border-collapse: separate; + overflow: hidden; + border-radius: 12px; + background-color: #fff; + border: 2px solid #fff; + box-shadow: 0 4px 16px 0 rgba(23, 6, 59, 8%); +} + +.email-header-card { + position: relative; + max-height: 100px; +} + +.email-header-card-banner-td { + border-radius: 12px 12px 0 0; + height: 80px; + background-color: #f3f2f5 !important; + background-position: center !important; + background-size: cover !important; +} + +.email-header-card-body-td { + padding: 12px; + + .email-btn-table { + width: 100%; + max-width: 212px; + } +} + +.email-header-card-instance { + margin-bottom: 4px; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + color: #17063b; + font-size: 14px; + line-height: 20px; + font-weight: 600; + + &:only-of-type { + margin-bottom: 12px; + } +} + +.email-header-card-description { + margin-bottom: 12px; + color: #746a89; + font-size: 12px; + line-height: 16px; + max-height: 32px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; +} + // To make the design work with images off // we create an empty div that overlaps with // the rest of the content with a dark background. @@ -336,6 +432,16 @@ table + p { mso-padding-alt: 32px; } +.email-body-columns-td { + border-top: 1px solid #dfdee3; + padding: 32px 24px 8px; +} + +.email-body-huge-padding-td { + padding: 110px 32px 32px; + mso-padding-alt: 32px; +} + .email-body-padding-td { & > p { font-size: 14px; @@ -353,6 +459,30 @@ table + p { } } +// Texts +.email-h2 { + margin-bottom: 4px; + color: #17063b; + font-size: 18px; + font-weight: 600; + line-height: 28px; +} + +.email-h-sub { + margin-bottom: 16px; + color: #746a89; + font-size: 14px; + line-height: 16px; +} + +.email-p { + margin-bottom: 16px; + color: #746a89; + font-size: 14px; + font-weight: 400; + line-height: 20px; +} + // Footer .email-footer-td { padding: 28px 32px 32px; @@ -539,8 +669,13 @@ table + p { background-color: #fff; } +.email-checklist-checked { + border-color: #c4e6d7; + background-color: #eaf6f1; +} + .email-checklist-td { - padding: 16px; + padding: 16px 16px 6px; } .email-checklist-icons-td { @@ -576,10 +711,15 @@ table + p { font-size: 14px; font-weight: 600; line-height: 16.8px; + + .email-checklist-checked & { + color: #746a89; + text-decoration: line-through; + } } p { - margin: 0 0 2px; + margin: 0 0 12px; color: #746a89; font-size: 14px; line-height: 16.8px; @@ -597,6 +737,194 @@ table + p { padding-left: 10px; padding-right: 10px; } + + div + div { + margin-inline-start: auto; + margin-bottom: 12px; + } +} + +// Welcome email +.email-welcome-apps-btns { + font-size: 12px; + line-height: 44px; +} + +.email-column-td { + padding: 0 8px; + vertical-align: top; +} + +.email-link-with-arrow { + color: #6364ff; + font-size: 14px; + font-weight: 600; + line-height: 16.8px; + + &:hover { + color: #563acc !important; + } + + span { + font-size: 12px; + font-weight: 400; + } +} + +.email-column-action-td { + padding: 24px 0; + color: #6364ff; + font-size: 14px; + font-weight: 600; + line-height: 16.8px; + text-align: center; +} + +// Follow and hashtags +.email-mini-wrapper-td { + padding: 4px 0; + + table { + table-layout: fixed; + } +} + +.email-mini-td { + border-radius: 12px; + border: 1px solid #e8e6eb; + background-color: #fff; + padding: 15px 16px; +} + +.email-mini-follow-img-td { + width: 40px; + vertical-align: top; + + img { + border-radius: 8px; + } +} + +.email-mini-follow-text-td { + padding-left: 8px; + padding-right: 16px; + vertical-align: top; + + h3 { + color: #17063b; + font-size: 14px; + font-weight: 600; + line-height: 20px; + } + + p { + color: #746a89; + font-size: 12px; + font-weight: 400; + line-height: 16px; + } +} + +.email-mini-follow-btn-td { + width: 68px; + vertical-align: top; + + .email-btn-table { + width: 100%; + } + + .email-btn-td { + mso-padding-alt: 10px; + } + + .email-btn-a { + padding-left: 10px; + padding-right: 10px; + } +} + +.email-mini-hashtag-td { + height: 40px; + + td { + vertical-align: middle; + } + + h3 { + color: #17063b; + font-size: 14px; + font-weight: 600; + line-height: 20px; + } + + p { + color: #746a89; + font-size: 12px; + font-weight: 400; + line-height: 16px; + word-break: break-all; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +} + +.email-mini-hashtag-img-td { + width: 40px; + height: 20px; + white-space: nowrap; + text-indent: -2px; + font-size: 0; + + & + td { + padding-left: 8px; + } +} + +.email-mini-hashtag-img-span { + display: inline-block; + max-width: 12px; + font-size: 12px; + + img { + width: 16px; + height: 16px; + border-radius: 50%; + max-width: none; + border: 2px solid #fff; + vertical-align: middle; + } +} + +// Extra content on light purple background +.email-extra-wave { + height: 42px; + background-image: url('../images/mailer-new/welcome/purple-extra-soft-wave.png'); + background-position: bottom center; + background-repeat: no-repeat; +} + +.email-extra-td { + padding: 32px 32px 24px; + background-color: #f0f0ff; + background-image: url('../images/mailer-new/welcome/purple-extra-soft-spacer.png'); // Using an image to maintain the color even in forced dark modes + + .email-column-td { + padding-top: 8px; + padding-bottom: 8px; + } +} + +// Feature card +.email-feature-wrapper-td { + padding: 8px 0; +} + +.email-feature-td { + padding: 24px; + background-color: #fff; + border: 1px solid #e8e6eb; + border-radius: 12px; } // Responsive @@ -617,4 +945,21 @@ table + p { .email-desktop-flex { display: flex; } + + .email-header-left { + padding-right: 32px; + } + + .email-header-right { + width: 240px; + margin-inline-start: auto; + } + + .email-desktop-column { + max-width: 346px !important; + } + + .email-desktop-text-right { + text-align: right; + } } diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index 520e91e28b..07e9d9868b 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -21,25 +21,6 @@ html { } // Change default background colors of columns -.column > .scrollable, -.getting-started, -.column-inline-form, -.regeneration-indicator { - background: $white; - border: 1px solid lighten($ui-base-color, 8%); - border-top: 0; -} - -.error-column { - border: 1px solid lighten($ui-base-color, 8%); -} - -.column > .scrollable.about { - border-top: 1px solid lighten($ui-base-color, 8%); -} - -.about__meta, -.about__section__title, .interaction-modal { background: $white; border: 1px solid lighten($ui-base-color, 8%); @@ -53,37 +34,10 @@ html { background: lighten($ui-base-color, 12%); } -.filter-form { - background: $white; - border-bottom: 1px solid lighten($ui-base-color, 8%); -} - -.column-back-button, -.column-header { - background: $white; - border: 1px solid lighten($ui-base-color, 8%); - - @media screen and (max-width: $no-gap-breakpoint) { - border-top: 0; - } - - &--slim-button { - top: -50px; - right: 0; - } -} - -.column-header__back-button, -.column-header__button, -.column-header__button.active, .account__header { background: $white; } -.column-header { - border-bottom: 0; -} - .column-header__button.active { color: $ui-highlight-color; @@ -91,7 +45,6 @@ html { &:active, &:focus { color: $ui-highlight-color; - background: $white; } } @@ -117,25 +70,6 @@ html { } } -.column-subheading { - background: darken($ui-base-color, 4%); - border-bottom: 1px solid lighten($ui-base-color, 8%); -} - -.getting-started, -.scrollable { - .column-link { - background: $white; - border-bottom: 1px solid lighten($ui-base-color, 8%); - - &:hover, - &:active, - &:focus { - background: $ui-base-color; - } - } -} - .getting-started .navigation-bar { border-top: 1px solid lighten($ui-base-color, 8%); border-bottom: 1px solid lighten($ui-base-color, 8%); @@ -146,6 +80,7 @@ html { } .search__input, +.search__popout, .setting-text, .report-dialog-modal__textarea, .audio-player { @@ -168,23 +103,6 @@ html { border-bottom: 0; } -.notification__filter-bar { - border: 1px solid lighten($ui-base-color, 8%); - border-top: 0; -} - -.drawer__header, -.drawer__inner { - background: $white; - border: 1px solid lighten($ui-base-color, 8%); -} - -.drawer__inner__mastodon { - background: $white - url('data:image/svg+xml;utf8,') - no-repeat bottom / 100% auto; -} - .upload-progress__backdrop { background: $ui-base-color; } @@ -194,11 +112,6 @@ html { background: lighten($white, 4%); } -.detailed-status, -.detailed-status__action-bar { - background: $white; -} - // Change the background colors of status__content__spoiler-link .reply-indicator__content .status__content__spoiler-link, .status__content .status__content__spoiler-link { @@ -210,12 +123,6 @@ html { } } -// Change the background colors of media and video spoilers -.media-spoiler, -.video-player__spoiler { - background: $ui-base-color; -} - .account-gallery__item a { background-color: $ui-base-color; } @@ -357,11 +264,11 @@ html { } .react-toggle-track { - background: $ui-secondary-color; + background: $ui-primary-color; } .react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { - background: darken($ui-secondary-color, 10%); + background: lighten($ui-primary-color, 10%); } .react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) @@ -533,7 +440,8 @@ html { .directory__tag > div, .card > a, .page-header, -.compose-form .compose-form__warning { +.compose-form, +.compose-form__warning { box-shadow: none; } @@ -575,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-light/variables.scss b/app/javascript/styles/mastodon-light/variables.scss index 3cf5561ca3..09a75a834b 100644 --- a/app/javascript/styles/mastodon-light/variables.scss +++ b/app/javascript/styles/mastodon-light/variables.scss @@ -59,4 +59,8 @@ $emojis-requiring-inversion: 'chains'; .theme-mastodon-light { --dropdown-border-color: #d9e1e8; --dropdown-background-color: #fff; + --background-border-color: #d9e1e8; + --background-color: #fff; + --background-color-tint: rgba(255, 255, 255, 90%); + --background-filter: blur(10px); } diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss index 0f02563b48..48fe9449f0 100644 --- a/app/javascript/styles/mastodon/about.scss +++ b/app/javascript/styles/mastodon/about.scss @@ -26,7 +26,7 @@ $fluid-breakpoint: $maximum-width + 20px; li { position: relative; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); padding: 1em 1.75em; padding-inline-start: 3em; font-weight: 500; @@ -53,4 +53,10 @@ $fluid-breakpoint: $maximum-width + 20px; border-bottom: 0; } } + + &__hint { + font-size: 14px; + font-weight: 400; + color: $darker-text-color; + } } diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 3f538d08d6..06a3b52021 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; @@ -324,6 +331,23 @@ $content-width: 840px; padding-bottom: 0; margin-bottom: 0; border-bottom: 0; + + .comment { + display: block; + overflow: hidden; + text-overflow: ellipsis; + margin-top: 4px; + + &.private-comment { + display: block; + color: $darker-text-color; + } + + &.public-comment { + display: block; + color: $secondary-text-color; + } + } } & > p { @@ -622,16 +646,6 @@ body, input.button { margin: 0 5px 5px 0; } - - .media-spoiler-toggle-buttons { - margin-inline-start: auto; - - .button { - overflow: visible; - margin: 0 0 5px 5px; - float: right; - } - } } .back-link { @@ -1054,6 +1068,7 @@ a.name-tag, display: flex; justify-content: space-between; margin-bottom: 0; + word-break: break-word; } &__permissions { @@ -1370,8 +1385,21 @@ a.sparkline { } .account-card { - background: $ui-base-color; border-radius: 4px; + border: 1px solid lighten($ui-base-color, 8%); + position: relative; + + &__warning-badge { + position: absolute; + padding: 4px 10px; + top: 10px; + inset-inline-start: 10px; + border-radius: 4px; + background: + url('../images/warning-stripes.svg') repeat-y left, + url('../images/warning-stripes.svg') repeat-y right, + var(--background-color); + } &__permalink { color: inherit; diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss index 28dad81da5..2e7d5e5e9c 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -8,7 +8,7 @@ body { font-family: $font-sans-serif, sans-serif; - background: darken($ui-base-color, 8%); + background: var(--background-color); font-size: 13px; line-height: 18px; font-weight: 400; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index af9fc88e7b..73d0e6220f 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -106,17 +106,17 @@ } &.button-secondary { - color: $ui-button-secondary-color; + color: $highlight-text-color; background: transparent; padding: 6px 17px; - border: 1px solid $ui-button-secondary-border-color; + border: 1px solid $highlight-text-color; &:active, &:focus, &:hover { - border-color: $ui-button-secondary-focus-background-color; - color: $ui-button-secondary-focus-color; - background-color: $ui-button-secondary-focus-background-color; + border-color: lighten($highlight-text-color, 4%); + color: lighten($highlight-text-color, 4%); + background-color: transparent; text-decoration: none; } @@ -669,12 +669,12 @@ body > [data-popper-placement] { } .icon-button.compose-form__upload__delete { - padding: 3px; + padding: 2px; border-radius: 50%; .icon { - width: 18px; - height: 18px; + width: 20px; + height: 20px; } } @@ -720,12 +720,12 @@ body > [data-popper-placement] { } .icon-button { - padding: 3px; + padding: 2px; } .icon-button .icon { - width: 18px; - height: 18px; + width: 20px; + height: 20px; } } @@ -903,9 +903,15 @@ body > [data-popper-placement] { padding: 10px; p { + font-size: 15px; + line-height: 22px; color: $darker-text-color; margin-bottom: 20px; + strong { + font-weight: 700; + } + a { color: $secondary-text-color; text-decoration: none; @@ -1311,7 +1317,7 @@ body > [data-popper-placement] { box-sizing: border-box; width: 100%; clear: both; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); &__button { display: inline; @@ -1332,19 +1338,14 @@ body > [data-popper-placement] { .focusable { &:focus { outline: 0; - background: lighten($ui-base-color, 4%); - - .detailed-status, - .detailed-status__action-bar { - background: lighten($ui-base-color, 8%); - } + background: rgba($ui-highlight-color, 0.05); } } .status { padding: 16px; min-height: 54px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); cursor: auto; @keyframes fade { @@ -1416,10 +1417,15 @@ body > [data-popper-placement] { .audio-player, .attachment-list, .picture-in-picture-placeholder, + .more-from-author, .status-card, .hashtag-bar { margin-inline-start: $thread-margin; - width: calc(100% - ($thread-margin)); + width: calc(100% - $thread-margin); + } + + .more-from-author { + width: calc(100% - $thread-margin + 2px); } .status__content__read-more-button { @@ -1588,10 +1594,10 @@ body > [data-popper-placement] { } .status__wrapper-direct { - background: mix($ui-base-color, $ui-highlight-color, 95%); + background: rgba($ui-highlight-color, 0.05); &:focus { - background: mix(lighten($ui-base-color, 4%), $ui-highlight-color, 95%); + background: rgba($ui-highlight-color, 0.05); } .status__prepend { @@ -1616,9 +1622,8 @@ body > [data-popper-placement] { } .detailed-status { - background: lighten($ui-base-color, 4%); padding: 16px; - border-top: 1px solid lighten($ui-base-color, 8%); + border-top: 1px solid var(--background-border-color); &--flex { display: flex; @@ -1665,22 +1670,42 @@ body > [data-popper-placement] { } .detailed-status__meta { - margin-top: 16px; + margin-top: 24px; color: $dark-text-color; font-size: 14px; line-height: 18px; + &__line { + border-bottom: 1px solid var(--background-border-color); + padding: 8px 0; + display: flex; + align-items: center; + gap: 8px; + + &:first-child { + padding-top: 0; + } + + &:last-child { + padding-bottom: 0; + border-bottom: 0; + } + } + .icon { - width: 15px; - height: 15px; - vertical-align: middle; + width: 18px; + height: 18px; + } + + .animated-number { + color: $secondary-text-color; + font-weight: 500; } } .detailed-status__action-bar { - background: lighten($ui-base-color, 4%); - border-top: 1px solid lighten($ui-base-color, 8%); - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-top: 1px solid var(--background-border-color); + border-bottom: 1px solid var(--background-border-color); display: flex; flex-direction: row; padding: 10px 0; @@ -1718,24 +1743,11 @@ body > [data-popper-placement] { color: inherit; text-decoration: none; gap: 6px; - position: relative; - top: 0.145em; - - .icon { - top: 0; - } -} - -.detailed-status__favorites, -.detailed-status__reblogs { - font-weight: 500; - font-size: 12px; - line-height: 18px; } .domain { padding: 10px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); .domain__domain-name { flex: 1 1 auto; @@ -1759,7 +1771,7 @@ body > [data-popper-placement] { .account { padding: 16px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); .account__display-name { flex: 1 1 auto; @@ -1792,6 +1804,118 @@ body > [data-popper-placement] { } } + &__domain-pill { + display: inline-flex; + background: rgba($highlight-text-color, 0.2); + border-radius: 4px; + border: 0; + color: $highlight-text-color; + font-weight: 500; + font-size: 12px; + line-height: 16px; + padding: 4px 8px; + + &.active { + color: $white; + background: $ui-highlight-color; + } + + &__popout { + background: var(--dropdown-background-color); + backdrop-filter: var(--background-filter); + border: 1px solid var(--dropdown-border-color); + box-shadow: var(--dropdown-shadow); + max-width: 320px; + padding: 16px; + border-radius: 8px; + display: flex; + flex-direction: column; + gap: 24px; + font-size: 14px; + line-height: 20px; + color: $darker-text-color; + + .link-button { + display: inline; + font-size: inherit; + line-height: inherit; + } + + &__header { + display: flex; + align-items: center; + gap: 12px; + + &__icon { + width: 40px; + height: 40px; + background: $ui-highlight-color; + color: $white; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + flex-shrink: 0; + } + + h3 { + font-size: 17px; + line-height: 22px; + color: $primary-text-color; + } + } + + &__handle { + border: 2px dashed $highlight-text-color; + background: rgba($highlight-text-color, 0.1); + padding: 12px 8px; + color: $highlight-text-color; + border-radius: 4px; + + &__label { + font-size: 11px; + line-height: 16px; + font-weight: 500; + } + + &__handle { + user-select: all; + } + } + + &__parts { + display: flex; + flex-direction: column; + gap: 8px; + font-size: 12px; + line-height: 16px; + + & > div { + display: flex; + align-items: flex-start; + gap: 12px; + } + + &__icon { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + color: $highlight-text-color; + } + + h6 { + font-size: 14px; + line-height: 20px; + font-weight: 500; + color: $primary-text-color; + } + } + } + } + &__note { font-size: 14px; font-weight: 400; @@ -1902,7 +2026,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 { @@ -2017,7 +2156,7 @@ a.account__display-name { .notification__report { padding: 16px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); display: flex; gap: 10px; @@ -2052,6 +2191,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; @@ -2093,14 +2271,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%; } } } @@ -2276,6 +2454,7 @@ a.account__display-name { .dropdown-menu { background: var(--dropdown-background-color); + backdrop-filter: var(--background-filter); border: 1px solid var(--dropdown-border-color); padding: 4px; border-radius: 4px; @@ -2298,6 +2477,10 @@ a.account__display-name { outline: 1px dotted; } + &:hover { + text-decoration: underline; + } + .icon { width: 15px; height: 15px; @@ -2456,6 +2639,7 @@ a.account__display-name { } $ui-header-height: 55px; +$ui-header-logo-wordmark-width: 99px; .ui__header { display: none; @@ -2466,10 +2650,15 @@ $ui-header-height: 55px; z-index: 3; justify-content: space-between; align-items: center; + backdrop-filter: var(--background-filter); &__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; @@ -2480,7 +2669,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; } @@ -2497,6 +2686,7 @@ $ui-header-height: 55px; gap: 10px; padding: 0 10px; overflow: hidden; + flex-shrink: 0; .button { flex: 0 0 auto; @@ -2514,7 +2704,8 @@ $ui-header-height: 55px; } .tabs-bar__wrapper { - background: darken($ui-base-color, 8%); + background: var(--background-color); + backdrop-filter: var(--background-filter); position: sticky; top: $ui-header-height; z-index: 2; @@ -2550,8 +2741,15 @@ $ui-header-height: 55px; flex-direction: column; > .scrollable { - background: $ui-base-color; + border: 1px solid var(--background-border-color); + border-top: 0; border-radius: 0 0 4px 4px; + + &.about, + &.privacy-policy { + border-top: 1px solid var(--background-border-color); + border-radius: 4px; + } } } @@ -2581,7 +2779,6 @@ $ui-header-height: 55px; font-size: 16px; align-items: center; justify-content: center; - border-bottom: 2px solid transparent; } .column, @@ -2710,8 +2907,7 @@ $ui-header-height: 55px; .navigation-panel { margin: 0; - background: $ui-base-color; - border-inline-start: 1px solid lighten($ui-base-color, 8%); + border-inline-start: 1px solid var(--background-border-color); height: 100vh; } @@ -2727,17 +2923,31 @@ $ui-header-height: 55px; } } - .layout-single-column .ui__header { - display: flex; - background: $ui-base-color; - border-bottom: 1px solid lighten($ui-base-color, 8%); - } + .layout-single-column { + .ui__header { + display: flex; + background: var(--background-color); + border-bottom: 1px solid var(--background-border-color); + } - .column-header, - .column-back-button, - .scrollable, - .error-column { - border-radius: 0 !important; + .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 { + border-top: 0; + } } } @@ -2769,6 +2979,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; @@ -2788,7 +3067,7 @@ $ui-header-height: 55px; inset-inline-start: 9px; top: -13px; background: $ui-highlight-color; - border: 2px solid lighten($ui-base-color, 8%); + border: 2px solid var(--background-color); padding: 1px 6px; border-radius: 6px; font-size: 10px; @@ -2810,7 +3089,7 @@ $ui-header-height: 55px; } .column-link--transparent .icon-with-badge__badge { - border-color: darken($ui-base-color, 8%); + border-color: var(--background-color); } .column-title { @@ -3160,7 +3439,7 @@ $ui-header-height: 55px; flex: 0 0 auto; border: 0; background: transparent; - border-top: 1px solid lighten($ui-base-color, 4%); + border-top: 1px solid var(--background-border-color); margin: 10px 0; } @@ -3177,13 +3456,14 @@ $ui-header-height: 55px; overflow: hidden; display: flex; border-radius: 4px; + border: 1px solid var(--background-border-color); } .drawer__inner { position: absolute; top: 0; inset-inline-start: 0; - background: darken($ui-base-color, 4%); + background: var(--background-color); box-sizing: border-box; padding: 0; display: flex; @@ -3192,15 +3472,11 @@ $ui-header-height: 55px; overflow-y: auto; width: 100%; height: 100%; - - &.darker { - background: $ui-base-color; - } } .drawer__inner__mastodon { - background: darken($ui-base-color, 4%) - url('data:image/svg+xml;utf8,') + background: var(--background-color) + url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; flex: 1; min-height: 47px; @@ -3224,7 +3500,7 @@ $ui-header-height: 55px; .drawer__header { flex: 0 0 auto; font-size: 16px; - background: darken($ui-base-color, 4%); + border: 1px solid var(--background-border-color); margin-bottom: 10px; display: flex; flex-direction: row; @@ -3234,7 +3510,7 @@ $ui-header-height: 55px; a:hover, a:focus, a:active { - background: $ui-base-color; + color: $primary-text-color; } } @@ -3279,22 +3555,22 @@ $ui-header-height: 55px; .column-back-button { box-sizing: border-box; width: 100%; - background: $ui-base-color; + background: transparent; + border: 1px solid var(--background-border-color); border-radius: 4px 4px 0 0; color: $highlight-text-color; cursor: pointer; flex: 0 0 auto; font-size: 16px; line-height: inherit; - border: 0; - border-bottom: 1px solid lighten($ui-base-color, 8%); text-align: unset; - padding: 15px; + padding: 13px; margin: 0; z-index: 3; outline: 0; display: flex; align-items: center; + gap: 5px; &:hover { text-decoration: underline; @@ -3304,30 +3580,27 @@ $ui-header-height: 55px; .column-header__back-button { display: flex; align-items: center; - background: $ui-base-color; + gap: 5px; + background: transparent; border: 0; font-family: inherit; color: $highlight-text-color; cursor: pointer; white-space: nowrap; font-size: 16px; - padding: 0 5px 0 0; + padding: 13px; z-index: 3; &:hover { text-decoration: underline; } - &:last-child { - padding: 0 15px 0 0; + &.compact { + padding-inline-end: 5px; + flex: 0 0 auto; } } -.column-back-button__icon { - display: inline-block; - margin-inline-end: 5px; -} - .react-toggle { display: inline-block; position: relative; @@ -3363,7 +3636,7 @@ $ui-header-height: 55px; height: 20px; padding: 0; border-radius: 10px; - background-color: #626982; + background-color: $ui-primary-color; } .react-toggle--focus { @@ -3386,7 +3659,7 @@ $ui-header-height: 55px; width: 16px; height: 16px; border-radius: 50%; - background-color: $primary-text-color; + background-color: $ui-button-color; box-sizing: border-box; transition: all 0.25s ease; transition-property: border-color, left; @@ -3397,6 +3670,15 @@ $ui-header-height: 55px; border-color: $ui-highlight-color; } +.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track { + background: darken($ui-primary-color, 5%); +} + +.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) + .react-toggle-track { + background: lighten($ui-highlight-color, 5%); +} + .switch-to-advanced { color: $light-text-color; background-color: $ui-base-color; @@ -3414,8 +3696,6 @@ $ui-header-height: 55px; } .column-link { - background: lighten($ui-base-color, 8%); - color: $primary-text-color; display: flex; align-items: center; gap: 5px; @@ -3425,12 +3705,18 @@ $ui-header-height: 55px; overflow: hidden; white-space: nowrap; border: 0; + background: transparent; + color: $secondary-text-color; border-left: 4px solid transparent; &:hover, &:focus, &:active { - background: lighten($ui-base-color, 11%); + color: $primary-text-color; + } + + &.active { + color: $highlight-text-color; } &:focus { @@ -3442,22 +3728,6 @@ $ui-header-height: 55px; border-radius: 0; } - &--transparent { - background: transparent; - color: $secondary-text-color; - - &:hover, - &:focus, - &:active { - background: transparent; - color: $primary-text-color; - } - - &.active { - color: $highlight-text-color; - } - } - &--logo { background: transparent; padding: 10px; @@ -3482,8 +3752,8 @@ $ui-header-height: 55px; } .column-subheading { - background: $ui-base-color; - color: $dark-text-color; + background: var(--surface-background-color); + color: $darker-text-color; padding: 8px 20px; font-size: 12px; font-weight: 500; @@ -3491,12 +3761,6 @@ $ui-header-height: 55px; cursor: default; } -.getting-started__wrapper, -.getting-started, -.flex-spacer { - background: $ui-base-color; -} - .getting-started__wrapper { flex: 0 0 auto; } @@ -3508,6 +3772,8 @@ $ui-header-height: 55px; .getting-started { color: $dark-text-color; overflow: auto; + border: 1px solid var(--background-border-color); + border-top: 0; &__trends { flex: 0 1 auto; @@ -3516,7 +3782,7 @@ $ui-header-height: 55px; margin-top: 10px; h4 { - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); padding: 10px; font-size: 12px; text-transform: uppercase; @@ -3638,9 +3904,13 @@ $ui-header-height: 55px; margin-top: 14px; text-decoration: none; overflow: hidden; - border: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); border-radius: 8px; + &.bottomless { + border-radius: 8px 8px 0 0; + } + &__actions { bottom: 0; inset-inline-start: 0; @@ -3870,6 +4140,13 @@ a.status-card { border-end-start-radius: 0; } +.status-card.bottomless .status-card__image, +.status-card.bottomless .status-card__image-image, +.status-card.bottomless .status-card__image-preview { + border-end-end-radius: 0; + border-end-start-radius: 0; +} + .status-card.expanded > a { width: 100%; } @@ -3895,7 +4172,7 @@ a.status-card { } .load-gap { - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); } .timeline-hint { @@ -3928,7 +4205,8 @@ a.status-card { font-size: 16px; font-weight: 500; color: $dark-text-color; - background: $ui-base-color; + border: 1px solid var(--background-border-color); + border-top: 0; cursor: default; display: flex; flex: 1 1 auto; @@ -4004,8 +4282,7 @@ a.status-card { .column-header { display: flex; font-size: 16px; - background: $ui-base-color; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); border-radius: 4px 4px 0 0; flex: 0 0 auto; cursor: pointer; @@ -4013,7 +4290,7 @@ a.status-card { z-index: 2; outline: 0; - & > button { + &__title { display: flex; align-items: center; gap: 5px; @@ -4035,8 +4312,18 @@ a.status-card { } } - & > .column-header__back-button { + .column-header__back-button + &__title { + padding-inline-start: 0; + } + + .column-header__back-button { + flex: 1; color: $highlight-text-color; + + &.compact { + flex: 0 0 auto; + color: $primary-text-color; + } } &.active { @@ -4050,6 +4337,18 @@ a.status-card { &:active { outline: 0; } + + &__advanced-buttons { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px; + padding-top: 0; + + &:first-child { + padding-top: 16px; + } + } } .column-header__buttons { @@ -4069,9 +4368,9 @@ a.status-card { display: flex; justify-content: center; align-items: center; - background: $ui-base-color; border: 0; color: $darker-text-color; + background: transparent; cursor: pointer; font-size: 16px; padding: 0 15px; @@ -4090,11 +4389,14 @@ a.status-card { &.active { color: $primary-text-color; - background: lighten($ui-base-color, 4%); &:hover { color: $primary-text-color; } + + .icon-sliders { + transform: rotate(60deg); + } } &:disabled { @@ -4103,11 +4405,14 @@ a.status-card { } } +.no-reduce-motion .column-header__button .icon-sliders { + transition: transform 150ms ease-in-out; +} + .column-header__collapsible { max-height: 70vh; overflow: hidden; overflow-y: auto; - border-bottom: 1px solid lighten($ui-base-color, 8%); color: $darker-text-color; transition: max-height 150ms ease-in-out, @@ -4129,14 +4434,14 @@ a.status-card { height: 0; background: transparent; border: 0; - border-top: 1px solid lighten($ui-base-color, 8%); + border-top: 1px solid var(--background-border-color); margin: 10px 0; } } .column-header__collapsible-inner { - background: $ui-base-color; - padding: 15px; + border: 1px solid var(--background-border-color); + border-top: 0; } .column-header__setting-btn { @@ -4158,20 +4463,8 @@ a.status-card { } .column-header__setting-arrows { - float: right; - - .column-header__setting-btn { - padding: 5px; - - &:first-child { - padding-inline-end: 7px; - } - - &:last-child { - padding-inline-start: 7px; - margin-inline-start: 5px; - } - } + display: flex; + align-items: center; } .text-btn { @@ -4325,35 +4618,6 @@ a.status-card { z-index: 100; } -.media-spoiler { - background: $base-overlay-background; - color: $darker-text-color; - border: 0; - padding: 0; - width: 100%; - height: 100%; - border-radius: 4px; - appearance: none; - - &:hover, - &:active, - &:focus { - padding: 0; - color: lighten($darker-text-color, 8%); - } -} - -.media-spoiler__warning { - display: block; - font-size: 14px; -} - -.media-spoiler__trigger { - display: block; - font-size: 11px; - font-weight: 700; -} - .spoiler-button { top: 0; inset-inline-start: 0; @@ -4423,9 +4687,8 @@ a.status-card { } .account--panel { - background: lighten($ui-base-color, 4%); - border-top: 1px solid lighten($ui-base-color, 8%); - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-top: 1px solid var(--background-border-color); + border-bottom: 1px solid var(--background-border-color); display: flex; flex-direction: row; padding: 10px 0; @@ -4437,24 +4700,56 @@ a.status-card { text-align: center; } -.column-settings__outer { - background: lighten($ui-base-color, 8%); - padding: 15px; -} +.column-settings { + display: flex; + flex-direction: column; -.column-settings__section { - color: $darker-text-color; - cursor: default; - display: block; - font-weight: 500; - margin-bottom: 10px; -} + &__section { + // FIXME: Legacy + color: $darker-text-color; + cursor: default; + display: block; + font-weight: 500; + } -.column-settings__row--with-margin { - margin-bottom: 15px; + .column-header__links { + margin: 0; + } + + section { + padding: 16px; + border-bottom: 1px solid lighten($ui-base-color, 8%); + + &:last-child { + border-bottom: 0; + } + } + + h3 { + font-size: 16px; + line-height: 24px; + letter-spacing: 0.5px; + font-weight: 500; + color: $primary-text-color; + margin-bottom: 16px; + } + + &__row { + display: flex; + flex-direction: column; + gap: 12px; + } + + .app-form__toggle { + &__toggle > div { + border: 0; + } + } } .column-settings__hashtags { + margin-top: 15px; + .column-settings__row { margin-bottom: 15px; } @@ -4578,16 +4873,13 @@ a.status-card { } .setting-toggle { - display: block; - line-height: 24px; + display: flex; + align-items: center; + gap: 8px; } .setting-toggle__label { color: $darker-text-color; - display: inline-block; - margin-bottom: 14px; - margin-inline-start: 8px; - vertical-align: middle; } .limited-account-hint { @@ -4602,7 +4894,6 @@ a.status-card { .empty-column-indicator, .follow_requests-unlocked_explanation { color: $dark-text-color; - background: $ui-base-color; text-align: center; padding: 20px; font-size: 15px; @@ -4628,15 +4919,15 @@ a.status-card { } .follow_requests-unlocked_explanation { - background: darken($ui-base-color, 4%); - border-bottom: 1px solid lighten($ui-base-color, 8%); + background: var(--surface-background-color); + border-bottom: 1px solid var(--background-border-color); contain: initial; flex-grow: 0; } .error-column { padding: 20px; - background: $ui-base-color; + border: 1px solid var(--background-border-color); border-radius: 4px; display: flex; flex: 1 1 auto; @@ -4715,6 +5006,11 @@ a.status-card { position: relative; margin-top: 5px; z-index: 2; + background: var(--dropdown-background-color); + backdrop-filter: var(--background-filter); + border: 1px solid var(--dropdown-border-color); + box-shadow: var(--dropdown-shadow); + border-radius: 5px; .emoji-mart-scroll { transition: opacity 200ms ease; @@ -4851,7 +5147,7 @@ a.status-card { width: 100%; height: 6px; border-radius: 6px; - background: darken($ui-base-color, 8%); + background: var(--background-color); position: relative; margin-top: 5px; } @@ -4909,6 +5205,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; @@ -5224,7 +5521,6 @@ a.status-card { .icon { position: absolute; top: 12px + 2px; - inset-inline-start: 16px - 2px; display: inline-block; opacity: 0; transition: all 100ms linear; @@ -5234,6 +5530,7 @@ a.status-card { color: $darker-text-color; cursor: default; pointer-events: none; + margin-inline-start: 16px - 2px; &.active { pointer-events: auto; @@ -5260,28 +5557,16 @@ a.status-card { } } -.search-results__header { - color: $dark-text-color; - background: lighten($ui-base-color, 2%); - padding: 15px; - font-weight: 500; - font-size: 16px; - cursor: default; - display: flex; - align-items: center; - gap: 5px; -} - .search-results__section { - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); &:last-child { border-bottom: 0; } &__header { - background: darken($ui-base-color, 4%); - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); + background: var(--surface-background-color); padding: 15px; font-weight: 500; font-size: 14px; @@ -5360,6 +5645,10 @@ a.status-card { pointer-events: auto; user-select: text; display: flex; + + @media screen and (width <= 630px) { + margin-top: auto; + } } .video-modal .video-player { @@ -5691,6 +5980,154 @@ a.status-card { margin-inline-start: 10px; } +.safety-action-modal { + width: 600px; + flex-direction: column; + + &__top, + &__bottom { + display: flex; + gap: 8px; + padding: 24px; + flex-direction: column; + background: var(--modal-background-color); + backdrop-filter: var(--background-filter); + border: 1px solid var(--modal-border-color); + } + + &__top { + border-radius: 16px 16px 0 0; + border-bottom: 0; + gap: 16px; + } + + &__bottom { + border-radius: 0 0 16px 16px; + border-top: 0; + + @media screen and (max-width: $no-gap-breakpoint) { + border-radius: 0; + border-bottom: 0; + padding-bottom: 32px; + } + } + + &__header { + display: flex; + gap: 16px; + align-items: center; + font-size: 14px; + line-height: 20px; + color: $darker-text-color; + + &__icon { + border-radius: 64px; + background: $ui-highlight-color; + color: $white; + display: flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + flex-shrink: 0; + + .icon { + width: 24px; + height: 24px; + } + } + + h1 { + font-size: 22px; + line-height: 28px; + color: $primary-text-color; + } + } + + &__bullet-points { + display: flex; + flex-direction: column; + gap: 8px; + font-size: 16px; + line-height: 24px; + + & > div { + display: flex; + gap: 16px; + align-items: center; + } + + &__icon { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + + .icon { + width: 24px; + height: 24px; + } + } + } + + &__field-group { + display: flex; + flex-direction: column; + + label { + display: flex; + gap: 16px; + align-items: center; + font-size: 16px; + line-height: 24px; + height: 32px; + padding: 0 12px; + } + } + + &__caveats { + font-size: 14px; + padding: 0 12px; + + strong { + font-weight: 500; + } + } + + &__bottom { + padding-top: 0; + + &__collapsible { + display: none; + flex-direction: column; + gap: 16px; + } + + &.active { + background: var(--modal-background-variant-color); + padding-top: 24px; + + .safety-action-modal__bottom__collapsible { + display: flex; + } + } + } + + &__actions { + display: flex; + align-items: center; + gap: 8px; + justify-content: flex-end; + + .link-button { + padding: 10px 12px; + font-weight: 600; + } + } +} + .boost-modal, .confirmation-modal, .report-modal, @@ -5994,6 +6431,7 @@ a.status-card { .report-modal__comment { box-sizing: border-box; width: 50%; + min-width: 50%; @media screen and (width <= 480px) { width: 100%; @@ -6062,6 +6500,14 @@ a.status-card { min-height: 100px; max-height: 50vh; border: 0; + + @media screen and (height <= 600px) { + max-height: 20vh; + } + + @media screen and (max-width: $no-columns-breakpoint) { + max-height: 20vh; + } } .setting-toggle { @@ -6319,7 +6765,7 @@ a.status-card { .attachment-list { display: flex; font-size: 14px; - border: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); border-radius: 4px; margin-top: 16px; overflow: hidden; @@ -6329,7 +6775,7 @@ a.status-card { color: $dark-text-color; padding: 8px 18px; cursor: default; - border-inline-end: 1px solid lighten($ui-base-color, 8%); + border-inline-end: 1px solid var(--background-border-color); display: flex; flex-direction: column; align-items: center; @@ -6481,7 +6927,7 @@ a.status-card { overflow: hidden; box-sizing: border-box; position: relative; - background: darken($ui-base-color, 8%); + background: var(--background-color); border-radius: 8px; padding-bottom: 44px; width: 100%; @@ -6877,7 +7323,6 @@ a.status-card { .scrollable .account-card { margin: 10px; - background: lighten($ui-base-color, 8%); } .scrollable .account-card__title__avatar { @@ -6888,11 +7333,7 @@ a.status-card { } .scrollable .account-card__bio::after { - background: linear-gradient( - to left, - lighten($ui-base-color, 8%), - transparent - ); + background: linear-gradient(to left, var(--background-color), transparent); } .account-gallery__container { @@ -6921,8 +7362,8 @@ a.status-card { .notification__filter-bar, .account__section-headline { - background: $ui-base-color; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); + border-top: 0; cursor: default; display: flex; flex-shrink: 0; @@ -6955,43 +7396,54 @@ 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; } } } + + .scrollable & { + border-left: 0; + border-right: 0; + } } .filter-form { - background: $ui-base-color; + border-bottom: 1px solid var(--background-border-color); &__column { - padding: 10px 15px; - padding-bottom: 0; + display: flex; + flex-direction: column; + gap: 15px; + padding: 15px; } .radio-button { - display: block; + display: flex; } } .column-settings__row .radio-button { - display: block; + display: flex; } -.radio-button { +.radio-button, +.check-box { font-size: 14px; position: relative; - display: inline-block; - padding: 6px 0; + display: inline-flex; + align-items: center; line-height: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; + gap: 10px; + color: $secondary-text-color; input[type='radio'], input[type='checkbox'] { @@ -6999,21 +7451,53 @@ a.status-card { } &__input { - display: inline-block; + display: flex; + align-items: center; + justify-content: center; position: relative; - border: 1px solid $ui-primary-color; + border: 2px solid $secondary-text-color; box-sizing: border-box; - width: 18px; - height: 18px; + width: 20px; + height: 20px; flex: 0 0 auto; - margin-inline-end: 10px; - top: -1px; border-radius: 50%; - vertical-align: middle; &.checked { - border-color: lighten($ui-highlight-color, 4%); - background: lighten($ui-highlight-color, 4%); + border-color: $ui-highlight-color; + + &::before { + position: absolute; + left: 2px; + top: 2px; + content: ''; + display: block; + border-radius: 50%; + width: 12px; + height: 12px; + background: $ui-highlight-color; + } + } + + .icon { + width: 18px; + height: 18px; + } + } +} + +.check-box { + &__input { + width: 18px; + height: 18px; + border-radius: 2px; + + &.checked { + background: $ui-highlight-color; + color: $white; + + &::before { + display: none; + } } } } @@ -7129,7 +7613,7 @@ noscript { .follow-request-banner, .account-memorial-banner { padding: 20px; - background: lighten($ui-base-color, 4%); + background: var(--surface-background-color); display: flex; align-items: center; flex-direction: column; @@ -7172,7 +7656,8 @@ noscript { justify-content: flex-start; gap: 15px; align-items: center; - background: lighten($ui-base-color, 4%); + border: 1px solid var(--background-border-color); + border-top: 0; label { flex: 1 1 auto; @@ -7273,7 +7758,7 @@ noscript { .list { padding: 10px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); } .list__wrapper { @@ -7417,7 +7902,7 @@ noscript { height: 145px; position: relative; background: darken($ui-base-color, 4%); - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); img { object-fit: cover; @@ -7431,7 +7916,7 @@ noscript { &__bar { position: relative; padding: 0 20px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); .avatar { display: block; @@ -7439,8 +7924,8 @@ noscript { width: 94px; .account__avatar { - background: darken($ui-base-color, 8%); - border: 2px solid $ui-base-color; + background: var(--background-color); + border: 2px solid var(--background-border-color); } } } @@ -7475,10 +7960,7 @@ noscript { .button { flex-shrink: 1; white-space: nowrap; - - @media screen and (max-width: $no-gap-breakpoint) { - min-width: 0; - } + min-width: 80px; } .icon-button { @@ -7497,8 +7979,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; } } @@ -7517,14 +8004,17 @@ noscript { font-size: 17px; line-height: 22px; color: $primary-text-color; - font-weight: 700; + font-weight: 600; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; small { - display: block; - font-size: 15px; + display: flex; + align-items: center; + gap: 4px; + font-size: 14px; + line-height: 20px; color: $darker-text-color; font-weight: 400; overflow: hidden; @@ -7535,10 +8025,8 @@ noscript { } .icon-lock { - height: 16px; - width: 16px; - position: relative; - top: 3px; + height: 18px; + width: 18px; } } } @@ -7558,13 +8046,12 @@ noscript { margin: 0; margin-top: 16px; border-radius: 4px; - background: darken($ui-base-color, 4%); - border: 0; + border: 1px solid var(--background-border-color); dl { display: block; padding: 11px 16px; - border-bottom-color: lighten($ui-base-color, 4%); + border-bottom-color: var(--background-border-color); } dd, @@ -7739,7 +8226,7 @@ noscript { display: flex; align-items: center; padding: 15px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); gap: 15px; &:last-child { @@ -7857,7 +8344,7 @@ noscript { .conversation { display: flex; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); padding: 5px; padding-bottom: 0; @@ -8212,7 +8699,7 @@ noscript { .picture-in-picture-placeholder { box-sizing: border-box; - border: 2px dashed lighten($ui-base-color, 8%); + border: 2px dashed var(--background-border-color); background: $base-shadow-color; display: flex; flex-direction: column; @@ -8240,7 +8727,7 @@ noscript { .notifications-permission-banner { padding: 30px; - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); display: flex; flex-direction: column; align-items: center; @@ -8264,6 +8751,12 @@ noscript { color: $darker-text-color; margin-bottom: 15px; text-align: center; + + .icon { + width: 20px; + height: 20px; + vertical-align: middle; + } } } @@ -8281,7 +8774,7 @@ noscript { .search__input { border: 1px solid lighten($ui-base-color, 8%); padding: 10px; - padding-inline-end: 28px; + padding-inline-end: 30px; } .search__popout { @@ -8299,7 +8792,8 @@ noscript { flex: 1 1 auto; display: flex; flex-direction: column; - background: $ui-base-color; + border: 1px solid var(--background-border-color); + border-top: 0; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; } @@ -8308,43 +8802,80 @@ noscript { display: flex; align-items: center; color: $primary-text-color; - text-decoration: none; - padding: 15px; - border-bottom: 1px solid lighten($ui-base-color, 8%); - gap: 15px; + padding: 16px; + border-bottom: 1px solid var(--background-border-color); + gap: 16px; &:last-child { border-bottom: 0; } - &:hover, - &:active, - &:focus { - color: $highlight-text-color; - - .story__details__publisher, - .story__details__shared { - color: $highlight-text-color; - } - } - &__details { flex: 1 1 auto; &__publisher { color: $darker-text-color; margin-bottom: 8px; + font-size: 14px; + line-height: 20px; } &__title { + display: block; font-size: 19px; line-height: 24px; font-weight: 500; margin-bottom: 8px; + text-decoration: none; + color: $primary-text-color; + + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + } } &__shared { + display: flex; + align-items: center; color: $darker-text-color; + gap: 8px; + justify-content: space-between; + font-size: 14px; + line-height: 20px; + + & > span { + display: flex; + align-items: center; + gap: 4px; + } + + &__pill { + background: var(--surface-variant-background-color); + border-radius: 4px; + color: inherit; + text-decoration: none; + padding: 4px 12px; + font-size: 12px; + font-weight: 500; + line-height: 16px; + } + + &__author-link { + display: inline-flex; + align-items: center; + gap: 4px; + color: $primary-text-color; + font-weight: 500; + text-decoration: none; + + &:hover, + &:active, + &:focus { + color: $highlight-text-color; + } + } } strong { @@ -8409,14 +8940,14 @@ noscript { } .server-banner { - padding: 20px 0; - &__introduction { + font-size: 15px; + line-height: 22px; color: $darker-text-color; margin-bottom: 20px; strong { - font-weight: 600; + font-weight: 700; } a { @@ -8444,6 +8975,9 @@ noscript { } &__description { + font-size: 15px; + line-height: 22px; + color: $darker-text-color; margin-bottom: 20px; } @@ -8492,22 +9026,37 @@ noscript { } } +.safety-action-modal, .interaction-modal { - max-width: 90vw; + max-width: 100vw; width: 600px; - background: var(--modal-background-color); - border: 1px solid var(--modal-border-color); - border-radius: 8px; + overflow-y: auto; +} + +.interaction-modal { overflow: visible; position: relative; display: block; - padding: 40px; + border-radius: 16px; + background: var(--modal-background-color); + backdrop-filter: var(--background-filter); + border: 1px solid var(--modal-border-color); + padding: 24px; + + @media screen and (max-width: $no-gap-breakpoint) { + border-radius: 16px 16px 0 0; + border-bottom: 0; + padding-bottom: 32px; + } h3 { font-size: 22px; line-height: 33px; font-weight: 700; - text-align: center; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; } p { @@ -8528,7 +9077,9 @@ noscript { &__icon { color: $highlight-text-color; - margin: 0 5px; + display: flex; + align-items: center; + justify-content: center; } &__lead { @@ -8561,6 +9112,7 @@ noscript { border: 0; padding: 15px - 4px 15px - 6px; flex: 1 1 auto; + min-width: 0; &::placeholder { color: lighten($darker-text-color, 4%); @@ -8689,7 +9241,6 @@ noscript { } .privacy-policy { - background: $ui-base-color; padding: 20px; @media screen and (min-width: $no-gap-breakpoint) { @@ -9058,6 +9609,7 @@ noscript { .about { padding: 20px; + border-top: 1px solid var(--background-border-color); @media screen and (min-width: $no-gap-breakpoint) { border-radius: 4px; @@ -9104,7 +9656,7 @@ noscript { } &__meta { - background: lighten($ui-base-color, 4%); + border: 1px solid var(--background-border-color); border-radius: 4px; display: flex; margin-bottom: 30px; @@ -9120,7 +9672,7 @@ noscript { width: 0; border: 0; border-style: solid; - border-color: lighten($ui-base-color, 8%); + border-color: var(--background-border-color); border-left-width: 1px; min-height: calc(100% - 60px); flex: 0 0 auto; @@ -9228,7 +9780,7 @@ noscript { line-height: 22px; padding: 20px; border-radius: 4px; - background: lighten($ui-base-color, 4%); + border: 1px solid var(--background-border-color); color: $highlight-text-color; cursor: pointer; } @@ -9238,7 +9790,7 @@ noscript { } &__body { - border: 1px solid lighten($ui-base-color, 4%); + border: 1px solid var(--background-border-color); border-top: 0; padding: 20px; font-size: 15px; @@ -9248,18 +9800,17 @@ noscript { &__domain-blocks { margin-top: 30px; - background: darken($ui-base-color, 4%); - border: 1px solid lighten($ui-base-color, 4%); + border: 1px solid var(--background-border-color); border-radius: 4px; &__domain { - border-bottom: 1px solid lighten($ui-base-color, 4%); + border-bottom: 1px solid var(--background-border-color); padding: 10px; font-size: 15px; color: $darker-text-color; &:nth-child(2n) { - background: darken($ui-base-color, 2%); + background: darken($ui-base-color, 4%); } &:last-child { @@ -9355,7 +9906,7 @@ noscript { } .hashtag-header { - border-bottom: 1px solid lighten($ui-base-color, 8%); + border-bottom: 1px solid var(--background-border-color); padding: 15px; font-size: 17px; line-height: 22px; @@ -9388,18 +9939,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: var(--surface-variant-background-color); + border-radius: 4px; + font-weight: 500; - &:hover span { - text-decoration: underline; + &:hover, + &:focus, + &:active { + background: var(--surface-variant-active-background-color); } } @@ -9416,8 +9973,9 @@ noscript { flex-direction: column; gap: 12px; padding: 16px 0; - border-bottom: 1px solid mix($ui-base-color, $ui-highlight-color, 75%); - background: mix($ui-base-color, $ui-highlight-color, 95%); + padding-bottom: 0; + border-bottom: 1px solid var(--background-border-color); + background: rgba($ui-highlight-color, 0.05); &__header { display: flex; @@ -9454,6 +10012,7 @@ noscript { cursor: pointer; top: 0; color: $primary-text-color; + opacity: 0.5; &.left { left: 0; @@ -9481,6 +10040,8 @@ noscript { &:hover, &:focus, &:active { + opacity: 1; + .inline-follow-suggestions__body__scroll-button__icon { background: lighten($ui-highlight-color, 4%); } @@ -9492,15 +10053,14 @@ noscript { flex-wrap: nowrap; gap: 16px; padding: 16px; - padding-bottom: 0; scroll-snap-type: x mandatory; scroll-padding: 16px; scroll-behavior: smooth; - overflow-x: hidden; + overflow-x: scroll; &__card { - background: darken($ui-base-color, 4%); - border: 1px solid lighten($ui-base-color, 8%); + background: var(--background-color); + border: 1px solid var(--background-border-color); border-radius: 4px; display: flex; flex-direction: column; @@ -9521,6 +10081,7 @@ noscript { position: absolute; inset-inline-end: 8px; top: 8px; + opacity: 0.75; } &__avatar { @@ -9536,7 +10097,7 @@ noscript { .account__avatar { flex-shrink: 0; align-self: flex-end; - border: 1px solid lighten($ui-base-color, 8%); + border: 1px solid var(--background-border-color); background-color: $ui-base-color; } @@ -9558,6 +10119,7 @@ noscript { gap: 4px; overflow: hidden; white-space: nowrap; + cursor: help; > span { overflow: hidden; @@ -9606,3 +10168,160 @@ noscript { } } } + +.filtered-notifications-banner { + display: flex; + align-items: center; + border: 1px solid var(--background-border-color); + border-top: 0; + padding: 24px 32px; + gap: 16px; + color: $darker-text-color; + text-decoration: none; + + &:hover, + &:active, + &:focus { + color: $secondary-text-color; + } + + .icon { + width: 24px; + height: 24px; + padding: 2px; + } + + &__text { + flex: 1 1 auto; + font-style: 14px; + line-height: 20px; + + strong { + font-size: 16px; + line-height: 24px; + display: block; + } + } + + &__badge { + 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; + word-break: keep-all; + + &__badge { + background: $ui-button-background-color; + color: $white; + border-radius: 100px; + padding: 2px 8px; + } + } +} + +.notification-request { + display: flex; + align-items: center; + gap: 16px; + padding: 15px; + border-bottom: 1px solid var(--background-border-color); + + &__link { + display: flex; + align-items: center; + gap: 12px; + flex: 1 1 auto; + text-decoration: none; + color: inherit; + overflow: hidden; + + .account__avatar { + flex-shrink: 0; + } + } + + &__name { + flex: 1 1 auto; + color: $darker-text-color; + font-style: 14px; + line-height: 20px; + overflow: hidden; + text-overflow: ellipsis; + + &__display-name { + display: flex; + align-items: center; + gap: 6px; + font-size: 16px; + letter-spacing: 0.5px; + line-height: 24px; + color: $secondary-text-color; + } + + .filtered-notifications-banner__badge { + background: $ui-button-background-color; + border-radius: 4px; + padding: 1px 6px; + color: $white; + } + } + + &__actions { + display: flex; + align-items: center; + gap: 8px; + + .icon-button { + border-radius: 4px; + border: 1px solid var(--background-border-color); + padding: 5px; + } + } +} + +.more-from-author { + box-sizing: border-box; + font-size: 14px; + color: $darker-text-color; + background: var(--surface-background-color); + border: 1px solid var(--background-border-color); + border-top: 0; + border-radius: 0 0 8px 8px; + padding: 15px; + display: flex; + align-items: center; + gap: 8px; + + .logo { + height: 16px; + color: $darker-text-color; + } + + & > span { + display: flex; + align-items: center; + gap: 8px; + } + + a { + display: inline-flex; + align-items: center; + gap: 4px; + font-weight: 500; + color: $primary-text-color; + text-decoration: none; + + &:hover, + &:focus, + &:active { + color: $highlight-text-color; + } + } +} diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss index fec0c10ddb..b9fdaa5847 100644 --- a/app/javascript/styles/mastodon/emoji_picker.scss +++ b/app/javascript/styles/mastodon/emoji_picker.scss @@ -14,21 +14,9 @@ } .emoji-mart-bar { - border: 0 solid var(--dropdown-border-color); - &:first-child { - border-bottom-width: 1px; - border-top-left-radius: 5px; - border-top-right-radius: 5px; background: var(--dropdown-border-color); } - - &:last-child { - border-top-width: 1px; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - display: none; - } } .emoji-mart-anchors { @@ -94,7 +82,6 @@ height: 270px; max-height: 35vh; padding: 0 6px 6px; - background: var(--dropdown-background-color); will-change: transform; &::-webkit-scrollbar-track:hover, @@ -106,7 +93,6 @@ .emoji-mart-search { padding: 10px; padding-inline-end: 45px; - background: var(--dropdown-background-color); position: relative; input { @@ -126,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 { @@ -195,7 +182,6 @@ width: 100%; font-weight: 500; padding: 5px 6px; - background: var(--dropdown-background-color); } } diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 555d43cc1c..26bb2bee14 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -613,9 +613,10 @@ code { font-family: inherit; pointer-events: none; cursor: default; - max-width: 140px; + max-width: 50%; white-space: nowrap; overflow: hidden; + text-overflow: ellipsis; &::after { content: ''; @@ -1078,6 +1079,7 @@ code { &__type { color: $darker-text-color; + word-break: break-word; } } @@ -1312,6 +1314,12 @@ code { font-weight: 600; } + .hint { + display: block; + font-size: 14px; + color: $darker-text-color; + } + .recommended { position: absolute; margin: 0 4px; diff --git a/app/javascript/styles/mastodon/rich_text.scss b/app/javascript/styles/mastodon/rich_text.scss index c77c23bc40..c57db26e03 100644 --- a/app/javascript/styles/mastodon/rich_text.scss +++ b/app/javascript/styles/mastodon/rich_text.scss @@ -1,5 +1,6 @@ .status__content__text, .e-content, +.edit-indicator__content, .reply-indicator__content { pre, blockquote { @@ -55,10 +56,3 @@ list-style-type: decimal; } } - -.reply-indicator__content { - blockquote { - border-left-color: $inverted-text-color; - color: $inverted-text-color; - } -} diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss index 611c8bb5d1..2848a42b3f 100644 --- a/app/javascript/styles/mastodon/variables.scss +++ b/app/javascript/styles/mastodon/variables.scss @@ -46,10 +46,10 @@ $ui-button-focus-background-color: $blurple-600 !default; $ui-button-focus-outline-color: $blurple-400 !default; $ui-button-focus-outline: solid 2px $ui-button-focus-outline-color !default; -$ui-button-secondary-color: $grey-100 !default; -$ui-button-secondary-border-color: $grey-100 !default; -$ui-button-secondary-focus-background-color: $grey-600 !default; -$ui-button-secondary-focus-color: $white !default; +$ui-button-secondary-color: $blurple-500 !default; +$ui-button-secondary-border-color: $blurple-500 !default; +$ui-button-secondary-focus-border-color: $blurple-300 !default; +$ui-button-secondary-focus-color: $blurple-300 !default; $ui-button-tertiary-color: $blurple-300 !default; $ui-button-tertiary-border-color: $blurple-300 !default; @@ -94,10 +94,18 @@ $font-display: 'mastodon-font-display' !default; $font-monospace: 'mastodon-font-monospace' !default; :root { - --dropdown-border-color: #{lighten($ui-base-color, 12%)}; - --dropdown-background-color: #{lighten($ui-base-color, 4%)}; + --dropdown-border-color: #{lighten($ui-base-color, 4%)}; + --dropdown-background-color: #{rgba(darken($ui-base-color, 8%), 0.9)}; --dropdown-shadow: 0 20px 25px -5px #{rgba($base-shadow-color, 0.25)}, 0 8px 10px -6px #{rgba($base-shadow-color, 0.25)}; - --modal-background-color: #{darken($ui-base-color, 4%)}; + --modal-background-color: #{rgba(darken($ui-base-color, 8%), 0.7)}; + --modal-background-variant-color: #{rgba($ui-base-color, 0.7)}; --modal-border-color: #{lighten($ui-base-color, 4%)}; + --background-border-color: #{lighten($ui-base-color, 4%)}; + --background-filter: blur(10px) saturate(180%) contrast(75%) brightness(70%); + --background-color: #{darken($ui-base-color, 8%)}; + --background-color-tint: #{rgba(darken($ui-base-color, 8%), 0.9)}; + --surface-background-color: #{darken($ui-base-color, 4%)}; + --surface-variant-background-color: #{$ui-base-color}; + --surface-variant-active-background-color: #{lighten($ui-base-color, 4%)}; } diff --git a/app/lib/access_grant_extension.rb b/app/lib/access_grant_extension.rb new file mode 100644 index 0000000000..bf8f5ae25a --- /dev/null +++ b/app/lib/access_grant_extension.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module AccessGrantExtension + extend ActiveSupport::Concern + + included do + scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') } + scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) } + end +end diff --git a/app/lib/access_token_extension.rb b/app/lib/access_token_extension.rb index f51bde4927..6e06f988a5 100644 --- a/app/lib/access_token_extension.rb +++ b/app/lib/access_token_extension.rb @@ -6,7 +6,13 @@ module AccessTokenExtension included do include Redisable + has_many :web_push_subscriptions, class_name: 'Web::PushSubscription', inverse_of: :access_token + after_commit :push_to_streaming_api + + scope :expired, -> { where.not(expires_in: nil).where('created_at + MAKE_INTERVAL(secs => expires_in) < NOW()') } + scope :not_revoked, -> { where(revoked_at: nil) } + scope :revoked, -> { where.not(revoked_at: nil).where(revoked_at: ...Time.now.utc) } end def revoke(clock = Time) diff --git a/app/lib/account_statuses_filter.rb b/app/lib/account_statuses_filter.rb index eb7592cdce..cfc9be9660 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/activity_tracker.rb b/app/lib/activity_tracker.rb index 9160ef22a6..d0e675f07d 100644 --- a/app/lib/activity_tracker.rb +++ b/app/lib/activity_tracker.rb @@ -24,7 +24,7 @@ class ActivityTracker end def get(start_at, end_at = Time.now.utc) - (start_at.to_date...end_at.to_date).map do |date| + (start_at.to_date..end_at.to_date).map do |date| key = key_at(date.to_time(:utc)) value = case @type diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 85195f4c39..7ec7e84bd1 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -110,7 +110,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity def process_status_params @status_parser = ActivityPub::Parser::StatusParser.new(@json, followers_collection: @account.followers_url, object: @object) - attachment_ids = process_attachments.take(4).map(&:id) + attachment_ids = process_attachments.take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:id) @params = { uri: @status_parser.uri, @@ -260,7 +260,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity as_array(@object['attachment']).each do |attachment| media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) - next if media_attachment_parser.remote_url.blank? || media_attachments.size >= 4 + next if media_attachment_parser.remote_url.blank? || media_attachments.size >= Status::MEDIA_ATTACHMENTS_LIMIT begin media_attachment = MediaAttachment.create( diff --git a/app/lib/activitypub/activity/flag.rb b/app/lib/activitypub/activity/flag.rb index 68ee43d0eb..b7a412485c 100644 --- a/app/lib/activitypub/activity/flag.rb +++ b/app/lib/activitypub/activity/flag.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class ActivityPub::Activity::Flag < ActivityPub::Activity + COMMENT_SIZE_LIMIT = 5000 + def perform return if skip_reports? @@ -38,6 +40,6 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity end def report_comment - (@json['content'] || '')[0...5000] + (@json['content'] || '')[0...COMMENT_SIZE_LIMIT] end end diff --git a/app/lib/activitypub/parser/status_parser.rb b/app/lib/activitypub/parser/status_parser.rb index cfc2b8788b..2940aea44b 100644 --- a/app/lib/activitypub/parser/status_parser.rb +++ b/app/lib/activitypub/parser/status_parser.rb @@ -3,6 +3,8 @@ class ActivityPub::Parser::StatusParser include JsonLdHelper + NORMALIZED_LOCALE_NAMES = LanguagesHelper::SUPPORTED_LOCALES.keys.index_by(&:downcase).freeze + # @param [Hash] json # @param [Hash] options # @option options [String] :followers_collection @@ -87,6 +89,13 @@ class ActivityPub::Parser::StatusParser end def language + lang = raw_language_code + lang.presence && NORMALIZED_LOCALE_NAMES.fetch(lang.downcase.to_sym, lang) + end + + private + + def raw_language_code if content_language_map? @object['contentMap'].keys.first elsif name_language_map? @@ -96,8 +105,6 @@ class ActivityPub::Parser::StatusParser end end - private - def audience_to as_array(@object['to'] || @json['to']).map { |x| value_or_id(x) } end diff --git a/app/lib/activitypub/serializer.rb b/app/lib/activitypub/serializer.rb index 1fdc793104..b17ec3fdfb 100644 --- a/app/lib/activitypub/serializer.rb +++ b/app/lib/activitypub/serializer.rb @@ -33,6 +33,6 @@ class ActivityPub::Serializer < ActiveModel::Serializer adapter_options[:named_contexts].merge!(_named_contexts) adapter_options[:context_extensions].merge!(_context_extensions) end - super(adapter_options, options, adapter_instance) + super end end diff --git a/app/lib/admin/metrics/dimension.rb b/app/lib/admin/metrics/dimension.rb index e0122a65b5..824cb6d7c1 100644 --- a/app/lib/admin/metrics/dimension.rb +++ b/app/lib/admin/metrics/dimension.rb @@ -2,15 +2,15 @@ class Admin::Metrics::Dimension DIMENSIONS = { - languages: Admin::Metrics::Dimension::LanguagesDimension, - sources: Admin::Metrics::Dimension::SourcesDimension, - servers: Admin::Metrics::Dimension::ServersDimension, - space_usage: Admin::Metrics::Dimension::SpaceUsageDimension, - software_versions: Admin::Metrics::Dimension::SoftwareVersionsDimension, - tag_servers: Admin::Metrics::Dimension::TagServersDimension, - tag_languages: Admin::Metrics::Dimension::TagLanguagesDimension, - instance_accounts: Admin::Metrics::Dimension::InstanceAccountsDimension, - instance_languages: Admin::Metrics::Dimension::InstanceLanguagesDimension, + languages: LanguagesDimension, + sources: SourcesDimension, + servers: ServersDimension, + space_usage: SpaceUsageDimension, + software_versions: SoftwareVersionsDimension, + tag_servers: TagServersDimension, + tag_languages: TagLanguagesDimension, + instance_accounts: InstanceAccountsDimension, + instance_languages: InstanceLanguagesDimension, }.freeze def self.retrieve(dimension_keys, start_at, end_at, limit, params) diff --git a/app/lib/admin/metrics/dimension/instance_languages_dimension.rb b/app/lib/admin/metrics/dimension/instance_languages_dimension.rb index b478213808..661e6d93b7 100644 --- a/app/lib/admin/metrics/dimension/instance_languages_dimension.rb +++ b/app/lib/admin/metrics/dimension/instance_languages_dimension.rb @@ -37,11 +37,11 @@ class Admin::Metrics::Dimension::InstanceLanguagesDimension < Admin::Metrics::Di 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 params diff --git a/app/lib/admin/metrics/dimension/servers_dimension.rb b/app/lib/admin/metrics/dimension/servers_dimension.rb index 42aba8e213..2c8406d52f 100644 --- a/app/lib/admin/metrics/dimension/servers_dimension.rb +++ b/app/lib/admin/metrics/dimension/servers_dimension.rb @@ -30,10 +30,10 @@ class Admin::Metrics::Dimension::ServersDimension < Admin::Metrics::Dimension::B end def earliest_status_id - Mastodon::Snowflake.id_at(@start_at) + Mastodon::Snowflake.id_at(@start_at.beginning_of_day, with_random: false) end def latest_status_id - Mastodon::Snowflake.id_at(@end_at) + Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false) end end diff --git a/app/lib/admin/metrics/dimension/software_versions_dimension.rb b/app/lib/admin/metrics/dimension/software_versions_dimension.rb index ccf556eae0..a260a66e2a 100644 --- a/app/lib/admin/metrics/dimension/software_versions_dimension.rb +++ b/app/lib/admin/metrics/dimension/software_versions_dimension.rb @@ -10,7 +10,7 @@ class Admin::Metrics::Dimension::SoftwareVersionsDimension < Admin::Metrics::Dim protected def perform_query - [mastodon_version, ruby_version, postgresql_version, redis_version, elasticsearch_version].compact + [mastodon_version, ruby_version, postgresql_version, redis_version, elasticsearch_version, libvips_version, imagemagick_version, ffmpeg_version].compact end def mastodon_version @@ -25,14 +25,11 @@ class Admin::Metrics::Dimension::SoftwareVersionsDimension < Admin::Metrics::Dim end def ruby_version - yjit = defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled? - value = "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}#{yjit ? ' +YJIT' : ''}" - { key: 'ruby', human_key: 'Ruby', - value: value, - human_value: value, + value: RUBY_DESCRIPTION, + human_value: "#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}", } end @@ -74,6 +71,45 @@ class Admin::Metrics::Dimension::SoftwareVersionsDimension < Admin::Metrics::Dim nil end + def libvips_version + return unless Rails.configuration.x.use_vips + + { + key: 'libvips', + human_key: 'libvips', + value: Vips.version_string, + human_value: Vips.version_string, + } + end + + def imagemagick_version + return if Rails.configuration.x.use_vips + + version = `convert -version`.match(/Version: ImageMagick ([\d\.]+)/)[1] + + { + key: 'imagemagick', + human_key: 'ImageMagick', + value: version, + human_value: version, + } + rescue Errno::ENOENT + nil + end + + def ffmpeg_version + version = `ffmpeg -version`.match(/ffmpeg version ([\d\.]+)/)[1] + + { + key: 'ffmpeg', + human_key: 'FFmpeg', + value: version, + human_value: version, + } + rescue Errno::ENOENT + nil + end + def redis_info @redis_info ||= if redis.is_a?(Redis::Namespace) redis.redis.info diff --git a/app/lib/admin/metrics/dimension/tag_languages_dimension.rb b/app/lib/admin/metrics/dimension/tag_languages_dimension.rb index cd077ff863..6e283d2c65 100644 --- a/app/lib/admin/metrics/dimension/tag_languages_dimension.rb +++ b/app/lib/admin/metrics/dimension/tag_languages_dimension.rb @@ -40,11 +40,11 @@ class Admin::Metrics::Dimension::TagLanguagesDimension < Admin::Metrics::Dimensi 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 params diff --git a/app/lib/admin/metrics/dimension/tag_servers_dimension.rb b/app/lib/admin/metrics/dimension/tag_servers_dimension.rb index fc5e49a966..db820e965c 100644 --- a/app/lib/admin/metrics/dimension/tag_servers_dimension.rb +++ b/app/lib/admin/metrics/dimension/tag_servers_dimension.rb @@ -40,11 +40,11 @@ class Admin::Metrics::Dimension::TagServersDimension < Admin::Metrics::Dimension 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 params diff --git a/app/lib/admin/metrics/measure.rb b/app/lib/admin/metrics/measure.rb index fe7e049290..d23162dfab 100644 --- a/app/lib/admin/metrics/measure.rb +++ b/app/lib/admin/metrics/measure.rb @@ -2,20 +2,20 @@ class Admin::Metrics::Measure MEASURES = { - active_users: Admin::Metrics::Measure::ActiveUsersMeasure, - new_users: Admin::Metrics::Measure::NewUsersMeasure, - interactions: Admin::Metrics::Measure::InteractionsMeasure, - opened_reports: Admin::Metrics::Measure::OpenedReportsMeasure, - resolved_reports: Admin::Metrics::Measure::ResolvedReportsMeasure, - tag_accounts: Admin::Metrics::Measure::TagAccountsMeasure, - tag_uses: Admin::Metrics::Measure::TagUsesMeasure, - tag_servers: Admin::Metrics::Measure::TagServersMeasure, - instance_accounts: Admin::Metrics::Measure::InstanceAccountsMeasure, - instance_media_attachments: Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure, - instance_reports: Admin::Metrics::Measure::InstanceReportsMeasure, - instance_statuses: Admin::Metrics::Measure::InstanceStatusesMeasure, - instance_follows: Admin::Metrics::Measure::InstanceFollowsMeasure, - instance_followers: Admin::Metrics::Measure::InstanceFollowersMeasure, + active_users: ActiveUsersMeasure, + new_users: NewUsersMeasure, + interactions: InteractionsMeasure, + opened_reports: OpenedReportsMeasure, + resolved_reports: ResolvedReportsMeasure, + tag_accounts: TagAccountsMeasure, + tag_uses: TagUsesMeasure, + tag_servers: TagServersMeasure, + instance_accounts: InstanceAccountsMeasure, + instance_media_attachments: InstanceMediaAttachmentsMeasure, + instance_reports: InstanceReportsMeasure, + instance_statuses: InstanceStatusesMeasure, + instance_follows: InstanceFollowsMeasure, + instance_followers: InstanceFollowersMeasure, }.freeze def self.retrieve(measure_keys, start_at, end_at, params) diff --git a/app/lib/admin/metrics/measure/active_users_measure.rb b/app/lib/admin/metrics/measure/active_users_measure.rb index e6f09d4bcf..c085ced629 100644 --- a/app/lib/admin/metrics/measure/active_users_measure.rb +++ b/app/lib/admin/metrics/measure/active_users_measure.rb @@ -22,12 +22,4 @@ class Admin::Metrics::Measure::ActiveUsersMeasure < Admin::Metrics::Measure::Bas def activity_tracker @activity_tracker ||= ActivityTracker.new('activity:logins', :unique) end - - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end end diff --git a/app/lib/admin/metrics/measure/base_measure.rb b/app/lib/admin/metrics/measure/base_measure.rb index e33a6c494f..8b7fe39b55 100644 --- a/app/lib/admin/metrics/measure/base_measure.rb +++ b/app/lib/admin/metrics/measure/base_measure.rb @@ -86,11 +86,11 @@ class Admin::Metrics::Measure::BaseMeasure end def time_period - (@start_at..@end_at) + (@start_at.to_date..@end_at.to_date) end def previous_time_period - ((@start_at - length_of_period)..(@end_at - length_of_period)) + ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) end def length_of_period diff --git a/app/lib/admin/metrics/measure/instance_accounts_measure.rb b/app/lib/admin/metrics/measure/instance_accounts_measure.rb index 3d081fdd90..889a5e6f05 100644 --- a/app/lib/admin/metrics/measure/instance_accounts_measure.rb +++ b/app/lib/admin/metrics/measure/instance_accounts_measure.rb @@ -43,19 +43,11 @@ class Admin::Metrics::Measure::InstanceAccountsMeasure < Admin::Metrics::Measure SELECT count(*) FROM new_accounts ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:domain, :include_subdomains) end diff --git a/app/lib/admin/metrics/measure/instance_followers_measure.rb b/app/lib/admin/metrics/measure/instance_followers_measure.rb index 378c6754d9..fa934c6b96 100644 --- a/app/lib/admin/metrics/measure/instance_followers_measure.rb +++ b/app/lib/admin/metrics/measure/instance_followers_measure.rb @@ -44,19 +44,11 @@ class Admin::Metrics::Measure::InstanceFollowersMeasure < Admin::Metrics::Measur SELECT count(*) FROM new_followers ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:domain, :include_subdomains) end diff --git a/app/lib/admin/metrics/measure/instance_follows_measure.rb b/app/lib/admin/metrics/measure/instance_follows_measure.rb index e213348fbc..3f3ab73fc9 100644 --- a/app/lib/admin/metrics/measure/instance_follows_measure.rb +++ b/app/lib/admin/metrics/measure/instance_follows_measure.rb @@ -44,19 +44,11 @@ class Admin::Metrics::Measure::InstanceFollowsMeasure < Admin::Metrics::Measure: SELECT count(*) FROM new_follows ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:domain, :include_subdomains) end diff --git a/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb index 2d4b5f56b0..996ca52e0b 100644 --- a/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb +++ b/app/lib/admin/metrics/measure/instance_media_attachments_measure.rb @@ -50,22 +50,14 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics: WHERE date_trunc('day', media_attachments.created_at)::date = axis.period AND #{account_domain_sql(params[:include_subdomains])} ) - SELECT SUM(size) FROM new_media_attachments + SELECT COALESCE(SUM(size), 0) FROM new_media_attachments ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:domain, :include_subdomains) end diff --git a/app/lib/admin/metrics/measure/instance_reports_measure.rb b/app/lib/admin/metrics/measure/instance_reports_measure.rb index 9da3d53e34..ae1bb6e68d 100644 --- a/app/lib/admin/metrics/measure/instance_reports_measure.rb +++ b/app/lib/admin/metrics/measure/instance_reports_measure.rb @@ -44,19 +44,11 @@ class Admin::Metrics::Measure::InstanceReportsMeasure < Admin::Metrics::Measure: SELECT count(*) FROM new_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:domain, :include_subdomains) end diff --git a/app/lib/admin/metrics/measure/instance_statuses_measure.rb b/app/lib/admin/metrics/measure/instance_statuses_measure.rb index 8c71c66145..324d427b18 100644 --- a/app/lib/admin/metrics/measure/instance_statuses_measure.rb +++ b/app/lib/admin/metrics/measure/instance_statuses_measure.rb @@ -45,25 +45,17 @@ class Admin::Metrics::Measure::InstanceStatusesMeasure < Admin::Metrics::Measure SELECT count(*) FROM new_statuses ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL 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) - end - - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) + Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false) end def params diff --git a/app/lib/admin/metrics/measure/interactions_measure.rb b/app/lib/admin/metrics/measure/interactions_measure.rb index 7a2b7e0fac..f4b4836b4a 100644 --- a/app/lib/admin/metrics/measure/interactions_measure.rb +++ b/app/lib/admin/metrics/measure/interactions_measure.rb @@ -22,12 +22,4 @@ class Admin::Metrics::Measure::InteractionsMeasure < Admin::Metrics::Measure::Ba def activity_tracker @activity_tracker ||= ActivityTracker.new('activity:interactions', :basic) end - - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end end diff --git a/app/lib/admin/metrics/measure/new_users_measure.rb b/app/lib/admin/metrics/measure/new_users_measure.rb index 6837c14c82..32057154d6 100644 --- a/app/lib/admin/metrics/measure/new_users_measure.rb +++ b/app/lib/admin/metrics/measure/new_users_measure.rb @@ -32,7 +32,7 @@ class Admin::Metrics::Measure::NewUsersMeasure < Admin::Metrics::Measure::BaseMe SELECT count(*) FROM new_users ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/opened_reports_measure.rb b/app/lib/admin/metrics/measure/opened_reports_measure.rb index c395c46341..47de38bbe6 100644 --- a/app/lib/admin/metrics/measure/opened_reports_measure.rb +++ b/app/lib/admin/metrics/measure/opened_reports_measure.rb @@ -32,7 +32,7 @@ class Admin::Metrics::Measure::OpenedReportsMeasure < Admin::Metrics::Measure::B SELECT count(*) FROM new_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/query_helper.rb b/app/lib/admin/metrics/measure/query_helper.rb index 969065f73f..47cfc63e5c 100644 --- a/app/lib/admin/metrics/measure/query_helper.rb +++ b/app/lib/admin/metrics/measure/query_helper.rb @@ -15,6 +15,14 @@ module Admin::Metrics::Measure::QueryHelper ActiveRecord::Base.sanitize_sql_array(sql_array) end + def generated_series_days + Arel.sql( + <<~SQL.squish + SELECT generate_series(:start_at::timestamp, :end_at::timestamp, '1 day')::date AS period + SQL + ) + end + def account_domain_sql(include_subdomains) if include_subdomains "accounts.domain IN (SELECT domain FROM instances WHERE reverse('.' || domain) LIKE reverse('.' || :domain::text))" diff --git a/app/lib/admin/metrics/measure/resolved_reports_measure.rb b/app/lib/admin/metrics/measure/resolved_reports_measure.rb index 780db75a10..ecfd779c86 100644 --- a/app/lib/admin/metrics/measure/resolved_reports_measure.rb +++ b/app/lib/admin/metrics/measure/resolved_reports_measure.rb @@ -32,7 +32,7 @@ class Admin::Metrics::Measure::ResolvedReportsMeasure < Admin::Metrics::Measure: SELECT count(*) FROM resolved_reports ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, interval '1 day') AS period + #{generated_series_days} ) AS axis SQL end diff --git a/app/lib/admin/metrics/measure/tag_accounts_measure.rb b/app/lib/admin/metrics/measure/tag_accounts_measure.rb index 8f4512efe7..906277b7d5 100644 --- a/app/lib/admin/metrics/measure/tag_accounts_measure.rb +++ b/app/lib/admin/metrics/measure/tag_accounts_measure.rb @@ -27,14 +27,6 @@ class Admin::Metrics::Measure::TagAccountsMeasure < Admin::Metrics::Measure::Bas @tag ||= Tag.find(params[:id]) end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:id) end diff --git a/app/lib/admin/metrics/measure/tag_servers_measure.rb b/app/lib/admin/metrics/measure/tag_servers_measure.rb index e6378b8021..5db1076062 100644 --- a/app/lib/admin/metrics/measure/tag_servers_measure.rb +++ b/app/lib/admin/metrics/measure/tag_servers_measure.rb @@ -28,26 +28,29 @@ class Admin::Metrics::Measure::TagServersMeasure < Admin::Metrics::Measure::Base def sql_query_string <<~SQL.squish SELECT axis.*, ( - SELECT count(distinct accounts.domain) AS value - FROM statuses - INNER JOIN statuses_tags ON statuses.id = statuses_tags.status_id - INNER JOIN accounts ON statuses.account_id = accounts.id - WHERE statuses_tags.tag_id = :tag_id - AND statuses.id BETWEEN :earliest_status_id AND :latest_status_id - AND date_trunc('day', statuses.created_at)::date = axis.day - ) + WITH tag_servers AS ( + SELECT DISTINCT accounts.domain + FROM statuses + INNER JOIN statuses_tags ON statuses.id = statuses_tags.status_id + INNER JOIN accounts ON statuses.account_id = accounts.id + WHERE statuses_tags.tag_id = :tag_id + AND statuses.id BETWEEN :earliest_status_id AND :latest_status_id + AND date_trunc('day', statuses.created_at)::date = axis.period + ) + SELECT COUNT(*) FROM tag_servers + ) AS value FROM ( - SELECT generate_series(date_trunc('day', :start_at::timestamp)::date, date_trunc('day', :end_at::timestamp)::date, ('1 day')::interval) AS day + #{generated_series_days} ) as axis SQL 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/admin/metrics/measure/tag_uses_measure.rb b/app/lib/admin/metrics/measure/tag_uses_measure.rb index bce86b89f1..2be96a02b3 100644 --- a/app/lib/admin/metrics/measure/tag_uses_measure.rb +++ b/app/lib/admin/metrics/measure/tag_uses_measure.rb @@ -27,14 +27,6 @@ class Admin::Metrics::Measure::TagUsesMeasure < Admin::Metrics::Measure::BaseMea @tag ||= Tag.find(params[:id]) end - def time_period - (@start_at.to_date..@end_at.to_date) - end - - def previous_time_period - ((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period)) - end - def params @params.permit(:id) end diff --git a/app/lib/annual_report/top_statuses.rb b/app/lib/annual_report/top_statuses.rb index 112e5591ce..1ab1709523 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/application_extension.rb b/app/lib/application_extension.rb index 400c51a023..2fea1057cb 100644 --- a/app/lib/application_extension.rb +++ b/app/lib/application_extension.rb @@ -23,6 +23,12 @@ module ApplicationExtension redirect_uri.lines.first.strip end + def redirect_uris + # Doorkeeper stores the redirect_uri value as a newline delimeted list in + # the database: + redirect_uri.split + end + def push_to_streaming_api # TODO: #28793 Combine into a single topic payload = Oj.dump(event: :kill) diff --git a/app/lib/cache_buster.rb b/app/lib/cache_buster.rb index 554f2ba95d..d3395f8f0a 100644 --- a/app/lib/cache_buster.rb +++ b/app/lib/cache_buster.rb @@ -2,13 +2,8 @@ class CacheBuster def initialize(options = {}) - Rails.application.deprecators[:mastodon].warn('Default values for the cache buster secret header name and values will be removed in Mastodon 4.3. Please set them explicitely if you rely on those.') unless options[:http_method] || (options[:secret] && options[:secret_header]) - - @secret_header = options[:secret_header] || - (options[:http_method] ? nil : 'Secret-Header') - @secret = options[:secret] || - (options[:http_method] ? nil : 'True') - + @secret_header = options[:secret_header] + @secret = options[:secret] @http_method = options[:http_method] || 'GET' end diff --git a/app/lib/connection_pool/shared_connection_pool.rb b/app/lib/connection_pool/shared_connection_pool.rb index 3ca22d0eff..1cfcc5823b 100644 --- a/app/lib/connection_pool/shared_connection_pool.rb +++ b/app/lib/connection_pool/shared_connection_pool.rb @@ -5,7 +5,7 @@ require_relative 'shared_timed_stack' class ConnectionPool::SharedConnectionPool < ConnectionPool def initialize(options = {}, &block) - super(options, &block) + super @available = ConnectionPool::SharedTimedStack.new(@size, &block) end diff --git a/app/lib/extractor.rb b/app/lib/extractor.rb index 9090773ae9..7e647a7587 100644 --- a/app/lib/extractor.rb +++ b/app/lib/extractor.rb @@ -86,10 +86,6 @@ module Extractor possible_entries end - def extract_cashtags_with_indices(_text) - [] - end - def extract_extra_uris_with_indices(text) return [] unless text&.index(':') diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 38a177e645..1fb224a133 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| @@ -420,10 +420,7 @@ class FeedManager check_for_blocks = status.active_mentions.pluck(:account_id) check_for_blocks.push(status.in_reply_to_account) if status.reply? && !status.in_reply_to_account_id.nil? - should_filter = blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted) - should_filter ||= status.account.silenced? && !Follow.exists?(account_id: receiver_id, target_account_id: status.account_id) # Filter if the account is silenced and I'm not following them - - should_filter + blocks_or_mutes?(receiver_id, check_for_blocks, :mentions) # Filter if it's from someone I blocked, in reply to someone I blocked, or mentioning someone I blocked (or muted) end # Check if status should not be added to the list feed @@ -431,10 +428,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 +446,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 bb031986d6..dbfdd33fcc 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 @@ -195,6 +195,10 @@ class LinkDetailsExtractor structured_data&.author_url end + def author_account + opengraph_tag('fediverse:creator') + end + def embed_url valid_url_or_nil(opengraph_tag('twitter:player:stream')) end @@ -265,16 +269,21 @@ class LinkDetailsExtractor end def document - @document ||= Nokogiri::HTML(@html, nil, encoding) + @document ||= detect_encoding_and_parse_document end - def encoding - @encoding ||= begin - guess = detector.detect(@html, @html_charset) - guess&.fetch(:confidence, 0).to_i > 60 ? guess&.fetch(:encoding, nil) : nil + def detect_encoding_and_parse_document + [detect_encoding, nil, @html_charset, 'UTF-8'].uniq.each do |encoding| + document = Nokogiri::HTML(@html, nil, encoding) + return document if document.to_s.valid_encoding? end end + def detect_encoding + guess = detector.detect(@html, @html_charset) + guess&.fetch(:confidence, 0).to_i > 60 ? guess&.fetch(:encoding, nil) : nil + end + def detector @detector ||= CharlockHolmes::EncodingDetector.new.tap do |detector| detector.strip_tags = true @@ -282,6 +291,6 @@ class LinkDetailsExtractor end def html_entities - @html_entities ||= HTMLEntities.new + @html_entities ||= HTMLEntities.new(:expanded) end end diff --git a/app/lib/redis_configuration.rb b/app/lib/redis_configuration.rb index f0e86d985b..fb1249640f 100644 --- a/app/lib/redis_configuration.rb +++ b/app/lib/redis_configuration.rb @@ -42,9 +42,13 @@ class RedisConfiguration ENV['REDIS_URL'] end + def redis_driver + ENV.fetch('REDIS_DRIVER', 'hiredis') == 'ruby' ? :ruby : :hiredis + end + private def raw_connection - Redis.new(url: url, driver: :hiredis) + Redis.new(url: url, driver: redis_driver) end end diff --git a/app/lib/rss/channel.rb b/app/lib/rss/channel.rb index 9013ed066a..518ea71405 100644 --- a/app/lib/rss/channel.rb +++ b/app/lib/rss/channel.rb @@ -2,7 +2,7 @@ class RSS::Channel < RSS::Element def initialize - super() + super @root = create_element('channel') end diff --git a/app/lib/rss/item.rb b/app/lib/rss/item.rb index 6739a2c184..8be8d4bf35 100644 --- a/app/lib/rss/item.rb +++ b/app/lib/rss/item.rb @@ -2,7 +2,7 @@ class RSS::Item < RSS::Element def initialize - super() + super @root = create_element('item') end diff --git a/app/lib/scope_transformer.rb b/app/lib/scope_transformer.rb index adcb711f8a..7dda709229 100644 --- a/app/lib/scope_transformer.rb +++ b/app/lib/scope_transformer.rb @@ -11,6 +11,9 @@ class ScopeTransformer < Parslet::Transform @namespace = scope[:namespace]&.to_s @access = scope[:access] ? [scope[:access].to_s] : DEFAULT_ACCESS.dup @term = scope[:term]&.to_s || DEFAULT_TERM + + # # override for profile scope which is read only + @access = %w(read) if @term == 'profile' end def key diff --git a/app/lib/text_formatter.rb b/app/lib/text_formatter.rb index 581ee835b3..2b3febc219 100644 --- a/app/lib/text_formatter.rb +++ b/app/lib/text_formatter.rb @@ -50,6 +50,7 @@ class TextFormatter class << self include ERB::Util + include ActionView::Helpers::TagHelper def shortened_link(url, rel_me: false) url = Addressable::URI.parse(url).to_s @@ -60,9 +61,11 @@ class TextFormatter suffix = url[prefix.length + 30..] cutoff = url[prefix.length..].length > 30 - <<~HTML.squish.html_safe # rubocop:disable Rails/OutputSafety - #{h(display_url)} - HTML + tag.a href: url, target: '_blank', rel: rel.join(' '), translate: 'no' do + tag.span(prefix, class: 'invisible') + + tag.span(display_url, class: (cutoff ? 'ellipsis' : '')) + + tag.span(suffix, class: 'invisible') + end rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError h(url) end diff --git a/app/lib/themes.rb b/app/lib/themes.rb index 243ffb9ab9..b6da980733 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/access_tokens_vacuum.rb b/app/lib/vacuum/access_tokens_vacuum.rb index a224f6d638..281ae22bf0 100644 --- a/app/lib/vacuum/access_tokens_vacuum.rb +++ b/app/lib/vacuum/access_tokens_vacuum.rb @@ -9,12 +9,12 @@ class Vacuum::AccessTokensVacuum private def vacuum_revoked_access_tokens! - Doorkeeper::AccessToken.where.not(expires_in: nil).where('created_at + make_interval(secs => expires_in) < NOW()').in_batches.delete_all - Doorkeeper::AccessToken.where.not(revoked_at: nil).where('revoked_at < NOW()').in_batches.delete_all + Doorkeeper::AccessToken.expired.in_batches.delete_all + Doorkeeper::AccessToken.revoked.in_batches.delete_all end def vacuum_revoked_access_grants! - Doorkeeper::AccessGrant.where.not(expires_in: nil).where('created_at + make_interval(secs => expires_in) < NOW()').in_batches.delete_all - Doorkeeper::AccessGrant.where.not(revoked_at: nil).where('revoked_at < NOW()').in_batches.delete_all + Doorkeeper::AccessGrant.expired.in_batches.delete_all + Doorkeeper::AccessGrant.revoked.in_batches.delete_all end end diff --git a/app/lib/vacuum/applications_vacuum.rb b/app/lib/vacuum/applications_vacuum.rb deleted file mode 100644 index ba88655f16..0000000000 --- a/app/lib/vacuum/applications_vacuum.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true - -class Vacuum::ApplicationsVacuum - def perform - Doorkeeper::Application.where(owner_id: nil) - .where.missing(:created_users, :access_tokens, :access_grants) - .where(created_at: ...1.day.ago) - .in_batches.delete_all - end -end diff --git a/app/lib/vacuum/feeds_vacuum.rb b/app/lib/vacuum/feeds_vacuum.rb index fb0b8a8472..4292157601 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 ffb9449a42..700bd81847 100644 --- a/app/lib/vacuum/imports_vacuum.rb +++ b/app/lib/vacuum/imports_vacuum.rb @@ -9,10 +9,10 @@ class Vacuum::ImportsVacuum private def clean_unconfirmed_imports! - BulkImport.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! - BulkImport.where('created_at <= ?', 1.week.ago).reorder(nil).in_batches.delete_all + BulkImport.where(created_at: ..1.week.ago).reorder(nil).in_batches.delete_all end end diff --git a/app/lib/vacuum/statuses_vacuum.rb b/app/lib/vacuum/statuses_vacuum.rb index ad1de07380..92d3ccf4f4 100644 --- a/app/lib/vacuum/statuses_vacuum.rb +++ b/app/lib/vacuum/statuses_vacuum.rb @@ -34,7 +34,7 @@ class Vacuum::StatusesVacuum def statuses_scope Status.unscoped.kept .joins(:account).merge(Account.remote) - .where('statuses.id < ?', retention_period_as_id) + .where(statuses: { id: ...retention_period_as_id }) end def retention_period_as_id diff --git a/app/lib/video_metadata_extractor.rb b/app/lib/video_metadata_extractor.rb index f27d34868a..2155766251 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 @@ -41,8 +41,8 @@ class VideoMetadataExtractor @colorspace = video_stream[:pix_fmt] @width = video_stream[:width] @height = video_stream[:height] - @frame_rate = video_stream[:avg_frame_rate] == '0/0' ? nil : Rational(video_stream[:avg_frame_rate]) - @r_frame_rate = video_stream[:r_frame_rate] == '0/0' ? nil : Rational(video_stream[:r_frame_rate]) + @frame_rate = parse_framerate(video_stream[:avg_frame_rate]) + @r_frame_rate = parse_framerate(video_stream[:r_frame_rate]) # For some video streams the frame_rate reported by `ffprobe` will be 0/0, but for these streams we # should use `r_frame_rate` instead. Video screencast generated by Gnome Screencast have this issue. @frame_rate ||= @r_frame_rate @@ -55,4 +55,10 @@ class VideoMetadataExtractor @invalid = true if @metadata.key?(:error) end + + def parse_framerate(raw) + Rational(raw) + rescue ZeroDivisionError + nil + end end diff --git a/app/mailers/admin_mailer.rb b/app/mailers/admin_mailer.rb index 2a6fbb0ab7..8dd7b6e59f 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' @@ -61,6 +65,12 @@ class AdminMailer < ApplicationMailer end end + def auto_close_registrations + locale_for_account(@me) do + mail subject: default_i18n_subject(instance: @instance) + end + end + private def process_params diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 3b1a085cb8..81a2c0c6d0 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -5,10 +5,10 @@ class UserMailer < Devise::Mailer helper :accounts helper :application - helper :instance - helper :statuses helper :formatting + helper :instance helper :routing + helper :statuses before_action :set_instance @@ -135,6 +135,12 @@ class UserMailer < Devise::Mailer return unless @resource.active_for_authentication? + @suggestions = AccountSuggestions.new(@resource.account).get(5) + @tags = Trends.tags.query.allowed.limit(5) + @has_account_fields = @resource.account.display_name.present? || @resource.account.note.present? || @resource.account.avatar.present? + @has_active_relationships = @resource.account.active_relationships.exists? + @has_statuses = @resource.account.statuses.exists? + I18n.with_locale(locale) do mail subject: default_i18n_subject end diff --git a/app/models/account.rb b/app/models/account.rb index 442d4a431d..8a990bb831 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -64,11 +64,16 @@ class Account < ApplicationRecord ) BACKGROUND_REFRESH_INTERVAL = 1.week.freeze + DEFAULT_FIELDS_SIZE = 4 + INSTANCE_ACTOR_ID = -99 USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i MENTION_RE = %r{(? { local? && will_save_change_to_username? && actor_type != 'Application' } + validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: USERNAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' } 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: 4 }, if: -> { local? && will_save_change_to_fields? } + validates :display_name, length: { maximum: DISPLAY_NAME_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_display_name? } + validates :note, note_length: { maximum: NOTE_LENGTH_LIMIT }, if: -> { local? && will_save_change_to_note? } + 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 @@ -110,6 +115,7 @@ class Account < ApplicationRecord normalizes :username, with: ->(username) { username.squish } + scope :without_internal, -> { where(id: 1...) } scope :remote, -> { where.not(domain: nil) } scope :local, -> { where(domain: nil) } scope :partitioned, -> { order(Arel.sql('row_number() over (partition by domain)')) } @@ -118,7 +124,7 @@ class Account < ApplicationRecord scope :sensitized, -> { where.not(sensitized_at: nil) } scope :without_suspended, -> { where(suspended_at: nil) } scope :without_silenced, -> { where(silenced_at: nil) } - scope :without_instance_actor, -> { where.not(id: -99) } + scope :without_instance_actor, -> { where.not(id: INSTANCE_ACTOR_ID) } scope :recent, -> { reorder(id: :desc) } scope :bots, -> { where(actor_type: %w(Application Service)) } scope :groups, -> { where(actor_type: 'Group') } @@ -130,12 +136,14 @@ 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) } + scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) } + scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) } after_update_commit :trigger_update_webhooks @@ -176,7 +184,7 @@ class Account < ApplicationRecord end def instance_actor? - id == -99 + id == INSTANCE_ACTOR_ID end alias bot bot? @@ -350,8 +358,6 @@ class Account < ApplicationRecord self[:fields] = fields end - DEFAULT_FIELDS_SIZE = 4 - def build_fields return if fields.size >= DEFAULT_FIELDS_SIZE @@ -440,7 +446,7 @@ class Account < ApplicationRecord end def inboxes - urls = reorder(nil).where(protocol: :activitypub).group(:preferred_inbox_url).pluck(Arel.sql("coalesce(nullif(accounts.shared_inbox_url, ''), accounts.inbox_url) AS preferred_inbox_url")) + urls = reorder(nil).activitypub.group(:preferred_inbox_url).pluck(Arel.sql("coalesce(nullif(accounts.shared_inbox_url, ''), accounts.inbox_url) AS preferred_inbox_url")) DeliveryFailureTracker.without_unavailable(urls) end diff --git a/app/models/account_moderation_note.rb b/app/models/account_moderation_note.rb index ff399bab0c..79b8b4d25e 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 = 2_000 + 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 9bc704d988..317e6873fa 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_relationship_severance_event.rb b/app/models/account_relationship_severance_event.rb new file mode 100644 index 0000000000..c1269fad6d --- /dev/null +++ b/app/models/account_relationship_severance_event.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# +# == Schema Information +# +# Table name: account_relationship_severance_events +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) not null +# relationship_severance_event_id :bigint(8) not null +# created_at :datetime not null +# updated_at :datetime not null +# followers_count :integer default(0), not null +# following_count :integer default(0), not null +# +class AccountRelationshipSeveranceEvent < ApplicationRecord + self.ignored_columns += %w( + relationships_count + ) + + belongs_to :account + belongs_to :relationship_severance_event + + has_many :severed_relationships, through: :relationship_severance_event + + delegate :type, + :target_name, + :purged, + :purged?, + to: :relationship_severance_event, + prefix: false + + before_create :set_relationships_count! + + private + + def set_relationships_count! + self.followers_count = severed_relationships.about_local_account(account).passive.count + self.following_count = severed_relationships.about_local_account(account).active.count + end +end diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb index 0fea7732e9..14aa7ef800 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_suggestions/friends_of_friends_source.rb b/app/models/account_suggestions/friends_of_friends_source.rb index 28d0ab99b3..825b24f419 100644 --- a/app/models/account_suggestions/friends_of_friends_source.rb +++ b/app/models/account_suggestions/friends_of_friends_source.rb @@ -1,8 +1,13 @@ # frozen_string_literal: true class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source - def get(account, limit: 10) - Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, key] } + def get(account, limit: DEFAULT_LIMIT) + source_query(account, limit: limit) + .map { |id, _frequency, _followers_count| [id, key] } + end + + def source_query(account, limit: DEFAULT_LIMIT) + Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, row.frequency, row.followers_count] } WITH first_degree AS ( SELECT target_account_id FROM follows @@ -10,12 +15,16 @@ class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source WHERE account_id = :id AND NOT target_accounts.hide_collections ) - SELECT accounts.id, COUNT(*) AS frequency + SELECT accounts.id, COUNT(*) AS frequency, account_stats.followers_count as followers_count FROM accounts JOIN follows ON follows.target_account_id = accounts.id JOIN account_stats ON account_stats.account_id = accounts.id LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = :id WHERE follows.account_id IN (SELECT * FROM first_degree) + AND NOT EXISTS (SELECT 1 FROM blocks b WHERE b.target_account_id = follows.target_account_id AND b.account_id = :id) + AND NOT EXISTS (SELECT 1 FROM blocks b WHERE b.target_account_id = :id AND b.account_id = follows.target_account_id) + AND NOT EXISTS (SELECT 1 FROM mutes m WHERE m.target_account_id = follows.target_account_id AND m.account_id = :id) + AND (accounts.domain IS NULL OR NOT EXISTS (SELECT 1 FROM account_domain_blocks b WHERE b.account_id = :id AND b.domain = accounts.domain)) AND NOT EXISTS (SELECT 1 FROM follows f WHERE f.target_account_id = follows.target_account_id AND f.account_id = :id) AND follows.target_account_id <> :id AND accounts.discoverable diff --git a/app/models/account_suggestions/global_source.rb b/app/models/account_suggestions/global_source.rb index d68f285e4f..c05bcf2ce8 100644 --- a/app/models/account_suggestions/global_source.rb +++ b/app/models/account_suggestions/global_source.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class AccountSuggestions::GlobalSource < AccountSuggestions::Source - def get(account, limit: 10) + def get(account, limit: DEFAULT_LIMIT) FollowRecommendation.localized(content_locale).joins(:account).merge(base_account_scope(account)).order(rank: :desc).limit(limit).pluck(:account_id, :reason) end diff --git a/app/models/account_suggestions/setting_source.rb b/app/models/account_suggestions/setting_source.rb index 4b7275bf7a..6143481723 100644 --- a/app/models/account_suggestions/setting_source.rb +++ b/app/models/account_suggestions/setting_source.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true class AccountSuggestions::SettingSource < AccountSuggestions::Source - def get(account, limit: 10) + def get(account, limit: DEFAULT_LIMIT) if setting_enabled? - base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle) + base_account_scope(account).merge(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle) else [] end @@ -25,11 +25,9 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source def setting_to_where_condition usernames_and_domains.map do |(username, domain)| - Arel::Nodes::Grouping.new( - Account.arel_table[:username].lower.eq(username.downcase).and( - Account.arel_table[:domain].lower.eq(domain&.downcase) - ) - ) + Account + .with_username(username) + .with_domain(domain) end.reduce(:or) end diff --git a/app/models/account_suggestions/similar_profiles_source.rb b/app/models/account_suggestions/similar_profiles_source.rb index 733c5f0bbc..7ecdd607e5 100644 --- a/app/models/account_suggestions/similar_profiles_source.rb +++ b/app/models/account_suggestions/similar_profiles_source.rb @@ -47,11 +47,12 @@ class AccountSuggestions::SimilarProfilesSource < AccountSuggestions::Source end end - def get(account, limit: 10) + def get(account, limit: DEFAULT_LIMIT) recently_followed_account_ids = account.active_relationships.recent.limit(5).pluck(:target_account_id) if Chewy.enabled? && !recently_followed_account_ids.empty? - QueryBuilder.new(recently_followed_account_ids, account).build.limit(limit).hits.pluck('_id').map(&:to_i).zip([key].cycle) + ids_from_es = QueryBuilder.new(recently_followed_account_ids, account).build.limit(limit).hits.pluck('_id').map(&:to_i) + base_account_scope(account).where(id: ids_from_es).pluck(:id).zip([key].cycle) else [] end diff --git a/app/models/account_suggestions/source.rb b/app/models/account_suggestions/source.rb index d83f5e3773..7afc4c80ed 100644 --- a/app/models/account_suggestions/source.rb +++ b/app/models/account_suggestions/source.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class AccountSuggestions::Source + DEFAULT_LIMIT = 10 + def get(_account, **kwargs) raise NotImplementedError end @@ -10,6 +12,8 @@ class AccountSuggestions::Source def base_account_scope(account) Account .searchable + .where(discoverable: true) + .without_silenced .where.not(follows_sql, id: account.id) .where.not(follow_requests_sql, id: account.id) .not_excluded_by_account(account) diff --git a/app/models/account_warning.rb b/app/models/account_warning.rb index a54387a562..7aa474887b 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 2b5560e2eb..3700ce4cd6 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/action_log_filter.rb b/app/models/admin/action_log_filter.rb index f581af74e8..fc984b2445 100644 --- a/app/models/admin/action_log_filter.rb +++ b/app/models/admin/action_log_filter.rb @@ -59,6 +59,7 @@ class Admin::ActionLogFilter unsuspend_account: { target_type: 'Account', action: 'unsuspend' }.freeze, update_announcement: { target_type: 'Announcement', action: 'update' }.freeze, update_custom_emoji: { target_type: 'CustomEmoji', action: 'update' }.freeze, + update_report: { target_type: 'Report', action: 'update' }.freeze, update_status: { target_type: 'Status', action: 'update' }.freeze, update_user_role: { target_type: 'UserRole', action: 'update' }.freeze, update_ip_block: { target_type: 'IpBlock', action: 'update' }.freeze, diff --git a/app/models/admin/import.rb b/app/models/admin/import.rb index 0fd4bdb824..c12c9a86b9 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 8a8e2fa378..4a10001935 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 4708785e7d..8d20e4f6ab 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 e630570020..54923ed081 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/appeal.rb b/app/models/appeal.rb index 395056b76f..fafa75e69d 100644 --- a/app/models/appeal.rb +++ b/app/models/appeal.rb @@ -18,6 +18,8 @@ class Appeal < ApplicationRecord MAX_STRIKE_AGE = 20.days + TEXT_LENGTH_LIMIT = 2_000 + belongs_to :account belongs_to :strike, class_name: 'AccountWarning', foreign_key: 'account_warning_id', inverse_of: :appeal @@ -26,7 +28,7 @@ class Appeal < ApplicationRecord belongs_to :rejected_by_account end - validates :text, presence: true, length: { maximum: 2_000 } + validates :text, presence: true, length: { maximum: TEXT_LENGTH_LIMIT } validates :account_warning_id, uniqueness: true validate :validate_time_frame, on: :create diff --git a/app/models/application_record.rb b/app/models/application_record.rb index 014a73997d..299aad6340 100644 --- a/app/models/application_record.rb +++ b/app/models/application_record.rb @@ -22,4 +22,10 @@ class ApplicationRecord < ActiveRecord::Base value end end + + # Prevent implicit serialization in ActiveModel::Serializer or other code paths. + # This is a hardening step to avoid accidental leaking of attributes. + def as_json + raise NotImplementedError + end end diff --git a/app/models/bulk_import.rb b/app/models/bulk_import.rb index 4cd228705a..9b3f4c8a3a 100644 --- a/app/models/bulk_import.rb +++ b/app/models/bulk_import.rb @@ -38,7 +38,7 @@ class BulkImport < ApplicationRecord scheduled: 1, in_progress: 2, finished: 3, - } + }, prefix: true validates :type, presence: true diff --git a/app/models/concerns/account/associations.rb b/app/models/concerns/account/associations.rb index 2bb6fed5ad..1c67b07e51 100644 --- a/app/models/concerns/account/associations.rb +++ b/app/models/concerns/account/associations.rb @@ -15,10 +15,15 @@ module Account::Associations has_many :favourites, inverse_of: :account, dependent: :destroy has_many :bookmarks, inverse_of: :account, dependent: :destroy has_many :mentions, inverse_of: :account, dependent: :destroy - has_many :notifications, inverse_of: :account, dependent: :destroy has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy + # Notifications + has_many :notifications, inverse_of: :account, dependent: :destroy + has_one :notification_policy, inverse_of: :account, dependent: :destroy + has_many :notification_permissions, inverse_of: :account, dependent: :destroy + has_many :notification_requests, inverse_of: :account, dependent: :destroy + # Pinned statuses has_many :status_pins, inverse_of: :account, dependent: :destroy has_many :pinned_statuses, -> { reorder('status_pins.created_at DESC') }, through: :status_pins, class_name: 'Status', source: :status @@ -57,7 +62,7 @@ module Account::Associations has_many :aliases, class_name: 'AccountAlias', dependent: :destroy, inverse_of: :account # Hashtags - has_and_belongs_to_many :tags + has_and_belongs_to_many :tags # rubocop:disable Rails/HasAndBelongsToMany has_many :featured_tags, -> { includes(:tag) }, dependent: :destroy, inverse_of: :account # Account deletion requests diff --git a/app/models/concerns/account/counters.rb b/app/models/concerns/account/counters.rb index 4488398128..536d5ca7bc 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/finder_concern.rb b/app/models/concerns/account/finder_concern.rb index 7faaddeb43..249a7b5fd1 100644 --- a/app/models/concerns/account/finder_concern.rb +++ b/app/models/concerns/account/finder_concern.rb @@ -13,11 +13,11 @@ module Account::FinderConcern end def representative - actor = Account.find(-99).tap(&:ensure_keys!) + actor = Account.find(Account::INSTANCE_ACTOR_ID).tap(&:ensure_keys!) actor.update!(username: 'mastodon.internal') if actor.username.include?(':') actor rescue ActiveRecord::RecordNotFound - Account.create!(id: -99, actor_type: 'Application', locked: true, username: 'mastodon.internal') + Account.create!(id: Account::INSTANCE_ACTOR_ID, actor_type: 'Application', locked: true, username: 'mastodon.internal') end def find_local(username) @@ -25,42 +25,11 @@ module Account::FinderConcern end def find_remote(username, domain) - AccountFinder.new(username, domain).account - end - end - - class AccountFinder - attr_reader :username, :domain - - def initialize(username, domain) - @username = username - @domain = domain - end - - def account - scoped_accounts.order(id: :asc).take - end - - private - - def scoped_accounts - Account.unscoped.tap do |scope| - scope.merge! with_usernames - scope.merge! matching_username - scope.merge! matching_domain - end - end - - def with_usernames - Account.where.not(Account.arel_table[:username].lower.eq '') - end - - def matching_username - Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase) - end - - def matching_domain - Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase)) + Account + .with_username(username) + .with_domain(domain) + .order(id: :asc) + .take end end end diff --git a/app/models/concerns/account/interactions.rb b/app/models/concerns/account/interactions.rb index 5b05c31e03..536afba17f 100644 --- a/app/models/concerns/account/interactions.rb +++ b/app/models/concerns/account/interactions.rb @@ -83,6 +83,11 @@ module Account::Interactions has_many :following, -> { order('follows.id desc') }, through: :active_relationships, source: :target_account has_many :followers, -> { order('follows.id desc') }, through: :passive_relationships, source: :account + with_options class_name: 'SeveredRelationship', dependent: :destroy do + has_many :severed_relationships, foreign_key: 'local_account_id', inverse_of: :local_account + has_many :remote_severed_relationships, foreign_key: 'remote_account_id', inverse_of: :remote_account + end + # Account notes has_many :account_notes, dependent: :destroy @@ -178,7 +183,7 @@ module Account::Interactions end def unblock_domain!(other_domain) - block = domain_blocks.find_by(domain: other_domain) + block = domain_blocks.find_by(domain: normalized_domain(other_domain)) block&.destroy end @@ -242,10 +247,6 @@ module Account::Interactions status_pins.exists?(status: status) end - def endorsed?(account) - account_pins.exists?(target_account: account) - end - def status_matches_filters(status) active_filters = CustomFilter.cached_filters_for(id) CustomFilter.apply_cached_filters(active_filters, status) @@ -254,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) @@ -300,4 +301,8 @@ module Account::Interactions domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id), }) end + + def normalized_domain(domain) + TagManager.instance.normalize_domain(domain) + end end diff --git a/app/models/concerns/account/merging.rb b/app/models/concerns/account/merging.rb index 960ee1819f..bd8b162238 100644 --- a/app/models/concerns/account/merging.rb +++ b/app/models/concerns/account/merging.rb @@ -27,6 +27,16 @@ module Account::Merging end end + [ + Notification, NotificationPermission, NotificationRequest + ].each do |klass| + klass.where(from_account_id: other_account.id).reorder(nil).find_each do |record| + record.update_attribute(:from_account_id, id) + rescue ActiveRecord::RecordNotUnique + next + end + end + target_classes = [ Follow, FollowRequest, Block, Mute, AccountModerationNote, AccountPin, AccountNote @@ -48,6 +58,18 @@ module Account::Merging record.update_attribute(:account_warning_id, id) end + SeveredRelationship.about_local_account(other_account).reorder(nil).find_each do |record| + record.update_attribute(:local_account_id, id) + rescue ActiveRecord::RecordNotUnique + next + end + + SeveredRelationship.about_remote_account(other_account).reorder(nil).find_each do |record| + record.update_attribute(:remote_account_id, id) + rescue ActiveRecord::RecordNotUnique + next + end + # Some follow relationships have moved, so the cache is stale Rails.cache.delete_matched("followers_hash:#{id}:*") Rails.cache.delete_matched("relationships:#{id}:*") diff --git a/app/models/concerns/account/statuses_search.rb b/app/models/concerns/account/statuses_search.rb index 334b714504..93452b78b0 100644 --- a/app/models/concerns/account/statuses_search.rb +++ b/app/models/concerns/account/statuses_search.rb @@ -31,7 +31,7 @@ module Account::StatusesSearch def add_to_public_statuses_index! return unless Chewy.enabled? - statuses.without_reblogs.where(visibility: :public).reorder(nil).find_in_batches do |batch| + statuses.without_reblogs.public_visibility.reorder(nil).find_in_batches do |batch| PublicStatusesIndex.import(batch) end end diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 3b7db1fcef..a83e178fc4 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -23,7 +23,7 @@ module Attachmentable included do def self.has_attached_file(name, options = {}) # rubocop:disable Naming/PredicateName - super(name, options) + super send(:"before_#{name}_validate", prepend: true) do attachment = send(name) @@ -69,7 +69,7 @@ module Attachmentable original_extension = Paperclip::Interpolations.extension(attachment, :original) proper_extension = extensions_for_mime_type.first.to_s extension = extensions_for_mime_type.include?(original_extension) ? original_extension : proper_extension - extension = 'jpeg' if extension == 'jpe' + extension = 'jpeg' if ['jpe', 'jfif'].include?(extension) extension end diff --git a/app/models/concerns/browser_detection.rb b/app/models/concerns/browser_detection.rb new file mode 100644 index 0000000000..d42d0a5c99 --- /dev/null +++ b/app/models/concerns/browser_detection.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module BrowserDetection + extend ActiveSupport::Concern + + included do + before_save :assign_user_agent + end + + def detection + @detection ||= Browser.new(user_agent) + end + + def browser + detection.id + end + + def platform + detection.platform.id + end + + private + + def assign_user_agent + self.user_agent ||= '' + end +end diff --git a/app/models/concerns/cacheable.rb b/app/models/concerns/cacheable.rb index d7524cdfd0..0633f20c77 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 0000000000..79b22f11f1 --- /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/domain_normalizable.rb b/app/models/concerns/domain_normalizable.rb index 8e244c1d87..76f91c5b64 100644 --- a/app/models/concerns/domain_normalizable.rb +++ b/app/models/concerns/domain_normalizable.rb @@ -5,6 +5,18 @@ module DomainNormalizable included do before_validation :normalize_domain + + scope :by_domain_length, -> { order(domain_char_length.desc) } + end + + class_methods do + def domain_char_length + Arel.sql( + <<~SQL.squish + CHAR_LENGTH(domain) + SQL + ) + end end private diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb index c64fc7d807..26740e8213 100644 --- a/app/models/concerns/expireable.rb +++ b/app/models/concerns/expireable.rb @@ -4,7 +4,7 @@ module Expireable extend ActiveSupport::Concern included do - scope :expired, -> { where.not(expires_at: nil).where('expires_at < ?', Time.now.utc) } + scope :expired, -> { where.not(expires_at: nil).where(expires_at: ...Time.now.utc) } def expires_in return @expires_in if defined?(@expires_in) diff --git a/app/models/concerns/legacy_otp_secret.rb b/app/models/concerns/legacy_otp_secret.rb new file mode 100644 index 0000000000..466c4ec9bb --- /dev/null +++ b/app/models/concerns/legacy_otp_secret.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +# TODO: This file is here for legacy support during devise-two-factor upgrade. +# It should be removed after all records have been migrated. + +module LegacyOtpSecret + extend ActiveSupport::Concern + + private + + # Decrypt and return the `encrypted_otp_secret` attribute which was used in + # prior versions of devise-two-factor + # @return [String] The decrypted OTP secret + def legacy_otp_secret + return nil unless self[:encrypted_otp_secret] + return nil unless self.class.otp_secret_encryption_key + + hmac_iterations = 2000 # a default set by the Encryptor gem + key = self.class.otp_secret_encryption_key + salt = Base64.decode64(encrypted_otp_secret_salt) + iv = Base64.decode64(encrypted_otp_secret_iv) + + raw_cipher_text = Base64.decode64(encrypted_otp_secret) + # The last 16 bytes of the ciphertext are the authentication tag - we use + # Galois Counter Mode which is an authenticated encryption mode + cipher_text = raw_cipher_text[0..-17] + auth_tag = raw_cipher_text[-16..-1] # rubocop:disable Style/SlicingWithRange + + # this alrorithm lifted from + # https://github.com/attr-encrypted/encryptor/blob/master/lib/encryptor.rb#L54 + + # create an OpenSSL object which will decrypt the AES cipher with 256 bit + # keys in Galois Counter Mode (GCM). See + # https://ruby.github.io/openssl/OpenSSL/Cipher.html + cipher = OpenSSL::Cipher.new('aes-256-gcm') + + # tell the cipher we want to decrypt. Symmetric algorithms use a very + # similar process for encryption and decryption, hence the same object can + # do both. + cipher.decrypt + + # Use a Password-Based Key Derivation Function to generate the key actually + # used for encryptoin from the key we got as input. + cipher.key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(key, salt, hmac_iterations, cipher.key_len) + + # set the Initialization Vector (IV) + cipher.iv = iv + + # The tag must be set after calling Cipher#decrypt, Cipher#key= and + # Cipher#iv=, but before calling Cipher#final. After all decryption is + # performed, the tag is verified automatically in the call to Cipher#final. + # + # If the auth_tag does not verify, then #final will raise OpenSSL::Cipher::CipherError + cipher.auth_tag = auth_tag + + # auth_data must be set after auth_tag has been set when decrypting See + # http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/Cipher.html#method-i-auth_data-3D + # we are not adding any authenticated data but OpenSSL docs say this should + # still be called. + cipher.auth_data = '' + + # #update is (somewhat confusingly named) the method which actually + # performs the decryption on the given chunk of data. Our OTP secret is + # short so we only need to call it once. + # + # It is very important that we call #final because: + # + # 1. The authentication tag is checked during the call to #final + # 2. Block based cipher modes (e.g. CBC) work on fixed size chunks. We need + # to call #final to get it to process the last chunk properly. The output + # of #final should be appended to the decrypted value. This isn't + # required for streaming cipher modes but including it is a best practice + # so that your code will continue to function correctly even if you later + # change to a block cipher mode. + cipher.update(cipher_text) + cipher.final + end +end diff --git a/app/models/concerns/ranked_trend.rb b/app/models/concerns/ranked_trend.rb new file mode 100644 index 0000000000..add36afb0c --- /dev/null +++ b/app/models/concerns/ranked_trend.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module RankedTrend + extend ActiveSupport::Concern + + included do + scope :by_rank, -> { order(rank: :desc) } + scope :ranked_below, ->(value) { where(rank: ..value) } + end + + class_methods do + def recalculate_ordered_rank + connection + .exec_update(<<~SQL.squish) + UPDATE #{table_name} + SET rank = inner_ordered.calculated_rank + FROM ( + SELECT id, row_number() OVER w AS calculated_rank + FROM #{table_name} + WINDOW w AS ( + PARTITION BY language + ORDER BY score DESC + ) + ) inner_ordered + WHERE #{table_name}.id = inner_ordered.id + SQL + end + end +end diff --git a/app/models/concerns/status/search_concern.rb b/app/models/concerns/status/search_concern.rb index c16db8bd8c..3f31b3b675 100644 --- a/app/models/concerns/status/search_concern.rb +++ b/app/models/concerns/status/search_concern.rb @@ -4,7 +4,7 @@ module Status::SearchConcern extend ActiveSupport::Concern included do - scope :indexable, -> { without_reblogs.where(visibility: :public).joins(:account).where(account: { indexable: true }) } + scope :indexable, -> { without_reblogs.public_visibility.joins(:account).where(account: { indexable: true }) } end def searchable_by diff --git a/app/models/concerns/status/threading_concern.rb b/app/models/concerns/status/threading_concern.rb index 2606fd2f27..478a139d63 100644 --- a/app/models/concerns/status/threading_concern.rb +++ b/app/models/concerns/status/threading_concern.rb @@ -3,6 +3,23 @@ module Status::ThreadingConcern extend ActiveSupport::Concern + class_methods do + def permitted_statuses_from_ids(ids, account, stable: false) + statuses = Status.with_accounts(ids).to_a + account_ids = statuses.map(&:account_id).uniq + domains = statuses.filter_map(&:account_domain).uniq + relations = account&.relations_map(account_ids, domains) || {} + + statuses.reject! { |status| StatusFilter.new(status, account, relations).filtered? } + + if stable + statuses.sort_by! { |status| ids.index(status.id) } + else + statuses + end + end + end + def ancestors(limit, account = nil) find_statuses_from_tree_path(ancestor_ids(limit), account) end @@ -12,7 +29,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 @@ -76,15 +93,7 @@ module Status::ThreadingConcern end def find_statuses_from_tree_path(ids, account, promote: false) - statuses = Status.with_accounts(ids).to_a - account_ids = statuses.map(&:account_id).uniq - domains = statuses.filter_map(&:account_domain).uniq - relations = account&.relations_map(account_ids, domains) || {} - - statuses.reject! { |status| StatusFilter.new(status, account, relations).filtered? } - - # Order ancestors/descendants by tree path - statuses.sort_by! { |status| ids.index(status.id) } + statuses = Status.permitted_statuses_from_ids(ids, account, stable: true) # Bring self-replies to the top if promote diff --git a/app/models/concerns/user/has_settings.rb b/app/models/concerns/user/has_settings.rb index bfa8aa2ca3..65373325f0 100644 --- a/app/models/concerns/user/has_settings.rb +++ b/app/models/concerns/user/has_settings.rb @@ -27,10 +27,6 @@ module User::HasSettings settings['default_sensitive'] end - def setting_unfollow_modal - settings['web.unfollow_modal'] - end - def setting_boost_modal settings['web.reblog_modal'] end diff --git a/app/models/concerns/user/ldap_authenticable.rb b/app/models/concerns/user/ldap_authenticable.rb index 180df9d310..fc1ee78d09 100644 --- a/app/models/concerns/user/ldap_authenticable.rb +++ b/app/models/concerns/user/ldap_authenticable.rb @@ -22,7 +22,7 @@ module User::LdapAuthenticable safe_username = safe_username.gsub(keys, replacement) end - resource = joins(:account).find_by(accounts: { username: safe_username }) + resource = joins(:account).merge(Account.with_username(safe_username)).take if resource.blank? resource = new( diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index 1c9b443959..31ba91ad02 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -39,7 +39,7 @@ class CustomEmoji < ApplicationRecord has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode, inverse_of: false, dependent: nil - has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' } }, validate_media_type: false + has_attached_file :image, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set date:modify +set date:create +set date:timestamp', file_geometry_parser: FastGeometryParser } }, validate_media_type: false, processors: [:lazy_thumbnail] normalizes :domain, with: ->(domain) { domain.downcase } diff --git a/app/models/custom_filter.rb b/app/models/custom_filter.rb index 5e2d152e34..bacf158261 100644 --- a/app/models/custom_filter.rb +++ b/app/models/custom_filter.rb @@ -28,6 +28,8 @@ class CustomFilter < ApplicationRecord account ).freeze + EXPIRATION_DURATIONS = [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].freeze + include Expireable include Redisable @@ -41,17 +43,17 @@ class CustomFilter < ApplicationRecord validates :title, :context, presence: true validate :context_must_be_valid - before_validation :clean_up_contexts + 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! after_commit :invalidate_cache! def expires_in - return @expires_in if defined?(@expires_in) return nil if expires_at.nil? - [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].find { |expires_in| expires_in.from_now >= expires_at } + EXPIRATION_DURATIONS.find { |expires_in| expires_in.from_now >= expires_at } end def irreversible=(value) @@ -66,14 +68,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)) @@ -114,10 +118,6 @@ class CustomFilter < ApplicationRecord private - def clean_up_contexts - self.context = Array(context).map(&:strip).filter_map(&:presence) - end - def context_must_be_valid errors.add(:context, I18n.t('filters.errors.invalid_context')) if invalid_context_value? end diff --git a/app/models/custom_filter_keyword.rb b/app/models/custom_filter_keyword.rb index 979d0b822e..112798b10a 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 0a5650204a..58b61cd79d 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/domain_block.rb b/app/models/domain_block.rb index e310918e9b..b5d1f2e079 100644 --- a/app/models/domain_block.rb +++ b/app/models/domain_block.rb @@ -70,7 +70,7 @@ class DomainBlock < ApplicationRecord segments = uri.normalized_host.split('.') variants = segments.map.with_index { |_, i| segments[i..].join('.') } - where(domain: variants).order(Arel.sql('char_length(domain) desc')).first + where(domain: variants).by_domain_length.first rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError nil end diff --git a/app/models/email_domain_block.rb b/app/models/email_domain_block.rb index 40be59420a..f3a86eae8f 100644 --- a/app/models/email_domain_block.rb +++ b/app/models/email_domain_block.rb @@ -56,7 +56,7 @@ class EmailDomainBlock < ApplicationRecord end def blocking?(allow_with_approval: false) - blocks = EmailDomainBlock.where(domain: domains_with_variants, allow_with_approval: allow_with_approval).order(Arel.sql('char_length(domain) desc')) + blocks = EmailDomainBlock.where(domain: domains_with_variants, allow_with_approval: allow_with_approval).by_domain_length blocks.each { |block| block.history.add(@attempt_ip) } if @attempt_ip.present? blocks.any? end diff --git a/app/models/featured_tag.rb b/app/models/featured_tag.rb index ea8aa4787c..cdd97205eb 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 d9cab2cd1e..27e1280994 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/admin_settings.rb b/app/models/form/admin_settings.rb index cb37a52217..85b913cf80 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -37,6 +37,8 @@ class Form::AdminSettings status_page_url captcha_enabled authorized_fetch + app_icon + favicon ).freeze INTEGER_KEYS = %i( @@ -63,6 +65,8 @@ class Form::AdminSettings UPLOAD_KEYS = %i( thumbnail mascot + app_icon + favicon ).freeze OVERRIDEN_SETTINGS = { diff --git a/app/models/form/import.rb b/app/models/form/import.rb index fc83d9c58c..3cc4af064f 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 c0cbc58458..ea095a3ac1 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)) } + 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/ip_block.rb b/app/models/ip_block.rb index 9def5b0cde..d6242efbf7 100644 --- a/app/models/ip_block.rb +++ b/app/models/ip_block.rb @@ -23,7 +23,7 @@ class IpBlock < ApplicationRecord sign_up_requires_approval: 5000, sign_up_block: 5500, no_access: 9999, - } + }, prefix: true validates :ip, :severity, presence: true validates :ip, uniqueness: true diff --git a/app/models/link_feed.rb b/app/models/link_feed.rb new file mode 100644 index 0000000000..32efb331b6 --- /dev/null +++ b/app/models/link_feed.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +class LinkFeed < PublicFeed + # @param [PreviewCard] preview_card + # @param [Account] account + # @param [Hash] options + def initialize(preview_card, account, options = {}) + @preview_card = preview_card + super(account, options) + end + + # @param [Integer] limit + # @param [Integer] max_id + # @param [Integer] since_id + # @param [Integer] min_id + # @return [Array] + def get(limit, max_id = nil, since_id = nil, min_id = nil) + scope = public_scope + + scope.merge!(discoverable) + scope.merge!(attached_to_preview_card) + + scope.to_a_paginated_by_id(limit, max_id: max_id, since_id: since_id, min_id: min_id) + end + + private + + def attached_to_preview_card + Status.joins(:preview_cards_status).where(preview_cards_status: { preview_card_id: @preview_card.id }) + end + + def discoverable + Account.discoverable + end +end diff --git a/app/models/login_activity.rb b/app/models/login_activity.rb index 654dd623ad..240d571c0e 100644 --- a/app/models/login_activity.rb +++ b/app/models/login_activity.rb @@ -16,21 +16,11 @@ # class LoginActivity < ApplicationRecord + include BrowserDetection + enum :authentication_method, { password: 'password', otp: 'otp', webauthn: 'webauthn', sign_in_token: 'sign_in_token', omniauth: 'omniauth' } belongs_to :user validates :authentication_method, inclusion: { in: authentication_methods.keys } - - def detection - @detection ||= Browser.new(user_agent) - end - - def browser - detection.id - end - - def platform - detection.platform.id - end end diff --git a/app/models/mention.rb b/app/models/mention.rb index 2348b2905c..af9bb7378b 100644 --- a/app/models/mention.rb +++ b/app/models/mention.rb @@ -5,10 +5,10 @@ # Table name: mentions # # id :bigint(8) not null, primary key -# status_id :bigint(8) +# status_id :bigint(8) not null # created_at :datetime not null # updated_at :datetime not null -# account_id :bigint(8) +# account_id :bigint(8) not null # silent :boolean default(FALSE), not null # diff --git a/app/models/notification.rb b/app/models/notification.rb index 54212d675f..01abe74f5e 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -12,6 +12,8 @@ # account_id :bigint(8) not null # from_account_id :bigint(8) not null # type :string +# filtered :boolean default(FALSE), not null +# group_key :string # class Notification < ApplicationRecord @@ -28,18 +30,46 @@ class Notification < ApplicationRecord 'Poll' => :poll, }.freeze - TYPES = %i( - mention - status - reblog - follow - follow_request - favourite - poll - update - admin.sign_up - admin.report - ).freeze + PROPERTIES = { + mention: { + filterable: true, + }.freeze, + status: { + filterable: false, + }.freeze, + reblog: { + filterable: true, + }.freeze, + follow: { + filterable: true, + }.freeze, + follow_request: { + filterable: true, + }.freeze, + favourite: { + filterable: true, + }.freeze, + poll: { + filterable: false, + }.freeze, + update: { + filterable: false, + }.freeze, + severed_relationships: { + filterable: false, + }.freeze, + moderation_warning: { + filterable: false, + }.freeze, + 'admin.sign_up': { + filterable: false, + }.freeze, + 'admin.report': { + filterable: false, + }.freeze, + }.freeze + + TYPES = PROPERTIES.keys.freeze TARGET_STATUS_INCLUDES_BY_TYPE = { status: :status, @@ -63,6 +93,8 @@ class Notification < ApplicationRecord belongs_to :favourite, inverse_of: :notification 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 } @@ -89,7 +121,7 @@ class Notification < ApplicationRecord end class << self - def browserable(types: [], exclude_types: [], from_account_id: nil) + def browserable(types: [], exclude_types: [], from_account_id: nil, include_filtered: false) requested_types = if types.empty? TYPES else @@ -99,11 +131,75 @@ class Notification < ApplicationRecord requested_types -= exclude_types.map(&:to_sym) all.tap do |scope| + scope.merge!(where(filtered: false)) unless include_filtered || from_account_id.present? scope.merge!(where(from_account_id: from_account_id)) if from_account_id.present? scope.merge!(where(type: requested_types)) unless requested_types.size == TYPES.size end end + # This returns notifications from the request page, but with at most one notification per group. + # Notifications that have no `group_key` each count as a separate group. + def paginate_groups_by_max_id(limit, max_id: nil, since_id: nil) + query = reorder(id: :desc) + query = query.where(id: ...max_id) if max_id.present? + query = query.where(id: (since_id + 1)...) if since_id.present? + + unscoped + .with_recursive( + grouped_notifications: [ + query + .select('notifications.*', "ARRAY[COALESCE(notifications.group_key, 'ungrouped-' || notifications.id)] groups") + .limit(1), + query + .joins('CROSS JOIN grouped_notifications') + .where('array_length(grouped_notifications.groups, 1) < :limit', limit: limit) + .where('notifications.id < grouped_notifications.id') + .where.not("COALESCE(notifications.group_key, 'ungrouped-' || notifications.id) = ANY(grouped_notifications.groups)") + .select('notifications.*', "array_append(grouped_notifications.groups, COALESCE(notifications.group_key, 'ungrouped-' || notifications.id))") + .limit(1), + ] + ) + .from('grouped_notifications AS notifications') + .order(id: :desc) + .limit(limit) + end + + # Differs from :paginate_groups_by_max_id in that it gives the results immediately following min_id, + # whereas since_id gives the items with largest id, but with since_id as a cutoff. + # Results will be in ascending order by id. + def paginate_groups_by_min_id(limit, max_id: nil, min_id: nil) + query = reorder(id: :asc) + query = query.where(id: (min_id + 1)...) if min_id.present? + query = query.where(id: ...max_id) if max_id.present? + + unscoped + .with_recursive( + grouped_notifications: [ + query + .select('notifications.*', "ARRAY[COALESCE(notifications.group_key, 'ungrouped-' || notifications.id)] groups") + .limit(1), + query + .joins('CROSS JOIN grouped_notifications') + .where('array_length(grouped_notifications.groups, 1) < :limit', limit: limit) + .where('notifications.id > grouped_notifications.id') + .where.not("COALESCE(notifications.group_key, 'ungrouped-' || notifications.id) = ANY(grouped_notifications.groups)") + .select('notifications.*', "array_append(grouped_notifications.groups, COALESCE(notifications.group_key, 'ungrouped-' || notifications.id))") + .limit(1), + ] + ) + .from('grouped_notifications AS notifications') + .order(id: :asc) + .limit(limit) + end + + def to_a_grouped_paginated_by_id(limit, options = {}) + if options[:min_id].present? + paginate_groups_by_min_id(limit, min_id: options[:min_id], max_id: options[:max_id]).reverse + else + paginate_groups_by_max_id(limit, max_id: options[:max_id], since_id: options[:since_id]).to_a + end + end + def preload_cache_collection_target_statuses(notifications, &_block) notifications.group_by(&:type).each do |type, grouped_notifications| associations = TARGET_STATUS_INCLUDES_BY_TYPE[type] @@ -144,6 +240,8 @@ class Notification < ApplicationRecord after_initialize :set_from_account before_validation :set_from_account + after_destroy :remove_from_notification_request + private def set_from_account @@ -156,6 +254,16 @@ class Notification < ApplicationRecord self.from_account_id = activity&.status&.account_id when 'Account' self.from_account_id = activity&.id + when 'AccountRelationshipSeveranceEvent', 'AccountWarning' + # These do not really have an originating account, but this is mandatory + # in the data model, and the recipient's account will by definition + # always exist + self.from_account_id = account_id end end + + def remove_from_notification_request + notification_request = NotificationRequest.find_by(account_id: account_id, from_account_id: from_account_id) + notification_request&.reconsider_existence! + end end diff --git a/app/models/notification_group.rb b/app/models/notification_group.rb new file mode 100644 index 0000000000..b1cbd7c19a --- /dev/null +++ b/app/models/notification_group.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class NotificationGroup < ActiveModelSerializers::Model + attributes :group_key, :sample_accounts, :notifications_count, :notification, :most_recent_notification_id + + def self.from_notification(notification, max_id: nil) + if notification.group_key.present? + # TODO: caching and preloading + scope = notification.account.notifications.where(group_key: notification.group_key) + scope = scope.where(id: ..max_id) if max_id.present? + + most_recent_notifications = scope.order(id: :desc).take(3) + most_recent_id = most_recent_notifications.first.id + sample_accounts = most_recent_notifications.map(&:from_account) + notifications_count = scope.count + else + most_recent_id = notification.id + sample_accounts = [notification.from_account] + notifications_count = 1 + end + + NotificationGroup.new( + notification: notification, + group_key: notification.group_key || "ungrouped-#{notification.id}", + sample_accounts: sample_accounts, + notifications_count: notifications_count, + most_recent_notification_id: most_recent_id + ) + end + + delegate :type, + :target_status, + :report, + :account_relationship_severance_event, + :account_warning, + to: :notification, prefix: false +end diff --git a/app/models/notification_permission.rb b/app/models/notification_permission.rb new file mode 100644 index 0000000000..e0001473f8 --- /dev/null +++ b/app/models/notification_permission.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: notification_permissions +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) not null +# from_account_id :bigint(8) not null +# created_at :datetime not null +# updated_at :datetime not null +# +class NotificationPermission < ApplicationRecord + belongs_to :account + belongs_to :from_account, class_name: 'Account' +end diff --git a/app/models/notification_policy.rb b/app/models/notification_policy.rb new file mode 100644 index 0000000000..f10b0c2a81 --- /dev/null +++ b/app/models/notification_policy.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: notification_policies +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) not null +# filter_not_following :boolean default(FALSE), not null +# filter_not_followers :boolean default(FALSE), not null +# filter_new_accounts :boolean default(FALSE), not null +# filter_private_mentions :boolean default(TRUE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class NotificationPolicy < ApplicationRecord + belongs_to :account + + has_many :notification_requests, primary_key: :account_id, foreign_key: :account_id, dependent: nil, inverse_of: false + + attr_reader :pending_requests_count, :pending_notifications_count + + MAX_MEANINGFUL_COUNT = 100 + + def summarize! + @pending_requests_count = pending_notification_requests.first + @pending_notifications_count = pending_notification_requests.last + end + + private + + def pending_notification_requests + @pending_notification_requests ||= notification_requests.where(dismissed: false).limit(MAX_MEANINGFUL_COUNT).pick(Arel.sql('count(*), coalesce(sum(notifications_count), 0)::bigint')) + end +end diff --git a/app/models/notification_request.rb b/app/models/notification_request.rb new file mode 100644 index 0000000000..6e9cae6625 --- /dev/null +++ b/app/models/notification_request.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: notification_requests +# +# id :bigint(8) not null, primary key +# account_id :bigint(8) not null +# from_account_id :bigint(8) not null +# last_status_id :bigint(8) +# notifications_count :bigint(8) default(0), not null +# dismissed :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class NotificationRequest < ApplicationRecord + include Paginable + + MAX_MEANINGFUL_COUNT = 100 + + belongs_to :account + belongs_to :from_account, class_name: 'Account' + belongs_to :last_status, class_name: 'Status' + + before_save :prepare_notifications_count + + def self.preload_cache_collection(requests) + cached_statuses_by_id = yield(requests.filter_map(&:last_status)).index_by(&:id) # Call cache_collection in block + + requests.each do |request| + request.last_status = cached_statuses_by_id[request.last_status_id] unless request.last_status_id.nil? + end + end + + def reconsider_existence! + return if dismissed? + + prepare_notifications_count + + if notifications_count.positive? + save + else + destroy + end + end + + private + + def prepare_notifications_count + self.notifications_count = Notification.where(account: account, from_account: from_account, filtered: true).limit(MAX_MEANINGFUL_COUNT).count + end +end diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb index 9fe02bd168..cbfc393786 100644 --- a/app/models/preview_card.rb +++ b/app/models/preview_card.rb @@ -32,6 +32,7 @@ # link_type :integer # published_at :datetime # image_description :string default(""), not null +# author_account_id :bigint(8) # class PreviewCard < ApplicationRecord @@ -54,8 +55,13 @@ class PreviewCard < ApplicationRecord has_many :statuses, through: :preview_cards_statuses has_one :trend, class_name: 'PreviewCardTrend', inverse_of: :preview_card, dependent: :destroy + belongs_to :author_account, class_name: 'Account', optional: true - has_attached_file :image, processors: [:thumbnail, :blurhash_transcoder], styles: ->(f) { image_styles(f) }, convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, validate_media_type: false + has_attached_file :image, + processors: [Rails.configuration.x.use_vips ? :lazy_thumbnail : :thumbnail, :blurhash_transcoder], + styles: ->(f) { image_styles(f) }, + convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' }, + validate_media_type: false validates :url, presence: true, uniqueness: true, url: true validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES diff --git a/app/models/preview_card_provider.rb b/app/models/preview_card_provider.rb index 8ba24331bb..756707e3f1 100644 --- a/app/models/preview_card_provider.rb +++ b/app/models/preview_card_provider.rb @@ -54,6 +54,6 @@ class PreviewCardProvider < ApplicationRecord def self.matching_domain(domain) segments = domain.split('.') - where(domain: segments.map.with_index { |_, i| segments[i..].join('.') }).order(Arel.sql('char_length(domain) desc')).first + where(domain: segments.map.with_index { |_, i| segments[i..].join('.') }).by_domain_length.first end end diff --git a/app/models/preview_card_trend.rb b/app/models/preview_card_trend.rb index 018400dfa9..58155971a3 100644 --- a/app/models/preview_card_trend.rb +++ b/app/models/preview_card_trend.rb @@ -12,6 +12,10 @@ # language :string # 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 c208d6f664..ba9473db0b 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 @@ -61,7 +61,7 @@ class PublicFeed end def public_scope - Status.with_public_visibility.joins(:account).merge(Account.without_suspended.without_silenced) + Status.public_visibility.joins(:account).merge(Account.without_suspended.without_silenced) end def local_only_scope diff --git a/app/models/relationship_filter.rb b/app/models/relationship_filter.rb index d686f9ed89..828610e46a 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/relationship_severance_event.rb b/app/models/relationship_severance_event.rb new file mode 100644 index 0000000000..30ada25767 --- /dev/null +++ b/app/models/relationship_severance_event.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: relationship_severance_events +# +# id :bigint(8) not null, primary key +# type :integer not null +# target_name :string not null +# purged :boolean default(FALSE), not null +# created_at :datetime not null +# updated_at :datetime not null +# +class RelationshipSeveranceEvent < ApplicationRecord + self.inheritance_column = nil + + has_many :severed_relationships, inverse_of: :relationship_severance_event, dependent: :delete_all + + enum :type, { + domain_block: 0, + user_domain_block: 1, + account_suspension: 2, + } + + scope :about_local_account, ->(account) { where(id: SeveredRelationship.about_local_account(account).select(:relationship_severance_event_id)) } + + def import_from_active_follows!(follows) + import_from_follows!(follows, true) + end + + def import_from_passive_follows!(follows) + import_from_follows!(follows, false) + end + + def affected_local_accounts + Account.where(id: severed_relationships.select(:local_account_id)) + end + + private + + def import_from_follows!(follows, active) + SeveredRelationship.insert_all( + follows.pluck(:account_id, :target_account_id, :show_reblogs, :notify, :languages).map do |account_id, target_account_id, show_reblogs, notify, languages| + { + local_account_id: active ? account_id : target_account_id, + remote_account_id: active ? target_account_id : account_id, + show_reblogs: show_reblogs, + notify: notify, + languages: languages, + relationship_severance_event_id: id, + direction: active ? :active : :passive, + } + end + ) + end +end diff --git a/app/models/report.rb b/app/models/report.rb index df7e3d2efc..3df5a20e18 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 74b46027e8..7361c97e67 100644 --- a/app/models/report_note.rb +++ b/app/models/report_note.rb @@ -13,10 +13,12 @@ # class ReportNote < ApplicationRecord + CONTENT_SIZE_LIMIT = 2_000 + 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 602e5d5874..99a36397aa 100644 --- a/app/models/rule.rb +++ b/app/models/rule.rb @@ -10,13 +10,16 @@ # text :text default(""), not null # created_at :datetime not null # updated_at :datetime not null +# hint :text default(""), not null # 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/session_activation.rb b/app/models/session_activation.rb index c67180d3ba..d0a77daf0a 100644 --- a/app/models/session_activation.rb +++ b/app/models/session_activation.rb @@ -16,6 +16,8 @@ # class SessionActivation < ApplicationRecord + include BrowserDetection + belongs_to :user, inverse_of: :session_activations belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', dependent: :destroy, optional: true belongs_to :web_push_subscription, class_name: 'Web::PushSubscription', dependent: :destroy, optional: true @@ -24,19 +26,6 @@ class SessionActivation < ApplicationRecord to: :access_token, allow_nil: true - def detection - @detection ||= Browser.new(user_agent) - end - - def browser - detection.id - end - - def platform - detection.platform.id - end - - before_save :assign_user_agent before_create :assign_access_token class << self @@ -67,10 +56,6 @@ class SessionActivation < ApplicationRecord private - def assign_user_agent - self.user_agent = '' if user_agent.nil? - end - def assign_access_token self.access_token = Doorkeeper::AccessToken.create!(access_token_attributes) end diff --git a/app/models/severed_relationship.rb b/app/models/severed_relationship.rb new file mode 100644 index 0000000000..64b5b0001b --- /dev/null +++ b/app/models/severed_relationship.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: severed_relationships +# +# id :bigint(8) not null, primary key +# relationship_severance_event_id :bigint(8) not null +# local_account_id :bigint(8) not null +# remote_account_id :bigint(8) not null +# direction :integer not null +# show_reblogs :boolean +# notify :boolean +# languages :string is an Array +# created_at :datetime not null +# updated_at :datetime not null +# +class SeveredRelationship < ApplicationRecord + belongs_to :relationship_severance_event + belongs_to :local_account, class_name: 'Account' + belongs_to :remote_account, class_name: 'Account' + + enum :direction, { + passive: 0, # analogous to `local_account.passive_relationships` + active: 1, # analogous to `local_account.active_relationships` + } + + scope :about_local_account, ->(account) { where(local_account: account) } + scope :about_remote_account, ->(account) { where(remote_account: account) } + + scope :active, -> { where(direction: :active) } + scope :passive, -> { where(direction: :passive) } + + def account + active? ? local_account : remote_account + end + + def target_account + active? ? remote_account : local_account + end +end diff --git a/app/models/site_upload.rb b/app/models/site_upload.rb index 03d472cdb2..6431d1007d 100644 --- a/app/models/site_upload.rb +++ b/app/models/site_upload.rb @@ -19,7 +19,30 @@ class SiteUpload < ApplicationRecord include Attachmentable + FAVICON_SIZES = [16, 32, 48].freeze + APPLE_ICON_SIZES = [57, 60, 72, 76, 114, 120, 144, 152, 167, 180, 1024].freeze + ANDROID_ICON_SIZES = [36, 48, 72, 96, 144, 192, 256, 384, 512].freeze + + APP_ICON_SIZES = (APPLE_ICON_SIZES + ANDROID_ICON_SIZES).uniq.freeze + STYLES = { + app_icon: + APP_ICON_SIZES.to_h do |size| + [:"#{size}", { format: 'png', geometry: "#{size}x#{size}#", file_geometry_parser: FastGeometryParser }] + end.freeze, + + favicon: { + ico: { + format: 'ico', + geometry: '48x48#', + file_geometry_parser: FastGeometryParser, + }.freeze, + }.merge( + FAVICON_SIZES.to_h do |size| + [:"#{size}", { format: 'png', geometry: "#{size}x#{size}#", file_geometry_parser: FastGeometryParser }] + end + ).freeze, + thumbnail: { '@1x': { format: 'png', diff --git a/app/models/status.rb b/app/models/status.rb index 0ec69c8dd1..baa6578005 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -39,6 +39,8 @@ class Status < ApplicationRecord include Status::SnapshotConcern include Status::ThreadingConcern + MEDIA_ATTACHMENTS_LIMIT = 4 + rate_limit by: :account, family: :statuses self.discard_column = :deleted_at @@ -82,7 +84,7 @@ class Status < ApplicationRecord has_many :local_reblogged, -> { merge(Account.local) }, through: :reblogs, source: :account has_many :local_bookmarked, -> { merge(Account.local) }, through: :bookmarks, source: :account - has_and_belongs_to_many :tags + has_and_belongs_to_many :tags # rubocop:disable Rails/HasAndBelongsToMany has_one :preview_cards_status, inverse_of: :status, dependent: :delete @@ -106,12 +108,13 @@ class Status < ApplicationRecord scope :remote, -> { where(local: false).where.not(uri: nil) } scope :local, -> { where(local: true).or(where(uri: nil)) } scope :with_accounts, ->(ids) { where(id: ids).includes(:account) } - scope :without_replies, -> { where('statuses.reply = FALSE OR statuses.in_reply_to_account_id = statuses.account_id') } + scope :without_replies, -> { not_reply.or(reply_to_account) } + scope :not_reply, -> { where(reply: false) } + scope :reply_to_account, -> { where(arel_table[:in_reply_to_account_id].eq arel_table[:account_id]) } scope :without_reblogs, -> { where(statuses: { reblog_of_id: nil }) } - scope :with_public_visibility, -> { where(visibility: :public) } 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) @@ -122,6 +125,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 @@ -152,9 +157,9 @@ class Status < ApplicationRecord :status_stat, :tags, :preloadable_poll, - preview_cards_status: [:preview_card], + preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } }, account: [:account_stat, user: :role], - active_mentions: { account: :account_stat }, + active_mentions: :account, reblog: [ :application, :tags, @@ -162,11 +167,11 @@ class Status < ApplicationRecord :conversation, :status_stat, :preloadable_poll, - preview_cards_status: [:preview_card], + preview_cards_status: { preview_card: { author_account: [:account_stat, user: :role] } }, account: [:account_stat, user: :role], - active_mentions: { account: :account_stat }, + active_mentions: :account, ], - thread: { account: :account_stat } + thread: :account delegate :domain, to: :account, prefix: true @@ -263,7 +268,7 @@ class Status < ApplicationRecord end def reported? - @reported ||= Report.where(target_account: account).unresolved.exists?(['? = ANY(status_ids)', id]) + @reported ||= account.targeted_reports.unresolved.exists?(['? = ANY(status_ids)', id]) || account.strikes.exists?(['? = ANY(status_ids)', id.to_s]) end def emojis @@ -347,38 +352,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? @@ -443,7 +416,6 @@ class Status < ApplicationRecord def set_visibility self.visibility = reblog.visibility if reblog? && visibility.nil? self.visibility = (account.locked? ? :private : :public) if visibility.nil? - self.sensitive = false if sensitive.nil? end def set_conversation diff --git a/app/models/status_trend.rb b/app/models/status_trend.rb index b0f1b6942d..807efec0ff 100644 --- a/app/models/status_trend.rb +++ b/app/models/status_trend.rb @@ -14,6 +14,8 @@ # class StatusTrend < ApplicationRecord + include RankedTrend + belongs_to :status belongs_to :account diff --git a/app/models/tag.rb b/app/models/tag.rb index f2168ae904..3f88cb0680 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -21,8 +21,10 @@ class Tag < ApplicationRecord include Paginable + # rubocop:disable Rails/HasAndBelongsToMany has_and_belongs_to_many :statuses has_and_belongs_to_many :accounts + # rubocop:enable Rails/HasAndBelongsToMany has_many :passive_relationships, class_name: 'TagFollow', inverse_of: :tag, dependent: :destroy has_many :featured_tags, dependent: :destroy, inverse_of: :tag @@ -35,7 +37,7 @@ class Tag < ApplicationRecord HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)' HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}" - HASHTAG_RE = %r{(? { 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 b8cd63557e..6b5831d246 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 b4eae9f702..0650c4109d 100644 --- a/app/models/trends/links.rb +++ b/app/models/trends/links.rb @@ -81,13 +81,13 @@ class Trends::Links < Trends::Base # Now that all trends have up-to-date scores, and all the ones below the threshold have # been removed, we can recalculate their positions - PreviewCardTrend.connection.exec_update('UPDATE preview_card_trends SET rank = t0.calculated_rank FROM (SELECT id, row_number() OVER w AS calculated_rank FROM preview_card_trends WINDOW w AS (PARTITION BY language ORDER BY score DESC)) t0 WHERE preview_card_trends.id = t0.id') + PreviewCardTrend.recalculate_ordered_rank end def request_review PreviewCardTrend.pluck('distinct language').flat_map do |language| - score_at_threshold = PreviewCardTrend.where(language: language, allowed: true).order(rank: :desc).where('rank <= ?', 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/trends/statuses.rb b/app/models/trends/statuses.rb index c47fb8427b..9be6eb13a5 100644 --- a/app/models/trends/statuses.rb +++ b/app/models/trends/statuses.rb @@ -74,12 +74,12 @@ class Trends::Statuses < Trends::Base # Now that all trends have up-to-date scores, and all the ones below the threshold have # been removed, we can recalculate their positions - StatusTrend.connection.exec_update('UPDATE status_trends SET rank = t0.calculated_rank FROM (SELECT id, row_number() OVER w AS calculated_rank FROM status_trends WINDOW w AS (PARTITION BY language ORDER BY score DESC)) t0 WHERE status_trends.id = t0.id') + StatusTrend.recalculate_ordered_rank end def request_review StatusTrend.pluck('distinct language').flat_map do |language| - score_at_threshold = StatusTrend.where(language: language, allowed: true).order(rank: :desc).where('rank <= ?', options[:review_threshold]).first&.score || 0 + score_at_threshold = StatusTrend.where(language: language, allowed: true).by_rank.ranked_below(options[:review_threshold]).first&.score || 0 status_trends = StatusTrend.where(language: language, allowed: false).joins(:status).includes(status: :account) status_trends.filter_map do |trend| diff --git a/app/models/user.rb b/app/models/user.rb index f706c91eff..8bc0b23ce8 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -14,7 +14,6 @@ # sign_in_count :integer default(0), not null # current_sign_in_at :datetime # last_sign_in_at :datetime -# admin :boolean default(FALSE), not null # confirmation_token :string # confirmed_at :datetime # confirmation_sent_at :datetime @@ -29,7 +28,6 @@ # otp_backup_codes :string is an Array # account_id :bigint(8) not null # disabled :boolean default(FALSE), not null -# moderator :boolean default(FALSE), not null # invite_id :bigint(8) # chosen_languages :string is an Array # created_by_application_id :bigint(8) @@ -41,6 +39,7 @@ # role_id :bigint(8) # settings :text # time_zone :string +# otp_secret :string # class User < ApplicationRecord @@ -74,6 +73,8 @@ class User < ApplicationRecord devise :two_factor_authenticatable, otp_secret_encryption_key: Rails.configuration.x.otp_secret + include LegacyOtpSecret # Must be after the above `devise` line in order to override the legacy method + devise :two_factor_backupable, otp_number_of_backup_codes: 10 @@ -97,6 +98,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 @@ -109,14 +112,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') } @@ -129,11 +134,6 @@ class User < ApplicationRecord normalizes :time_zone, with: ->(time_zone) { ActiveSupport::TimeZone[time_zone].nil? ? nil : time_zone } normalizes :chosen_languages, with: ->(chosen_languages) { chosen_languages.compact_blank.presence } - # This avoids a deprecation warning from Rails 5.1 - # It seems possible that a future release of devise-two-factor will - # handle this itself, and this can be removed from our User class. - attribute :otp_secret - has_many :session_activations, dependent: :destroy delegate :can?, to: :role @@ -446,7 +446,7 @@ class User < ApplicationRecord end def sign_up_from_ip_requires_approval? - sign_up_ip.present? && IpBlock.sign_up_requires_approval.exists?(['ip >>= ?', sign_up_ip.to_s]) + sign_up_ip.present? && IpBlock.severity_sign_up_requires_approval.exists?(['ip >>= ?', sign_up_ip.to_s]) end def sign_up_email_requires_approval? @@ -490,7 +490,7 @@ class User < ApplicationRecord BootstrapTimelineWorker.perform_async(account_id) ActivityTracker.increment('activity:accounts:local') ActivityTracker.record('activity:logins', id) - UserMailer.welcome(self).deliver_later + UserMailer.welcome(self).deliver_later(wait: 1.hour) TriggerWebhookWorker.perform_async('account.approved', 'Account', account_id) end diff --git a/app/models/user_invite_request.rb b/app/models/user_invite_request.rb index 2b76c88b94..9dd6775166 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 87b86a24d4..a6da2c0740 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/models/user_role.rb b/app/models/user_role.rb index 89354da542..23cc28b9b7 100644 --- a/app/models/user_role.rb +++ b/app/models/user_role.rb @@ -38,6 +38,9 @@ class UserRole < ApplicationRecord delete_user_data: (1 << 19), }.freeze + EVERYONE_ROLE_ID = -99 + NOBODY_POSITION = -1 + module Flags NONE = 0 ALL = FLAGS.values.reduce(&:|) @@ -94,18 +97,21 @@ class UserRole < ApplicationRecord before_validation :set_position - scope :assignable, -> { where.not(id: -99).order(position: :asc) } + scope :assignable, -> { where.not(id: EVERYONE_ROLE_ID).order(position: :asc) } + scope :highlighted, -> { where(highlighted: true) } + scope :with_color, -> { where.not(color: [nil, '']) } + scope :providing_styles, -> { highlighted.with_color } has_many :users, inverse_of: :role, foreign_key: 'role_id', dependent: :nullify def self.nobody - @nobody ||= UserRole.new(permissions: Flags::NONE, position: -1) + @nobody ||= UserRole.new(permissions: Flags::NONE, position: NOBODY_POSITION) end def self.everyone - UserRole.find(-99) + UserRole.find(EVERYONE_ROLE_ID) rescue ActiveRecord::RecordNotFound - UserRole.create!(id: -99, permissions: Flags::DEFAULT) + UserRole.create!(id: EVERYONE_ROLE_ID, permissions: Flags::DEFAULT) end def self.that_can(*any_of_privileges) @@ -113,7 +119,7 @@ class UserRole < ApplicationRecord end def everyone? - id == -99 + id == EVERYONE_ROLE_ID end def nobody? @@ -168,7 +174,7 @@ class UserRole < ApplicationRecord end def set_position - self.position = -1 if everyone? + self.position = NOBODY_POSITION if everyone? end def validate_own_role_edition diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb index 030cbec4d8..6571632fcd 100644 --- a/app/models/user_settings.rb +++ b/app/models/user_settings.rb @@ -27,7 +27,6 @@ class UserSettings setting :disable_swiping, default: false setting :delete_modal, default: true setting :reblog_modal, default: false - setting :unfollow_modal, default: true setting :reduce_motion, default: false setting :expand_content_warnings, default: false setting :display_media, default: 'default', in: %w(default show_all hide_all) diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb index a3a2ec3f03..ddfd08146e 100644 --- a/app/models/web/push_subscription.rb +++ b/app/models/web/push_subscription.rb @@ -21,10 +21,12 @@ class Web::PushSubscription < ApplicationRecord has_one :session_activation, foreign_key: 'web_push_subscription_id', inverse_of: :web_push_subscription, dependent: nil - validates :endpoint, presence: true + validates :endpoint, presence: true, url: true validates :key_p256dh, presence: true validates :key_auth, presence: true + validates_with WebPushKeyValidator + delegate :locale, to: :associated_user def encrypt(payload) @@ -73,7 +75,7 @@ class Web::PushSubscription < ApplicationRecord class << self def unsubscribe_for(application_id, resource_owner) - access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id, revoked_at: nil).pluck(:id) + access_token_ids = Doorkeeper::AccessToken.where(application_id: application_id, resource_owner_id: resource_owner.id).not_revoked.pluck(:id) where(access_token_id: access_token_ids).delete_all end end diff --git a/app/models/webauthn_credential.rb b/app/models/webauthn_credential.rb index 4fa31ece52..d7ed1b9d40 100644 --- a/app/models/webauthn_credential.rb +++ b/app/models/webauthn_credential.rb @@ -15,9 +15,11 @@ # class WebauthnCredential < ApplicationRecord + SIGN_COUNT_LIMIT = (2**63) + validates :external_id, :public_key, :nickname, :sign_count, presence: true validates :external_id, uniqueness: true validates :nickname, uniqueness: { scope: :user_id } validates :sign_count, - numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: (2**63) - 1 } + numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: SIGN_COUNT_LIMIT - 1 } end diff --git a/app/policies/backup_policy.rb b/app/policies/backup_policy.rb index 86b8efbe96..7a4c5b4347 100644 --- a/app/policies/backup_policy.rb +++ b/app/policies/backup_policy.rb @@ -4,6 +4,6 @@ class BackupPolicy < ApplicationPolicy MIN_AGE = 6.days def create? - user_signed_in? && current_user.backups.where('created_at >= ?', MIN_AGE.ago).count.zero? + user_signed_in? && current_user.backups.where(created_at: MIN_AGE.ago..).count.zero? end end diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb index 25df4d85aa..92415a6903 100644 --- a/app/presenters/instance_presenter.rb +++ b/app/presenters/instance_presenter.rb @@ -81,4 +81,16 @@ class InstancePresenter < ActiveModelSerializers::Model def mascot @mascot ||= Rails.cache.fetch('site_uploads/mascot') { SiteUpload.find_by(var: 'mascot') } end + + def favicon + return @favicon if defined?(@favicon) + + @favicon ||= Rails.cache.fetch('site_uploads/favicon') { SiteUpload.find_by(var: 'favicon') } + end + + def app_icon + return @app_icon if defined?(@app_icon) + + @app_icon ||= Rails.cache.fetch('site_uploads/app_icon') { SiteUpload.find_by(var: 'app_icon') } + end end diff --git a/app/presenters/oauth_metadata_presenter.rb b/app/presenters/oauth_metadata_presenter.rb new file mode 100644 index 0000000000..546503bfcc --- /dev/null +++ b/app/presenters/oauth_metadata_presenter.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +class OauthMetadataPresenter < ActiveModelSerializers::Model + include RoutingHelper + + attributes :issuer, :authorization_endpoint, :token_endpoint, + :revocation_endpoint, :scopes_supported, + :response_types_supported, :response_modes_supported, + :grant_types_supported, :token_endpoint_auth_methods_supported, + :service_documentation, :app_registration_endpoint + + def issuer + root_url + end + + def service_documentation + 'https://docs.joinmastodon.org/' + end + + def authorization_endpoint + oauth_authorization_url + end + + def token_endpoint + oauth_token_url + end + + # As the api_v1_apps route doesn't technically conform to the specification + # for OAuth 2.0 Dynamic Client Registration defined in RFC 7591 we use a + # non-standard property for now to indicate the mastodon specific registration + # endpoint. See: https://datatracker.ietf.org/doc/html/rfc7591 + def app_registration_endpoint + api_v1_apps_url + end + + def revocation_endpoint + oauth_revoke_url + end + + def scopes_supported + doorkeeper.scopes + end + + def response_types_supported + doorkeeper.authorization_response_types + end + + def response_modes_supported + doorkeeper.authorization_response_flows.flat_map(&:response_mode_matches).uniq + end + + def grant_types_supported + grant_types_supported = doorkeeper.grant_flows.dup + grant_types_supported << 'refresh_token' if doorkeeper.refresh_token_enabled? + grant_types_supported + end + + def token_endpoint_auth_methods_supported + %w(client_secret_basic client_secret_post) + end + + private + + def doorkeeper + @doorkeeper ||= Doorkeeper.configuration + end +end diff --git a/app/serializers/activitypub/outbox_serializer.rb b/app/serializers/activitypub/outbox_serializer.rb index 4f4f950a5a..4d3d9706de 100644 --- a/app/serializers/activitypub/outbox_serializer.rb +++ b/app/serializers/activitypub/outbox_serializer.rb @@ -2,7 +2,7 @@ class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer def self.serializer_for(model, options) - if model.class.name == 'ActivityPub::ActivityPresenter' + if model.instance_of?(::ActivityPub::ActivityPresenter) ActivityPub::ActivitySerializer else super diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 9f7921461d..72aaabcfcb 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -17,7 +17,6 @@ class InitialStateSerializer < ActiveModel::Serializer if object.current_account store[:me] = object.current_account.id.to_s - store[:unfollow_modal] = object_account_user.setting_unfollow_modal store[:boost_modal] = object_account_user.setting_boost_modal store[:delete_modal] = object_account_user.setting_delete_modal store[:auto_play_gif] = object_account_user.setting_auto_play_gif diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb index 1c1f7d0ad5..a39fb5ef54 100644 --- a/app/serializers/manifest_serializer.rb +++ b/app/serializers/manifest_serializer.rb @@ -1,21 +1,10 @@ # frozen_string_literal: true class ManifestSerializer < ActiveModel::Serializer + include ApplicationHelper include RoutingHelper include ActionView::Helpers::TextHelper - ICON_SIZES = %w( - 36 - 48 - 72 - 96 - 144 - 192 - 256 - 384 - 512 - ).freeze - attributes :id, :name, :short_name, :icons, :theme_color, :background_color, :display, :start_url, :scope, @@ -37,9 +26,12 @@ class ManifestSerializer < ActiveModel::Serializer end def icons - ICON_SIZES.map do |size| + SiteUpload::ANDROID_ICON_SIZES.map do |size| + src = app_icon_path(size.to_i) + src = URI.join(root_url, src).to_s if src.present? + { - src: frontend_asset_url("icons/android-chrome-#{size}x#{size}.png"), + src: src || frontend_asset_url("icons/android-chrome-#{size}x#{size}.png"), sizes: "#{size}x#{size}", type: 'image/png', purpose: 'any maskable', diff --git a/app/serializers/oauth_metadata_serializer.rb b/app/serializers/oauth_metadata_serializer.rb new file mode 100644 index 0000000000..5f3dc7b87e --- /dev/null +++ b/app/serializers/oauth_metadata_serializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class OauthMetadataSerializer < ActiveModel::Serializer + attributes :issuer, :authorization_endpoint, :token_endpoint, + :revocation_endpoint, :scopes_supported, + :response_types_supported, :response_modes_supported, + :grant_types_supported, :token_endpoint_auth_methods_supported, + :service_documentation, :app_registration_endpoint +end diff --git a/app/serializers/rest/account_relationship_severance_event_serializer.rb b/app/serializers/rest/account_relationship_severance_event_serializer.rb new file mode 100644 index 0000000000..751bc103c2 --- /dev/null +++ b/app/serializers/rest/account_relationship_severance_event_serializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class REST::AccountRelationshipSeveranceEventSerializer < ActiveModel::Serializer + attributes :id, :type, :purged, :target_name, :followers_count, :following_count, :created_at + + def id + object.id.to_s + end +end diff --git a/app/serializers/rest/account_warning_serializer.rb b/app/serializers/rest/account_warning_serializer.rb new file mode 100644 index 0000000000..a0ef341d25 --- /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 8cee271272..d1a011425d 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 0000000000..a24cabc272 --- /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/application_serializer.rb b/app/serializers/rest/application_serializer.rb index 635508a17c..1a7b9265f1 100644 --- a/app/serializers/rest/application_serializer.rb +++ b/app/serializers/rest/application_serializer.rb @@ -1,24 +1,18 @@ # frozen_string_literal: true class REST::ApplicationSerializer < ActiveModel::Serializer - attributes :id, :name, :website, :scopes, :redirect_uri, - :client_id, :client_secret + attributes :id, :name, :website, :scopes, :redirect_uris # NOTE: Deprecated in 4.3.0, needs to be removed in 5.0.0 attribute :vapid_key + # We should consider this property deprecated for 4.3.0 + attribute :redirect_uri + def id object.id.to_s end - def client_id - object.uid - end - - def client_secret - object.secret - end - def website object.website.presence end diff --git a/app/serializers/rest/credential_application_serializer.rb b/app/serializers/rest/credential_application_serializer.rb new file mode 100644 index 0000000000..bfec7d03e8 --- /dev/null +++ b/app/serializers/rest/credential_application_serializer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class REST::CredentialApplicationSerializer < REST::ApplicationSerializer + attributes :client_id, :client_secret + + def client_id + object.uid + end + + def client_secret + object.secret + end +end diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index fa926cd287..8df79db6c7 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -54,11 +54,12 @@ class REST::InstanceSerializer < ActiveModel::Serializer accounts: { max_featured_tags: FeaturedTag::LIMIT, + max_pinned_statuses: StatusPinValidator::PIN_LIMIT, }, statuses: { max_characters: StatusLengthValidator::MAX_CHARS, - max_media_attachments: 4, + max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT, characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS, }, diff --git a/app/serializers/rest/marker_serializer.rb b/app/serializers/rest/marker_serializer.rb index 2eaf3d5076..b0c1c553ff 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 f27dda832a..90a2a97275 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_group_serializer.rb b/app/serializers/rest/notification_group_serializer.rb new file mode 100644 index 0000000000..9aa5663f4e --- /dev/null +++ b/app/serializers/rest/notification_group_serializer.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +class REST::NotificationGroupSerializer < ActiveModel::Serializer + attributes :group_key, :notifications_count, :type, :most_recent_notification_id + + attribute :page_min_id, if: :paginated? + attribute :page_max_id, if: :paginated? + attribute :latest_page_notification_at, if: :paginated? + + has_many :sample_accounts, serializer: REST::AccountSerializer + 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 status_type? + [:favourite, :reblog, :status, :mention, :poll, :update].include?(object.type) + end + + def report_type? + object.type == :'admin.report' + end + + def relationship_severance_event? + object.type == :severed_relationships + end + + def moderation_warning_event? + object.type == :moderation_warning + end + + def page_min_id + range = instance_options[:group_metadata][object.group_key] + range.present? ? range[:min_id].to_s : object.notification.id.to_s + end + + def page_max_id + range = instance_options[:group_metadata][object.group_key] + range.present? ? range[:max_id].to_s : object.notification.id.to_s + end + + def latest_page_notification_at + range = instance_options[:group_metadata][object.group_key] + range.present? ? range[:latest_notification_at] : object.notification.created_at + end + + def paginated? + !instance_options[:group_metadata].nil? + end +end diff --git a/app/serializers/rest/notification_policy_serializer.rb b/app/serializers/rest/notification_policy_serializer.rb new file mode 100644 index 0000000000..8bf85250fa --- /dev/null +++ b/app/serializers/rest/notification_policy_serializer.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class REST::NotificationPolicySerializer < ActiveModel::Serializer + # Please update `app/javascript/mastodon/api_types/notification_policies.ts` when making changes to the attributes + + attributes :filter_not_following, + :filter_not_followers, + :filter_new_accounts, + :filter_private_mentions, + :summary + + def summary + { + 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_request_serializer.rb b/app/serializers/rest/notification_request_serializer.rb new file mode 100644 index 0000000000..581959d827 --- /dev/null +++ b/app/serializers/rest/notification_request_serializer.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class REST::NotificationRequestSerializer < ActiveModel::Serializer + attributes :id, :created_at, :updated_at, :notifications_count + + belongs_to :from_account, key: :account, serializer: REST::AccountSerializer + belongs_to :last_status, serializer: REST::StatusSerializer + + def id + object.id.to_s + end + + def notifications_count + object.notifications_count.to_s + end +end diff --git a/app/serializers/rest/notification_serializer.rb b/app/serializers/rest/notification_serializer.rb index 137fc53dda..966819585f 100644 --- a/app/serializers/rest/notification_serializer.rb +++ b/app/serializers/rest/notification_serializer.rb @@ -1,16 +1,22 @@ # frozen_string_literal: true class REST::NotificationSerializer < ActiveModel::Serializer - attributes :id, :type, :created_at + attributes :id, :type, :created_at, :group_key belongs_to :from_account, key: :account, serializer: REST::AccountSerializer 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 end + def group_key + object.group_key || "ungrouped-#{object.id}" + end + def status_type? [:favourite, :reblog, :status, :mention, :poll, :update].include?(object.type) end @@ -18,4 +24,12 @@ class REST::NotificationSerializer < ActiveModel::Serializer def report_type? object.type == :'admin.report' end + + 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 df6ebd0d44..6e00060735 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/preview_card_serializer.rb b/app/serializers/rest/preview_card_serializer.rb index 039262cd5f..7d4c99c2d1 100644 --- a/app/serializers/rest/preview_card_serializer.rb +++ b/app/serializers/rest/preview_card_serializer.rb @@ -8,6 +8,8 @@ class REST::PreviewCardSerializer < ActiveModel::Serializer :provider_url, :html, :width, :height, :image, :image_description, :embed_url, :blurhash, :published_at + has_one :author_account, serializer: REST::AccountSerializer, if: -> { object.author_account.present? } + def url object.original_url.presence || object.url end diff --git a/app/serializers/rest/rule_serializer.rb b/app/serializers/rest/rule_serializer.rb index fc925925a9..9e2bcda15e 100644 --- a/app/serializers/rest/rule_serializer.rb +++ b/app/serializers/rest/rule_serializer.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class REST::RuleSerializer < ActiveModel::Serializer - attributes :id, :text + attributes :id, :text, :hint def id object.id.to_s diff --git a/app/serializers/rest/status_serializer.rb b/app/serializers/rest/status_serializer.rb index d32621541a..e17e8c823e 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/serializers/rest/v1/instance_serializer.rb b/app/serializers/rest/v1/instance_serializer.rb index fdf939cfc3..636925b973 100644 --- a/app/serializers/rest/v1/instance_serializer.rb +++ b/app/serializers/rest/v1/instance_serializer.rb @@ -64,7 +64,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer statuses: { max_characters: StatusLengthValidator::MAX_CHARS, - max_media_attachments: 4, + max_media_attachments: Status::MEDIA_ATTACHMENTS_LIMIT, characters_reserved_per_url: StatusLengthValidator::URL_PLACEHOLDER_CHARS, }, diff --git a/app/services/accept_notification_request_service.rb b/app/services/accept_notification_request_service.rb new file mode 100644 index 0000000000..e49eae6fd3 --- /dev/null +++ b/app/services/accept_notification_request_service.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class AcceptNotificationRequestService < BaseService + def call(request) + NotificationPermission.create!(account: request.account, from_account: request.from_account) + UnfilterNotificationsWorker.perform_async(request.id) + end +end diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb index 571a0fa57d..b86c9b9e7e 100644 --- a/app/services/account_search_service.rb +++ b/app/services/account_search_service.rb @@ -151,13 +151,23 @@ class AccountSearchService < BaseService end def call(query, account = nil, options = {}) - @query = query&.strip&.gsub(/\A@/, '') - @limit = options[:limit].to_i - @offset = options[:offset].to_i - @options = options - @account = account + MastodonOTELTracer.in_span('AccountSearchService#call') do |span| + @query = query&.strip&.gsub(/\A@/, '') + @limit = options[:limit].to_i + @offset = options[:offset].to_i + @options = options + @account = account - search_service_results.compact.uniq + span.add_attributes( + 'search.offset' => @offset, + 'search.limit' => @limit, + 'search.backend' => Chewy.enabled? ? 'elasticsearch' : 'database' + ) + + search_service_results.compact.uniq.tap do |results| + span.set_attribute('search.results.count', results.size) + end + end end private diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 9e787ace50..b667e97f4d 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -201,10 +201,15 @@ class ActivityPub::ProcessAccountService < BaseService value = first_of_value(@json[key]) return if value.nil? - return value['url'] if value.is_a?(Hash) - image = fetch_resource_without_id_validation(value) - image['url'] if image + if value.is_a?(String) + value = fetch_resource_without_id_validation(value) + return if value.nil? + end + + value = first_of_value(value['url']) if value.is_a?(Hash) && value['type'] == 'Image' + value = value['href'] if value.is_a?(Hash) + value if value.is_a?(String) end def public_key diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index fb2b33114e..1dbed27f28 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -73,7 +73,7 @@ class ActivityPub::ProcessStatusUpdateService < BaseService as_array(@json['attachment']).each do |attachment| media_attachment_parser = ActivityPub::Parser::MediaAttachmentParser.new(attachment) - next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > 4 + next if media_attachment_parser.remote_url.blank? || @next_media_attachments.size > Status::MEDIA_ATTACHMENTS_LIMIT begin media_attachment = previous_media_attachments.find { |previous_media_attachment| previous_media_attachment.remote_url == media_attachment_parser.remote_url } diff --git a/app/services/after_block_domain_from_account_service.rb b/app/services/after_block_domain_from_account_service.rb index 89d007c1cd..fc5dc65681 100644 --- a/app/services/after_block_domain_from_account_service.rb +++ b/app/services/after_block_domain_from_account_service.rb @@ -9,18 +9,22 @@ class AfterBlockDomainFromAccountService < BaseService def call(account, domain) @account = account @domain = domain + @domain_block_event = nil clear_notifications! + clear_notification_permissions! remove_follows! reject_existing_followers! reject_pending_follow_requests! + notify_of_severed_relationships! end private def remove_follows! - @account.active_relationships.where(target_account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).find_each do |follow| - UnfollowService.new.call(@account, follow.target_account) + @account.active_relationships.where(target_account: Account.where(domain: @domain)).includes(:target_account).reorder(nil).in_batches do |follows| + domain_block_event.import_from_active_follows!(follows) + follows.each { |follow| UnfollowService.new.call(@account, follow.target_account) } end end @@ -28,9 +32,14 @@ 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).find_each do |follow| - reject_follow!(follow) + @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) + follows.each { |follow| reject_follow!(follow) } end end @@ -47,4 +56,15 @@ class AfterBlockDomainFromAccountService < BaseService ActivityPub::DeliveryWorker.perform_async(Oj.dump(serialize_payload(follow, ActivityPub::RejectFollowSerializer)), @account.id, follow.account.inbox_url) end + + def notify_of_severed_relationships! + return if @domain_block_event.nil? + + event = AccountRelationshipSeveranceEvent.create!(account: @account, relationship_severance_event: @domain_block_event) + LocalNotificationWorker.perform_async(@account.id, event.id, 'AccountRelationshipSeveranceEvent', 'severed_relationships') + end + + def domain_block_event + @domain_block_event ||= RelationshipSeveranceEvent.create!(type: :user_domain_block, target_name: @domain) + end end diff --git a/app/services/backup_service.rb b/app/services/backup_service.rb index 886bab1ebf..1e90184376 100644 --- a/app/services/backup_service.rb +++ b/app/services/backup_service.rb @@ -19,8 +19,8 @@ class BackupService < BaseService def build_outbox_json!(file) skeleton = serialize(collection_presenter, ActivityPub::CollectionSerializer) - skeleton[:@context] = full_context - skeleton[:orderedItems] = ['!PLACEHOLDER!'] + skeleton['@context'] = full_context + skeleton['orderedItems'] = ['!PLACEHOLDER!'] skeleton = Oj.dump(skeleton) prepend, append = skeleton.split('"!PLACEHOLDER!"') add_comma = false diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 76cc36ff6b..00d020d2b3 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -5,8 +5,11 @@ class BlockDomainService < BaseService def call(domain_block, update = false) @domain_block = domain_block + @domain_block_event = nil + process_domain_block! process_retroactive_updates! if update + notify_of_severed_relationships! end private @@ -37,7 +40,17 @@ class BlockDomainService < BaseService blocked_domain_accounts.without_suspended.in_batches.update_all(suspended_at: @domain_block.created_at, suspension_origin: :local) blocked_domain_accounts.where(suspended_at: @domain_block.created_at).reorder(nil).find_each do |account| - DeleteAccountService.new.call(account, reserve_username: true, suspended_at: @domain_block.created_at) + DeleteAccountService.new.call(account, reserve_username: true, suspended_at: @domain_block.created_at, relationship_severance_event: domain_block_event) + end + end + + def notify_of_severed_relationships! + return if @domain_block_event.nil? + + # TODO: check how efficient that query is, also check `push_bulk`/`perform_bulk` + @domain_block_event.affected_local_accounts.reorder(nil).find_each do |account| + event = AccountRelationshipSeveranceEvent.create!(account: account, relationship_severance_event: @domain_block_event) + LocalNotificationWorker.perform_async(account.id, event.id, 'AccountRelationshipSeveranceEvent', 'severed_relationships') end end @@ -45,6 +58,10 @@ class BlockDomainService < BaseService domain_block.domain end + def domain_block_event + @domain_block_event ||= RelationshipSeveranceEvent.create!(type: :domain_block, target_name: blocked_domain) + end + def blocked_domain_accounts Account.by_domain_and_subdomains(blocked_domain) end diff --git a/app/services/block_service.rb b/app/services/block_service.rb index 266a0f4b9d..98229d98c0 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 ef4c18e789..26909dfe04 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/delete_account_service.rb b/app/services/delete_account_service.rb index 7c7cb97df2..328d8ae8f8 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -58,6 +58,8 @@ class DeleteAccountService < BaseService reports targeted_moderation_notes targeted_reports + severed_relationships + remote_severed_relationships ).freeze # Suspend or remove an account and remove as much of its data @@ -72,6 +74,7 @@ class DeleteAccountService < BaseService # @option [Boolean] :skip_side_effects Side effects are ActivityPub and streaming API payloads # @option [Boolean] :skip_activitypub Skip sending ActivityPub payloads. Implied by :skip_side_effects # @option [Time] :suspended_at Only applicable when :reserve_username is true + # @option [RelationshipSeveranceEvent] :relationship_severance_event Event used to record severed relationships not initiated by the user def call(account, **options) @account = account @options = { reserve_username: true, reserve_email: true }.merge(options) @@ -84,6 +87,7 @@ class DeleteAccountService < BaseService @options[:skip_activitypub] = true if @options[:skip_side_effects] + record_severed_relationships! distribute_activities! purge_content! fulfill_deletion_request! @@ -181,6 +185,7 @@ class DeleteAccountService < BaseService # polymorphically associated notifications generated by this account Notification.where(from_account: @account).in_batches.delete_all + NotificationRequest.where(from_account: @account).in_batches.delete_all end def purge_favourites! @@ -266,6 +271,20 @@ class DeleteAccountService < BaseService end end + def record_severed_relationships! + return if relationship_severance_event.nil? + + @account.active_relationships.in_batches do |follows| + # NOTE: these follows are passive with regards to the local accounts + relationship_severance_event.import_from_passive_follows!(follows) + end + + @account.passive_relationships.in_batches do |follows| + # NOTE: these follows are active with regards to the local accounts + relationship_severance_event.import_from_active_follows!(follows) + end + end + def delete_actor_json @delete_actor_json ||= Oj.dump(serialize_payload(@account, ActivityPub::DeleteActorSerializer, signer: @account, always_sign: true)) end @@ -305,4 +324,8 @@ class DeleteAccountService < BaseService def skip_activitypub? @options[:skip_activitypub] end + + def relationship_severance_event + @options[:relationship_severance_event] + end end diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index c6b600dd7c..900cb9863d 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -56,7 +56,7 @@ class FetchLinkCardService < BaseService @html_charset = res.charset - res.body_with_limit + res.truncated_body end end @@ -147,9 +147,12 @@ class FetchLinkCardService < BaseService return if html.nil? link_details_extractor = LinkDetailsExtractor.new(@url, @html, @html_charset) + provider = PreviewCardProvider.matching_domain(Addressable::URI.parse(link_details_extractor.canonical_url).normalized_host) + linked_account = ResolveAccountService.new.call(link_details_extractor.author_account, suppress_errors: true) if link_details_extractor.author_account.present? && provider&.trendable? @card = PreviewCard.find_or_initialize_by(url: link_details_extractor.canonical_url) if link_details_extractor.canonical_url != @card.url @card.assign_attributes(link_details_extractor.to_preview_card_attributes) + @card.author_account = linked_account @card.save_with_optional_image! unless @card.title.blank? && @card.html.blank? end end diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index 13eb20986e..d69b5af141 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -3,134 +3,241 @@ class NotifyService < BaseService include Redisable + MAXIMUM_GROUP_SPAN_HOURS = 12 + MAXIMUM_GROUP_GAP_TIME = 4.hours.to_i + NON_EMAIL_TYPES = %i( admin.report admin.sign_up update poll status + moderation_warning + # TODO: this probably warrants an email notification + severed_relationships ).freeze + class DismissCondition + def initialize(notification) + @recipient = notification.account + @sender = notification.from_account + @notification = notification + end + + def dismiss? + blocked = @recipient.unavailable? + blocked ||= from_self? && %i(poll severed_relationships moderation_warning).exclude?(@notification.type) + + return blocked if message? && from_staff? + + blocked ||= domain_blocking? + blocked ||= @recipient.blocking?(@sender) + blocked ||= @recipient.muting_notifications?(@sender) + blocked ||= conversation_muted? + blocked ||= blocked_mention? if message? + blocked + end + + private + + def blocked_mention? + FeedManager.instance.filter?(:mentions, @notification.target_status, @recipient) + end + + def message? + @notification.type == :mention + end + + def from_staff? + @sender.local? && @sender.user.present? && @sender.user_role&.overrides?(@recipient.user_role) + end + + def from_self? + @recipient.id == @sender.id + end + + def domain_blocking? + @recipient.domain_blocking?(@sender.domain) && !following_sender? + end + + def conversation_muted? + @notification.target_status && @recipient.muting_conversation?(@notification.target_status.conversation) + end + + def following_sender? + @recipient.following?(@sender) + end + end + + class FilterCondition + NEW_ACCOUNT_THRESHOLD = 30.days.freeze + + NEW_FOLLOWER_THRESHOLD = 3.days.freeze + + NON_FILTERABLE_TYPES = %i( + admin.sign_up + admin.report + poll + update + account_warning + ).freeze + + def initialize(notification) + @notification = notification + @recipient = notification.account + @sender = notification.from_account + @policy = NotificationPolicy.find_or_initialize_by(account: @recipient) + end + + def filter? + return false unless Notification::PROPERTIES[@notification.type][:filterable] + return false if override_for_sender? + + from_limited? || + filtered_by_not_following_policy? || + filtered_by_not_followers_policy? || + filtered_by_new_accounts_policy? || + filtered_by_private_mentions_policy? + end + + private + + def filtered_by_not_following_policy? + @policy.filter_not_following? && not_following? + end + + def filtered_by_not_followers_policy? + @policy.filter_not_followers? && not_follower? + end + + def filtered_by_new_accounts_policy? + @policy.filter_new_accounts? && new_account? + end + + def filtered_by_private_mentions_policy? + @policy.filter_private_mentions? && not_following? && private_mention_not_in_response? + end + + def not_following? + !@recipient.following?(@sender) + end + + def not_follower? + follow = Follow.find_by(account: @sender, target_account: @recipient) + follow.nil? || follow.created_at > NEW_FOLLOWER_THRESHOLD.ago + end + + def new_account? + @sender.created_at > NEW_ACCOUNT_THRESHOLD.ago + end + + def override_for_sender? + NotificationPermission.exists?(account: @recipient, from_account: @sender) + end + + def from_limited? + @sender.silenced? && not_following? + end + + def private_mention_not_in_response? + @notification.type == :mention && @notification.target_status.direct_visibility? && !response_to_recipient? + end + + def response_to_recipient? + return false if @notification.target_status.in_reply_to_id.nil? + + statuses_that_mention_sender.positive? + end + + def statuses_that_mention_sender + # This queries private mentions from the recipient to the sender up in the thread. + # This allows up to 100 messages that do not match in the thread, allowing conversations + # involving multiple people. + Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100]) + WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS ( + SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0 + FROM statuses s + LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id + WHERE s.id = :id + UNION ALL + SELECT s.id, s.in_reply_to_id, m.id, ancestors.path || s.id, ancestors.depth + 1 + FROM ancestors + JOIN statuses s ON s.id = ancestors.in_reply_to_id + /* early exit if we already have a mention matching our requirements */ + LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id AND s.account_id = :recipient_id + WHERE ancestors.mention_id IS NULL AND NOT s.id = ANY(path) AND ancestors.depth < :depth_limit + ) + SELECT COUNT(*) + FROM ancestors + JOIN statuses s ON s.id = ancestors.id + WHERE ancestors.mention_id IS NOT NULL AND s.account_id = :recipient_id AND s.visibility = 3 + SQL + end + end + def call(recipient, type, activity) + return if recipient.user.nil? + @recipient = recipient @activity = activity @notification = Notification.new(account: @recipient, type: type, activity: @activity) - return if recipient.user.nil? || blocked? + # For certain conditions we don't need to create a notification at all + return if dismiss? + @notification.filtered = filter? + @notification.group_key = notification_group_key @notification.save! # It's possible the underlying activity has been deleted # between the save call and now return if @notification.activity.nil? - push_notification! - push_to_conversation! if direct_message? - send_email! if email_needed? + if @notification.filtered? + update_notification_request! + else + push_notification! + push_to_conversation! if direct_message? + send_email! if email_needed? + end rescue ActiveRecord::RecordInvalid nil end private - def blocked_mention? - FeedManager.instance.filter?(:mentions, @notification.mention.status, @recipient) + def notification_group_key + return nil if @notification.filtered || %i(favourite reblog).exclude?(@notification.type) + + type_prefix = "#{@notification.type}-#{@notification.target_status.id}" + redis_key = "notif-group/#{@recipient.id}/#{type_prefix}" + hour_bucket = @notification.activity.created_at.utc.to_i / 1.hour.to_i + + # Reuse previous group if it does not span too large an amount of time + previous_bucket = redis.get(redis_key).to_i + hour_bucket = previous_bucket if hour_bucket < previous_bucket + MAXIMUM_GROUP_SPAN_HOURS + + # Do not track groups past a given inactivity time + # We do not concern ourselves with race conditions since we use hour buckets + redis.set(redis_key, hour_bucket, ex: MAXIMUM_GROUP_GAP_TIME) + + "#{type_prefix}-#{hour_bucket}" end - def following_sender? - return @following_sender if defined?(@following_sender) - - @following_sender = @recipient.following?(@notification.from_account) || @recipient.requested?(@notification.from_account) + def dismiss? + DismissCondition.new(@notification).dismiss? end - def optional_non_follower? - @recipient.user.settings['interactions.must_be_follower'] && !@notification.from_account.following?(@recipient) + def filter? + FilterCondition.new(@notification).filter? end - def optional_non_following? - @recipient.user.settings['interactions.must_be_following'] && !following_sender? - end + def update_notification_request! + return unless @notification.type == :mention - def message? - @notification.type == :mention - end - - def direct_message? - message? && @notification.target_status.direct_visibility? - end - - # Returns true if the sender has been mentioned by the recipient up the thread - def response_to_recipient? - return false if @notification.target_status.in_reply_to_id.nil? - - # Using an SQL CTE to avoid unneeded back-and-forth with SQL server in case of long threads - !Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @notification.from_account.id, depth_limit: 100]).zero? - WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS ( - SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0 - FROM statuses s - LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id - WHERE s.id = :id - UNION ALL - SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1 - FROM ancestors st - JOIN statuses s ON s.id = st.in_reply_to_id - LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id - WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit - ) - SELECT COUNT(*) - FROM ancestors st - JOIN statuses s ON s.id = st.id - WHERE st.mention_id IS NOT NULL AND s.visibility = 3 - SQL - end - - def from_staff? - @notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user_role&.overrides?(@recipient.user_role) - end - - def optional_non_following_and_direct? - direct_message? && - @recipient.user.settings['interactions.must_be_following_dm'] && - !following_sender? && - !response_to_recipient? - end - - def hellbanned? - @notification.from_account.silenced? && !following_sender? - end - - def from_self? - @recipient.id == @notification.from_account.id - end - - def domain_blocking? - @recipient.domain_blocking?(@notification.from_account.domain) && !following_sender? - end - - def blocked? - blocked = @recipient.unavailable? - blocked ||= from_self? && @notification.type != :poll - - return blocked if message? && from_staff? - - blocked ||= domain_blocking? - blocked ||= @recipient.blocking?(@notification.from_account) - blocked ||= @recipient.muting_notifications?(@notification.from_account) - blocked ||= hellbanned? - blocked ||= optional_non_follower? - blocked ||= optional_non_following? - blocked ||= optional_non_following_and_direct? - blocked ||= conversation_muted? - blocked ||= blocked_mention? if @notification.type == :mention - blocked - end - - def conversation_muted? - if @notification.target_status - @recipient.muting_conversation?(@notification.target_status.conversation) - else - false - end + notification_request = NotificationRequest.find_or_initialize_by(account_id: @recipient.id, from_account_id: @notification.from_account_id) + notification_request.last_status_id = @notification.target_status.id + notification_request.save end def push_notification! @@ -150,6 +257,10 @@ class NotifyService < BaseService AccountConversation.add_status(@recipient, @notification.target_status) end + def direct_message? + @notification.type == :mention && @notification.target_status.direct_visibility? + end + def push_to_web_push_subscriptions! ::Web::PushNotificationWorker.push_bulk(web_push_subscriptions.select { |subscription| subscription.pushable?(@notification) }) { |subscription| [subscription.id, @notification.id] } end diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 8aa43ab245..8b18ce038d 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -130,9 +130,9 @@ class PostStatusService < BaseService return end - raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present? - @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)) + @media = @account.media_attachments.where(status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i)) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if @media.any?(&:not_processed?) @@ -160,7 +160,7 @@ class PostStatusService < BaseService def idempotency_duplicate if scheduled? - @account.schedule_statuses.find(@idempotency_duplicate) + @account.scheduled_statuses.find(@idempotency_duplicate) else @account.statuses.find(@idempotency_duplicate) end @@ -171,7 +171,7 @@ class PostStatusService < BaseService end def scheduled_in_the_past? - @scheduled_at.present? && @scheduled_at <= Time.now.utc + MIN_SCHEDULE_OFFSET + @scheduled_at.present? && @scheduled_at <= Time.now.utc end def bump_potential_friendship! @@ -211,7 +211,7 @@ class PostStatusService < BaseService end def scheduled_options - @options.tap do |options_hash| + @options.dup.tap do |options_hash| options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id options_hash[:application_id] = options_hash.delete(:application)&.id options_hash[:scheduled_at] = nil diff --git a/app/services/purge_domain_service.rb b/app/services/purge_domain_service.rb index 9df81f13e6..ca0f0d441f 100644 --- a/app/services/purge_domain_service.rb +++ b/app/services/purge_domain_service.rb @@ -2,10 +2,26 @@ class PurgeDomainService < BaseService def call(domain) - Account.remote.where(domain: domain).reorder(nil).find_each do |account| - DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) - end - CustomEmoji.remote.where(domain: domain).reorder(nil).find_each(&:destroy) + @domain = domain + + purge_relationship_severance_events! + purge_accounts! + purge_emojis! + Instance.refresh end + + def purge_relationship_severance_events! + RelationshipSeveranceEvent.where(type: [:domain_block, :user_domain_block], target_name: @domain).in_batches.update_all(purged: true) + end + + def purge_accounts! + Account.remote.where(domain: @domain).reorder(nil).find_each do |account| + DeleteAccountService.new.call(account, reserve_username: false, skip_side_effects: true) + end + end + + def purge_emojis! + CustomEmoji.remote.where(domain: @domain).reorder(nil).find_each(&:destroy) + end end diff --git a/app/services/report_service.rb b/app/services/report_service.rb index fe546c383e..dea6df7b0a 100644 --- a/app/services/report_service.rb +++ b/app/services/report_service.rb @@ -81,7 +81,7 @@ class ReportService < BaseService # If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses. domain = @source_account.domain.to_s.downcase - has_followers = @target_account.followers.where(Account.arel_table[:domain].lower.eq(domain)).exists? + has_followers = @target_account.followers.with_domain(domain).exists? visibility = has_followers ? %i(public unlisted private) : %i(public unlisted) scope = @target_account.statuses.with_discarded scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain))) diff --git a/app/services/statuses_search_service.rb b/app/services/statuses_search_service.rb index 7d5b0203a0..ab8e28f61c 100644 --- a/app/services/statuses_search_service.rb +++ b/app/services/statuses_search_service.rb @@ -2,14 +2,24 @@ class StatusesSearchService < BaseService def call(query, account = nil, options = {}) - @query = query&.strip - @account = account - @options = options - @limit = options[:limit].to_i - @offset = options[:offset].to_i + MastodonOTELTracer.in_span('StatusesSearchService#call') do |span| + @query = query&.strip + @account = account + @options = options + @limit = options[:limit].to_i + @offset = options[:offset].to_i + convert_deprecated_options! - convert_deprecated_options! - status_search_results + span.add_attributes( + 'search.offset' => @offset, + 'search.limit' => @limit, + 'search.backend' => Chewy.enabled? ? 'elasticsearch' : 'database' + ) + + status_search_results.tap do |results| + span.set_attribute('search.results.count', results.size) + end + end end private diff --git a/app/services/tag_search_service.rb b/app/services/tag_search_service.rb index d5d1974275..57400b76ad 100644 --- a/app/services/tag_search_service.rb +++ b/app/services/tag_search_service.rb @@ -2,21 +2,56 @@ class TagSearchService < BaseService def call(query, options = {}) - @query = query.strip.delete_prefix('#') - @offset = options.delete(:offset).to_i - @limit = options.delete(:limit).to_i - @options = options + MastodonOTELTracer.in_span('TagSearchService#call') do |span| + @query = query.strip.delete_prefix('#') + @offset = options.delete(:offset).to_i + @limit = options.delete(:limit).to_i + @options = options - results = from_elasticsearch if Chewy.enabled? - results ||= from_database + span.add_attributes( + 'search.offset' => @offset, + 'search.limit' => @limit, + 'search.backend' => Chewy.enabled? ? 'elasticsearch' : 'database' + ) - results + results = from_elasticsearch if Chewy.enabled? + results ||= from_database + + span.set_attribute('search.results.count', results.size) + + results + end end private def from_elasticsearch - query = { + definition = TagsIndex.query(elastic_search_query) + definition = definition.filter(elastic_search_filter) if @options[:exclude_unreviewed] + + ensure_exact_match(definition.limit(@limit).offset(@offset).objects.compact) + rescue Faraday::ConnectionFailed, Parslet::ParseFailed + nil + end + + # Since the ElasticSearch Query doesn't guarantee the exact match will be the + # first result or that it will even be returned, patch the results accordingly + def ensure_exact_match(results) + return results unless @offset.nil? || @offset.zero? + + normalized_query = Tag.normalize(@query) + exact_match = results.find { |tag| tag.name.downcase == normalized_query } + exact_match ||= Tag.find_normalized(normalized_query) + unless exact_match.nil? + results.delete(exact_match) + results = [exact_match] + results + end + + results + end + + def elastic_search_query + { function_score: { query: { multi_match: { @@ -50,8 +85,10 @@ class TagSearchService < BaseService boost_mode: 'multiply', }, } + end - filter = { + def elastic_search_filter + { bool: { should: [ { @@ -72,29 +109,6 @@ class TagSearchService < BaseService ], }, } - - definition = TagsIndex.query(query) - definition = definition.filter(filter) if @options[:exclude_unreviewed] - - ensure_exact_match(definition.limit(@limit).offset(@offset).objects.compact) - rescue Faraday::ConnectionFailed, Parslet::ParseFailed - nil - end - - # Since the ElasticSearch Query doesn't guarantee the exact match will be the - # first result or that it will even be returned, patch the results accordingly - def ensure_exact_match(results) - return results unless @offset.nil? || @offset.zero? - - normalized_query = Tag.normalize(@query) - exact_match = results.find { |tag| tag.name.downcase == normalized_query } - exact_match ||= Tag.find_normalized(normalized_query) - unless exact_match.nil? - results.delete(exact_match) - results = [exact_match] + results - end - - results end def from_database diff --git a/app/services/update_status_service.rb b/app/services/update_status_service.rb index cdfe283659..dc7d177e2d 100644 --- a/app/services/update_status_service.rb +++ b/app/services/update_status_service.rb @@ -69,9 +69,9 @@ class UpdateStatusService < BaseService def validate_media! return [] if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable) - raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4 || @options[:poll].present? + raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > Status::MEDIA_ATTACHMENTS_LIMIT || @options[:poll].present? - media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i)).to_a + media_attachments = @status.account.media_attachments.where(status_id: [nil, @status.id]).where(scheduled_status_id: nil).where(id: @options[:media_ids].take(Status::MEDIA_ATTACHMENTS_LIMIT).map(&:to_i)).to_a raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media_attachments.size > 1 && media_attachments.find(&:audio_or_video?) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.not_ready') if media_attachments.any?(&:not_processed?) diff --git a/app/services/verify_link_service.rb b/app/services/verify_link_service.rb index 707aeb4e08..b317fc31a8 100644 --- a/app/services/verify_link_service.rb +++ b/app/services/verify_link_service.rb @@ -19,7 +19,7 @@ class VerifyLinkService < BaseService def perform_request! @body = Request.new(:get, @url).add_headers('Accept' => 'text/html').perform do |res| - res.code == 200 ? res.body_with_limit : nil + res.code == 200 ? res.truncated_body : nil end end diff --git a/app/validators/email_address_validator.rb b/app/validators/email_address_validator.rb new file mode 100644 index 0000000000..ed0bb11652 --- /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/validators/unique_username_validator.rb b/app/validators/unique_username_validator.rb index 09c8fadb55..c417e2f696 100644 --- a/app/validators/unique_username_validator.rb +++ b/app/validators/unique_username_validator.rb @@ -6,10 +6,7 @@ class UniqueUsernameValidator < ActiveModel::Validator def validate(account) return if account.username.blank? - normalized_username = account.username.downcase - normalized_domain = account.domain&.downcase - - scope = Account.where(Account.arel_table[:username].lower.eq normalized_username).where(Account.arel_table[:domain].lower.eq normalized_domain) + scope = Account.with_username(account.username).with_domain(account.domain) scope = scope.where.not(id: account.id) if account.persisted? account.errors.add(:username, :taken) if scope.exists? diff --git a/app/validators/web_push_key_validator.rb b/app/validators/web_push_key_validator.rb new file mode 100644 index 0000000000..a8ad5c9c6b --- /dev/null +++ b/app/validators/web_push_key_validator.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class WebPushKeyValidator < ActiveModel::Validator + def validate(subscription) + begin + Webpush::Encryption.encrypt('validation_test', subscription.key_p256dh, subscription.key_auth) + rescue ArgumentError, OpenSSL::PKey::EC::Point::Error + subscription.errors.add(:base, I18n.t('crypto.errors.invalid_key')) + end + end +end diff --git a/app/views/admin/account_actions/new.html.haml b/app/views/admin/account_actions/new.html.haml index 4cb4401c70..bce1c31760 100644 --- a/app/views/admin/account_actions/new.html.haml +++ b/app/views/admin/account_actions/new.html.haml @@ -2,29 +2,48 @@ = t('admin.account_actions.title', acct: @account.pretty_acct) = simple_form_for @account_action, url: admin_account_action_path(@account.id) do |f| - = f.input :report_id, as: :hidden + = f.input :report_id, + as: :hidden .fields-group - = f.input :type, as: :radio_buttons, collection: Admin::AccountAction.types_for_account(@account), include_blank: false, wrapper: :with_block_label, label_method: ->(type) { account_action_type_label(type) }, hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct) + = f.input :type, + as: :radio_buttons, + collection: Admin::AccountAction.types_for_account(@account), + hint: t('simple_form.hints.admin_account_action.type_html', acct: @account.pretty_acct), + include_blank: false, + label_method: ->(type) { account_action_type_label(type) }, + wrapper: :with_block_label - if @account.local? %hr.spacer/ .fields-group - = f.input :send_email_notification, as: :boolean, wrapper: :with_label + = f.input :send_email_notification, + as: :boolean, + wrapper: :with_label - if params[:report_id].present? .fields-group - = f.input :include_statuses, as: :boolean, wrapper: :with_label + = f.input :include_statuses, + as: :boolean, + wrapper: :with_label %hr.spacer/ - unless @warning_presets.empty? .fields-group - = f.input :warning_preset_id, collection: @warning_presets, label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') }, wrapper: :with_block_label + = f.input :warning_preset_id, + collection: @warning_presets, + label_method: ->(warning_preset) { [warning_preset.title.presence, truncate(warning_preset.text)].compact.join(' - ') }, + wrapper: :with_block_label .fields-group - = f.input :text, as: :text, wrapper: :with_block_label, hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path) + = f.input :text, + as: :text, + hint: t('simple_form.hints.admin_account_action.text_html', path: admin_warning_presets_path), + wrapper: :with_block_label .actions - = f.button :button, t('admin.account_actions.action'), type: :submit + = f.button :button, + t('admin.account_actions.action'), + type: :submit diff --git a/app/views/admin/account_warnings/_account_warning.html.haml b/app/views/admin/account_warnings/_account_warning.html.haml index 5702e4f6d2..368e69e63e 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 82197cda43..3ed392cd1a 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 99996e1d46..6755af2496 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 0000000000..1938cf7edf --- /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 8354441895..9dd4f0e4e4 100644 --- a/app/views/admin/accounts/index.html.haml +++ b/app/views/admin/accounts/index.html.haml @@ -1,31 +1,41 @@ - content_for :page_title do = t('admin.accounts.title') -= form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do += form_with url: admin_accounts_url, method: :get, class: :simple_form do |form| .filters .filter-subset.filter-subset--with-select %strong= t('admin.accounts.location.title') .input.select.optional - = select_tag :origin, options_for_select([[t('admin.accounts.location.local'), 'local'], [t('admin.accounts.location.remote'), 'remote']], params[:origin]), prompt: I18n.t('generic.all') + = form.select :origin, + options_for_select([[t('admin.accounts.location.local'), 'local'], [t('admin.accounts.location.remote'), 'remote']], params[:origin]), + prompt: I18n.t('generic.all') .filter-subset.filter-subset--with-select %strong= t('admin.accounts.moderation.title') .input.select.optional - = select_tag :status, options_for_select(admin_accounts_moderation_options, params[:status]), prompt: I18n.t('generic.all') + = form.select :status, + options_for_select(admin_accounts_moderation_options, params[:status]), + prompt: I18n.t('generic.all') .filter-subset.filter-subset--with-select %strong= t('admin.accounts.role') .input.select.optional - = select_tag :role_ids, options_from_collection_for_select(UserRole.assignable, :id, :name, params[:role_ids]), prompt: I18n.t('admin.accounts.moderation.all') + = form.select :role_ids, + options_from_collection_for_select(UserRole.assignable, :id, :name, params[:role_ids]), + prompt: I18n.t('admin.accounts.moderation.all') .filter-subset.filter-subset--with-select %strong= t 'generic.order_by' .input.select - = select_tag :order, options_for_select([[t('relationships.most_recent'), 'recent'], [t('relationships.last_active'), 'active']], params[:order]) + = form.select :order, + options_for_select([[t('relationships.most_recent'), 'recent'], [t('relationships.last_active'), 'active']], params[:order]) .fields-group - %i(username by_domain display_name email ip).each do |key| - next if key == :by_domain && params[:origin] != 'remote' .input.string.optional - = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}") + = form.text_field key, + value: params[key], + class: 'string optional', + placeholder: I18n.t("admin.accounts.#{key}") .actions %button.button= t('admin.accounts.search') @@ -33,7 +43,7 @@ %hr.spacer/ -= form_for(@form, url: batch_admin_accounts_path) do |f| += form_with model: @form, url: batch_admin_accounts_path do |f| = hidden_field_tag :page, params[:page] || 1 = hidden_field_tag :select_all_matching, '0' @@ -46,11 +56,23 @@ = 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')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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, + type: :submit - if @accounts.total_count > @accounts.size .batch-table__select-all .not-selected.active diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index da2f2055d0..f148b9a082 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? @@ -62,14 +62,16 @@ .report-notes = render partial: 'admin/report_notes/report_note', collection: @moderation_notes - = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f| - = f.hidden_field :target_account_id + = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |form| + = form.hidden_field :target_account_id + + = render 'shared/error_messages', object: @account_moderation_note .field-group - = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6 + = form.input :content, input_html: { placeholder: t('admin.reports.notes.placeholder'), maxlength: AccountModerationNote::CONTENT_SIZE_LIMIT, rows: 6, autofocus: @account_moderation_note.errors.any? } .actions - = f.button :button, t('admin.account_moderation_notes.create'), type: :submit + = form.button :button, t('admin.account_moderation_notes.create'), type: :submit %hr.spacer/ diff --git a/app/views/admin/action_logs/index.html.haml b/app/views/admin/action_logs/index.html.haml index c4929cc422..c02c8f0ad4 100644 --- a/app/views/admin/action_logs/index.html.haml +++ b/app/views/admin/action_logs/index.html.haml @@ -1,19 +1,23 @@ - content_for :page_title do = t('admin.action_logs.title') -= form_tag admin_action_logs_url, method: 'GET', class: 'simple_form' do += form_with url: admin_action_logs_url, method: :get, class: :simple_form do |form| = hidden_field_tag :target_account_id, params[:target_account_id] if params[:target_account_id].present? .filters .filter-subset.filter-subset--with-select %strong= t('admin.action_logs.filter_by_user') .input.select.optional - = select_tag :account_id, options_from_collection_for_select(@auditable_accounts, :id, :username, params[:account_id]), prompt: I18n.t('admin.accounts.moderation.all') + = form.select :account_id, + options_from_collection_for_select(@auditable_accounts, :id, :username, params[:account_id]), + prompt: I18n.t('admin.accounts.moderation.all') .filter-subset.filter-subset--with-select %strong= t('admin.action_logs.filter_by_action') .input.select.optional - = select_tag :action_type, options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] }, params[:action_type]), prompt: I18n.t('admin.accounts.moderation.all') + = form.select :action_type, + options_for_select(Admin::ActionLogFilter::ACTION_TYPE_MAP.keys.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] }, params[:action_type]), + prompt: I18n.t('admin.accounts.moderation.all') - if @action_logs.empty? .muted-hint.center-text diff --git a/app/views/admin/announcements/_form.html.haml b/app/views/admin/announcements/_form.html.haml new file mode 100644 index 0000000000..3a9b371907 --- /dev/null +++ b/app/views/admin/announcements/_form.html.haml @@ -0,0 +1,28 @@ +.fields-group + = form.input :starts_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label + = form.input :ends_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label + +.fields-group + = form.input :all_day, + as: :boolean, + wrapper: :with_label + +.fields-group + = form.input :text, + wrapper: :with_block_label + +- unless form.object.published? + .fields-group + = form.input :scheduled_at, + html5: true, + include_blank: true, + input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder }, + wrapper: :with_block_label diff --git a/app/views/admin/announcements/edit.html.haml b/app/views/admin/announcements/edit.html.haml index 150d98272f..8cec7d36c2 100644 --- a/app/views/admin/announcements/edit.html.haml +++ b/app/views/admin/announcements/edit.html.haml @@ -1,22 +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, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } - = f.input :ends_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } - - .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, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } + = 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 0123632ff4..266ca65e80 100644 --- a/app/views/admin/announcements/new.html.haml +++ b/app/views/admin/announcements/new.html.haml @@ -1,21 +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, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } - = f.input :ends_at, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } - - .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, include_blank: true, wrapper: :with_block_label, html5: true, input_html: { pattern: datetime_pattern, placeholder: datetime_placeholder } + = 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 8b4e93ac35..82fec554b0 100644 --- a/app/views/admin/custom_emojis/index.html.haml +++ b/app/views/admin/custom_emojis/index.html.haml @@ -21,20 +21,23 @@ - else = filter_link_to t('admin.accounts.location.remote'), remote: '1', local: nil -= form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do += form_with url: admin_custom_emojis_url, method: :get, class: :simple_form do |form| .fields-group - CustomEmojiFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? - %i(shortcode by_domain).each do |key| .input.string.optional - = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.custom_emojis.#{key}") + = form.text_field key, + value: params[key], + class: 'string optional', + placeholder: I18n.t("admin.custom_emojis.#{key}") .actions %button.button= t('admin.accounts.search') = link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative' -= form_for(@form, url: batch_admin_custom_emojis_path) do |f| += form_with model: @form, url: batch_admin_custom_emojis_path do |f| = hidden_field_tag :page, params[:page] || 1 - CustomEmojiFilter::KEYS.each do |key| @@ -48,19 +51,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 @@ -68,12 +71,19 @@ .fields-group.fields-row__column.fields-row__column-6 .input.select.optional .label_input - = f.select :category_id, options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'), prompt: t('admin.custom_emojis.assign_category'), class: 'select optional', 'aria-label': t('admin.custom_emojis.assign_category') + = f.select :category_id, + options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'), + 'aria-label': t('admin.custom_emojis.assign_category'), + class: 'select optional', + prompt: t('admin.custom_emojis.assign_category') .fields-group.fields-row__column.fields-row__column-6 .input.string.optional .label_input - = f.text_field :category_name, class: 'string optional', placeholder: t('admin.custom_emojis.create_new_category'), 'aria-label': t('admin.custom_emojis.create_new_category') + = f.text_field :category_name, + 'aria-label': t('admin.custom_emojis.create_new_category'), + class: 'string optional', + placeholder: t('admin.custom_emojis.create_new_category') .batch-table__body - if @custom_emojis.empty? diff --git a/app/views/admin/custom_emojis/new.html.haml b/app/views/admin/custom_emojis/new.html.haml index a03676b001..e59ae02b3b 100644 --- a/app/views/admin/custom_emojis/new.html.haml +++ b/app/views/admin/custom_emojis/new.html.haml @@ -5,9 +5,17 @@ = render 'shared/error_messages', object: @custom_emoji .fields-group - = f.input :shortcode, wrapper: :with_label, label: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint') + = f.input :shortcode, + wrapper: :with_label, + label: t('admin.custom_emojis.shortcode'), + hint: t('admin.custom_emojis.shortcode_hint') .fields-group - = f.input :image, wrapper: :with_label, input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(',') }, hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT)) + = f.input :image, + wrapper: :with_label, + input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(',') }, + hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT)) .actions - = f.button :button, t('admin.custom_emojis.upload'), type: :submit + = f.button :button, + t('admin.custom_emojis.upload'), + type: :submit diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index 3597152e09..8430dd3c4f 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -16,53 +16,106 @@ .dashboard .dashboard__item - = react_admin_component :counter, measure: 'new_users', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.new_users'), href: admin_accounts_path(origin: 'local') + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_accounts_path(origin: 'local'), + label: t('admin.dashboard.new_users'), + measure: 'new_users', + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'active_users', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.active_users'), href: admin_accounts_path(origin: 'local') + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_accounts_path(origin: 'local'), + label: t('admin.dashboard.active_users'), + measure: 'active_users', + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'interactions', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.interactions') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.dashboard.interactions'), + measure: 'interactions', + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'opened_reports', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.opened_reports'), href: admin_reports_path + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_reports_path, + label: t('admin.dashboard.opened_reports'), + measure: 'opened_reports', + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'resolved_reports', start_at: @time_period.first, end_at: @time_period.last, label: t('admin.dashboard.resolved_reports'), href: admin_reports_path(resolved: '1') + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_reports_path(resolved: '1'), + label: t('admin.dashboard.resolved_reports'), + measure: 'resolved_reports', + start_at: @time_period.first .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', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.sources') + = react_admin_component :dimension, + dimension: 'sources', + end_at: @time_period.last, + label: t('admin.dashboard.sources'), + limit: 8, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'languages', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.top_languages') + = react_admin_component :dimension, + dimension: 'languages', + end_at: @time_period.last, + label: t('admin.dashboard.top_languages'), + limit: 8, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'servers', start_at: @time_period.first, end_at: @time_period.last, limit: 8, label: t('admin.dashboard.top_servers') + = react_admin_component :dimension, + dimension: 'servers', + end_at: @time_period.last, + label: t('admin.dashboard.top_servers'), + limit: 8, + start_at: @time_period.first .dashboard__item.dashboard__item--span-double-column - = react_admin_component :retention, start_at: @time_period.last - 6.months, end_at: @time_period.last, frequency: 'month' + = react_admin_component :retention, + end_at: @time_period.last, + frequency: 'month', + start_at: @time_period.last - 6.months .dashboard__item.dashboard__item--span-double-row - = react_admin_component :trends, limit: 7 + = react_admin_component :trends, + limit: 7 .dashboard__item - = react_admin_component :dimension, dimension: 'software_versions', start_at: @time_period.first, end_at: @time_period.last, limit: 4, label: t('admin.dashboard.software') + = react_admin_component :dimension, + dimension: 'software_versions', + end_at: @time_period.last, + label: t('admin.dashboard.software'), + limit: 4, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'space_usage', start_at: @time_period.first, end_at: @time_period.last, limit: 3, label: t('admin.dashboard.space') + = react_admin_component :dimension, + dimension: 'space_usage', + end_at: @time_period.last, + label: t('admin.dashboard.space'), + limit: 3, + start_at: @time_period.first 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 0000000000..f1785a1fdd --- /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/confirm_suspension.html.haml b/app/views/admin/domain_blocks/confirm_suspension.html.haml index a5df8ba3f3..4c4f92d710 100644 --- a/app/views/admin/domain_blocks/confirm_suspension.html.haml +++ b/app/views/admin/domain_blocks/confirm_suspension.html.haml @@ -14,7 +14,8 @@ %hr.spacer - = react_admin_component :impact_report, domain: @domain_block.domain + = react_admin_component :impact_report, + domain: @domain_block.domain .actions = link_to t('.cancel'), admin_instances_path, class: 'button button-tertiary' diff --git a/app/views/admin/domain_blocks/edit.html.haml b/app/views/admin/domain_blocks/edit.html.haml index ae76b6777a..40c46b8b6b 100644 --- a/app/views/admin/domain_blocks/edit.html.haml +++ b/app/views/admin/domain_blocks/edit.html.haml @@ -1,30 +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, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('admin.domain_blocks.new.hint'), required: true, readonly: true, disabled: true - - .fields-row__column.fields-row__column-6.fields-group - = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: ->(type) { t("admin.domain_blocks.new.severity.#{type}") }, hint: t('admin.domain_blocks.new.severity.desc_html') - - .fields-group - = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint') - - .fields-group - = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint') - - .fields-group - = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint') - - .field-group - = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), as: :string - - .field-group - = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), as: :string + = 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 86e519f451..78bcfcba8e 100644 --- a/app/views/admin/domain_blocks/new.html.haml +++ b/app/views/admin/domain_blocks/new.html.haml @@ -1,30 +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, wrapper: :with_label, label: t('admin.domain_blocks.domain'), hint: t('.hint'), required: true - - .fields-row__column.fields-row__column-6.fields-group - = f.input :severity, collection: DomainBlock.severities.keys, wrapper: :with_label, include_blank: false, label_method: ->(type) { t(".severity.#{type}") }, hint: t('.severity.desc_html') - - .fields-group - = f.input :reject_media, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_media'), hint: I18n.t('admin.domain_blocks.reject_media_hint') - - .fields-group - = f.input :reject_reports, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.reject_reports'), hint: I18n.t('admin.domain_blocks.reject_reports_hint') - - .fields-group - = f.input :obfuscate, as: :boolean, wrapper: :with_label, label: I18n.t('admin.domain_blocks.obfuscate'), hint: I18n.t('admin.domain_blocks.obfuscate_hint') - - .field-group - = f.input :private_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.private_comment'), hint: t('admin.domain_blocks.private_comment_hint'), as: :string - - .field-group - = f.input :public_comment, wrapper: :with_label, label: I18n.t('admin.domain_blocks.public_comment'), hint: t('admin.domain_blocks.public_comment_hint'), as: :string + = 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 9f16e0d5c3..4fae6557a5 100644 --- a/app/views/admin/email_domain_blocks/index.html.haml +++ b/app/views/admin/email_domain_blocks/index.html.haml @@ -4,7 +4,7 @@ - content_for :heading_actions do = link_to t('admin.email_domain_blocks.add_new'), new_admin_email_domain_block_path, class: 'button' -= form_for(@form, url: batch_admin_email_domain_blocks_path) do |f| += form_with model: @form, url: batch_admin_email_domain_blocks_path do |f| = hidden_field_tag :page, params[:page] || 1 .batch-table @@ -12,7 +12,11 @@ %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')]), 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.email_domain_blocks.delete')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :delete, + type: :submit .batch-table__body - if @email_domain_blocks.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/email_domain_blocks/new.html.haml b/app/views/admin/email_domain_blocks/new.html.haml index 3d31487733..dd4b83ee3f 100644 --- a/app/views/admin/email_domain_blocks/new.html.haml +++ b/app/views/admin/email_domain_blocks/new.html.haml @@ -5,10 +5,16 @@ = render 'shared/error_messages', object: @email_domain_block .fields-group - = f.input :domain, wrapper: :with_block_label, label: t('admin.email_domain_blocks.domain'), input_html: { readonly: defined?(@resolved_records) } + = f.input :domain, + input_html: { readonly: defined?(@resolved_records) }, + label: t('admin.email_domain_blocks.domain'), + wrapper: :with_block_label .fields-group - = f.input :allow_with_approval, wrapper: :with_label, hint: false, label: I18n.t('admin.email_domain_blocks.allow_registrations_with_approval') + = f.input :allow_with_approval, + hint: false, + label: I18n.t('admin.email_domain_blocks.allow_registrations_with_approval'), + wrapper: :with_label - if defined?(@resolved_records) %p.hint= t('admin.email_domain_blocks.resolved_dns_records_hint_html') @@ -22,7 +28,11 @@ - @resolved_records.each do |record| .batch-table__row %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox - = f.input_field :other_domains, as: :boolean, checked_value: record.exchange.to_s, include_hidden: false, multiple: true + = f.input_field :other_domains, + as: :boolean, + checked_value: record.exchange.to_s, + include_hidden: false, + multiple: true .batch-table__row__content.pending-account .pending-account__header %samp= record.exchange.to_s diff --git a/app/views/admin/export_domain_allows/new.html.haml b/app/views/admin/export_domain_allows/new.html.haml index dc0cf8c52a..66c6aa8d8a 100644 --- a/app/views/admin/export_domain_allows/new.html.haml +++ b/app/views/admin/export_domain_allows/new.html.haml @@ -4,7 +4,10 @@ = simple_form_for @import, url: import_admin_export_domain_allows_path, html: { multipart: true } do |f| .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data'), as: :file + = f.input :data, + as: :file, + hint: t('simple_form.hints.imports.data'), + wrapper: :with_block_label .actions = f.button :button, t('imports.upload'), type: :submit 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 cdce4fd28a..79cc5595ca 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 01add232d1..2b0d2c5eb3 100644 --- a/app/views/admin/export_domain_blocks/import.html.haml +++ b/app/views/admin/export_domain_blocks/import.html.haml @@ -6,13 +6,17 @@ - if defined?(@global_private_comment) && @global_private_comment.present? %p= t('admin.export_domain_blocks.import.private_comment_description_html', comment: @global_private_comment) -= form_for(@form, url: batch_admin_domain_blocks_path) do |f| += form_with model: @form, url: batch_admin_domain_blocks_path do |f| .batch-table .batch-table__toolbar %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')]), name: :save, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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, + type: :submit .batch-table__body - if @domain_blocks.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/export_domain_blocks/new.html.haml b/app/views/admin/export_domain_blocks/new.html.haml index 0291aeed77..9c960d47fe 100644 --- a/app/views/admin/export_domain_blocks/new.html.haml +++ b/app/views/admin/export_domain_blocks/new.html.haml @@ -4,7 +4,10 @@ = simple_form_for @import, url: import_admin_export_domain_blocks_path, html: { multipart: true } do |f| .fields-row .fields-group.fields-row__column.fields-row__column-6 - = f.input :data, wrapper: :with_block_label, hint: t('simple_form.hints.imports.data'), as: :file + = f.input :data, + as: :file, + hint: t('simple_form.hints.imports.data'), + wrapper: :with_block_label .actions = f.button :button, t('imports.upload'), type: :submit diff --git a/app/views/admin/follow_recommendations/show.html.haml b/app/views/admin/follow_recommendations/show.html.haml index 9c2063d3c5..62cd315725 100644 --- a/app/views/admin/follow_recommendations/show.html.haml +++ b/app/views/admin/follow_recommendations/show.html.haml @@ -5,22 +5,23 @@ %hr.spacer/ -= form_tag admin_follow_recommendations_path, method: 'GET', class: 'simple_form' do += form_with url: admin_follow_recommendations_path, method: :get, class: :simple_form do |form| - RelationshipFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? .filters .filter-subset.filter-subset--with-select %strong= t('admin.follow_recommendations.language') .input.select.optional - = select_tag :language, options_for_select(Trends.available_locales.map { |key| [standard_locale_name(key), key] }, @language) + = form.select :language, + options_for_select(Trends.available_locales.map { |key| [standard_locale_name(key), key] }, @language) .filter-subset %strong= t('admin.follow_recommendations.status') %ul %li= filter_link_to t('admin.accounts.moderation.active'), status: nil %li= filter_link_to t('admin.follow_recommendations.suppressed'), status: 'suppressed' -= form_for(@form, url: admin_follow_recommendations_path, method: :patch) do |f| += form_with model: @form, url: admin_follow_recommendations_path, method: :patch do |f| - RelationshipFilter::KEYS.each do |key| = hidden_field_tag key, params[key] if params[key].present? @@ -30,9 +31,16 @@ = 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')]), name: :suppress, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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')]), name: :unsuppress, class: 'table-action-link', type: :submit + = f.button safe_join([material_symbol('add'), t('admin.follow_recommendations.unsuppress')]), + class: 'table-action-link', + name: :unsuppress, + type: :submit .batch-table__body - if @accounts.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/instances/_instance.html.haml b/app/views/admin/instances/_instance.html.haml index 65cf789ce3..522a2444bb 100644 --- a/app/views/admin/instances/_instance.html.haml +++ b/app/views/admin/instances/_instance.html.haml @@ -7,6 +7,10 @@ %small - if instance.domain_block = instance.domain_block.policies.map { |policy| t(policy, scope: 'admin.instances.content_policies.policies') }.join(' ยท ') + - if instance.domain_block.public_comment.present? + %span.comment.public-comment #{t('admin.domain_blocks.public_comment')}: #{instance.domain_block.public_comment} + - if instance.domain_block.private_comment.present? + %span.comment.private-comment #{t('admin.domain_blocks.private_comment')}: #{instance.domain_block.private_comment} - elsif instance.domain_allow = t('admin.accounts.whitelisted') - else diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml index 7e43b4c538..b5f084f880 100644 --- a/app/views/admin/instances/index.html.haml +++ b/app/views/admin/instances/index.html.haml @@ -28,14 +28,17 @@ %li= filter_link_to t('admin.instances.delivery.unavailable'), availability: 'unavailable' - unless limited_federation_mode? - = form_tag admin_instances_url, method: 'GET', class: 'simple_form' do + = form_with url: admin_instances_url, method: :get, class: :simple_form do |form| .fields-group - InstanceFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? - %i(by_domain).each do |key| .input.string.optional - = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.instances.#{key}") + = form.text_field key, + value: params[key], + class: 'string optional', + placeholder: I18n.t("admin.instances.#{key}") .actions %button.button= t('admin.accounts.search') diff --git a/app/views/admin/instances/show.html.haml b/app/views/admin/instances/show.html.haml index 5f2664df76..d916203d0c 100644 --- a/app/views/admin/instances/show.html.haml +++ b/app/views/admin/instances/show.html.haml @@ -9,26 +9,71 @@ - if @instance.persisted? %p - = fa_icon 'info fw' + = material_symbol 'info' = t('admin.instances.totals_time_period_hint_html') .dashboard .dashboard__item - = react_admin_component :counter, measure: 'instance_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_accounts_measure'), href: admin_accounts_path(origin: 'remote', by_domain: @instance.domain) + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_accounts_path(origin: 'remote', by_domain: @instance.domain), + label: t('admin.instances.dashboard.instance_accounts_measure'), + measure: 'instance_accounts', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'instance_statuses', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_statuses_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_statuses_measure'), + measure: 'instance_statuses', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'instance_media_attachments', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_media_attachments_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_media_attachments_measure'), + measure: 'instance_media_attachments', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'instance_follows', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_follows_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_follows_measure'), + measure: 'instance_follows', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'instance_followers', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_followers_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_followers_measure'), + measure: 'instance_followers', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'instance_reports', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, label: t('admin.instances.dashboard.instance_reports_measure'), href: admin_reports_path(by_target_domain: @instance.domain) + = react_admin_component :counter, + end_at: @time_period.last, + href: admin_reports_path(by_target_domain: @instance.domain), + label: t('admin.instances.dashboard.instance_reports_measure'), + measure: 'instance_reports', + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'instance_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, limit: 8, label: t('admin.instances.dashboard.instance_accounts_dimension') + = react_admin_component :dimension, + dimension: 'instance_accounts', + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_accounts_dimension'), + limit: 8, + params: { domain: @instance.domain }, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'instance_languages', start_at: @time_period.first, end_at: @time_period.last, params: { domain: @instance.domain }, limit: 8, label: t('admin.instances.dashboard.instance_languages_dimension') + = react_admin_component :dimension, + dimension: 'instance_languages', + end_at: @time_period.last, + label: t('admin.instances.dashboard.instance_languages_dimension'), + limit: 8, + params: { domain: @instance.domain }, + start_at: @time_period.first + - else %p = t('admin.instances.unknown_instance') diff --git a/app/views/admin/invites/_invite.html.haml b/app/views/admin/invites/_invite.html.haml index e6ad9de34c..f9cd6003f3 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 a48e4791a3..207d23aeeb 100644 --- a/app/views/admin/ip_blocks/index.html.haml +++ b/app/views/admin/ip_blocks/index.html.haml @@ -5,7 +5,7 @@ - content_for :heading_actions do = link_to t('admin.ip_blocks.add_new'), new_admin_ip_block_path, class: 'button' -= form_for(@form, url: batch_admin_ip_blocks_path) do |f| += form_with model: @form, url: batch_admin_ip_blocks_path do |f| = hidden_field_tag :page, params[:page] || 1 .batch-table @@ -14,7 +14,11 @@ = 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')]), 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.ip_blocks.delete')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :delete, + type: :submit .batch-table__body - if @ip_blocks.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/ip_blocks/new.html.haml b/app/views/admin/ip_blocks/new.html.haml index ecaf04315b..81493012c6 100644 --- a/app/views/admin/ip_blocks/new.html.haml +++ b/app/views/admin/ip_blocks/new.html.haml @@ -5,16 +5,30 @@ = render 'shared/error_messages', object: @ip_block .fields-group - = f.input :ip, as: :string, wrapper: :with_block_label, input_html: { placeholder: '192.0.2.0/24' } + = f.input :ip, + as: :string, + input_html: { placeholder: '192.0.2.0/24' }, + wrapper: :with_block_label .fields-group - = f.input :expires_in, wrapper: :with_block_label, collection: [1.day, 2.weeks, 1.month, 6.months, 1.year, 3.years].map(&:to_i), label_method: ->(i) { I18n.t("admin.ip_blocks.expires_in.#{i}") }, prompt: I18n.t('invites.expires_in_prompt') + = f.input :expires_in, + collection: [1.day, 2.weeks, 1.month, 6.months, 1.year, 3.years].map(&:to_i), + label_method: ->(i) { I18n.t("admin.ip_blocks.expires_in.#{i}") }, + prompt: I18n.t('invites.expires_in_prompt'), + wrapper: :with_block_label .fields-group - = f.input :severity, as: :radio_buttons, collection: IpBlock.severities.keys, include_blank: false, wrapper: :with_block_label, label_method: ->(severity) { ip_blocks_severity_label(severity) } + = f.input :severity, + as: :radio_buttons, + collection: IpBlock.severities.keys, + include_blank: false, + label_method: ->(severity) { ip_blocks_severity_label(severity) }, + wrapper: :with_block_label .fields-group - = f.input :comment, as: :string, wrapper: :with_block_label + = f.input :comment, + as: :string, + wrapper: :with_block_label .actions = f.button :button, t('admin.ip_blocks.add_new'), type: :submit diff --git a/app/views/admin/relationships/index.html.haml b/app/views/admin/relationships/index.html.haml index f82cf26a38..83ffd139de 100644 --- a/app/views/admin/relationships/index.html.haml +++ b/app/views/admin/relationships/index.html.haml @@ -19,18 +19,22 @@ .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/ -= form_for(@form, url: batch_admin_accounts_path) do |f| += form_with model: @form, url: batch_admin_accounts_path do |f| .batch-table .batch-table__toolbar %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')]), name: :suspend, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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, + type: :submit .batch-table__body - if @accounts.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/relays/_relay.html.haml b/app/views/admin/relays/_relay.html.haml index f1dd2b2dd1..0960124ccf 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/_actions.html.haml b/app/views/admin/reports/_actions.html.haml index da9ac89315..5fb540931b 100644 --- a/app/views/admin/reports/_actions.html.haml +++ b/app/views/admin/reports/_actions.html.haml @@ -1,4 +1,4 @@ -= form_tag preview_admin_report_actions_path(report), method: :post do += form_with url: preview_admin_report_actions_path(report) do |form| .report-actions .report-actions__item .report-actions__item__button @@ -8,26 +8,36 @@ - if statuses.any? { |status| (status.with_media? || status.with_preview_card?) && !status.discarded? } .report-actions__item .report-actions__item__button - = button_tag t('admin.reports.mark_as_sensitive'), name: :mark_as_sensitive, class: 'button' + = form.button t('admin.reports.mark_as_sensitive'), + name: :mark_as_sensitive, + class: 'button' .report-actions__item__description = t('admin.reports.actions.mark_as_sensitive_description_html') .report-actions__item .report-actions__item__button - = button_tag t('admin.reports.delete_and_resolve'), name: :delete, class: 'button button--destructive' + = form.button t('admin.reports.delete_and_resolve'), + name: :delete, + class: 'button button--destructive' .report-actions__item__description = t('admin.reports.actions.delete_description_html') .report-actions__item .report-actions__item__button - = button_tag t('admin.accounts.silence'), name: :silence, class: 'button button--destructive' + = form.button t('admin.accounts.silence'), + name: :silence, + class: 'button button--destructive' .report-actions__item__description = t('admin.reports.actions.silence_description_html') .report-actions__item .report-actions__item__button - = button_tag t('admin.accounts.suspend'), name: :suspend, class: 'button button--destructive' + = form.button t('admin.accounts.suspend'), + name: :suspend, + class: 'button button--destructive' .report-actions__item__description = t('admin.reports.actions.suspend_description_html') .report-actions__item .report-actions__item__button - = link_to t('admin.accounts.custom'), new_admin_account_action_path(report.target_account_id, report_id: report.id), class: 'button' + = link_to t('admin.accounts.custom'), + new_admin_account_action_path(report.target_account_id, report_id: report.id), + class: 'button' .report-actions__item__description = t('admin.reports.actions.other_description_html') diff --git a/app/views/admin/reports/_header_card.html.haml b/app/views/admin/reports/_header_card.html.haml index 6fd8b4ecc8..52e62b4499 100644 --- a/app/views/admin/reports/_header_card.html.haml +++ b/app/views/admin/reports/_header_card.html.haml @@ -1,5 +1,11 @@ .report-header__card .account-card + - if report.target_account.suspended? + .account-card__warning-badge + - if report.target_account.suspension_origin_local? + = t('admin.reports.already_suspended_badges.local') + - else + = t('admin.reports.already_suspended_badges.remote') .account-card__header = image_tag report.target_account.header.url, alt: '' .account-card__title @@ -10,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 b2982a42bf..66820f0a6e 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -22,7 +22,9 @@ %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) - if status.edited? ยท - = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')), admin_account_status_path(status.account_id, status), class: 'detailed-status__datetime' + = link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')), + admin_account_status_path(status.account_id, status), + class: 'detailed-status__datetime' - if status.discarded? ยท %span.negative-hint= t('admin.statuses.deleted') @@ -35,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 8634bb215c..79c444453f 100644 --- a/app/views/admin/reports/actions/preview.html.haml +++ b/app/views/admin/reports/actions/preview.html.haml @@ -4,8 +4,8 @@ - content_for :page_title do = t('admin.reports.confirm_action', acct: target_acct) -= form_tag admin_report_actions_path(@report), class: 'simple_form', method: :post do - = hidden_field_tag :moderation_action, @moderation_action += form_with url: admin_report_actions_path(@report), class: :simple_form do |form| + = form.hidden_field :moderation_action, value: @moderation_action %p.hint= t("admin.reports.summary.action_preambles.#{@moderation_action}_html", acct: target_acct) %ul.hint @@ -30,7 +30,9 @@ %p= t "user_mailer.warning.explanation.#{warning_action}", instance: Rails.configuration.x.local_domain .fields-group - = text_area_tag :text, nil, placeholder: t('admin.reports.summary.warning_placeholder') + = form.text_area :text, + value: nil, + placeholder: t('admin.reports.summary.warning_placeholder') - unless @report.other? %p @@ -58,7 +60,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 @@ -75,4 +77,7 @@ .actions = link_to t('admin.reports.cancel'), admin_report_path(@report), class: 'button button-tertiary' - = button_tag t('admin.reports.confirm'), name: :confirm, class: 'button', type: :submit + = form.button t('admin.reports.confirm'), + name: :confirm, + class: 'button', + type: :submit diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index e2a9868aa5..dae2c1aa5b 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -14,14 +14,17 @@ %li= filter_link_to t('admin.accounts.location.local'), target_origin: 'local' %li= filter_link_to t('admin.accounts.location.remote'), target_origin: 'remote' -= form_tag admin_reports_url, method: 'GET', class: 'simple_form' do += form_with url: admin_reports_url, method: :get, class: :simple_form do |form| .fields-group - ReportFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? - %i(by_target_domain).each do |key| .input.string.optional - = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.reports.#{key}") + = form.text_field key, + value: params[key], + class: 'string optional', + placeholder: I18n.t("admin.reports.#{key}") .actions %button.button= t('admin.accounts.search') diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index 4376e5af4d..ca1edea0fe 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -20,7 +20,11 @@ %p= t 'admin.reports.category_description_html' -= react_admin_component :report_reason_selector, id: @report.id, category: @report.category, rule_ids: @report.rule_ids&.map(&:to_s), disabled: @report.action_taken? += react_admin_component :report_reason_selector, + category: @report.category, + disabled: @report.action_taken?, + id: @report.id, + rule_ids: @report.rule_ids&.map(&:to_s) - if @report.comment.present? = render 'admin/reports/comment', report: @report @@ -37,16 +41,18 @@ %p = t 'admin.reports.statuses_description_html' โ€” - = link_to safe_join([fa_icon('plus'), t('admin.reports.add_to_report')]), admin_account_statuses_path(@report.target_account_id, report_id: @report.id), class: 'table-action-link' + = 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' -= form_for(@form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id)) do |f| += form_with model: @form, url: batch_admin_account_statuses_path(@report.target_account_id, report_id: @report.id) do |f| .batch-table .batch-table__toolbar %label.batch-table__toolbar__select.batch-checkbox-all = 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' @@ -77,15 +83,17 @@ .report-notes = render @report_notes -= simple_form_for @report_note, url: admin_report_notes_path do |f| - = f.input :report_id, as: :hidden += simple_form_for @report_note, url: admin_report_notes_path do |form| + = form.input :report_id, as: :hidden + + = render 'shared/error_messages', object: @report_note .field-group - = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6 + = form.input :content, input_html: { placeholder: t('admin.reports.notes.placeholder'), maxlength: ReportNote::CONTENT_SIZE_LIMIT, rows: 6, autofocus: @report_note.errors.any? } .actions - if @report.unresolved? - = f.button :button, t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, type: :submit + = form.button :button, t('admin.reports.notes.create_and_resolve'), name: :create_and_resolve, type: :submit - else - = f.button :button, t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, type: :submit - = f.button :button, t('admin.reports.notes.create'), type: :submit + = form.button :button, t('admin.reports.notes.create_and_unresolve'), name: :create_and_unresolve, type: :submit + = form.button :button, t('admin.reports.notes.create'), type: :submit diff --git a/app/views/admin/roles/_form.html.haml b/app/views/admin/roles/_form.html.haml index 46a1c537a7..0b1c310162 100644 --- a/app/views/admin/roles/_form.html.haml +++ b/app/views/admin/roles/_form.html.haml @@ -5,19 +5,25 @@ = t('admin.roles.everyone_full_description_html') - else .fields-group - = form.input :name, wrapper: :with_label + = form.input :name, + wrapper: :with_label - unless current_user.role == form.object .fields-group - = form.input :position, wrapper: :with_label, input_html: { max: current_user.role.position - 1 } + = form.input :position, + input_html: { max: current_user.role.position - 1 }, + wrapper: :with_label .fields-group - = form.input :color, wrapper: :with_label, input_html: { placeholder: '#000000', type: 'color' } + = form.input :color, + input_html: { placeholder: '#000000', type: 'color' }, + wrapper: :with_label %hr.spacer/ .fields-group - = form.input :highlighted, wrapper: :with_label + = form.input :highlighted, + wrapper: :with_label %hr.spacer/ @@ -31,6 +37,17 @@ - (form.object.everyone? ? UserRole::Flags::CATEGORIES.slice(:invites) : UserRole::Flags::CATEGORIES).each do |category, permissions| %h4= t(category, scope: 'admin.roles.categories') - = form.input :permissions_as_keys, collection: permissions, wrapper: :with_block_label, include_blank: false, label_method: ->(privilege) { privilege_label(privilege) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label: false, hint: false, disabled: disable_permissions?(permissions) + = form.input :permissions_as_keys, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: permissions, + disabled: disable_permissions?(permissions), + hint: false, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(privilege) { privilege_label(privilege) }, + label: false, + required: false, + wrapper: :with_block_label %hr.spacer/ diff --git a/app/views/admin/roles/_role.html.haml b/app/views/admin/roles/_role.html.haml index d6c6b62c81..fd37644c83 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/_form.html.haml b/app/views/admin/rules/_form.html.haml new file mode 100644 index 0000000000..9fc54e2887 --- /dev/null +++ b/app/views/admin/rules/_form.html.haml @@ -0,0 +1,7 @@ +.fields-group + = form.input :text, + wrapper: :with_block_label + +.fields-group + = form.input :hint, + wrapper: :with_block_label diff --git a/app/views/admin/rules/_rule.html.haml b/app/views/admin/rules/_rule.html.haml index a0896fe806..5f37f69354 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/rules/edit.html.haml b/app/views/admin/rules/edit.html.haml index ba7e6451a1..9e3c915812 100644 --- a/app/views/admin/rules/edit.html.haml +++ b/app/views/admin/rules/edit.html.haml @@ -1,11 +1,10 @@ - content_for :page_title do = t('admin.rules.edit') -= simple_form_for @rule, url: admin_rule_path(@rule) do |f| += simple_form_for @rule, url: admin_rule_path(@rule) do |form| = render 'shared/error_messages', object: @rule - .fields-group - = f.input :text, 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/rules/index.html.haml b/app/views/admin/rules/index.html.haml index aa6a4c1b6a..5a2789edcf 100644 --- a/app/views/admin/rules/index.html.haml +++ b/app/views/admin/rules/index.html.haml @@ -6,14 +6,13 @@ %hr.spacer/ - if can? :create, :rule - = simple_form_for @rule, url: admin_rules_path do |f| + = simple_form_for @rule, url: admin_rules_path do |form| = render 'shared/error_messages', object: @rule - .fields-group - = f.input :text, wrapper: :with_block_label + = render form .actions - = f.button :button, t('admin.rules.add_new'), type: :submit + = form.button :button, t('admin.rules.add_new'), type: :submit %hr.spacer/ diff --git a/app/views/admin/settings/about/show.html.haml b/app/views/admin/settings/about/show.html.haml index 1237c20fa8..1eb47a0b54 100644 --- a/app/views/admin/settings/about/show.html.haml +++ b/app/views/admin/settings/about/show.html.haml @@ -11,7 +11,10 @@ %p.lead= t('admin.settings.about.preamble') .fields-group - = f.input :site_extended_description, wrapper: :with_block_label, as: :text, input_html: { rows: 8 } + = f.input :site_extended_description, + as: :text, + input_html: { rows: 8 }, + wrapper: :with_block_label %p.hint = t 'admin.settings.about.rules_hint' @@ -19,15 +22,32 @@ .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :show_domain_blocks, wrapper: :with_label, collection: %i(disabled users all), label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :show_domain_blocks, + collection_wrapper_tag: 'ul', + collection: %i(disabled users all), + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, + wrapper: :with_label .fields-row__column.fields-row__column-6.fields-group - = f.input :show_domain_blocks_rationale, wrapper: :with_label, collection: %i(disabled users all), label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, include_blank: false, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li' + = f.input :show_domain_blocks_rationale, + collection_wrapper_tag: 'ul', + collection: %i(disabled users all), + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(value) { t("admin.settings.domain_blocks.#{value}") }, + wrapper: :with_label .fields-group - = f.input :status_page_url, wrapper: :with_block_label, input_html: { placeholder: "https://status.#{Rails.configuration.x.local_domain}" } + = f.input :status_page_url, + input_html: { placeholder: "https://status.#{Rails.configuration.x.local_domain}" }, + wrapper: :with_block_label .fields-group - = f.input :site_terms, wrapper: :with_block_label, as: :text, input_html: { rows: 8 } + = f.input :site_terms, + as: :text, + input_html: { rows: 8 }, + wrapper: :with_block_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/appearance/show.html.haml b/app/views/admin/settings/appearance/show.html.haml index ed61774c9b..3ef4920cd5 100644 --- a/app/views/admin/settings/appearance/show.html.haml +++ b/app/views/admin/settings/appearance/show.html.haml @@ -11,14 +11,23 @@ %p.lead= t('admin.settings.appearance.preamble') .fields-group - = f.input :theme, collection: Themes.instance.names, label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false + = f.input :theme, + collection: Themes.instance.names, + include_blank: false, + label_method: ->(theme) { I18n.t("themes.#{theme}", default: theme) }, + wrapper: :with_label .fields-group - = f.input :custom_css, wrapper: :with_block_label, as: :text, input_html: { rows: 8 } + = f.input :custom_css, + as: :text, + input_html: { rows: 8 }, + wrapper: :with_block_label .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :mascot, as: :file, wrapper: :with_block_label + = f.input :mascot, + as: :file, + wrapper: :with_block_label .fields-row__column.fields-row__column-6.fields-group - if @admin_settings.mascot.persisted? diff --git a/app/views/admin/settings/branding/show.html.haml b/app/views/admin/settings/branding/show.html.haml index aee7306892..71aac5ead1 100644 --- a/app/views/admin/settings/branding/show.html.haml +++ b/app/views/admin/settings/branding/show.html.haml @@ -11,20 +11,28 @@ %p.lead= t('admin.settings.branding.preamble') .fields-group - = f.input :site_title, wrapper: :with_label + = f.input :site_title, + wrapper: :with_label .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :site_contact_username, wrapper: :with_label + = f.input :site_contact_username, + wrapper: :with_label .fields-row__column.fields-row__column-6.fields-group - = f.input :site_contact_email, wrapper: :with_label + = f.input :site_contact_email, + wrapper: :with_label .fields-group - = f.input :site_short_description, wrapper: :with_block_label, as: :text, input_html: { rows: 2, maxlength: 200 } + = f.input :site_short_description, + as: :text, + input_html: { rows: 2, maxlength: 200 }, + wrapper: :with_block_label .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :thumbnail, as: :file, wrapper: :with_block_label + = f.input :thumbnail, + as: :file, + wrapper: :with_block_label .fields-row__column.fields-row__column-6.fields-group - if @admin_settings.thumbnail.persisted? = image_tag @admin_settings.thumbnail.file.url(:'@1x'), class: 'fields-group__thumbnail' @@ -32,5 +40,33 @@ = fa_icon 'trash fw' = t('admin.site_uploads.delete') + .fields-row + .fields-row__column.fields-row__column-6.fields-group + = f.input :favicon, + as: :file, + input_html: { accept: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].join(',') }, + wrapper: :with_block_label + + .fields-row__column.fields-row__column-6.fields-group + - if @admin_settings.favicon.persisted? + = image_tag @admin_settings.favicon.file.url('48'), class: 'fields-group__thumbnail' + = link_to admin_site_upload_path(@admin_settings.favicon), data: { method: :delete }, class: 'link-button link-button--destructive' do + = fa_icon 'trash fw' + = t('admin.site_uploads.delete') + + .fields-row + .fields-row__column.fields-row__column-6.fields-group + = f.input :app_icon, + as: :file, + input_html: { accept: ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].join(',') }, + wrapper: :with_block_label + + .fields-row__column.fields-row__column-6.fields-group + - if @admin_settings.app_icon.persisted? + = image_tag @admin_settings.app_icon.file.url('48'), class: 'fields-group__thumbnail' + = link_to admin_site_upload_path(@admin_settings.app_icon), data: { method: :delete }, class: 'link-button link-button--destructive' do + = fa_icon 'trash fw' + = t('admin.site_uploads.delete') + .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/content_retention/show.html.haml b/app/views/admin/settings/content_retention/show.html.haml index 5a67016148..57485c1108 100644 --- a/app/views/admin/settings/content_retention/show.html.haml +++ b/app/views/admin/settings/content_retention/show.html.haml @@ -11,9 +11,21 @@ %p.lead= t('admin.settings.content_retention.preamble') .fields-group - = f.input :media_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' } - = f.input :content_cache_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' }, hint: false, warning_hint: t('simple_form.hints.form_admin_settings.content_cache_retention_period') - = f.input :backups_retention_period, wrapper: :with_block_label, input_html: { pattern: '[0-9]+' } + = f.input :media_cache_retention_period, + input_html: { pattern: '[0-9]+' }, + wrapper: :with_block_label + = f.input :backups_retention_period, + input_html: { pattern: '[0-9]+' }, + wrapper: :with_block_label + + %h4= t('admin.settings.content_retention.danger_zone') + + .fields-group + = f.input :content_cache_retention_period, + hint: false, + input_html: { pattern: '[0-9]+' }, + warning_hint: t('simple_form.hints.form_admin_settings.content_cache_retention_period'), + wrapper: :with_block_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/discovery/show.html.haml b/app/views/admin/settings/discovery/show.html.haml index 59fc3226ac..82ce01aaed 100644 --- a/app/views/admin/settings/discovery/show.html.haml +++ b/app/views/admin/settings/discovery/show.html.haml @@ -13,46 +13,75 @@ %h4= t('admin.settings.discovery.trends') .fields-group - = f.input :trends, as: :boolean, wrapper: :with_label + = f.input :trends, + as: :boolean, + wrapper: :with_label .fields-group - = f.input :trends_as_landing_page, as: :boolean, wrapper: :with_label + = f.input :trends_as_landing_page, + as: :boolean, + wrapper: :with_label .fields-group - = f.input :trendable_by_default, as: :boolean, wrapper: :with_label, recommended: :not_recommended + = f.input :trendable_by_default, + as: :boolean, + wrapper: :with_label, + recommended: :not_recommended %h4= t('admin.settings.discovery.public_timelines') .fields-group - = f.input :timeline_preview, as: :boolean, wrapper: :with_label + = f.input :timeline_preview, + as: :boolean, + wrapper: :with_label .fields-group - = f.input :noindex, as: :boolean, wrapper: :with_label, label: t('admin.settings.default_noindex.title'), hint: t('admin.settings.default_noindex.desc_html') + = f.input :noindex, + as: :boolean, + hint: t('admin.settings.default_noindex.desc_html'), + label: t('admin.settings.default_noindex.title'), + wrapper: :with_label %h4= t('admin.settings.discovery.publish_statistics') .fields-group - = f.input :activity_api_enabled, as: :boolean, wrapper: :with_label, recommended: :recommended + = f.input :activity_api_enabled, + as: :boolean, + wrapper: :with_label, + recommended: :recommended %h4= t('admin.settings.discovery.publish_discovered_servers') .fields-group - = f.input :peers_api_enabled, as: :boolean, wrapper: :with_label, recommended: :recommended + = f.input :peers_api_enabled, + as: :boolean, + wrapper: :with_label, + recommended: :recommended %h4= t('admin.settings.security.federation_authentication') .fields-group - = f.input :authorized_fetch, as: :boolean, wrapper: :with_label, label: t('admin.settings.security.authorized_fetch'), warning_hint: discovery_warning_hint_text, hint: discovery_hint_text, disabled: authorized_fetch_overridden?, recommended: discovery_recommended_value + = f.input :authorized_fetch, + as: :boolean, + disabled: authorized_fetch_overridden?, + hint: discovery_hint_text, + label: t('admin.settings.security.authorized_fetch'), + recommended: discovery_recommended_value, + warning_hint: discovery_warning_hint_text, + wrapper: :with_label %h4= t('admin.settings.discovery.follow_recommendations') .fields-group - = f.input :bootstrap_timeline_accounts, wrapper: :with_block_label + = f.input :bootstrap_timeline_accounts, + wrapper: :with_block_label %h4= t('admin.settings.discovery.profile_directory') .fields-group - = f.input :profile_directory, as: :boolean, wrapper: :with_label + = f.input :profile_directory, + as: :boolean, + wrapper: :with_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/registrations/show.html.haml b/app/views/admin/settings/registrations/show.html.haml index 168f109757..4dbc5fbecf 100644 --- a/app/views/admin/settings/registrations/show.html.haml +++ b/app/views/admin/settings/registrations/show.html.haml @@ -10,19 +10,36 @@ %p.lead= t('admin.settings.registrations.preamble') + .flash-message= t('admin.settings.registrations.moderation_recommandation') + .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :registrations_mode, collection: %w(open approved none), wrapper: :with_label, include_blank: false, label_method: ->(mode) { I18n.t("admin.settings.registrations_mode.modes.#{mode}") } + = f.input :registrations_mode, + collection: %w(open approved none), + include_blank: false, + label_method: ->(mode) { I18n.t("admin.settings.registrations_mode.modes.#{mode}") }, + warning_hint: I18n.t('admin.settings.registrations_mode.warning_hint'), + wrapper: :with_label .fields-row__column.fields-row__column-6.fields-group - = f.input :require_invite_text, as: :boolean, wrapper: :with_label, disabled: !approved_registrations? + = f.input :require_invite_text, + as: :boolean, + disabled: !approved_registrations?, + wrapper: :with_label - if captcha_available? .fields-group - = f.input :captcha_enabled, as: :boolean, wrapper: :with_label, label: t('admin.settings.captcha_enabled.title'), hint: t('admin.settings.captcha_enabled.desc_html') + = f.input :captcha_enabled, + as: :boolean, + hint: t('admin.settings.captcha_enabled.desc_html'), + label: t('admin.settings.captcha_enabled.title'), + wrapper: :with_label .fields-group - = f.input :closed_registrations_message, as: :text, wrapper: :with_block_label, input_html: { rows: 2 } + = f.input :closed_registrations_message, + as: :text, + input_html: { rows: 2 }, + wrapper: :with_block_label .actions = f.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/settings/shared/_links.html.haml b/app/views/admin/settings/shared/_links.html.haml index d8b697592a..8b0678d4c9 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 19a0e063da..0bec0159ee 100644 --- a/app/views/admin/status_edits/_status_edit.html.haml +++ b/app/views/admin/status_edits/_status_edit.html.haml @@ -1,20 +1,30 @@ -.status - .status__content>< - - if status_edit.spoiler_text.blank? - = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis) - - else - %details< - %summary>< - %strong> Content warning: #{prerender_custom_emojis(h(status_edit.spoiler_text), status_edit.emojis)} - = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis) - - - unless status_edit.ordered_media_attachments.empty? - = render partial: 'admin/reports/media_attachments', locals: { status: status_edit } - - .detailed-status__meta - %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) - - - if status_edit.sensitive? +%li + .history__entry + %h5 + - if status_edit_iteration.first? + = t('admin.statuses.original_status') + - else + = t('admin.statuses.status_changed') ยท - = fa_icon('eye-slash fw') - = t('stream_entries.sensitive_content') + %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) + + .status + .status__content>< + - if status_edit.spoiler_text.blank? + = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis) + - else + %details< + %summary>< + %strong> Content warning: #{prerender_custom_emojis(h(status_edit.spoiler_text), status_edit.emojis)} + = prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis) + + - unless status_edit.ordered_media_attachments.empty? + = render partial: 'admin/reports/media_attachments', locals: { status: status_edit } + + .detailed-status__meta + %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) + + - if status_edit.sensitive? + ยท + = 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 a2e3cbc0da..770d972d93 100644 --- a/app/views/admin/statuses/index.html.haml +++ b/app/views/admin/statuses/index.html.haml @@ -12,16 +12,16 @@ .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/ -= form_for(@status_batch_action, url: batch_admin_account_statuses_path(@account.id)) do |f| += form_with model: @status_batch_action, url: batch_admin_account_statuses_path(@account.id) do |f| = hidden_field_tag :page, params[:page] || 1 - Admin::StatusFilter::KEYS.each do |key| @@ -33,7 +33,11 @@ = check_box_tag :batch_checkbox_all, nil, false .batch-table__toolbar__actions - unless @statuses.empty? - = f.button safe_join([fa_icon('flag'), t('admin.statuses.batch.report')]), name: :report, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([fa_icon('flag'), t('admin.statuses.batch.report')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :report, + type: :submit .batch-table__body - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/statuses/show.html.haml b/app/views/admin/statuses/show.html.haml index 0e88624def..9cadde2870 100644 --- a/app/views/admin/statuses/show.html.haml +++ b/app/views/admin/statuses/show.html.haml @@ -47,15 +47,4 @@ %h3= t('admin.statuses.history') %ol.history - - batched_ordered_status_edits.with_index do |status_edit, i| - %li - .history__entry - %h5 - - if i.zero? - = t('admin.statuses.original_status') - - else - = t('admin.statuses.status_changed') - ยท - %time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at) - - = render status_edit + = render partial: 'admin/status_edits/status_edit', collection: batched_ordered_status_edits diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index e4c985c19e..f2d87b54b0 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -9,39 +9,69 @@ .dashboard .dashboard__item - = react_admin_component :counter, measure: 'tag_accounts', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_accounts_measure'), href: tag_url(@tag), target: '_blank', rel: 'noopener noreferrer' + = react_admin_component :counter, + end_at: @time_period.last, + href: tag_url(@tag), + label: t('admin.trends.tags.dashboard.tag_accounts_measure'), + measure: 'tag_accounts', + params: { id: @tag.id }, + rel: 'noopener noreferrer', + start_at: @time_period.first, + target: '_blank' .dashboard__item - = react_admin_component :counter, measure: 'tag_uses', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_uses_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.trends.tags.dashboard.tag_uses_measure'), + measure: 'tag_uses', + params: { id: @tag.id }, + start_at: @time_period.first .dashboard__item - = react_admin_component :counter, measure: 'tag_servers', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, label: t('admin.trends.tags.dashboard.tag_servers_measure') + = react_admin_component :counter, + end_at: @time_period.last, + label: t('admin.trends.tags.dashboard.tag_servers_measure'), + measure: 'tag_servers', + params: { id: @tag.id }, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'tag_servers', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, limit: 8, label: t('admin.trends.tags.dashboard.tag_servers_dimension') + = react_admin_component :dimension, + dimension: 'tag_servers', + end_at: @time_period.last, + label: t('admin.trends.tags.dashboard.tag_servers_dimension'), + limit: 8, + params: { id: @tag.id }, + start_at: @time_period.first .dashboard__item - = react_admin_component :dimension, dimension: 'tag_languages', start_at: @time_period.first, end_at: @time_period.last, params: { id: @tag.id }, limit: 8, label: t('admin.trends.tags.dashboard.tag_languages_dimension') + = react_admin_component :dimension, + dimension: 'tag_languages', + end_at: @time_period.last, + label: t('admin.trends.tags.dashboard.tag_languages_dimension'), + limit: 8, + params: { id: @tag.id }, + start_at: @time_period.first .dashboard__item = 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 e6ed9d95f6..647c24b1e9 100644 --- a/app/views/admin/trends/links/index.html.haml +++ b/app/views/admin/trends/links/index.html.haml @@ -5,15 +5,17 @@ %hr.spacer/ -= form_tag admin_trends_links_path, method: 'GET', class: 'simple_form' do += form_with url: admin_trends_links_path, method: :get, class: :simple_form do |form| - Trends::PreviewCardFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? .filters .filter-subset.filter-subset--with-select %strong= t('admin.follow_recommendations.language') .input.select.optional - = select_tag :locale, options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), include_blank: true + = form.select :locale, + options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), + include_blank: true .filter-subset %strong= t('admin.trends.trending') %ul @@ -22,9 +24,9 @@ .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| += form_with model: @form, url: batch_admin_trends_links_path do |f| = hidden_field_tag :page, params[:page] || 1 - Trends::PreviewCardFilter::KEYS.each do |key| @@ -35,10 +37,26 @@ %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')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('check'), t('admin.trends.links.allow_provider')]), name: :approve_providers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.links.disallow_provider')]), name: :reject_providers, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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([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([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([material_symbol('close'), t('admin.trends.links.disallow_provider')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :reject_providers, + type: :submit .batch-table__body - if @preview_cards.empty? = nothing_here 'nothing-here--under-tabs' 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 d9ad12fc96..b43b8dfff9 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,12 +15,12 @@ %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/ -= form_for(@form, url: batch_admin_trends_links_preview_card_providers_path) do |f| += form_with model: @form, url: batch_admin_trends_links_preview_card_providers_path do |f| = hidden_field_tag :page, params[:page] || 1 - Trends::PreviewCardProviderFilter::KEYS.each do |key| @@ -31,8 +31,16 @@ %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')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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([material_symbol('close'), t('admin.trends.disallow')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :reject, + type: :submit .batch-table__body - if @preview_card_providers.empty? diff --git a/app/views/admin/trends/statuses/_status.html.haml b/app/views/admin/trends/statuses/_status.html.haml index 98f2e77090..09547ff036 100644 --- a/app/views/admin/trends/statuses/_status.html.haml +++ b/app/views/admin/trends/statuses/_status.html.haml @@ -11,10 +11,12 @@ - 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', count: status.reblogs_count + status.favourites_count, friendly_count: friendly_number_to_human(status.reblogs_count + status.favourites_count)) + = t 'admin.trends.statuses.shared_by', + count: status.reblogs_count + status.favourites_count, + friendly_count: friendly_number_to_human(status.reblogs_count + status.favourites_count) - if status.account.domain.present? ยท diff --git a/app/views/admin/trends/statuses/index.html.haml b/app/views/admin/trends/statuses/index.html.haml index bf04772f22..4713f8c2ae 100644 --- a/app/views/admin/trends/statuses/index.html.haml +++ b/app/views/admin/trends/statuses/index.html.haml @@ -5,22 +5,24 @@ %hr.spacer/ -= form_tag admin_trends_statuses_path, method: 'GET', class: 'simple_form' do += form_with url: admin_trends_statuses_path, method: :get, class: :simple_form do |form| - Trends::StatusFilter::KEYS.each do |key| - = hidden_field_tag key, params[key] if params[key].present? + = form.hidden_field key, value: params[key] if params[key].present? .filters .filter-subset.filter-subset--with-select %strong= t('admin.follow_recommendations.language') .input.select.optional - = select_tag :locale, options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), include_blank: true + = form.select :locale, + options_for_select(@locales.map { |key| [standard_locale_name(key), key] }, params[:locale]), + include_blank: true .filter-subset %strong= t('admin.trends.trending') %ul %li= filter_link_to t('generic.all'), trending: nil %li= filter_link_to t('admin.trends.only_allowed'), trending: 'allowed' -= form_for(@form, url: batch_admin_trends_statuses_path) do |f| += form_with model: @form, url: batch_admin_trends_statuses_path do |f| = hidden_field_tag :page, params[:page] || 1 - Trends::StatusFilter::KEYS.each do |key| @@ -31,10 +33,26 @@ %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')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('check'), t('admin.trends.statuses.allow_account')]), name: :approve_accounts, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.statuses.disallow_account')]), name: :reject_accounts, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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([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([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([material_symbol('close'), t('admin.trends.statuses.disallow_account')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :reject_accounts, + type: :submit .batch-table__body - if @statuses.empty? = nothing_here 'nothing-here--under-tabs' diff --git a/app/views/admin/trends/tags/_tag.html.haml b/app/views/admin/trends/tags/_tag.html.haml index 70c7d8dbd4..8cc0d713b9 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 4730d20c18..3a44cf3a70 100644 --- a/app/views/admin/trends/tags/index.html.haml +++ b/app/views/admin/trends/tags/index.html.haml @@ -14,7 +14,7 @@ %li= filter_link_to t('admin.trends.rejected'), status: 'rejected' %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), status: 'pending_review' -= form_for(@form, url: batch_admin_trends_tags_path) do |f| += form_with model: @form, url: batch_admin_trends_tags_path do |f| = hidden_field_tag :page, params[:page] || 1 - Trends::TagFilter::KEYS.each do |key| @@ -25,8 +25,16 @@ %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')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } - = f.button safe_join([fa_icon('times'), t('admin.trends.disallow')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = 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([material_symbol('close'), t('admin.trends.disallow')]), + class: 'table-action-link', + data: { confirm: t('admin.reports.are_you_sure') }, + name: :reject, + type: :submit .batch-table__body - if @tags.empty? diff --git a/app/views/admin/users/roles/show.html.haml b/app/views/admin/users/roles/show.html.haml index 8216180607..f26640f2a1 100644 --- a/app/views/admin/users/roles/show.html.haml +++ b/app/views/admin/users/roles/show.html.haml @@ -3,7 +3,13 @@ = simple_form_for @user, url: admin_user_role_path(@user) do |f| .fields-group - = f.association :role, wrapper: :with_block_label, collection: UserRole.assignable, label_method: :name, include_blank: I18n.t('admin.accounts.change_role.no_role') + = f.association :role, + collection: UserRole.assignable, + include_blank: I18n.t('admin.accounts.change_role.no_role'), + label_method: :name, + wrapper: :with_block_label .actions - = f.button :button, t('generic.save_changes'), type: :submit + = f.button :button, + t('generic.save_changes'), + type: :submit diff --git a/app/views/admin/warning_presets/_form.html.haml b/app/views/admin/warning_presets/_form.html.haml new file mode 100644 index 0000000000..cba74163c5 --- /dev/null +++ b/app/views/admin/warning_presets/_form.html.haml @@ -0,0 +1,7 @@ +.fields-group + = form.input :title, + wrapper: :with_block_label + +.fields-group + = form.input :text, + wrapper: :with_block_label diff --git a/app/views/admin/warning_presets/edit.html.haml b/app/views/admin/warning_presets/edit.html.haml index b5c5107ef4..f0bd9c12ec 100644 --- a/app/views/admin/warning_presets/edit.html.haml +++ b/app/views/admin/warning_presets/edit.html.haml @@ -1,14 +1,10 @@ - content_for :page_title do = t('admin.warning_presets.edit_preset') -= simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |f| += simple_form_for @warning_preset, url: admin_warning_preset_path(@warning_preset) do |form| = render 'shared/error_messages', object: @warning_preset - .fields-group - = f.input :title, wrapper: :with_block_label - - .fields-group - = f.input :text, 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/warning_presets/index.html.haml b/app/views/admin/warning_presets/index.html.haml index b26a13d966..22fee21050 100644 --- a/app/views/admin/warning_presets/index.html.haml +++ b/app/views/admin/warning_presets/index.html.haml @@ -2,17 +2,13 @@ = t('admin.warning_presets.title') - if can? :create, :account_warning_preset - = simple_form_for @warning_preset, url: admin_warning_presets_path do |f| + = simple_form_for @warning_preset, url: admin_warning_presets_path do |form| = render 'shared/error_messages', object: @warning_preset - .fields-group - = f.input :title, wrapper: :with_block_label - - .fields-group - = f.input :text, wrapper: :with_block_label + = render form .actions - = f.button :button, t('admin.warning_presets.add_new'), type: :submit + = form.button :button, t('admin.warning_presets.add_new'), type: :submit %hr.spacer/ diff --git a/app/views/admin/webhooks/_form.html.haml b/app/views/admin/webhooks/_form.html.haml index 6c4574fd3b..2b948b9a6a 100644 --- a/app/views/admin/webhooks/_form.html.haml +++ b/app/views/admin/webhooks/_form.html.haml @@ -1,10 +1,21 @@ = render 'shared/error_messages', object: form.object .fields-group - = form.input :url, wrapper: :with_block_label, input_html: { placeholder: 'https://' } + = form.input :url, + wrapper: :with_block_label, + input_html: { placeholder: 'https://' } .fields-group - = form.input :events, collection: Webhook::EVENTS, wrapper: :with_block_label, include_blank: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', disabled: Webhook::EVENTS.filter { |event| !current_user.role.can?(Webhook.permission_for_event(event)) } + = form.input :events, + collection: Webhook::EVENTS, + wrapper: :with_block_label, + include_blank: false, + as: :check_boxes, + collection_wrapper_tag: 'ul', + item_wrapper_tag: 'li', + disabled: Webhook::EVENTS.filter { |event| !current_user.role.can?(Webhook.permission_for_event(event)) } .fields-group - = form.input :template, wrapper: :with_block_label, input_html: { placeholder: '{ "content": "Hello {{object.username}}" }' } + = form.input :template, + wrapper: :with_block_label, + input_html: { placeholder: '{ "content": "Hello {{object.username}}" }' } diff --git a/app/views/admin/webhooks/edit.html.haml b/app/views/admin/webhooks/edit.html.haml index 2c2a7aa034..abc9bdfabc 100644 --- a/app/views/admin/webhooks/edit.html.haml +++ b/app/views/admin/webhooks/edit.html.haml @@ -2,6 +2,6 @@ = t('admin.webhooks.edit') = simple_form_for @webhook, url: admin_webhook_path(@webhook) do |form| - = render partial: 'form', object: form + = render form .actions = form.button :button, t('generic.save_changes'), type: :submit diff --git a/app/views/admin/webhooks/new.html.haml b/app/views/admin/webhooks/new.html.haml index f51b039ce8..50fcdc2be7 100644 --- a/app/views/admin/webhooks/new.html.haml +++ b/app/views/admin/webhooks/new.html.haml @@ -2,6 +2,6 @@ = t('admin.webhooks.new') = simple_form_for @webhook, url: admin_webhooks_path do |form| - = render partial: 'form', object: form + = render form .actions = form.button :button, t('admin.webhooks.add_new'), type: :submit diff --git a/app/views/admin_mailer/auto_close_registrations.text.erb b/app/views/admin_mailer/auto_close_registrations.text.erb new file mode 100644 index 0000000000..c0f8486929 --- /dev/null +++ b/app/views/admin_mailer/auto_close_registrations.text.erb @@ -0,0 +1,3 @@ +<%= raw t('admin_mailer.auto_close_registrations.body', instance: @instance) %> + +<%= raw t('application_mailer.view')%> <%= admin_settings_registrations_url %> 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 63c170dc0d..a3f031bdad 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 96808f3cb3..0eccbbf9ef 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/_button.html.haml b/app/views/application/mailer/_button.html.haml index 61430732eb..0bf80b505a 100644 --- a/app/views/application/mailer/_button.html.haml +++ b/app/views/application/mailer/_button.html.haml @@ -1,4 +1,7 @@ %table.email-btn-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-btn-td - = link_to "#{text}ย โžœ", url, class: 'email-btn-a email-btn-hover' + - if defined?(has_arrow) && !has_arrow + = link_to text, url, class: 'email-btn-a email-btn-hover' + - else + = link_to "#{text}ย โžœ", url, class: 'email-btn-a email-btn-hover' diff --git a/app/views/application/mailer/_checklist.html.haml b/app/views/application/mailer/_checklist.html.haml index 83072bd36b..91c7c98f26 100644 --- a/app/views/application/mailer/_checklist.html.haml +++ b/app/views/application/mailer/_checklist.html.haml @@ -1,7 +1,7 @@ %table.email-w-full.email-checklist-wrapper-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } %tr %td.email-checklist-wrapper-td - %table.email-w-full.email-checklist-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %table.email-w-full.email-checklist-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation', class: ('email-checklist-checked' if defined?(checked) && checked) } %tr %td.email-checklist-td %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } @@ -15,15 +15,23 @@ - else = 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?(step_image_url) - = image_tag step_image_url, alt: '', width: 40, height: 40 + - if defined?(key) + = 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 - - if defined?(button_text) && defined?(button_url) && defined?(checked) && !checked - = render 'application/mailer/button', text: button_text, url: button_url + - if defined?(show_apps_buttons) && show_apps_buttons + .email-welcome-apps-btns + = link_to image_tag(frontend_asset_url('images/mailer-new/store-icons/btn-app-store.png'), alt: t('user_mailer.welcome.apps_ios_action'), width: 120, height: 40), 'https://apps.apple.com/app/mastodon-for-iphone-and-ipad/id1571998974' + = link_to image_tag(frontend_asset_url('images/mailer-new/store-icons/btn-google-play.png'), alt: t('user_mailer.welcome.apps_android_action'), width: 120, height: 40), 'https://play.google.com/store/apps/details?id=org.joinmastodon.android' + - elsif defined?(button_text) && defined?(button_url) && defined?(checked) && !checked + = render 'application/mailer/button', text: button_text, url: button_url, has_arrow: false + /[if mso] +
diff --git a/app/views/application/mailer/_feature.html.haml b/app/views/application/mailer/_feature.html.haml new file mode 100644 index 0000000000..94dd4b9cff --- /dev/null +++ b/app/views/application/mailer/_feature.html.haml @@ -0,0 +1,30 @@ +%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-feature-wrapper-td + %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 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 + %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')}ย  + %span= 'โฏ' + /[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) + %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/_follow.html.haml b/app/views/application/mailer/_follow.html.haml new file mode 100644 index 0000000000..382151a234 --- /dev/null +++ b/app/views/application/mailer/_follow.html.haml @@ -0,0 +1,15 @@ +%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-wrapper-td + %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-td + %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-follow-img-td + = image_tag full_asset_url(follow.account.avatar.url), alt: '', width: 40, height: 40 + %td.email-mini-follow-text-td + %h3= follow.account.display_name.presence || follow.account.username + %p @#{follow.account.pretty_acct} + %td.email-mini-follow-btn-td + = render 'application/mailer/button', text: t('user_mailer.welcome.follow_action'), url: web_url("@#{follow.account.acct}"), has_arrow: false diff --git a/app/views/application/mailer/_hashtag.html.haml b/app/views/application/mailer/_hashtag.html.haml new file mode 100644 index 0000000000..b740ba31b9 --- /dev/null +++ b/app/views/application/mailer/_hashtag.html.haml @@ -0,0 +1,21 @@ +- 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 + %td.email-mini-wrapper-td + %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-td + %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-hashtag-td{ height: 40 } + %h3 ##{hashtag.display_name} + %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' } + %tr + %td.email-mini-hashtag-img-td + - accounts.each do |account| + %span.email-mini-hashtag-img-span + = image_tag full_asset_url(account.avatar.url), alt: '', width: 16, height: 16 + %td + - 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/auth/confirmations/captcha.html.haml b/app/views/auth/confirmations/captcha.html.haml index 964d0e63e7..035ac3a86a 100644 --- a/app/views/auth/confirmations/captcha.html.haml +++ b/app/views/auth/confirmations/captcha.html.haml @@ -1,11 +1,13 @@ - content_for :page_title do = t('auth.captcha_confirmation.title') -= form_tag auth_captcha_confirmation_url, method: 'POST', class: 'simple_form' do += form_with url: auth_captcha_confirmation_url, class: :simple_form do |form| = render 'auth/shared/progress', stage: 'confirm' - = hidden_field_tag :confirmation_token, params[:confirmation_token] - = hidden_field_tag :redirect_to_app, params[:redirect_to_app] + = form.hidden_field :confirmation_token, + value: params[:confirmation_token] + = form.hidden_field :redirect_to_app, + value: params[:redirect_to_app] %h1.title= t('auth.captcha_confirmation.title') %p.lead= t('auth.captcha_confirmation.hint_html') @@ -15,4 +17,6 @@ %p.lead= t('auth.captcha_confirmation.help_html', email: mail_to(Setting.site_contact_email, nil)) .actions - = button_tag t('challenge.confirm'), class: 'button', type: :submit + = form.button t('challenge.confirm'), + class: 'button', + type: :submit diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml index 48350f478e..07d6c1af51 100644 --- a/app/views/auth/registrations/edit.html.haml +++ b/app/views/auth/registrations/edit.html.haml @@ -3,7 +3,7 @@ - if self_destruct? .flash-message.warning - = t('auth.status.self_destruct', domain: ENV.fetch('LOCAL_DOMAIN')) + = t('auth.status.self_destruct', domain: Rails.configuration.x.local_domain) - else = render partial: 'status', locals: { user: @user, strikes: @strikes } diff --git a/app/views/auth/registrations/rules.html.haml b/app/views/auth/registrations/rules.html.haml index 234f4a601d..3a05ed54f0 100644 --- a/app/views/auth/registrations/rules.html.haml +++ b/app/views/auth/registrations/rules.html.haml @@ -20,6 +20,7 @@ - @rules.each do |rule| %li .rules-list__text= rule.text + .rules-list__hint= rule.hint .stacked-actions - accept_path = @invite_code.present? ? public_invite_url(invite_code: @invite_code, accept: @accept_token) : new_user_registration_path(accept: @accept_token) diff --git a/app/views/errors/self_destruct.html.haml b/app/views/errors/self_destruct.html.haml index 09b17a5a94..b9ff48f684 100644 --- a/app/views/errors/self_destruct.html.haml +++ b/app/views/errors/self_destruct.html.haml @@ -3,7 +3,7 @@ .simple_form %h1.title= t('self_destruct.title') - %p.lead= t('self_destruct.lead_html', domain: ENV.fetch('LOCAL_DOMAIN')) + %p.lead= t('self_destruct.lead_html', domain: Rails.configuration.x.local_domain) .form-footer %ul.no-list diff --git a/app/views/filters/_filter_fields.html.haml b/app/views/filters/_filter_fields.html.haml index a3260816ed..0f4049ffb6 100644 --- a/app/views/filters/_filter_fields.html.haml +++ b/app/views/filters/_filter_fields.html.haml @@ -1,16 +1,37 @@ .fields-row .fields-row__column.fields-row__column-6.fields-group - = f.input :title, as: :string, wrapper: :with_label, hint: false + = f.input :title, + as: :string, + hint: false, + wrapper: :with_label .fields-row__column.fields-row__column-6.fields-group - = f.input :expires_in, wrapper: :with_label, collection: [30.minutes, 1.hour, 6.hours, 12.hours, 1.day, 1.week].map(&:to_i), label_method: ->(i) { I18n.t("invites.expires_in.#{i}") }, include_blank: I18n.t('invites.expires_in_prompt') + = f.input :expires_in, + collection: CustomFilter::EXPIRATION_DURATIONS.map(&:to_i), + include_blank: I18n.t('invites.expires_in_prompt'), + label_method: ->(i) { I18n.t("invites.expires_in.#{i}") }, + wrapper: :with_label .fields-group - = f.input :context, wrapper: :with_block_label, collection: CustomFilter::VALID_CONTEXTS, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', label_method: ->(context) { I18n.t("filters.contexts.#{context}") }, include_blank: false + = f.input :context, + as: :check_boxes, + collection_wrapper_tag: 'ul', + collection: CustomFilter::VALID_CONTEXTS, + include_blank: false, + item_wrapper_tag: 'li', + label_method: ->(context) { I18n.t("filters.contexts.#{context}") }, + wrapper: :with_block_label %hr.spacer/ .fields-group - = f.input :filter_action, as: :radio_buttons, collection: %i(warn hide), include_blank: false, wrapper: :with_block_label, label_method: ->(action) { filter_action_label(action) }, hint: t('simple_form.hints.filters.action'), required: true + = f.input :filter_action, + as: :radio_buttons, + collection: %i(warn hide), + hint: t('simple_form.hints.filters.action'), + include_blank: false, + label_method: ->(action) { filter_action_label(action) }, + required: true, + wrapper: :with_block_label %hr.spacer/ diff --git a/app/views/filters/statuses/index.html.haml b/app/views/filters/statuses/index.html.haml index eaa39e170f..915ec59caf 100644 --- a/app/views/filters/statuses/index.html.haml +++ b/app/views/filters/statuses/index.html.haml @@ -13,7 +13,7 @@ %hr.spacer/ -= form_for(@status_filter_batch_action, url: batch_filter_statuses_path(@filter.id)) do |f| += form_with model: @status_filter_batch_action, url: batch_filter_statuses_path(@filter.id) do |f| = hidden_field_tag :page, params[:page] || 1 - Admin::StatusFilter::KEYS.each do |key| diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index c721073670..e7f1a595e5 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -11,25 +11,26 @@ - if storage_host? %link{ rel: 'dns-prefetch', href: storage_host }/ - %link{ rel: 'icon', href: '/favicon.ico', type: 'image/x-icon' }/ + %link{ rel: 'icon', href: favicon_path('ico') || '/favicon.ico', type: 'image/x-icon' }/ - - %w(16 32 48).each do |size| - %link{ rel: 'icon', sizes: "#{size}x#{size}", href: frontend_asset_path("icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/ + - SiteUpload::FAVICON_SIZES.each do |size| + %link{ rel: 'icon', sizes: "#{size}x#{size}", href: favicon_path(size.to_i) || frontend_asset_path("icons/favicon-#{size}x#{size}.png"), type: 'image/png' }/ - - %w(57 60 72 76 114 120 144 152 167 180 1024).each do |size| - %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: frontend_asset_path("icons/apple-touch-icon-#{size}x#{size}.png") }/ + - SiteUpload::APPLE_ICON_SIZES.each do |size| + %link{ rel: 'apple-touch-icon', sizes: "#{size}x#{size}", href: app_icon_path(size.to_i) || frontend_asset_path("icons/apple-touch-icon-#{size}x#{size}.png") }/ - %link{ rel: 'mask-icon', href: frontend_asset_path('images/logo-symbol-icon.svg'), color: '#6364FF' }/ + - if use_mask_icon? + %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