Compare commits

..

73 commits

Author SHA1 Message Date
ed4a0bba04 Merge remote-tracking branch 'upstream/main'
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-31 10:02:26 +01:00
Eugen Rochko
fa0ba67753
Change materialized views to be refreshed concurrently to avoid locks (#29015) 2024-01-30 18:21:30 +00:00
Eugen Rochko
c4af668e5c
Fix follow recommendations for less used languages (#29017) 2024-01-30 17:24:40 +00:00
renovate[bot]
0c0d077276
Update dependency chewy to v7.5.1 (#29018)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 15:40:43 +00:00
renovate[bot]
0bc526a967
Update eslint (non-major) (#29001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 15:39:59 +00:00
renovate[bot]
8c08e5cdb2
Update devDependencies (non-major) (#29000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 15:39:34 +00:00
Matt Jankowski
ce0d134147
Add redirect_with_vary to AllowedMethods for Style/FormatStringToken cop (#28973) 2024-01-30 15:39:01 +00:00
Matt Jankowski
86fbde7b46
Fix Style/NumericLiterals cop in ProfileStories support module (#28971) 2024-01-30 15:38:33 +00:00
Yamagishi Kazutoshi
b3075a9993
Remove unused l18n messages (#28964) 2024-01-30 15:34:07 +00:00
Matt Jankowski
f91acba70a
Combine repeated requests in account controller concern spec (#28957) 2024-01-30 15:32:20 +00:00
renovate[bot]
9d3830344f
Update dependency immutable to v4.3.5 (#28933)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-30 15:30:39 +00:00
Matt Jankowski
adcd693b71
Use existing MediaAttachment.remote scope in media CLI (#28912) 2024-01-30 15:29:42 +00:00
J H
1467f1e1e1
Fixed the toggle emoji dropdown bug (#29012) 2024-01-30 13:38:49 +00:00
Matt Jankowski
ff8937aa2c
Move api/v1/statuses/* to request spec (#28954) 2024-01-26 17:45:54 +00:00
Matt Jankowski
44f6d285af
Combine repeated subject in ap fetch remote actor service spec (#28953) 2024-01-26 17:44:12 +00:00
Matt Jankowski
239244e2ed
Combine repeated subject in ap fetch remote account service spec (#28952) 2024-01-26 17:43:08 +00:00
Matt Jankowski
5119fbc9b7
Move api/v1/admin/trends/links/preview_card_providers to request spec (#28951) 2024-01-26 17:41:39 +00:00
Matt Jankowski
b6baab447d
Move api/v2/admin/accounts to request spec (#28950) 2024-01-26 17:41:13 +00:00
Matt Jankowski
7adcc0aae3
Move api/v1/trends/* to request specs (#28949) 2024-01-26 17:40:39 +00:00
Matt Jankowski
0b0ca6f3b8
Move api/v1/timelines/list to request spec (#28948) 2024-01-26 17:40:15 +00:00
renovate[bot]
87ad398ddc
Update formatjs monorepo (#28925)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 16:49:16 +00:00
renovate[bot]
f4a12adfb7
Update dependency axios to v1.6.7 (#28917)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 16:49:09 +00:00
renovate[bot]
160c8f4923
Update babel monorepo to v7.23.9 (#28916)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-26 16:49:03 +00:00
Matt Jankowski
e519f113e8
Combine repeated subject in cacheable response shared example (#28945) 2024-01-26 16:37:05 +00:00
Matt Jankowski
d791bca11b
Combine double subject in well_known/webfinger shared example (#28944) 2024-01-26 16:36:21 +00:00
Matt Jankowski
09a3493fca
Combine double subject in api/v1/media shared example (#28943) 2024-01-26 16:35:49 +00:00
Matt Jankowski
5fbdb2055b
Combine repeated subject in cli/accounts spec shared example (#28942) 2024-01-26 16:35:19 +00:00
Matt Jankowski
1a30a517d6
Combine repeated subjects in link details extractor spec (#28941) 2024-01-26 16:31:07 +00:00
Matt Jankowski
685eaa04d4
Combine double subject in admin/statuses controller shared example (#28940) 2024-01-26 16:30:30 +00:00
Matt Jankowski
beb74fd71c
Combine double subjects in instance actors controller shared example (#28939) 2024-01-26 16:28:50 +00:00
Matt Jankowski
beaef4b672
Combine double subjects in application controller shared example (#28938) 2024-01-26 16:23:12 +00:00
Matt Jankowski
6d35a77c92
Combine repeated subjects in models/user spec (#28937) 2024-01-26 16:22:44 +00:00
Matt Jankowski
2f8656334d
Combine double subjects in admin/accounts controller spec (#28936) 2024-01-26 16:21:31 +00:00
Matt Jankowski
9cc1817bb4
Fix intmermittent failure in api/v1/accounts/statuses controller spec (#28931) 2024-01-26 14:10:26 +00:00
Claire
805dba7f8d
Change compose form to use server-provided post character limit (#28928) 2024-01-26 14:09:45 +00:00
github-actions[bot]
45287049ab
New Crowdin Translations (automated) (#28923)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-26 09:15:55 +00:00
Matt Jankowski
0e0a94f483
Handle CLI failure exit status at the top-level script (#28322) 2024-01-26 08:53:44 +00:00
Emelia Smith
881e8c113c
Refactor: fix streaming postgresql and redis typing issues (#28747) 2024-01-25 16:46:02 +00:00
Eugen Rochko
6936e5aa69
Change design of compose form in web UI (#28119)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-25 15:41:31 +00:00
Matt Jankowski
42ab855b23
Add specs for Instance model scopes and add with_domain_follows scope (#28767) 2024-01-25 15:28:27 +00:00
Matt Jankowski
4cdf62e576
Extract rebuild_index method in maintenance CLI (#28911) 2024-01-25 15:26:51 +00:00
Matt Jankowski
0b38946c87
Update paperclip and climate_control gems (#28379) 2024-01-25 15:18:15 +00:00
Matt Jankowski
17ea22671d
Fix Style/GuardClause cop in app/controllers (#28420) 2024-01-25 15:13:41 +00:00
Eugen Rochko
3205a654ca
Refactor conversations components in web UI (#28833)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-25 14:34:26 +00:00
Matt Jankowski
274a48a9f4
Extract helper methods for db connection and table existence check in CLI::Maintenance task (#28281) 2024-01-25 13:49:33 +00:00
Matt Jankowski
2866106ec1
Reduce factory creation in spec/models/account_statuses_cleanup_policy (#28361) 2024-01-25 13:37:25 +00:00
Matt Jankowski
c8f59d2ca4
Fix Style/TernaryParentheses cop (#28387) 2024-01-25 13:28:49 +00:00
Matt Jankowski
ca7053f19c
Consolidate db test prep steps to rake task (#28886) 2024-01-25 13:10:39 +00:00
github-actions[bot]
59d2ea0d82
New Crowdin Translations (automated) (#28899)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-25 13:00:44 +00:00
Matt Jankowski
6b6586f5d0
Add CustomFilterKeyword#to_regex method (#28893) 2024-01-25 13:00:34 +00:00
renovate[bot]
a69506a434
fix(deps): update dependency dotenv to v16.4.1 (#28889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:37:23 +00:00
Matt Jankowski
7c9c6c7f80
Fix remaining Rails/WhereExists cop violations, regenerate todo (#28892) 2024-01-25 12:37:07 +00:00
renovate[bot]
1a565e4bea
fix(deps): update dependency axios to v1.6.6 (#28895)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:36:20 +00:00
renovate[bot]
d158f7e622
chore(deps): update dependency rspec-rails to v6.1.1 (#28905)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-25 12:33:56 +00:00
Claire
087415d0fe
Add tests for processing statuses using bearcap URIs (#28904) 2024-01-25 11:13:36 +00:00
Claire
0471a78055
Add tests for redirect confirmations (#28903) 2024-01-25 11:13:33 +00:00
Claire
c50274a0ac
Fix redirect confirmation for accounts (#28902) 2024-01-25 10:44:25 +00:00
KMY(雪あすか)
9a8293f58d
Fix process of receiving posts with bearcaps is not working (#26527) 2024-01-25 10:37:09 +00:00
Matt Jankowski
38f7f8b909
Tidy up association declaration in Instance model (#28880) 2024-01-24 17:30:28 +00:00
renovate[bot]
9c5be13980
chore(deps): update dependency chewy to v7.5.0 (#28730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:47 +00:00
renovate[bot]
7019af431d
fix(deps): update dependency dotenv to v16.4.0 (#28872)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:36 +00:00
renovate[bot]
559bbf0aa6
chore(deps): update artifact actions (major) to v4 (major) (#28415)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 16:51:18 +00:00
renovate[bot]
ea5397c373
chore(deps): update dependency selenium-webdriver to v4.17.0 (#28858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 14:55:06 +00:00
renovate[bot]
64993d3f77
chore(deps): update dependency haml_lint to v0.55.0 (#28856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 13:37:37 +00:00
Claire
5a838ceaa9
Use active variants for boost icons and increase icon size (#27924) 2024-01-24 12:37:43 +00:00
Matt Jankowski
1290fede65
Fix Rails/WhereExists cop in app/lib (#28862) 2024-01-24 11:51:09 +00:00
renovate[bot]
41c2af2270
chore(deps): update dependency rubocop to v1.60.1 (#28731)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-24 11:50:41 +00:00
Eugen Rochko
b19ae521b7
Add confirmation when redirecting logged-out requests to permalink (#27792)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2024-01-24 10:49:19 +00:00
Matt Jankowski
7a1f087659
Add created_before and updated_before scopes to MediaAttachment (#28869) 2024-01-24 10:32:54 +00:00
Matt Jankowski
a11a2fb052
Add error classes to api/base errors coverage (#28864) 2024-01-24 10:31:31 +00:00
github-actions[bot]
a34d27c18f
New Crowdin Translations (automated) (#28875)
Co-authored-by: GitHub Actions <noreply@github.com>
2024-01-24 10:06:56 +00:00
Matt Jankowski
9d413cbaf8
Fix Rails/WhereExists cop in app/models (#28863) 2024-01-24 09:57:49 +00:00
Matt Jankowski
599bc69503
Simplify AccountSummary.filtered query generation (#28868) 2024-01-24 09:57:32 +00:00
340 changed files with 4107 additions and 5385 deletions

View file

@ -165,7 +165,7 @@ module.exports = defineConfig({
// }, // },
// ], // ],
'jsx-a11y/no-noninteractive-tabindex': 'off', 'jsx-a11y/no-noninteractive-tabindex': 'off',
'jsx-a11y/no-onchange': 'warn', 'jsx-a11y/no-onchange': 'off',
// recommended is full 'error' // recommended is full 'error'
'jsx-a11y/no-static-element-interactions': [ 'jsx-a11y/no-static-element-interactions': [
'warn', 'warn',

View file

@ -78,23 +78,8 @@ jobs:
- name: Create database - name: Create database
run: './bin/rails db:create' run: './bin/rails db:create'
- name: Run migrations up to v2.0.0 - name: Run historical migrations with data population
run: './bin/rails db:migrate VERSION=20171010025614' run: './bin/rails tests:migrations:prepare_database'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- name: Run all remaining migrations - name: Run all remaining migrations
run: './bin/rails db:migrate' run: './bin/rails db:migrate'

View file

@ -45,6 +45,7 @@ jobs:
--health-retries 5 --health-retries 5
ports: ports:
- 5432:5432 - 5432:5432
redis: redis:
image: redis:7-alpine image: redis:7-alpine
options: >- options: >-
@ -77,28 +78,11 @@ jobs:
- name: Create database - name: Create database
run: './bin/rails db:create' run: './bin/rails db:create'
- name: Run migrations up to v2.0.0 - name: Run historical migrations with data population
run: './bin/rails db:migrate VERSION=20171010025614' run: './bin/rails tests:migrations:prepare_database'
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2'
- name: Run pre-deployment migrations up to v2.4.0
run: './bin/rails db:migrate VERSION=20180514140000'
env: env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4'
- name: Run migrations up to v2.4.3
run: './bin/rails db:migrate VERSION=20180707154237'
env:
SKIP_POST_DEPLOYMENT_MIGRATIONS: true
- name: Populate database with test data
run: './bin/rails tests:migrations:populate_v2_4_3'
- name: Run all remaining pre-deployment migrations - name: Run all remaining pre-deployment migrations
run: './bin/rails db:migrate' run: './bin/rails db:migrate'
env: env:

View file

@ -52,7 +52,7 @@ jobs:
run: | run: |
tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs* tar --exclude={"*.br","*.gz"} -zcf artifacts.tar.gz public/assets public/packs*
- uses: actions/upload-artifact@v3 - uses: actions/upload-artifact@v4
if: matrix.mode == 'test' if: matrix.mode == 'test'
with: with:
path: |- path: |-
@ -117,7 +117,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
path: './' path: './'
name: ${{ github.sha }} name: ${{ github.sha }}
@ -193,7 +193,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
path: './public' path: './public'
name: ${{ github.sha }} name: ${{ github.sha }}
@ -213,14 +213,14 @@ jobs:
- run: bundle exec rake spec:system - run: bundle exec rake spec:system
- name: Archive logs - name: Archive logs
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: e2e-logs-${{ matrix.ruby-version }} name: e2e-logs-${{ matrix.ruby-version }}
path: log/ path: log/
- name: Archive test screenshots - name: Archive test screenshots
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: e2e-screenshots name: e2e-screenshots
@ -297,7 +297,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/download-artifact@v3 - uses: actions/download-artifact@v4
with: with:
path: './public' path: './public'
name: ${{ github.sha }} name: ${{ github.sha }}
@ -317,14 +317,14 @@ jobs:
- run: bin/rspec --tag search - run: bin/rspec --tag search
- name: Archive logs - name: Archive logs
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: test-search-logs-${{ matrix.ruby-version }} name: test-search-logs-${{ matrix.ruby-version }}
path: log/ path: log/
- name: Archive test screenshots - name: Archive test screenshots
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
if: failure() if: failure()
with: with:
name: test-search-screenshots name: test-search-screenshots

View file

@ -96,12 +96,11 @@ Rails/FilePath:
Rails/HttpStatus: Rails/HttpStatus:
EnforcedStyle: numeric EnforcedStyle: numeric
# Reason: Allowed in `tootctl` CLI code and in boot ENV checker # Reason: Allowed in boot ENV checker
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsexit
Rails/Exit: Rails/Exit:
Exclude: Exclude:
- 'config/boot.rb' - 'config/boot.rb'
- 'lib/mastodon/cli/*.rb'
# Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions # Reason: Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter # https://docs.rubocop.org/rubocop-rails/cops_rails.html#railslexicallyscopedactionfilter
@ -175,6 +174,15 @@ Style/ClassAndModuleChildren:
Style/Documentation: Style/Documentation:
Enabled: false 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 # Reason: Enforce modern Ruby style
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax # https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
Style/HashSyntax: Style/HashSyntax:

View file

@ -1,6 +1,6 @@
# This configuration was generated by # This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp` # `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.59.0. # using RuboCop version 1.60.2.
# The point is for the user to remove these configuration records # The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base. # one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new # Note that changes in the inspected code, or installation of new
@ -70,28 +70,6 @@ Rails/UniqueValidationWithoutIndex:
- 'app/models/identity.rb' - 'app/models/identity.rb'
- 'app/models/webauthn_credential.rb' - 'app/models/webauthn_credential.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: exists, where
Rails/WhereExists:
Exclude:
- 'app/controllers/activitypub/inboxes_controller.rb'
- 'app/controllers/admin/email_domain_blocks_controller.rb'
- 'app/lib/activitypub/activity/create.rb'
- 'app/lib/delivery_failure_tracker.rb'
- 'app/lib/feed_manager.rb'
- 'app/lib/suspicious_sign_in_detector.rb'
- 'app/models/poll.rb'
- 'app/models/session_activation.rb'
- 'app/models/status.rb'
- 'app/policies/status_policy.rb'
- 'app/serializers/rest/announcement_serializer.rb'
- 'app/workers/move_worker.rb'
- 'spec/models/account_spec.rb'
- 'spec/services/activitypub/process_collection_service_spec.rb'
- 'spec/services/purge_domain_service_spec.rb'
- 'spec/services/unallow_domain_service_spec.rb'
# This cop supports unsafe autocorrection (--autocorrect-all). # This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods, AllowedPatterns. # Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql? # AllowedMethods: ==, equal?, eql?
@ -143,10 +121,6 @@ Style/GlobalStdStream:
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals. # Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
Style/GuardClause: Style/GuardClause:
Exclude: Exclude:
- 'app/controllers/admin/confirmations_controller.rb'
- 'app/controllers/auth/confirmations_controller.rb'
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/settings/two_factor_authentication/webauthn_credentials_controller.rb'
- 'app/lib/activitypub/activity/block.rb' - 'app/lib/activitypub/activity/block.rb'
- 'app/lib/request.rb' - 'app/lib/request.rb'
- 'app/lib/request_pool.rb' - 'app/lib/request_pool.rb'
@ -301,13 +275,6 @@ Style/StringLiterals:
- 'config/initializers/webauthn.rb' - 'config/initializers/webauthn.rb'
- 'config/routes.rb' - 'config/routes.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
Style/TernaryParentheses:
Exclude:
- 'config/environments/development.rb'
# This cop supports safe autocorrection (--autocorrect). # This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyleForMultiline. # Configuration parameters: EnforcedStyleForMultiline.
# SupportedStylesForMultiline: comma, consistent_comma, no_comma # SupportedStylesForMultiline: comma, consistent_comma, no_comma

View file

@ -123,7 +123,7 @@ group :test do
gem 'database_cleaner-active_record' gem 'database_cleaner-active_record'
# Used to mock environment variables # Used to mock environment variables
gem 'climate_control', '~> 0.2' gem 'climate_control'
# Generating fake data for specs # Generating fake data for specs
gem 'faker', '~> 3.2' gem 'faker', '~> 3.2'

View file

@ -180,12 +180,12 @@ GEM
activesupport activesupport
cbor (0.5.9.6) cbor (0.5.9.6)
charlock_holmes (0.7.7) charlock_holmes (0.7.7)
chewy (7.4.0) chewy (7.5.1)
activesupport (>= 5.2) activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl elasticsearch-dsl
chunky_png (1.4.0) chunky_png (1.4.0)
climate_control (0.2.0) climate_control (1.2.0)
cocoon (1.2.15) cocoon (1.2.15)
color_diff (0.1) color_diff (0.1)
concurrent-ruby (1.2.3) concurrent-ruby (1.2.3)
@ -319,7 +319,7 @@ GEM
activesupport (>= 5.1) activesupport (>= 5.1)
haml (>= 4.0.6) haml (>= 4.0.6)
railties (>= 5.1) railties (>= 5.1)
haml_lint (0.53.0) haml_lint (0.55.0)
haml (>= 5.0) haml (>= 5.0)
parallel (~> 1.10) parallel (~> 1.10)
rainbow rainbow
@ -360,7 +360,7 @@ GEM
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1) terminal-table (>= 1.5.1)
idn-ruby (0.1.5) idn-ruby (0.1.5)
io-console (0.7.1) io-console (0.7.2)
irb (1.11.1) irb (1.11.1)
rdoc rdoc
reline (>= 0.4.2) reline (>= 0.4.2)
@ -445,7 +445,7 @@ GEM
mime-types-data (3.2023.1205) mime-types-data (3.2023.1205)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.5) mini_portile2 (2.8.5)
minitest (5.20.0) minitest (5.21.2)
msgpack (1.7.2) msgpack (1.7.2)
multi_json (1.15.0) multi_json (1.15.0)
multipart-post (2.3.0) multipart-post (2.3.0)
@ -504,7 +504,7 @@ GEM
orm_adapter (0.5.0) orm_adapter (0.5.0)
ox (2.14.17) ox (2.14.17)
parallel (1.24.0) parallel (1.24.0)
parser (3.2.2.4) parser (3.3.0.5)
ast (~> 2.4.1) ast (~> 2.4.1)
racc racc
parslet (2.0.0) parslet (2.0.0)
@ -610,7 +610,7 @@ GEM
redis (>= 4) redis (>= 4)
redlock (1.3.2) redlock (1.3.2)
redis (>= 3.0.0, < 6.0) redis (>= 3.0.0, < 6.0)
regexp_parser (2.8.3) regexp_parser (2.9.0)
reline (0.4.2) reline (0.4.2)
io-console (~> 0.5) io-console (~> 0.5)
request_store (1.5.1) request_store (1.5.1)
@ -636,7 +636,7 @@ GEM
rspec-mocks (3.12.6) rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0) rspec-support (~> 3.12.0)
rspec-rails (6.1.0) rspec-rails (6.1.1)
actionpack (>= 6.1) actionpack (>= 6.1)
activesupport (>= 6.1) activesupport (>= 6.1)
railties (>= 6.1) railties (>= 6.1)
@ -650,11 +650,11 @@ GEM
rspec-mocks (~> 3.0) rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8) sidekiq (>= 5, < 8)
rspec-support (3.12.1) rspec-support (3.12.1)
rubocop (1.59.0) rubocop (1.60.2)
json (~> 2.3) json (~> 2.3)
language_server-protocol (>= 3.17.0) language_server-protocol (>= 3.17.0)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 3.2.2.4) parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0) regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0) rexml (>= 3.2.5, < 4.0)
@ -696,7 +696,8 @@ GEM
scenic (1.7.0) scenic (1.7.0)
activerecord (>= 4.0.0) activerecord (>= 4.0.0)
railties (>= 4.0.0) railties (>= 4.0.0)
selenium-webdriver (4.16.0) selenium-webdriver (4.17.0)
base64 (~> 0.2)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0) websocket (~> 1.0)
@ -745,8 +746,8 @@ GEM
temple (0.10.3) temple (0.10.3)
terminal-table (3.0.2) terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3) unicode-display_width (>= 1.1.1, < 3)
terrapin (0.6.0) terrapin (1.0.1)
climate_control (>= 0.0.3, < 1.0) climate_control
test-prof (1.3.1) test-prof (1.3.1)
thor (1.3.0) thor (1.3.0)
tilt (2.3.0) tilt (2.3.0)
@ -835,7 +836,7 @@ DEPENDENCIES
capybara (~> 3.39) capybara (~> 3.39)
charlock_holmes (~> 0.7.7) charlock_holmes (~> 0.7.7)
chewy (~> 7.3) chewy (~> 7.3)
climate_control (~> 0.2) climate_control
cocoon (~> 1.2) cocoon (~> 1.2)
color_diff (~> 0.1) color_diff (~> 0.1)
concurrent-ruby concurrent-ruby

View file

@ -24,7 +24,7 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
def unknown_affected_account? def unknown_affected_account?
json = Oj.load(body, mode: :strict) json = Oj.load(body, mode: :strict)
json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.where(uri: json['actor']).exists? json.is_a?(Hash) && %w(Delete Update).include?(json['type']) && json['actor'].present? && json['actor'] == value_or_id(json['object']) && !Account.exists?(uri: json['actor'])
rescue Oj::ParseError rescue Oj::ParseError
false false
end end

View file

@ -3,7 +3,7 @@
module Admin module Admin
class ConfirmationsController < BaseController class ConfirmationsController < BaseController
before_action :set_user before_action :set_user
before_action :check_confirmation, only: [:resend] before_action :redirect_confirmed_user, only: [:resend], if: :user_confirmed?
def create def create
authorize @user, :confirm? authorize @user, :confirm?
@ -25,11 +25,13 @@ module Admin
private private
def check_confirmation def redirect_confirmed_user
if @user.confirmed? flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed')
flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed') redirect_to admin_accounts_path
redirect_to admin_accounts_path end
end
def user_confirmed?
@user.confirmed?
end end
end end
end end

View file

@ -38,7 +38,7 @@ module Admin
log_action :create, @email_domain_block log_action :create, @email_domain_block
(@email_domain_block.other_domains || []).uniq.each do |domain| (@email_domain_block.other_domains || []).uniq.each do |domain|
next if EmailDomainBlock.where(domain: domain).exists? next if EmailDomainBlock.exists?(domain: domain)
other_email_domain_block = EmailDomainBlock.create!(domain: domain, allow_with_approval: @email_domain_block.allow_with_approval, parent: @email_domain_block) other_email_domain_block = EmailDomainBlock.create!(domain: domain, allow_with_approval: @email_domain_block.allow_with_approval, parent: @email_domain_block)
log_action :create, other_email_domain_block log_action :create, other_email_domain_block

View file

@ -49,7 +49,7 @@ module Admin
next next
end end
@warning_domains = Instance.where(domain: @domain_blocks.map(&:domain)).where('EXISTS (SELECT 1 FROM follows JOIN accounts ON follows.account_id = accounts.id OR follows.target_account_id = accounts.id WHERE accounts.domain = instances.domain)').pluck(:domain) @warning_domains = instances_from_imported_blocks.pluck(:domain)
rescue ActionController::ParameterMissing rescue ActionController::ParameterMissing
flash.now[:alert] = I18n.t('admin.export_domain_blocks.no_file') flash.now[:alert] = I18n.t('admin.export_domain_blocks.no_file')
set_dummy_import! set_dummy_import!
@ -58,6 +58,10 @@ module Admin
private private
def instances_from_imported_blocks
Instance.with_domain_follows(@domain_blocks.map(&:domain))
end
def export_filename def export_filename
'domain_blocks.csv' 'domain_blocks.csv'
end end

View file

@ -7,7 +7,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
before_action :set_body_classes before_action :set_body_classes
before_action :set_confirmation_user!, only: [:show, :confirm_captcha] before_action :set_confirmation_user!, only: [:show, :confirm_captcha]
before_action :require_unconfirmed! before_action :redirect_confirmed_user, if: :signed_in_confirmed_user?
before_action :extend_csp_for_captcha!, only: [:show, :confirm_captcha] before_action :extend_csp_for_captcha!, only: [:show, :confirm_captcha]
before_action :require_captcha_if_needed!, only: [:show] before_action :require_captcha_if_needed!, only: [:show]
@ -65,10 +65,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
@confirmation_user.nil? || @confirmation_user.confirmed? @confirmation_user.nil? || @confirmation_user.confirmed?
end end
def require_unconfirmed! def redirect_confirmed_user
if user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank? redirect_to(current_user.approved? ? root_path : edit_user_registration_path)
redirect_to(current_user.approved? ? root_path : edit_user_registration_path) end
end
def signed_in_confirmed_user?
user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank?
end end
def set_body_classes def set_body_classes

View file

@ -2,7 +2,7 @@
class Auth::PasswordsController < Devise::PasswordsController class Auth::PasswordsController < Devise::PasswordsController
skip_before_action :check_self_destruct! skip_before_action :check_self_destruct!
before_action :check_validity_of_reset_password_token, only: :edit before_action :redirect_invalid_reset_token, only: :edit, unless: :reset_password_token_is_valid?
before_action :set_body_classes before_action :set_body_classes
layout 'auth' layout 'auth'
@ -19,11 +19,9 @@ class Auth::PasswordsController < Devise::PasswordsController
private private
def check_validity_of_reset_password_token def redirect_invalid_reset_token
unless reset_password_token_is_valid? flash[:error] = I18n.t('auth.invalid_reset_password_token')
flash[:error] = I18n.t('auth.invalid_reset_password_token') redirect_to new_password_path(resource_name)
redirect_to new_password_path(resource_name)
end
end end
def set_body_classes def set_body_classes

View file

@ -21,10 +21,19 @@ module WebAppControllerConcern
def redirect_unauthenticated_to_permalinks! def redirect_unauthenticated_to_permalinks!
return if user_signed_in? && current_account.moved_to_account_id.nil? return if user_signed_in? && current_account.moved_to_account_id.nil?
redirect_path = PermalinkRedirector.new(request.path).redirect_path permalink_redirector = PermalinkRedirector.new(request.path)
return if redirect_path.blank? return if permalink_redirector.redirect_path.blank?
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in? expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
redirect_to(redirect_path)
respond_to do |format|
format.html do
redirect_to(permalink_redirector.redirect_confirmation_path, allow_other_host: false)
end
format.json do
redirect_to(permalink_redirector.redirect_uri, allow_other_host: true)
end
end
end end
end end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
class Redirect::AccountsController < Redirect::BaseController
private
def set_resource
@resource = Account.find(params[:id])
not_found if @resource.local?
end
end

View file

@ -0,0 +1,24 @@
# frozen_string_literal: true
class Redirect::BaseController < ApplicationController
vary_by 'Accept-Language'
before_action :set_resource
before_action :set_app_body_class
def show
@redirect_path = ActivityPub::TagManager.instance.url_for(@resource)
render 'redirects/show', layout: 'application'
end
private
def set_app_body_class
@body_classes = 'app-body'
end
def set_resource
raise NotImplementedError
end
end

View file

@ -0,0 +1,10 @@
# frozen_string_literal: true
class Redirect::StatusesController < Redirect::BaseController
private
def set_resource
@resource = Status.find(params[:id])
not_found if @resource.local? || !@resource.distributable?
end
end

View file

@ -6,8 +6,8 @@ module Settings
skip_before_action :check_self_destruct! skip_before_action :check_self_destruct!
skip_before_action :require_functional! skip_before_action :require_functional!
before_action :require_otp_enabled before_action :redirect_invalid_otp, unless: -> { current_user.otp_enabled? }
before_action :require_webauthn_enabled, only: [:index, :destroy] before_action :redirect_invalid_webauthn, only: [:index, :destroy], unless: -> { current_user.webauthn_enabled? }
def index; end def index; end
def new; end def new; end
@ -85,18 +85,14 @@ module Settings
private private
def require_otp_enabled def redirect_invalid_otp
unless current_user.otp_enabled? flash[:error] = t('webauthn_credentials.otp_required')
flash[:error] = t('webauthn_credentials.otp_required') redirect_to settings_two_factor_authentication_methods_path
redirect_to settings_two_factor_authentication_methods_path
end
end end
def require_webauthn_enabled def redirect_invalid_webauthn
unless current_user.webauthn_enabled? flash[:error] = t('webauthn_credentials.not_enabled')
flash[:error] = t('webauthn_credentials.not_enabled') redirect_to settings_two_factor_authentication_methods_path
redirect_to settings_two_factor_authentication_methods_path
end
end end
end end
end end

View file

@ -0,0 +1,25 @@
<svg width="5" height="80" viewBox="0 0 5 80" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_253_1286)">
<rect width="5" height="80" fill="url(#paint0_linear_253_1286)"/>
<line x1="-0.860365" y1="6.80136" x2="10.6078" y2="-1.22871" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="14.8314" x2="10.6078" y2="6.80132" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="22.8615" x2="10.6078" y2="14.8314" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="30.8916" x2="10.6078" y2="22.8615" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="38.9216" x2="10.6078" y2="30.8915" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="46.9517" x2="10.6078" y2="38.9216" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="54.9818" x2="10.6078" y2="46.9517" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="63.0118" x2="10.6078" y2="54.9817" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="71.0419" x2="10.6078" y2="63.0118" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="79.072" x2="10.6078" y2="71.0419" stroke="black" stroke-width="3"/>
<line x1="-0.860365" y1="87.102" x2="10.6078" y2="79.072" stroke="black" stroke-width="3"/>
</g>
<defs>
<linearGradient id="paint0_linear_253_1286" x1="2.5" y1="0" x2="2.5" y2="80" gradientUnits="userSpaceOnUse">
<stop stop-color="#FEC84B"/>
<stop offset="1" stop-color="#F79009"/>
</linearGradient>
<clipPath id="clip0_253_1286">
<rect width="5" height="80" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -9,7 +9,11 @@ exports[`<AutosuggestEmoji /> renders emoji with custom url 1`] = `
className="emojione" className="emojione"
src="http://example.com/emoji.png" src="http://example.com/emoji.png"
/> />
:foobar: <div
className="autosuggest-emoji__name"
>
:foobar:
</div>
</div> </div>
`; `;
@ -22,6 +26,10 @@ exports[`<AutosuggestEmoji /> renders native emoji 1`] = `
className="emojione" className="emojione"
src="/emoji/1f499.svg" src="/emoji/1f499.svg"
/> />
:foobar: <div
className="autosuggest-emoji__name"
>
:foobar:
</div>
</div> </div>
`; `;

View file

@ -37,10 +37,10 @@ class Account extends ImmutablePureComponent {
static propTypes = { static propTypes = {
size: PropTypes.number, size: PropTypes.number,
account: ImmutablePropTypes.record, account: ImmutablePropTypes.record,
onFollow: PropTypes.func.isRequired, onFollow: PropTypes.func,
onBlock: PropTypes.func.isRequired, onBlock: PropTypes.func,
onMute: PropTypes.func.isRequired, onMute: PropTypes.func,
onMuteNotifications: PropTypes.func.isRequired, onMuteNotifications: PropTypes.func,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
hidden: PropTypes.bool, hidden: PropTypes.bool,
minimal: PropTypes.bool, minimal: PropTypes.bool,

View file

@ -35,7 +35,7 @@ export default class AutosuggestEmoji extends PureComponent {
alt={emoji.native || emoji.colons} alt={emoji.native || emoji.colons}
/> />
{emoji.colons} <div className='autosuggest-emoji__name'>{emoji.colons}</div>
</div> </div>
); );
} }

View file

@ -1,5 +1,3 @@
import { FormattedMessage } from 'react-intl';
import { ShortNumber } from 'mastodon/components/short_number'; import { ShortNumber } from 'mastodon/components/short_number';
interface Props { interface Props {
@ -16,27 +14,18 @@ interface Props {
}; };
} }
export const AutosuggestHashtag: React.FC<Props> = ({ tag }) => { export const AutosuggestHashtag: React.FC<Props> = ({ tag }) => (
const weeklyUses = tag.history && ( <div className='autosuggest-hashtag'>
<ShortNumber <div className='autosuggest-hashtag__name'>
value={tag.history.reduce((total, day) => total + day.uses * 1, 0)} #<strong>{tag.name}</strong>
/>
);
return (
<div className='autosuggest-hashtag'>
<div className='autosuggest-hashtag__name'>
#<strong>{tag.name}</strong>
</div>
{tag.history !== undefined && (
<div className='autosuggest-hashtag__uses'>
<FormattedMessage
id='autosuggest_hashtag.per_week'
defaultMessage='{count} per week'
values={{ count: weeklyUses }}
/>
</div>
)}
</div> </div>
);
}; {tag.history !== undefined && (
<div className='autosuggest-hashtag__uses'>
<ShortNumber
value={tag.history.reduce((total, day) => total + day.uses * 1, 0)}
/>
</div>
)}
</div>
);

View file

@ -5,6 +5,8 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import Overlay from 'react-overlays/Overlay';
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
import AutosuggestEmoji from './autosuggest_emoji'; import AutosuggestEmoji from './autosuggest_emoji';
@ -195,34 +197,37 @@ export default class AutosuggestInput extends ImmutablePureComponent {
return ( return (
<div className='autosuggest-input'> <div className='autosuggest-input'>
<label> <input
<span style={{ display: 'none' }}>{placeholder}</span> type='text'
ref={this.setInput}
disabled={disabled}
placeholder={placeholder}
autoFocus={autoFocus}
value={value}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
onKeyUp={onKeyUp}
onFocus={this.onFocus}
onBlur={this.onBlur}
dir='auto'
aria-autocomplete='list'
aria-label={placeholder}
id={id}
className={className}
maxLength={maxLength}
lang={lang}
spellCheck={spellCheck}
/>
<input <Overlay show={!(suggestionsHidden || suggestions.isEmpty())} offset={[0, 0]} placement='bottom' target={this.input} popperConfig={{ strategy: 'fixed' }}>
type='text' {({ props }) => (
ref={this.setInput} <div {...props}>
disabled={disabled} <div className='autosuggest-textarea__suggestions' style={{ width: this.input?.clientWidth }}>
placeholder={placeholder} {suggestions.map(this.renderSuggestion)}
autoFocus={autoFocus} </div>
value={value} </div>
onChange={this.onChange} )}
onKeyDown={this.onKeyDown} </Overlay>
onKeyUp={onKeyUp}
onFocus={this.onFocus}
onBlur={this.onBlur}
dir='auto'
aria-autocomplete='list'
id={id}
className={className}
maxLength={maxLength}
lang={lang}
spellCheck={spellCheck}
/>
</label>
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
{suggestions.map(this.renderSuggestion)}
</div>
</div> </div>
); );
} }

View file

@ -5,6 +5,7 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import Overlay from 'react-overlays/Overlay';
import Textarea from 'react-textarea-autosize'; import Textarea from 'react-textarea-autosize';
import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container';
@ -52,7 +53,6 @@ const AutosuggestTextarea = forwardRef(({
onFocus, onFocus,
autoFocus = true, autoFocus = true,
lang, lang,
children,
}, textareaRef) => { }, textareaRef) => {
const [suggestionsHidden, setSuggestionsHidden] = useState(true); const [suggestionsHidden, setSuggestionsHidden] = useState(true);
@ -183,40 +183,38 @@ const AutosuggestTextarea = forwardRef(({
); );
}; };
return [ return (
<div className='compose-form__autosuggest-wrapper' key='autosuggest-wrapper'> <div className='autosuggest-textarea'>
<div className='autosuggest-textarea'> <Textarea
<label> ref={textareaRef}
<span style={{ display: 'none' }}>{placeholder}</span> className='autosuggest-textarea__textarea'
disabled={disabled}
placeholder={placeholder}
autoFocus={autoFocus}
value={value}
onChange={handleChange}
onKeyDown={handleKeyDown}
onKeyUp={onKeyUp}
onFocus={handleFocus}
onBlur={handleBlur}
onPaste={handlePaste}
dir='auto'
aria-autocomplete='list'
aria-label={placeholder}
lang={lang}
/>
<Textarea <Overlay show={!(suggestionsHidden || suggestions.isEmpty())} offset={[0, 0]} placement='bottom' target={textareaRef} popperConfig={{ strategy: 'fixed' }}>
ref={textareaRef} {({ props }) => (
className='autosuggest-textarea__textarea' <div {...props}>
disabled={disabled} <div className='autosuggest-textarea__suggestions' style={{ width: textareaRef.current?.clientWidth }}>
placeholder={placeholder} {suggestions.map(renderSuggestion)}
autoFocus={autoFocus} </div>
value={value} </div>
onChange={handleChange} )}
onKeyDown={handleKeyDown} </Overlay>
onKeyUp={onKeyUp} </div>
onFocus={handleFocus} );
onBlur={handleBlur}
onPaste={handlePaste}
dir='auto'
aria-autocomplete='list'
lang={lang}
/>
</label>
</div>
{children}
</div>,
<div className='autosuggest-textarea__suggestions-wrapper' key='suggestions-wrapper'>
<div className={`autosuggest-textarea__suggestions ${suggestionsHidden || suggestions.isEmpty() ? '' : 'autosuggest-textarea__suggestions--visible'}`}>
{suggestions.map(renderSuggestion)}
</div>
</div>,
];
}); });
AutosuggestTextarea.propTypes = { AutosuggestTextarea.propTypes = {
@ -232,7 +230,6 @@ AutosuggestTextarea.propTypes = {
onKeyDown: PropTypes.func, onKeyDown: PropTypes.func,
onPaste: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired,
onFocus:PropTypes.func, onFocus:PropTypes.func,
children: PropTypes.node,
autoFocus: PropTypes.bool, autoFocus: PropTypes.bool,
lang: PropTypes.string, lang: PropTypes.string,
}; };

View file

@ -165,7 +165,7 @@ class Dropdown extends PureComponent {
children: PropTypes.node, children: PropTypes.node,
icon: PropTypes.string, icon: PropTypes.string,
iconComponent: PropTypes.func, iconComponent: PropTypes.func,
items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired, items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]),
loading: PropTypes.bool, loading: PropTypes.bool,
size: PropTypes.number, size: PropTypes.number,
title: PropTypes.string, title: PropTypes.string,

View file

@ -70,9 +70,9 @@ export const defaultMediaVisibility = (status) => {
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' }, unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Quiet public' },
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' }, private_short: { id: 'privacy.private.short', defaultMessage: 'Followers' },
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' }, direct_short: { id: 'privacy.direct.short', defaultMessage: 'Specific people' },
edited: { id: 'status.edited', defaultMessage: 'Edited {date}' }, edited: { id: 'status.edited', defaultMessage: 'Edited {date}' },
}); });

View file

@ -18,8 +18,10 @@ import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import StarBorderIcon from '@/material-icons/400-24px/star.svg?react'; import StarBorderIcon from '@/material-icons/400-24px/star.svg?react';
import VisibilityIcon from '@/material-icons/400-24px/visibility.svg?react'; import VisibilityIcon from '@/material-icons/400-24px/visibility.svg?react';
import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react'; import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react'; import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { WithRouterPropTypes } from 'mastodon/utils/react_router';
@ -366,7 +368,7 @@ class StatusActionBar extends ImmutablePureComponent {
if (status.get('reblogged')) { if (status.get('reblogged')) {
reblogTitle = intl.formatMessage(messages.cancel_reblog_private); reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon; reblogIconComponent = publicStatus ? RepeatActiveIcon : RepeatPrivateActiveIcon;
} else if (publicStatus) { } else if (publicStatus) {
reblogTitle = intl.formatMessage(messages.reblog); reblogTitle = intl.formatMessage(messages.reblog);
reblogIconComponent = RepeatIcon; reblogIconComponent = RepeatIcon;

View file

@ -2,8 +2,8 @@ import { defineMessages, useIntl } from 'react-intl';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import LockIcon from '@/material-icons/400-24px/lock.svg?react'; import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.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 './icon'; import { Icon } from './icon';
@ -11,14 +11,17 @@ type Visibility = 'public' | 'unlisted' | 'private' | 'direct';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' }, unlisted_short: {
id: 'privacy.unlisted.short',
defaultMessage: 'Quiet public',
},
private_short: { private_short: {
id: 'privacy.private.short', id: 'privacy.private.short',
defaultMessage: 'Followers only', defaultMessage: 'Followers',
}, },
direct_short: { direct_short: {
id: 'privacy.direct.short', id: 'privacy.direct.short',
defaultMessage: 'Mentioned people only', defaultMessage: 'Specific people',
}, },
}); });
@ -35,7 +38,7 @@ export const VisibilityIcon: React.FC<{ visibility: Visibility }> = ({
}, },
unlisted: { unlisted: {
icon: 'unlock', icon: 'unlock',
iconComponent: LockOpenIcon, iconComponent: QuietTimeIcon,
text: intl.formatMessage(messages.unlisted_short), text: intl.formatMessage(messages.unlisted_short),
}, },
private: { private: {

View file

@ -1,14 +1,12 @@
import { PureComponent } from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import { fetchCustomEmojis } from '../actions/custom_emojis'; import { fetchCustomEmojis } from 'mastodon/actions/custom_emojis';
import { hydrateStore } from '../actions/store'; import { hydrateStore } from 'mastodon/actions/store';
import Compose from '../features/standalone/compose'; import { Router } from 'mastodon/components/router';
import initialState from '../initial_state'; import Compose from 'mastodon/features/standalone/compose';
import { IntlProvider } from '../locales'; import initialState from 'mastodon/initial_state';
import { store } from '../store'; import { IntlProvider } from 'mastodon/locales';
import { store } from 'mastodon/store';
if (initialState) { if (initialState) {
store.dispatch(hydrateStore(initialState)); store.dispatch(hydrateStore(initialState));
@ -16,16 +14,14 @@ if (initialState) {
store.dispatch(fetchCustomEmojis()); store.dispatch(fetchCustomEmojis());
export default class ComposeContainer extends PureComponent { const ComposeContainer = () => (
<IntlProvider>
<Provider store={store}>
<Router>
<Compose />
</Router>
</Provider>
</IntlProvider>
);
render () { export default ComposeContainer;
return (
<IntlProvider>
<Provider store={store}>
<Compose />
</Provider>
</IntlProvider>
);
}
}

View file

@ -1,13 +1,13 @@
import PropTypes from 'prop-types'; import { useCallback } from 'react';
import { PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import ImmutablePropTypes from 'react-immutable-proptypes'; import { useDispatch } from 'react-redux';
import MenuIcon from '@/material-icons/400-24px/menu.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import { openModal } from 'mastodon/actions/modal';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import { logOut } from 'mastodon/utils/log_out';
const messages = defineMessages({ const messages = defineMessages({
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
@ -23,51 +23,52 @@ const messages = defineMessages({
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' }, filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' },
bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' },
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
}); });
class ActionBar extends PureComponent { export const ActionBar = () => {
const dispatch = useDispatch();
const intl = useIntl();
static propTypes = { const handleLogoutClick = useCallback(() => {
account: ImmutablePropTypes.record.isRequired, dispatch(openModal({
onLogout: PropTypes.func.isRequired, modalType: 'CONFIRM',
intl: PropTypes.object.isRequired, modalProps: {
}; message: intl.formatMessage(messages.logoutMessage),
confirm: intl.formatMessage(messages.logoutConfirm),
closeWhenConfirm: false,
onConfirm: () => logOut(),
},
}));
}, [dispatch, intl]);
handleLogout = () => { let menu = [];
this.props.onLogout();
};
render () { menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
const { intl } = this.props; menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' });
menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
menu.push({ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.logout), action: handleLogoutClick });
let menu = []; return (
<DropdownMenuContainer
menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' }); items={menu}
menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' }); icon='bars'
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' }); iconComponent={MoreHorizIcon}
menu.push(null); size={24}
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' }); direction='right'
menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' }); />
menu.push({ text: intl.formatMessage(messages.bookmarks), to: '/bookmarks' }); );
menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' }); };
menu.push({ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
menu.push({ text: intl.formatMessage(messages.filters), href: '/filters' });
menu.push(null);
menu.push({ text: intl.formatMessage(messages.logout), action: this.handleLogout });
return (
<div className='compose__action-bar'>
<div className='compose__action-bar-dropdown'>
<DropdownMenuContainer items={menu} icon='bars' iconComponent={MenuIcon} size={24} direction='right' />
</div>
</div>
);
}
}
export default injectIntl(ActionBar);

View file

@ -15,7 +15,7 @@ export default class AutosuggestAccount extends ImmutablePureComponent {
return ( return (
<div className='autosuggest-account' title={account.get('acct')}> <div className='autosuggest-account' title={account.get('acct')}>
<div className='autosuggest-account-icon'><Avatar account={account} size={18} /></div> <Avatar account={account} size={24} />
<DisplayName account={account} /> <DisplayName account={account} />
</div> </div>
); );

View file

@ -1,26 +1,18 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { length } from 'stringz'; import { length } from 'stringz';
export default class CharacterCounter extends PureComponent { export const CharacterCounter = ({ text, max }) => {
const diff = max - length(text);
static propTypes = { if (diff < 0) {
text: PropTypes.string.isRequired, return <span className='character-counter character-counter--over'>{diff}</span>;
max: PropTypes.number.isRequired,
};
checkRemainingText (diff) {
if (diff < 0) {
return <span className='character-counter character-counter--over'>{diff}</span>;
}
return <span className='character-counter'>{diff}</span>;
} }
render () { return <span className='character-counter'>{diff}</span>;
const diff = this.props.max - length(this.props.text); };
return this.checkRemainingText(diff);
}
} CharacterCounter.propTypes = {
text: PropTypes.string.isRequired,
max: PropTypes.number.isRequired,
};

View file

@ -10,8 +10,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { length } from 'stringz'; import { length } from 'stringz';
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
import { Icon } from 'mastodon/components/icon';
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router'; import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router';
import AutosuggestInput from '../../../components/autosuggest_input'; import AutosuggestInput from '../../../components/autosuggest_input';
@ -20,25 +18,27 @@ import { Button } from '../../../components/button';
import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container'; import EmojiPickerDropdown from '../containers/emoji_picker_dropdown_container';
import LanguageDropdown from '../containers/language_dropdown_container'; import LanguageDropdown from '../containers/language_dropdown_container';
import PollButtonContainer from '../containers/poll_button_container'; import PollButtonContainer from '../containers/poll_button_container';
import PollFormContainer from '../containers/poll_form_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container'; import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import ReplyIndicatorContainer from '../containers/reply_indicator_container';
import SpoilerButtonContainer from '../containers/spoiler_button_container'; import SpoilerButtonContainer from '../containers/spoiler_button_container';
import UploadButtonContainer from '../containers/upload_button_container'; import UploadButtonContainer from '../containers/upload_button_container';
import UploadFormContainer from '../containers/upload_form_container'; import UploadFormContainer from '../containers/upload_form_container';
import WarningContainer from '../containers/warning_container'; import WarningContainer from '../containers/warning_container';
import { countableText } from '../util/counter'; import { countableText } from '../util/counter';
import CharacterCounter from './character_counter'; import { CharacterCounter } from './character_counter';
import { EditIndicator } from './edit_indicator';
import { NavigationBar } from './navigation_bar';
import { PollForm } from "./poll_form";
import { ReplyIndicator } from './reply_indicator';
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'; 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';
const messages = defineMessages({ const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' }, placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' }, spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Content warning (optional)' },
publish: { id: 'compose_form.publish', defaultMessage: 'Publish' }, publish: { id: 'compose_form.publish', defaultMessage: 'Post' },
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Update' },
saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' }, reply: { id: 'compose_form.reply', defaultMessage: 'Reply' },
}); });
class ComposeForm extends ImmutablePureComponent { class ComposeForm extends ImmutablePureComponent {
@ -65,10 +65,12 @@ class ComposeForm extends ImmutablePureComponent {
onPaste: PropTypes.func.isRequired, onPaste: PropTypes.func.isRequired,
onPickEmoji: PropTypes.func.isRequired, onPickEmoji: PropTypes.func.isRequired,
autoFocus: PropTypes.bool, autoFocus: PropTypes.bool,
withoutNavigation: PropTypes.bool,
anyMedia: PropTypes.bool, anyMedia: PropTypes.bool,
isInReply: PropTypes.bool, isInReply: PropTypes.bool,
singleColumn: PropTypes.bool, singleColumn: PropTypes.bool,
lang: PropTypes.string, lang: PropTypes.string,
maxChars: PropTypes.number,
...WithOptionalRouterPropTypes ...WithOptionalRouterPropTypes
}; };
@ -100,11 +102,11 @@ class ComposeForm extends ImmutablePureComponent {
}; };
canSubmit = () => { canSubmit = () => {
const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props; const { isSubmitting, isChangingUpload, isUploading, anyMedia, maxChars } = this.props;
const fulltext = this.getFulltextForCharacterCounting(); const fulltext = this.getFulltextForCharacterCounting();
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0; const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 1000 || (isOnlyWhitespace && !anyMedia)); return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
}; };
handleSubmit = (e) => { handleSubmit = (e) => {
@ -223,93 +225,90 @@ class ComposeForm extends ImmutablePureComponent {
}; };
render () { render () {
const { intl, onPaste, autoFocus } = this.props; const { intl, onPaste, autoFocus, withoutNavigation, maxChars } = this.props;
const { highlighted } = this.state; const { highlighted } = this.state;
const disabled = this.props.isSubmitting; const disabled = this.props.isSubmitting;
let publishText = '';
if (this.props.isEditing) {
publishText = intl.formatMessage(messages.saveChanges);
} else if (this.props.privacy === 'private' || this.props.privacy === 'direct') {
publishText = <><Icon id='lock' icon={LockIcon} /> {intl.formatMessage(messages.publish)}</>;
} else {
publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
}
return ( return (
<form className='compose-form' onSubmit={this.handleSubmit}> <form className='compose-form' onSubmit={this.handleSubmit}>
<ReplyIndicator />
{!withoutNavigation && <NavigationBar />}
<WarningContainer /> <WarningContainer />
<ReplyIndicatorContainer /> <div className={classNames('compose-form__highlightable', { active: highlighted })} ref={this.setRef}>
<div className='compose-form__scrollable'>
<EditIndicator />
<div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`} ref={this.setRef} aria-hidden={!this.props.spoiler}> {this.props.spoiler && (
<AutosuggestInput <div className='spoiler-input'>
placeholder={intl.formatMessage(messages.spoiler_placeholder)} <div className='spoiler-input__border' />
value={this.props.spoilerText}
onChange={this.handleChangeSpoilerText}
onKeyDown={this.handleKeyDown}
disabled={!this.props.spoiler}
ref={this.setSpoilerText}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSpoilerSuggestionSelected}
searchTokens={[':']}
id='cw-spoiler-input'
className='spoiler-input__input'
lang={this.props.lang}
spellCheck
/>
</div>
<div className={classNames('compose-form__highlightable', { active: highlighted })}> <AutosuggestInput
<AutosuggestTextarea placeholder={intl.formatMessage(messages.spoiler_placeholder)}
ref={this.textareaRef} value={this.props.spoilerText}
placeholder={intl.formatMessage(messages.placeholder)} disabled={disabled}
disabled={disabled} onChange={this.handleChangeSpoilerText}
value={this.props.text} onKeyDown={this.handleKeyDown}
onChange={this.handleChange} ref={this.setSpoilerText}
suggestions={this.props.suggestions} suggestions={this.props.suggestions}
onFocus={this.handleFocus} onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onKeyDown={this.handleKeyDown} onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} onSuggestionSelected={this.onSpoilerSuggestionSelected}
onSuggestionsClearRequested={this.onSuggestionsClearRequested} searchTokens={[':']}
onSuggestionSelected={this.onSuggestionSelected} id='cw-spoiler-input'
onPaste={onPaste} className='spoiler-input__input'
autoFocus={autoFocus} lang={this.props.lang}
lang={this.props.lang} spellCheck
> />
<div className='compose-form__modifiers'>
<UploadFormContainer />
<PollFormContainer />
</div>
</AutosuggestTextarea>
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
<div className='compose-form__buttons-wrapper'> <div className='spoiler-input__border' />
<div className='compose-form__buttons'> </div>
<UploadButtonContainer /> )}
<PollButtonContainer />
<AutosuggestTextarea
ref={this.textareaRef}
placeholder={intl.formatMessage(messages.placeholder)}
disabled={disabled}
value={this.props.text}
onChange={this.handleChange}
suggestions={this.props.suggestions}
onFocus={this.handleFocus}
onKeyDown={this.handleKeyDown}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
onPaste={onPaste}
autoFocus={autoFocus}
lang={this.props.lang}
/>
</div>
<UploadFormContainer />
<PollForm />
<div className='compose-form__footer'>
<div className='compose-form__dropdowns'>
<PrivacyDropdownContainer disabled={this.props.isEditing} /> <PrivacyDropdownContainer disabled={this.props.isEditing} />
<SpoilerButtonContainer />
<LanguageDropdown /> <LanguageDropdown />
</div> </div>
<div className='character-counter__wrapper'> <div className='compose-form__actions'>
<CharacterCounter max={1000} text={this.getFulltextForCharacterCounting()} /> <div className='compose-form__buttons'>
</div> <UploadButtonContainer />
</div> <PollButtonContainer />
</div> <SpoilerButtonContainer />
<EmojiPickerDropdown onPickEmoji={this.handleEmojiPick} />
<CharacterCounter max={maxChars} text={this.getFulltextForCharacterCounting()} />
</div>
<div className='compose-form__publish'> <div className='compose-form__submit'>
<div className='compose-form__publish-button-wrapper'> <Button
<Button type='submit'
type='submit' text={intl.formatMessage(this.props.isEditing ? messages.saveChanges : (this.props.isInReply ? messages.reply : messages.publish))}
text={publishText} disabled={!this.canSubmit()}
disabled={!this.canSubmit()} />
block </div>
/> </div>
</div> </div>
</div> </div>
</form> </form>

View file

@ -0,0 +1,62 @@
import { useCallback } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
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 { cancelReplyCompose } from 'mastodon/actions/compose';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
const messages = defineMessages({
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
});
export const EditIndicator = () => {
const intl = useIntl();
const dispatch = useDispatch();
const id = useSelector(state => state.getIn(['compose', 'id']));
const status = useSelector(state => state.getIn(['statuses', id]));
const account = useSelector(state => state.getIn(['accounts', status?.get('account')]));
const handleCancelClick = useCallback(() => {
dispatch(cancelReplyCompose());
}, [dispatch]);
if (!status) {
return null;
}
const content = { __html: status.get('contentHtml') };
return (
<div className='edit-indicator'>
<div className='edit-indicator__header'>
<div className='edit-indicator__display-name'>
<Link to={`/@${account.get('acct')}`}>@{account.get('acct')}</Link>
·
<Link to={`/@${account.get('acct')}/${status.get('id')}`}><RelativeTimestamp timestamp={status.get('created_at')} /></Link>
</div>
<div className='edit-indicator__cancel'>
<IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={handleCancelClick} inverted />
</div>
</div>
<div className='edit-indicator__content translate' dangerouslySetInnerHTML={content} />
{(status.get('poll') || status.get('media_attachments').size > 0) && (
<div className='edit-indicator__attachments'>
{status.get('poll') && <><Icon icon={BarChart4BarsIcon} /><FormattedMessage id='reply_indicator.poll' defaultMessage='Poll' /></>}
{status.get('media_attachments').size > 0 && <><Icon icon={PhotoLibraryIcon} /><FormattedMessage id='reply_indicator.attachments' defaultMessage='{count, plural, one {# attachment} other {# attachments}}' values={{ count: status.get('media_attachments').size }} /></>}
</div>
)}
</div>
);
};

View file

@ -10,6 +10,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { supportsPassiveEvents } from 'detect-passive-events'; import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import MoodIcon from 'mastodon/../material-icons/400-24px/mood.svg?react';
import { IconButton } from 'mastodon/components/icon_button';
import { assetHost } from 'mastodon/utils/config'; import { assetHost } from 'mastodon/utils/config';
import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji'; import { buildCustomEmojis, categoriesFromEmojis } from '../../emoji/emoji';
@ -162,6 +164,7 @@ class EmojiPickerMenuImpl extends PureComponent {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
skinTone: PropTypes.number.isRequired, skinTone: PropTypes.number.isRequired,
onSkinTone: PropTypes.func.isRequired, onSkinTone: PropTypes.func.isRequired,
pickerButtonRef: PropTypes.func.isRequired
}; };
static defaultProps = { static defaultProps = {
@ -176,7 +179,7 @@ class EmojiPickerMenuImpl extends PureComponent {
}; };
handleDocumentClick = e => { handleDocumentClick = e => {
if (this.node && !this.node.contains(e.target)) { if (this.node && !this.node.contains(e.target) && !this.props.pickerButtonRef.contains(e.target)) {
this.props.onClose(); this.props.onClose();
} }
}; };
@ -231,6 +234,7 @@ class EmojiPickerMenuImpl extends PureComponent {
emoji.native = emoji.colons; emoji.native = emoji.colons;
} }
if (!(event.ctrlKey || event.metaKey)) { if (!(event.ctrlKey || event.metaKey)) {
this.props.onClose(); this.props.onClose();
} }
this.props.onPick(emoji); this.props.onPick(emoji);
@ -321,7 +325,6 @@ class EmojiPickerDropdown extends PureComponent {
onPickEmoji: PropTypes.func.isRequired, onPickEmoji: PropTypes.func.isRequired,
onSkinTone: PropTypes.func.isRequired, onSkinTone: PropTypes.func.isRequired,
skinTone: PropTypes.number.isRequired, skinTone: PropTypes.number.isRequired,
button: PropTypes.node,
}; };
state = { state = {
@ -379,23 +382,24 @@ class EmojiPickerDropdown extends PureComponent {
}; };
render () { render () {
const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props; const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis } = this.props;
const title = intl.formatMessage(messages.emoji); const title = intl.formatMessage(messages.emoji);
const { active, loading } = this.state; const { active, loading } = this.state;
return ( return (
<div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown}> <div className='emoji-picker-dropdown' onKeyDown={this.handleKeyDown} ref={this.setTargetRef}>
<div ref={this.setTargetRef} className='emoji-button' title={title} aria-label={title} aria-expanded={active} role='button' onClick={this.onToggle} onKeyDown={this.onToggle} tabIndex={0}> <IconButton
{button || <img title={title}
className={classNames('emojione', { 'pulse-loading': active && loading })} aria-expanded={active}
alt='🙂' active={active}
src={`${assetHost}/emoji/1f642.svg`} iconComponent={MoodIcon}
/>} onClick={this.onToggle}
</div> inverted
/>
<Overlay show={active} placement={'bottom'} target={this.findTarget} popperConfig={{ strategy: 'fixed' }}> <Overlay show={active} placement={'bottom'} target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
{({ props, placement })=> ( {({ props, placement })=> (
<div {...props} style={{ ...props.style, width: 299 }}> <div {...props} style={{ ...props.style }}>
<div className={`dropdown-animation ${placement}`}> <div className={`dropdown-animation ${placement}`}>
<EmojiPickerMenu <EmojiPickerMenu
custom_emojis={this.props.custom_emojis} custom_emojis={this.props.custom_emojis}
@ -405,6 +409,7 @@ class EmojiPickerDropdown extends PureComponent {
onSkinTone={onSkinTone} onSkinTone={onSkinTone}
skinTone={skinTone} skinTone={skinTone}
frequentlyUsedEmojis={frequentlyUsedEmojis} frequentlyUsedEmojis={frequentlyUsedEmojis}
pickerButtonRef={this.target}
/> />
</div> </div>
</div> </div>

View file

@ -9,10 +9,11 @@ import { supportsPassiveEvents } from 'detect-passive-events';
import fuzzysort from 'fuzzysort'; import fuzzysort from 'fuzzysort';
import Overlay from 'react-overlays/Overlay'; 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 { Icon } from 'mastodon/components/icon';
import { languages as preloadedLanguages } from 'mastodon/initial_state'; import { languages as preloadedLanguages } from 'mastodon/initial_state';
import { loupeIcon, deleteIcon } from 'mastodon/utils/icons';
import TextIconButton from './text_icon_button';
const messages = defineMessages({ const messages = defineMessages({
changeLanguage: { id: 'compose.language.change', defaultMessage: 'Change language' }, changeLanguage: { id: 'compose.language.change', defaultMessage: 'Change language' },
@ -231,7 +232,7 @@ class LanguageDropdownMenu extends PureComponent {
<div ref={this.setRef}> <div ref={this.setRef}>
<div className='emoji-mart-search'> <div className='emoji-mart-search'>
<input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} /> <input type='search' value={searchValue} onChange={this.handleSearchChange} onKeyDown={this.handleSearchKeyDown} placeholder={intl.formatMessage(messages.search)} />
<button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}>{!isSearching ? loupeIcon : deleteIcon}</button> <button type='button' className='emoji-mart-search-icon' disabled={!isSearching} aria-label={intl.formatMessage(messages.clear)} onClick={this.handleClear}><Icon icon={!isSearching ? SearchIcon : CancelIcon} /></button>
</div> </div>
<div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}> <div className='language-dropdown__dropdown__results emoji-mart-scroll' role='listbox' ref={this.setListRef}>
@ -297,20 +298,24 @@ class LanguageDropdown extends PureComponent {
render () { render () {
const { value, intl, frequentlyUsedLanguages } = this.props; const { value, intl, frequentlyUsedLanguages } = this.props;
const { open, placement } = this.state; const { open, placement } = this.state;
const current = preloadedLanguages.find(lang => lang[0] === value) ?? [];
return ( return (
<div className={classNames('privacy-dropdown', placement, { active: open })}> <div ref={this.setTargetRef} onKeyDown={this.handleKeyDown}>
<div className='privacy-dropdown__value' ref={this.setTargetRef} > <button
<TextIconButton type='button'
className='privacy-dropdown__value-icon' title={intl.formatMessage(messages.changeLanguage)}
label={value && value.toUpperCase()} aria-expanded={open}
title={intl.formatMessage(messages.changeLanguage)} onClick={this.handleToggle}
active={open} onMouseDown={this.handleMouseDown}
onClick={this.handleToggle} onKeyDown={this.handleButtonKeyDown}
/> className={classNames('dropdown-button', { active: open })}
</div> >
<Icon icon={TranslateIcon} />
<span className='dropdown-button__label'>{current[2] ?? value}</span>
</button>
<Overlay show={open} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}> <Overlay show={open} offset={[5, 5]} placement={placement} flip target={this.findTarget} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
{({ props, placement }) => ( {({ props, placement }) => (
<div {...props}> <div {...props}>
<div className={`dropdown-animation language-dropdown__dropdown ${placement}`} > <div className={`dropdown-animation language-dropdown__dropdown ${placement}`} >

View file

@ -1,50 +1,36 @@
import PropTypes from 'prop-types'; import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl'; import { useIntl, defineMessages } from 'react-intl';
import { Link } from 'react-router-dom'; import { useSelector, useDispatch } from 'react-redux';
import ImmutablePropTypes from 'react-immutable-proptypes'; import CloseIcon from 'mastodon/../material-icons/400-24px/close.svg?react';
import ImmutablePureComponent from 'react-immutable-pure-component'; import { cancelReplyCompose } from 'mastodon/actions/compose';
import Account from 'mastodon/components/account';
import { IconButton } from 'mastodon/components/icon_button';
import { me } from 'mastodon/initial_state';
import { Avatar } from '../../../components/avatar'; import { ActionBar } from './action_bar';
import ActionBar from './action_bar';
export default class NavigationBar extends ImmutablePureComponent { const messages = defineMessages({
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
});
static propTypes = { export const NavigationBar = () => {
account: ImmutablePropTypes.record.isRequired, const dispatch = useDispatch();
onLogout: PropTypes.func.isRequired, const intl = useIntl();
onClose: PropTypes.func, const account = useSelector(state => state.getIn(['accounts', me]));
}; const isReplying = useSelector(state => !!state.getIn(['compose', 'in_reply_to']));
render () { const handleCancelClick = useCallback(() => {
const username = this.props.account.get('acct'); dispatch(cancelReplyCompose());
return ( }, [dispatch]);
<div className='navigation-bar'>
<Link to={`/@${username}`}>
<span style={{ display: 'none' }}>{username}</span>
<Avatar account={this.props.account} size={46} />
</Link>
<div className='navigation-bar__profile'> return (
<span> <div className='navigation-bar'>
<Link to={`/@${username}`}> <Account account={account} minimal />
<strong className='navigation-bar__profile-account'>@{username}</strong> {isReplying ? <IconButton title={intl.formatMessage(messages.cancel)} iconComponent={CloseIcon} onClick={handleCancelClick} /> : <ActionBar />}
</Link> </div>
</span> );
};
<span>
<a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a>
</span>
</div>
<div className='navigation-bar__actions'>
<ActionBar account={this.props.account} onLogout={this.props.onLogout} />
</div>
</div>
);
}
}

View file

@ -3,11 +3,10 @@ import { PureComponent } from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react';
import { IconButton } from '../../../components/icon_button'; import { IconButton } from '../../../components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
add_poll: { id: 'poll_button.add_poll', defaultMessage: 'Add a poll' }, add_poll: { id: 'poll_button.add_poll', defaultMessage: 'Add a poll' },
remove_poll: { id: 'poll_button.remove_poll', defaultMessage: 'Remove poll' }, remove_poll: { id: 'poll_button.remove_poll', defaultMessage: 'Remove poll' },
@ -22,7 +21,6 @@ class PollButton extends PureComponent {
static propTypes = { static propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,
unavailable: PropTypes.bool,
active: PropTypes.bool, active: PropTypes.bool,
onClick: PropTypes.func.isRequired, onClick: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
@ -33,17 +31,13 @@ class PollButton extends PureComponent {
}; };
render () { render () {
const { intl, active, unavailable, disabled } = this.props; const { intl, active, disabled } = this.props;
if (unavailable) {
return null;
}
return ( return (
<div className='compose-form__poll-button'> <div className='compose-form__poll-button'>
<IconButton <IconButton
icon='tasks' icon='tasks'
iconComponent={InsertChartIcon} iconComponent={BarChart4BarsIcon}
title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)} title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)}
disabled={disabled} disabled={disabled}
onClick={this.handleClick} onClick={this.handleClick}

View file

@ -1,189 +1,160 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent } from 'react'; import { useCallback } from 'react';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes'; import { useDispatch, useSelector } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';
import AddIcon from '@/material-icons/400-24px/add.svg?react'; import {
import CloseIcon from '@/material-icons/400-24px/close.svg?react'; changePollSettings,
changePollOption,
clearComposeSuggestions,
fetchComposeSuggestions,
selectComposeSuggestion,
} from 'mastodon/actions/compose';
import AutosuggestInput from 'mastodon/components/autosuggest_input'; import AutosuggestInput from 'mastodon/components/autosuggest_input';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' }, option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Option {number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' }, duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll length' },
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' }, type: { id: 'compose_form.poll.type', defaultMessage: 'Style' },
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple choices' }, switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple choices' },
switchToSingle: { id: 'compose_form.poll.switch_to_single', defaultMessage: 'Change poll to allow for a single choice' }, switchToSingle: { id: 'compose_form.poll.switch_to_single', defaultMessage: 'Change poll to allow for a single choice' },
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' }, minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' }, hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' }, days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
singleChoice: { id: 'compose_form.poll.single', defaultMessage: 'Pick one' },
multipleChoice: { id: 'compose_form.poll.multiple', defaultMessage: 'Multiple choice' },
}); });
class OptionIntl extends PureComponent { const Select = ({ label, options, value, onChange }) => {
return (
<label className='compose-form__poll__select'>
<span className='compose-form__poll__select__label'>{label}</span>
static propTypes = { <select className='compose-form__poll__select__value' value={value} onChange={onChange}>
title: PropTypes.string.isRequired, {options.map((option, i) => (
lang: PropTypes.string, <option key={i} value={option.value}>{option.label}</option>
index: PropTypes.number.isRequired, ))}
isPollMultiple: PropTypes.bool, </select>
autoFocus: PropTypes.bool, </label>
onChange: PropTypes.func.isRequired, );
onRemove: PropTypes.func.isRequired, };
onToggleMultiple: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleOptionTitleChange = e => { Select.propTypes = {
this.props.onChange(this.props.index, e.target.value); label: PropTypes.node,
}; value: PropTypes.any,
onChange: PropTypes.func,
options: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.node,
value: PropTypes.any,
})),
};
handleOptionRemove = () => { const Option = ({ multipleChoice, index, title, autoFocus }) => {
this.props.onRemove(this.props.index); const intl = useIntl();
}; const dispatch = useDispatch();
const suggestions = useSelector(state => state.getIn(['compose', 'suggestions']));
const lang = useSelector(state => state.getIn(['compose', 'language']));
const handleChange = useCallback(({ target: { value } }) => {
dispatch(changePollOption(index, value));
}, [dispatch, index]);
handleToggleMultiple = e => { const handleSuggestionsFetchRequested = useCallback(token => {
this.props.onToggleMultiple(); dispatch(fetchComposeSuggestions(token));
e.preventDefault(); }, [dispatch]);
e.stopPropagation();
};
handleCheckboxKeypress = e => { const handleSuggestionsClearRequested = useCallback(() => {
if (e.key === 'Enter' || e.key === ' ') { dispatch(clearComposeSuggestions());
this.handleToggleMultiple(e); }, [dispatch]);
}
};
onSuggestionsClearRequested = () => { const handleSuggestionSelected = useCallback((tokenStart, token, value) => {
this.props.onClearSuggestions(); dispatch(selectComposeSuggestion(tokenStart, token, value, ['poll', 'options', index]));
}; }, [dispatch, index]);
onSuggestionsFetchRequested = (token) => { return (
this.props.onFetchSuggestions(token); <label className={classNames('poll__option editable', { empty: index > 1 && title.length === 0 })}>
}; <span className={classNames('poll__input', { checkbox: multipleChoice })} />
onSuggestionSelected = (tokenStart, token, value) => { <AutosuggestInput
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]); placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
}; maxLength={50}
value={title}
lang={lang}
spellCheck
onChange={handleChange}
suggestions={suggestions}
onSuggestionsFetchRequested={handleSuggestionsFetchRequested}
onSuggestionsClearRequested={handleSuggestionsClearRequested}
onSuggestionSelected={handleSuggestionSelected}
searchTokens={[':']}
autoFocus={autoFocus}
/>
</label>
);
};
render () { Option.propTypes = {
const { isPollMultiple, title, lang, index, autoFocus, intl } = this.props; title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
multipleChoice: PropTypes.bool,
autoFocus: PropTypes.bool,
};
return ( export const PollForm = () => {
<li> const intl = useIntl();
<label className='poll__option editable'> const dispatch = useDispatch();
<span const poll = useSelector(state => state.getIn(['compose', 'poll']));
className={classNames('poll__input', { checkbox: isPollMultiple })} const options = poll?.get('options');
onClick={this.handleToggleMultiple} const expiresIn = poll?.get('expires_in');
onKeyPress={this.handleCheckboxKeypress} const isMultiple = poll?.get('multiple');
role='button'
tabIndex={0}
title={intl.formatMessage(isPollMultiple ? messages.switchToSingle : messages.switchToMultiple)}
aria-label={intl.formatMessage(isPollMultiple ? messages.switchToSingle : messages.switchToMultiple)}
/>
<AutosuggestInput const handleDurationChange = useCallback(({ target: { value } }) => {
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })} dispatch(changePollSettings(value, isMultiple));
maxLength={50} }, [dispatch, isMultiple]);
value={title}
lang={lang}
spellCheck
onChange={this.handleOptionTitleChange}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
autoFocus={autoFocus}
/>
</label>
<div className='poll__cancel'> const handleTypeChange = useCallback(({ target: { value } }) => {
<IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' iconComponent={CloseIcon} onClick={this.handleOptionRemove} /> dispatch(changePollSettings(expiresIn, value === 'true'));
</div> }, [dispatch, expiresIn]);
</li>
); if (poll === null) {
return null;
} }
} return (
<div className='compose-form__poll'>
{options.map((title, i) => (
<Option
title={title}
key={i}
index={i}
multipleChoice={isMultiple}
autoFocus={i === 0}
/>
))}
const Option = injectIntl(OptionIntl); <div className='compose-form__poll__footer'>
<Select label={intl.formatMessage(messages.duration)} options={[
{ value: 300, label: intl.formatMessage(messages.minutes, { number: 5 })},
{ value: 1800, label: intl.formatMessage(messages.minutes, { number: 30 })},
{ value: 3600, label: intl.formatMessage(messages.hours, { number: 1 })},
{ value: 21600, label: intl.formatMessage(messages.hours, { number: 6 })},
{ value: 43200, label: intl.formatMessage(messages.hours, { number: 12 })},
{ value: 86400, label: intl.formatMessage(messages.days, { number: 1 })},
{ value: 259200, label: intl.formatMessage(messages.days, { number: 3 })},
{ value: 604800, label: intl.formatMessage(messages.days, { number: 7 })},
]} value={expiresIn} onChange={handleDurationChange} />
class PollForm extends ImmutablePureComponent { <div className='compose-form__poll__footer__sep' />
static propTypes = { <Select label={intl.formatMessage(messages.type)} options={[
options: ImmutablePropTypes.list, { value: false, label: intl.formatMessage(messages.singleChoice) },
lang: PropTypes.string, { value: true, label: intl.formatMessage(messages.multipleChoice) },
expiresIn: PropTypes.number, ]} value={isMultiple} onChange={handleTypeChange} />
isMultiple: PropTypes.bool,
onChangeOption: PropTypes.func.isRequired,
onAddOption: PropTypes.func.isRequired,
onRemoveOption: PropTypes.func.isRequired,
onChangeSettings: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleAddOption = () => {
this.props.onAddOption('');
};
handleSelectDuration = e => {
this.props.onChangeSettings(e.target.value, this.props.isMultiple);
};
handleToggleMultiple = () => {
this.props.onChangeSettings(this.props.expiresIn, !this.props.isMultiple);
};
render () {
const { options, lang, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
if (!options) {
return null;
}
const autoFocusIndex = options.indexOf('');
return (
<div className='compose-form__poll-wrapper'>
<ul>
{options.map((title, i) => <Option title={title} lang={lang} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} autoFocus={i === autoFocusIndex} {...other} />)}
</ul>
<div className='poll__footer'>
<button type='button' disabled={options.size >= 4} className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' icon={AddIcon} /> <FormattedMessage {...messages.add_option} /></button>
{/* eslint-disable-next-line jsx-a11y/no-onchange */}
<select value={expiresIn} onChange={this.handleSelectDuration}>
<option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
<option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
<option value={3600}>{intl.formatMessage(messages.hours, { number: 1 })}</option>
<option value={21600}>{intl.formatMessage(messages.hours, { number: 6 })}</option>
<option value={43200}>{intl.formatMessage(messages.hours, { number: 12 })}</option>
<option value={86400}>{intl.formatMessage(messages.days, { number: 1 })}</option>
<option value={259200}>{intl.formatMessage(messages.days, { number: 3 })}</option>
<option value={604800}>{intl.formatMessage(messages.days, { number: 7 })}</option>
</select>
</div>
</div> </div>
); </div>
} );
};
}
export default injectIntl(PollForm);

View file

@ -5,28 +5,27 @@ import { injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { supportsPassiveEvents } from 'detect-passive-events'; import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay'; import Overlay from 'react-overlays/Overlay';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; 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 LockIcon from '@/material-icons/400-24px/lock.svg?react';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import PublicIcon from '@/material-icons/400-24px/public.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 { Icon } from 'mastodon/components/icon';
import { IconButton } from '../../../components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
public_short: { id: 'privacy.public.short', defaultMessage: 'Public' }, public_short: { id: 'privacy.public.short', defaultMessage: 'Public' },
public_long: { id: 'privacy.public.long', defaultMessage: 'Visible for all' }, public_long: { id: 'privacy.public.long', defaultMessage: 'Anyone on and off Mastodon' },
unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Unlisted' }, unlisted_short: { id: 'privacy.unlisted.short', defaultMessage: 'Quiet public' },
unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Visible for all, but opted-out of discovery features' }, unlisted_long: { id: 'privacy.unlisted.long', defaultMessage: 'Fewer algorithmic fanfares' },
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' }, private_short: { id: 'privacy.private.short', defaultMessage: 'Followers' },
private_long: { id: 'privacy.private.long', defaultMessage: 'Visible for followers only' }, private_long: { id: 'privacy.private.long', defaultMessage: 'Only your followers' },
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' }, direct_short: { id: 'privacy.direct.short', defaultMessage: 'Specific people' },
direct_long: { id: 'privacy.direct.long', defaultMessage: 'Visible for mentioned users only' }, direct_long: { id: 'privacy.direct.long', defaultMessage: 'Everyone mentioned in the post' },
change_privacy: { id: 'privacy.change', defaultMessage: 'Adjust status privacy' }, change_privacy: { id: 'privacy.change', defaultMessage: 'Change post privacy' },
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; const listenerOptions = supportsPassiveEvents ? { passive: true, capture: true } : true;
@ -135,6 +134,12 @@ class PrivacyDropdownMenu extends PureComponent {
<strong>{item.text}</strong> <strong>{item.text}</strong>
{item.meta} {item.meta}
</div> </div>
{item.extra && (
<div className='privacy-dropdown__option__additional' title={item.extra}>
<Icon id='info-circle' icon={InfoIcon} />
</div>
)}
</div> </div>
))} ))}
</div> </div>
@ -163,30 +168,11 @@ class PrivacyDropdown extends PureComponent {
}; };
handleToggle = () => { handleToggle = () => {
if (this.props.isUserTouching && this.props.isUserTouching()) { if (this.state.open && this.activeElement) {
if (this.state.open) { this.activeElement.focus({ preventScroll: true });
this.props.onModalClose();
} else {
this.props.onModalOpen({
actions: this.options.map(option => ({ ...option, active: option.value === this.props.value })),
onClick: this.handleModalActionClick,
});
}
} else {
if (this.state.open && this.activeElement) {
this.activeElement.focus({ preventScroll: true });
}
this.setState({ open: !this.state.open });
} }
};
handleModalActionClick = (e) => { this.setState({ open: !this.state.open });
e.preventDefault();
const { value } = this.options[e.currentTarget.getAttribute('data-index')];
this.props.onModalClose();
this.props.onChange(value);
}; };
handleKeyDown = e => { handleKeyDown = e => {
@ -228,7 +214,7 @@ class PrivacyDropdown extends PureComponent {
this.options = [ this.options = [
{ icon: 'globe', iconComponent: PublicIcon, value: 'public', text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) }, { icon: 'globe', iconComponent: PublicIcon, value: 'public', text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) },
{ icon: 'unlock', iconComponent: LockOpenIcon, value: 'unlisted', text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long) }, { icon: 'unlock', iconComponent: QuietTimeIcon, value: 'unlisted', text: formatMessage(messages.unlisted_short), meta: formatMessage(messages.unlisted_long), extra: formatMessage(messages.unlisted_extra) },
{ icon: 'lock', iconComponent: LockIcon, value: 'private', text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) }, { icon: 'lock', iconComponent: LockIcon, value: 'private', text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) },
]; ];
@ -259,23 +245,21 @@ class PrivacyDropdown extends PureComponent {
return ( return (
<div ref={this.setTargetRef} onKeyDown={this.handleKeyDown}> <div ref={this.setTargetRef} onKeyDown={this.handleKeyDown}>
<IconButton <button
className='privacy-dropdown__value-icon' type='button'
icon={valueOption.icon}
iconComponent={valueOption.iconComponent}
title={intl.formatMessage(messages.change_privacy)} title={intl.formatMessage(messages.change_privacy)}
size={18} aria-expanded={open}
expanded={open}
active={open}
inverted
onClick={this.handleToggle} onClick={this.handleToggle}
onMouseDown={this.handleMouseDown} onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown} onKeyDown={this.handleButtonKeyDown}
style={{ height: null, lineHeight: '27px' }}
disabled={disabled} disabled={disabled}
/> className={classNames('dropdown-button', { active: open })}
>
<Icon id={valueOption.icon} icon={valueOption.iconComponent} />
<span className='dropdown-button__label'>{valueOption.text}</span>
</button>
<Overlay show={open} placement={placement} flip target={this.findTarget} container={container} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}> <Overlay show={open} offset={[5, 5]} placement={placement} flip target={this.findTarget} container={container} popperConfig={{ strategy: 'fixed', onFirstUpdate: this.handleOverlayEnter }}>
{({ props, placement }) => ( {({ props, placement }) => (
<div {...props}> <div {...props}>
<div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}> <div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>

View file

@ -1,74 +1,48 @@
import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl'; import { Link } from 'react-router-dom';
import ImmutablePropTypes from 'react-immutable-proptypes'; import { useSelector } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';
import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import BarChart4BarsIcon from '@/material-icons/400-24px/bar_chart_4_bars.svg?react';
import AttachmentList from 'mastodon/components/attachment_list'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react';
import { WithOptionalRouterPropTypes, withOptionalRouter } from 'mastodon/utils/react_router'; import { Avatar } from 'mastodon/components/avatar';
import { DisplayName } from 'mastodon/components/display_name';
import { Icon } from 'mastodon/components/icon';
import { Avatar } from '../../../components/avatar'; export const ReplyIndicator = () => {
import { DisplayName } from '../../../components/display_name'; const inReplyToId = useSelector(state => state.getIn(['compose', 'in_reply_to']));
import { IconButton } from '../../../components/icon_button'; const status = useSelector(state => state.getIn(['statuses', inReplyToId]));
const account = useSelector(state => state.getIn(['accounts', status?.get('account')]));
const messages = defineMessages({ if (!status) {
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' }, return null;
}); }
class ReplyIndicator extends ImmutablePureComponent { const content = { __html: status.get('contentHtml') };
static propTypes = { return (
status: ImmutablePropTypes.map, <div className='reply-indicator'>
onCancel: PropTypes.func.isRequired, <div className='reply-indicator__line' />
intl: PropTypes.object.isRequired,
...WithOptionalRouterPropTypes,
};
handleClick = () => { <Link to={`/@${account.get('acct')}`} className='detailed-status__display-avatar'>
this.props.onCancel(); <Avatar account={account} size={46} />
}; </Link>
handleAccountClick = (e) => { <div className='reply-indicator__main'>
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { <Link to={`/@${account.get('acct')}`} className='detailed-status__display-name'>
e.preventDefault(); <DisplayName account={account} />
this.props.history?.push(`/@${this.props.status.getIn(['account', 'acct'])}`); </Link>
}
};
render () {
const { status, intl } = this.props;
if (!status) {
return null;
}
const content = { __html: status.get('contentHtml') };
return (
<div className='reply-indicator'>
<div className='reply-indicator__header'>
<div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' iconComponent={CloseIcon} onClick={this.handleClick} inverted /></div>
<a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='reply-indicator__display-name'>
<div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div>
<DisplayName account={status.get('account')} />
</a>
</div>
<div className='reply-indicator__content translate' dangerouslySetInnerHTML={content} /> <div className='reply-indicator__content translate' dangerouslySetInnerHTML={content} />
{status.get('media_attachments').size > 0 && ( {(status.get('poll') || status.get('media_attachments').size > 0) && (
<AttachmentList <div className='reply-indicator__attachments'>
compact {status.get('poll') && <><Icon icon={BarChart4BarsIcon} /><FormattedMessage id='reply_indicator.poll' defaultMessage='Poll' /></>}
media={status.get('media_attachments')} {status.get('media_attachments').size > 0 && <><Icon icon={PhotoLibraryIcon} /><FormattedMessage id='reply_indicator.attachments' defaultMessage='{count, plural, one {# attachment} other {# attachments}}' values={{ count: status.get('media_attachments').size }} /></>}
/> </div>
)} )}
</div> </div>
); </div>
} );
};
}
export default withOptionalRouter(injectIntl(ReplyIndicator));

View file

@ -2,6 +2,8 @@ import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
@ -9,7 +11,8 @@ import spring from 'react-motion/lib/spring';
import CloseIcon from '@/material-icons/400-24px/close.svg?react'; import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import EditIcon from '@/material-icons/400-24px/edit.svg?react'; import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import InfoIcon from '@/material-icons/400-24px/info.svg?react'; import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon'; import { Icon } from 'mastodon/components/icon';
import Motion from '../../ui/util/optional_motion'; import Motion from '../../ui/util/optional_motion';
@ -18,6 +21,7 @@ export default class Upload extends ImmutablePureComponent {
static propTypes = { static propTypes = {
media: ImmutablePropTypes.map.isRequired, media: ImmutablePropTypes.map.isRequired,
sensitive: PropTypes.bool,
onUndo: PropTypes.func.isRequired, onUndo: PropTypes.func.isRequired,
onOpenFocalPoint: PropTypes.func.isRequired, onOpenFocalPoint: PropTypes.func.isRequired,
}; };
@ -33,7 +37,7 @@ export default class Upload extends ImmutablePureComponent {
}; };
render () { render () {
const { media } = this.props; const { media, sensitive } = this.props;
if (!media) { if (!media) {
return null; return null;
@ -43,22 +47,26 @@ export default class Upload extends ImmutablePureComponent {
const focusY = media.getIn(['meta', 'focus', 'y']); const focusY = media.getIn(['meta', 'focus', 'y']);
const x = ((focusX / 2) + .5) * 100; const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100; const y = ((focusY / -2) + .5) * 100;
const missingDescription = (media.get('description') || '').length === 0;
return ( return (
<div className='compose-form__upload'> <div className='compose-form__upload'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}> <Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => ( {({ scale }) => (
<div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}> <div className='compose-form__upload__thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: !sensitive ? `url(${media.get('preview_url')})` : null, backgroundPosition: `${x}% ${y}%` }}>
{sensitive && <Blurhash
hash={media.get('blurhash')}
className='compose-form__upload__preview'
/>}
<div className='compose-form__upload__actions'> <div className='compose-form__upload__actions'>
<button type='button' className='icon-button' onClick={this.handleUndoClick}><Icon id='times' icon={CloseIcon} /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button> <button type='button' className='icon-button compose-form__upload__delete' onClick={this.handleUndoClick}><Icon icon={CloseIcon} /></button>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button> <button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div> </div>
{(media.get('description') || '').length === 0 && ( <div className='compose-form__upload__warning'>
<div className='compose-form__upload__warning'> <button type='button' className={classNames('icon-button', { active: missingDescription })} onClick={this.handleFocalPointClick}>{missingDescription && <Icon icon={WarningIcon} />} ALT</button>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon id='info-circle' icon={InfoIcon} /> <FormattedMessage id='upload_form.description_missing' defaultMessage='No description added' /></button> </div>
</div>
)}
</div> </div>
)} )}
</Motion> </Motion>

View file

@ -6,9 +6,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import AddPhotoAlternateIcon from '@/material-icons/400-24px/add_photo_alternate.svg?react'; import PhotoLibraryIcon from '@/material-icons/400-24px/photo_library.svg?react';
import { IconButton } from 'mastodon/components/icon_button';
import { IconButton } from '../../../components/icon_button';
const messages = defineMessages({ const messages = defineMessages({
upload: { id: 'upload_button.label', defaultMessage: 'Add images, a video or an audio file' }, upload: { id: 'upload_button.label', defaultMessage: 'Add images, a video or an audio file' },
@ -31,7 +30,6 @@ class UploadButton extends ImmutablePureComponent {
static propTypes = { static propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,
unavailable: PropTypes.bool,
onSelectFile: PropTypes.func.isRequired, onSelectFile: PropTypes.func.isRequired,
style: PropTypes.object, style: PropTypes.object,
resetFileKey: PropTypes.number, resetFileKey: PropTypes.number,
@ -54,17 +52,13 @@ class UploadButton extends ImmutablePureComponent {
}; };
render () { render () {
const { intl, resetFileKey, unavailable, disabled, acceptContentTypes } = this.props; const { intl, resetFileKey, disabled, acceptContentTypes } = this.props;
if (unavailable) {
return null;
}
const message = intl.formatMessage(messages.upload); const message = intl.formatMessage(messages.upload);
return ( return (
<div className='compose-form__upload-button'> <div className='compose-form__upload-button'>
<IconButton icon='paperclip' iconComponent={AddPhotoAlternateIcon} title={message} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} /> <IconButton icon='paperclip' iconComponent={PhotoLibraryIcon} title={message} disabled={disabled} onClick={this.handleClick} className='compose-form__upload-button-icon' size={18} inverted style={iconStyle} />
<label> <label>
<span style={{ display: 'none' }}>{message}</span> <span style={{ display: 'none' }}>{message}</span>
<input <input

View file

@ -1,7 +1,6 @@
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import SensitiveButtonContainer from '../containers/sensitive_button_container';
import UploadContainer from '../containers/upload_container'; import UploadContainer from '../containers/upload_container';
import UploadProgressContainer from '../containers/upload_progress_container'; import UploadProgressContainer from '../containers/upload_progress_container';
@ -15,17 +14,17 @@ export default class UploadForm extends ImmutablePureComponent {
const { mediaIds } = this.props; const { mediaIds } = this.props;
return ( return (
<div className='compose-form__upload-wrapper'> <>
<UploadProgressContainer /> <UploadProgressContainer />
<div className='compose-form__uploads-wrapper'> {mediaIds.size > 0 && (
{mediaIds.map(id => ( <div className='compose-form__uploads'>
<UploadContainer id={id} key={id} /> {mediaIds.map(id => (
))} <UploadContainer id={id} key={id} />
</div> ))}
</div>
{!mediaIds.isEmpty() && <SensitiveButtonContainer />} )}
</div> </>
); );
} }

View file

@ -35,9 +35,7 @@ export default class UploadProgress extends PureComponent {
return ( return (
<div className='upload-progress'> <div className='upload-progress'>
<div className='upload-progress__icon'> <Icon id='upload' icon={UploadFileIcon} />
<Icon id='upload' icon={UploadFileIcon} />
</div>
<div className='upload-progress__message'> <div className='upload-progress__message'>
{message} {message}

View file

@ -28,6 +28,7 @@ const mapStateToProps = state => ({
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
isInReply: state.getIn(['compose', 'in_reply_to']) !== null, isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
lang: state.getIn(['compose', 'language']), lang: state.getIn(['compose', 'language']),
maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500),
}); });
const mapDispatchToProps = (dispatch) => ({ const mapDispatchToProps = (dispatch) => ({

View file

@ -1,36 +0,0 @@
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { openModal } from 'mastodon/actions/modal';
import { logOut } from 'mastodon/utils/log_out';
import { me } from '../../../initial_state';
import NavigationBar from '../components/navigation_bar';
const messages = defineMessages({
logoutMessage: { id: 'confirmations.logout.message', defaultMessage: 'Are you sure you want to log out?' },
logoutConfirm: { id: 'confirmations.logout.confirm', defaultMessage: 'Log out' },
});
const mapStateToProps = state => {
return {
account: state.getIn(['accounts', me]),
};
};
const mapDispatchToProps = (dispatch, { intl }) => ({
onLogout () {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: intl.formatMessage(messages.logoutMessage),
confirm: intl.formatMessage(messages.logoutConfirm),
closeWhenConfirm: false,
onConfirm: () => logOut(),
},
}));
},
});
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(NavigationBar));

View file

@ -4,7 +4,7 @@ import { addPoll, removePoll } from '../../../actions/compose';
import PollButton from '../components/poll_button'; import PollButton from '../components/poll_button';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
unavailable: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0), disabled: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0),
active: state.getIn(['compose', 'poll']) !== null, active: state.getIn(['compose', 'poll']) !== null,
}); });

View file

@ -1,53 +0,0 @@
import { connect } from 'react-redux';
import {
addPollOption,
removePollOption,
changePollOption,
changePollSettings,
clearComposeSuggestions,
fetchComposeSuggestions,
selectComposeSuggestion,
} from '../../../actions/compose';
import PollForm from '../components/poll_form';
const mapStateToProps = state => ({
suggestions: state.getIn(['compose', 'suggestions']),
options: state.getIn(['compose', 'poll', 'options']),
lang: state.getIn(['compose', 'language']),
expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
isMultiple: state.getIn(['compose', 'poll', 'multiple']),
});
const mapDispatchToProps = dispatch => ({
onAddOption(title) {
dispatch(addPollOption(title));
},
onRemoveOption(index) {
dispatch(removePollOption(index));
},
onChangeOption(index, title) {
dispatch(changePollOption(index, title));
},
onChangeSettings(expiresIn, isMultiple) {
dispatch(changePollSettings(expiresIn, isMultiple));
},
onClearSuggestions () {
dispatch(clearComposeSuggestions());
},
onFetchSuggestions (token) {
dispatch(fetchComposeSuggestions(token));
},
onSuggestionSelected (position, token, accountId, path) {
dispatch(selectComposeSuggestion(position, token, accountId, path));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(PollForm);

View file

@ -1,36 +0,0 @@
import { connect } from 'react-redux';
import { cancelReplyCompose } from '../../../actions/compose';
import { makeGetStatus } from '../../../selectors';
import ReplyIndicator from '../components/reply_indicator';
const makeMapStateToProps = () => {
const getStatus = makeGetStatus();
const mapStateToProps = state => {
let statusId = state.getIn(['compose', 'id'], null);
let editing = true;
if (statusId === null) {
statusId = state.getIn(['compose', 'in_reply_to']);
editing = false;
}
return {
status: getStatus(state, { id: statusId }),
editing,
};
};
return mapStateToProps;
};
const mapDispatchToProps = dispatch => ({
onCancel () {
dispatch(cancelReplyCompose());
},
});
export default connect(makeMapStateToProps, mapDispatchToProps)(ReplyIndicator);

View file

@ -1,73 +0,0 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { injectIntl, defineMessages, FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { changeComposeSensitivity } from 'mastodon/actions/compose';
const messages = defineMessages({
marked: {
id: 'compose_form.sensitive.marked',
defaultMessage: '{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}',
},
unmarked: {
id: 'compose_form.sensitive.unmarked',
defaultMessage: '{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}',
},
});
const mapStateToProps = state => ({
active: state.getIn(['compose', 'sensitive']),
disabled: state.getIn(['compose', 'spoiler']),
mediaCount: state.getIn(['compose', 'media_attachments']).size,
});
const mapDispatchToProps = dispatch => ({
onClick () {
dispatch(changeComposeSensitivity());
},
});
class SensitiveButton extends PureComponent {
static propTypes = {
active: PropTypes.bool,
disabled: PropTypes.bool,
mediaCount: PropTypes.number,
onClick: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
render () {
const { active, disabled, mediaCount, onClick, intl } = this.props;
return (
<div className='compose-form__sensitive-button'>
<label className={classNames('icon-button', { active })} title={intl.formatMessage(active ? messages.marked : messages.unmarked, { count: mediaCount })}>
<input
name='mark-sensitive'
type='checkbox'
checked={active}
onChange={onClick}
disabled={disabled}
/>
<FormattedMessage
id='compose_form.sensitive.hide'
defaultMessage='{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}'
values={{ count: mediaCount }}
/>
</label>
</div>
);
}
}
export default connect(mapStateToProps, mapDispatchToProps)(injectIntl(SensitiveButton));

View file

@ -2,8 +2,10 @@ import { injectIntl, defineMessages } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import WarningIcon from 'mastodon/../material-icons/400-24px/warning.svg?react';
import { IconButton } from 'mastodon/components/icon_button';
import { changeComposeSpoilerness } from '../../../actions/compose'; import { changeComposeSpoilerness } from '../../../actions/compose';
import TextIconButton from '../components/text_icon_button';
const messages = defineMessages({ const messages = defineMessages({
marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' }, marked: { id: 'compose_form.spoiler.marked', defaultMessage: 'Text is hidden behind warning' },
@ -11,10 +13,12 @@ const messages = defineMessages({
}); });
const mapStateToProps = (state, { intl }) => ({ const mapStateToProps = (state, { intl }) => ({
label: 'CW', iconComponent: WarningIcon,
title: intl.formatMessage(state.getIn(['compose', 'spoiler']) ? messages.marked : messages.unmarked), title: intl.formatMessage(state.getIn(['compose', 'spoiler']) ? messages.marked : messages.unmarked),
active: state.getIn(['compose', 'spoiler']), active: state.getIn(['compose', 'spoiler']),
ariaControls: 'cw-spoiler-input', ariaControls: 'cw-spoiler-input',
size: 18,
inverted: true,
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
@ -25,4 +29,4 @@ const mapDispatchToProps = dispatch => ({
}); });
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(TextIconButton)); export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(IconButton));

View file

@ -4,8 +4,7 @@ import { uploadCompose } from '../../../actions/compose';
import UploadButton from '../components/upload_button'; import UploadButton from '../components/upload_button';
const mapStateToProps = state => ({ const mapStateToProps = state => ({
disabled: 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')))), 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')))),
unavailable: state.getIn(['compose', 'poll']) !== null,
resetFileKey: state.getIn(['compose', 'resetFileKey']), resetFileKey: state.getIn(['compose', 'resetFileKey']),
}); });

View file

@ -5,6 +5,7 @@ import Upload from '../components/upload';
const mapStateToProps = (state, { id }) => ({ const mapStateToProps = (state, { id }) => ({
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
sensitive: state.getIn(['compose', 'spoiler']),
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View file

@ -30,7 +30,6 @@ import { isMobile } from '../../is_mobile';
import Motion from '../ui/util/optional_motion'; import Motion from '../ui/util/optional_motion';
import ComposeFormContainer from './containers/compose_form_container'; import ComposeFormContainer from './containers/compose_form_container';
import NavigationContainer from './containers/navigation_container';
import SearchContainer from './containers/search_container'; import SearchContainer from './containers/search_container';
import SearchResultsContainer from './containers/search_results_container'; import SearchResultsContainer from './containers/search_results_container';
@ -129,8 +128,6 @@ class Compose extends PureComponent {
<div className='drawer__pager'> <div className='drawer__pager'>
<div className='drawer__inner' onFocus={this.onFocus}> <div className='drawer__inner' onFocus={this.onFocus}>
<NavigationContainer onClose={this.onBlur} />
<ComposeFormContainer autoFocus={!isMobile(window.innerWidth)} /> <ComposeFormContainer autoFocus={!isMobile(window.innerWidth)} />
<div className='drawer__inner__mastodon'> <div className='drawer__inner__mastodon'>
@ -152,7 +149,6 @@ class Compose extends PureComponent {
return ( return (
<Column onFocus={this.onFocus}> <Column onFocus={this.onFocus}>
<NavigationContainer onClose={this.onBlur} />
<ComposeFormContainer /> <ComposeFormContainer />
<Helmet> <Helmet>

View file

@ -1,17 +1,24 @@
import PropTypes from 'prop-types'; 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 classNames from 'classnames';
import { Link, withRouter } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import { createSelector } from '@reduxjs/toolkit';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import { useDispatch, useSelector } from 'react-redux';
import { HotKeys } from 'react-hotkeys'; import { HotKeys } from 'react-hotkeys';
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react'; import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react'; import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
import { replyCompose } from 'mastodon/actions/compose';
import { markConversationRead, deleteConversation } from 'mastodon/actions/conversations';
import { openModal } from 'mastodon/actions/modal';
import { muteStatus, unmuteStatus, revealStatus, hideStatus } from 'mastodon/actions/statuses';
import AttachmentList from 'mastodon/components/attachment_list'; import AttachmentList from 'mastodon/components/attachment_list';
import AvatarComposite from 'mastodon/components/avatar_composite'; import AvatarComposite from 'mastodon/components/avatar_composite';
import { IconButton } from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
@ -19,7 +26,7 @@ import { RelativeTimestamp } from 'mastodon/components/relative_timestamp';
import StatusContent from 'mastodon/components/status_content'; import StatusContent from 'mastodon/components/status_content';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import { autoPlayGif } from 'mastodon/initial_state'; import { autoPlayGif } from 'mastodon/initial_state';
import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { makeGetStatus } from 'mastodon/selectors';
const messages = defineMessages({ const messages = defineMessages({
more: { id: 'status.more', defaultMessage: 'More' }, more: { id: 'status.more', defaultMessage: 'More' },
@ -29,25 +36,31 @@ const messages = defineMessages({
delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' }, delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' }, muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' }, unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
}); });
class Conversation extends ImmutablePureComponent { const getAccounts = createSelector(
(state) => state.get('accounts'),
(_, accountIds) => accountIds,
(accounts, accountIds) =>
accountIds.map(id => accounts.get(id))
);
static propTypes = { const getStatus = makeGetStatus();
conversationId: PropTypes.string.isRequired,
accounts: ImmutablePropTypes.list.isRequired,
lastStatus: ImmutablePropTypes.map,
unread:PropTypes.bool.isRequired,
scrollKey: PropTypes.string,
onMoveUp: PropTypes.func,
onMoveDown: PropTypes.func,
markRead: PropTypes.func.isRequired,
delete: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
...WithRouterPropTypes,
};
handleMouseEnter = ({ currentTarget }) => { export const Conversation = ({ conversation, scrollKey, onMoveUp, onMoveDown }) => {
const id = conversation.get('id');
const unread = conversation.get('unread');
const lastStatusId = conversation.get('last_status');
const accountIds = conversation.get('accounts');
const intl = useIntl();
const dispatch = useDispatch();
const history = useHistory();
const lastStatus = useSelector(state => getStatus(state, { id: lastStatusId }));
const accounts = useSelector(state => getAccounts(state, accountIds));
const handleMouseEnter = useCallback(({ currentTarget }) => {
if (autoPlayGif) { if (autoPlayGif) {
return; return;
} }
@ -58,9 +71,9 @@ class Conversation extends ImmutablePureComponent {
let emoji = emojis[i]; let emoji = emojis[i];
emoji.src = emoji.getAttribute('data-original'); emoji.src = emoji.getAttribute('data-original');
} }
}; }, []);
handleMouseLeave = ({ currentTarget }) => { const handleMouseLeave = useCallback(({ currentTarget }) => {
if (autoPlayGif) { if (autoPlayGif) {
return; return;
} }
@ -71,136 +84,161 @@ class Conversation extends ImmutablePureComponent {
let emoji = emojis[i]; let emoji = emojis[i];
emoji.src = emoji.getAttribute('data-static'); emoji.src = emoji.getAttribute('data-static');
} }
}; }, []);
handleClick = () => {
if (!this.props.history) {
return;
}
const { lastStatus, unread, markRead } = this.props;
const handleClick = useCallback(() => {
if (unread) { if (unread) {
markRead(); dispatch(markConversationRead(id));
} }
this.props.history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`); history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`);
}; }, [dispatch, history, unread, id, lastStatus]);
handleMarkAsRead = () => { const handleMarkAsRead = useCallback(() => {
this.props.markRead(); dispatch(markConversationRead(id));
}; }, [dispatch, id]);
handleReply = () => { const handleReply = useCallback(() => {
this.props.reply(this.props.lastStatus, this.props.history); dispatch((_, getState) => {
}; let state = getState();
handleDelete = () => { if (state.getIn(['compose', 'text']).trim().length !== 0) {
this.props.delete(); dispatch(openModal({
}; modalType: 'CONFIRM',
modalProps: {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(lastStatus, history)),
},
}));
} else {
dispatch(replyCompose(lastStatus, history));
}
});
}, [dispatch, lastStatus, history, intl]);
handleHotkeyMoveUp = () => { const handleDelete = useCallback(() => {
this.props.onMoveUp(this.props.conversationId); dispatch(deleteConversation(id));
}; }, [dispatch, id]);
handleHotkeyMoveDown = () => { const handleHotkeyMoveUp = useCallback(() => {
this.props.onMoveDown(this.props.conversationId); onMoveUp(id);
}; }, [id, onMoveUp]);
handleConversationMute = () => { const handleHotkeyMoveDown = useCallback(() => {
this.props.onMute(this.props.lastStatus); onMoveDown(id);
}; }, [id, onMoveDown]);
handleShowMore = () => { const handleConversationMute = useCallback(() => {
this.props.onToggleHidden(this.props.lastStatus); if (lastStatus.get('muted')) {
}; dispatch(unmuteStatus(lastStatus.get('id')));
} else {
render () { dispatch(muteStatus(lastStatus.get('id')));
const { accounts, lastStatus, unread, scrollKey, intl } = this.props;
if (lastStatus === null) {
return null;
} }
}, [dispatch, lastStatus]);
const menu = [ const handleShowMore = useCallback(() => {
{ text: intl.formatMessage(messages.open), action: this.handleClick }, if (lastStatus.get('hidden')) {
null, dispatch(revealStatus(lastStatus.get('id')));
]; } else {
dispatch(hideStatus(lastStatus.get('id')));
menu.push({ text: intl.formatMessage(lastStatus.get('muted') ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMute });
if (unread) {
menu.push({ text: intl.formatMessage(messages.markAsRead), action: this.handleMarkAsRead });
menu.push(null);
} }
}, [dispatch, lastStatus]);
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete }); if (!lastStatus) {
return null;
}
const names = accounts.map(a => <Link to={`/@${a.get('acct')}`} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Link>).reduce((prev, cur) => [prev, ', ', cur]); const menu = [
{ text: intl.formatMessage(messages.open), action: handleClick },
null,
{ text: intl.formatMessage(lastStatus.get('muted') ? messages.unmuteConversation : messages.muteConversation), action: handleConversationMute },
];
const handlers = { if (unread) {
reply: this.handleReply, menu.push({ text: intl.formatMessage(messages.markAsRead), action: handleMarkAsRead });
open: this.handleClick, menu.push(null);
moveUp: this.handleHotkeyMoveUp, }
moveDown: this.handleHotkeyMoveDown,
toggleHidden: this.handleShowMore,
};
return ( menu.push({ text: intl.formatMessage(messages.delete), action: handleDelete });
<HotKeys handlers={handlers}>
<div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex={0}>
<div className='conversation__avatar' onClick={this.handleClick} role='presentation'>
<AvatarComposite accounts={accounts} size={48} />
</div>
<div className='conversation__content'> const names = accounts.map(a => (
<div className='conversation__content__info'> <Link to={`/@${a.get('acct')}`} key={a.get('id')} title={a.get('acct')}>
<div className='conversation__content__relative-time'> <bdi>
{unread && <span className='conversation__unread' />} <RelativeTimestamp timestamp={lastStatus.get('created_at')} /> <strong
</div> className='display-name__html'
dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }}
/>
</bdi>
</Link>
)).reduce((prev, cur) => [prev, ', ', cur]);
<div className='conversation__content__names' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}> const handlers = {
<FormattedMessage id='conversation.with' defaultMessage='With {names}' values={{ names: <span>{names}</span> }} /> reply: handleReply,
</div> open: handleClick,
moveUp: handleHotkeyMoveUp,
moveDown: handleHotkeyMoveDown,
toggleHidden: handleShowMore,
};
return (
<HotKeys handlers={handlers}>
<div className={classNames('conversation focusable muted', { 'conversation--unread': unread })} tabIndex={0}>
<div className='conversation__avatar' onClick={handleClick} role='presentation'>
<AvatarComposite accounts={accounts} size={48} />
</div>
<div className='conversation__content'>
<div className='conversation__content__info'>
<div className='conversation__content__relative-time'>
{unread && <span className='conversation__unread' />} <RelativeTimestamp timestamp={lastStatus.get('created_at')} />
</div> </div>
<StatusContent <div className='conversation__content__names' onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave}>
status={lastStatus} <FormattedMessage id='conversation.with' defaultMessage='With {names}' values={{ names: <span>{names}</span> }} />
onClick={this.handleClick} </div>
expanded={!lastStatus.get('hidden')} </div>
onExpandedToggle={this.handleShowMore}
collapsible <StatusContent
status={lastStatus}
onClick={handleClick}
expanded={!lastStatus.get('hidden')}
onExpandedToggle={handleShowMore}
collapsible
/>
{lastStatus.get('media_attachments').size > 0 && (
<AttachmentList
compact
media={lastStatus.get('media_attachments')}
/> />
)}
{lastStatus.get('media_attachments').size > 0 && ( <div className='status__action-bar'>
<AttachmentList <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.reply)} icon='reply' iconComponent={ReplyIcon} onClick={handleReply} />
compact
media={lastStatus.get('media_attachments')} <div className='status__action-bar-dropdown'>
<DropdownMenuContainer
scrollKey={scrollKey}
status={lastStatus}
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}
size={18}
direction='right'
title={intl.formatMessage(messages.more)}
/> />
)}
<div className='status__action-bar'>
<IconButton className='status__action-bar-button' title={intl.formatMessage(messages.reply)} icon='reply' iconComponent={ReplyIcon} onClick={this.handleReply} />
<div className='status__action-bar-dropdown'>
<DropdownMenuContainer
scrollKey={scrollKey}
status={lastStatus}
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}
size={18}
direction='right'
title={intl.formatMessage(messages.more)}
/>
</div>
</div> </div>
</div> </div>
</div> </div>
</HotKeys> </div>
); </HotKeys>
} );
};
} Conversation.propTypes = {
conversation: ImmutablePropTypes.map.isRequired,
export default withRouter(injectIntl(Conversation)); scrollKey: PropTypes.string,
onMoveUp: PropTypes.func,
onMoveDown: PropTypes.func,
};

View file

@ -1,77 +1,72 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useRef, useMemo, useCallback } from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import { useSelector, useDispatch } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import ScrollableList from '../../../components/scrollable_list'; import { expandConversations } from 'mastodon/actions/conversations';
import ConversationContainer from '../containers/conversation_container'; import ScrollableList from 'mastodon/components/scrollable_list';
export default class ConversationsList extends ImmutablePureComponent { import { Conversation } from './conversation';
static propTypes = { const focusChild = (node, index, alignTop) => {
conversations: ImmutablePropTypes.list.isRequired, const element = node.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
scrollKey: PropTypes.string.isRequired,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
onLoadMore: PropTypes.func,
};
getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id); if (element) {
if (alignTop && node.scrollTop > element.offsetTop) {
handleMoveUp = id => { element.scrollIntoView(true);
const elementIndex = this.getCurrentIndex(id) - 1; } else if (!alignTop && node.scrollTop + node.clientHeight < element.offsetTop + element.offsetHeight) {
this._selectChild(elementIndex, true); element.scrollIntoView(false);
};
handleMoveDown = id => {
const elementIndex = this.getCurrentIndex(id) + 1;
this._selectChild(elementIndex, false);
};
_selectChild (index, align_top) {
const container = this.node.node;
const element = container.querySelector(`article:nth-of-type(${index + 1}) .focusable`);
if (element) {
if (align_top && container.scrollTop > element.offsetTop) {
element.scrollIntoView(true);
} else if (!align_top && container.scrollTop + container.clientHeight < element.offsetTop + element.offsetHeight) {
element.scrollIntoView(false);
}
element.focus();
} }
element.focus();
} }
};
setRef = c => { export const ConversationsList = ({ scrollKey, ...other }) => {
this.node = c; const listRef = useRef();
}; const conversations = useSelector(state => state.getIn(['conversations', 'items']));
const isLoading = useSelector(state => state.getIn(['conversations', 'isLoading'], true));
const hasMore = useSelector(state => state.getIn(['conversations', 'hasMore'], false));
const dispatch = useDispatch();
const lastStatusId = conversations.last()?.get('last_status');
handleLoadOlder = debounce(() => { const handleMoveUp = useCallback(id => {
const last = this.props.conversations.last(); const elementIndex = conversations.findIndex(x => x.get('id') === id) - 1;
focusChild(listRef.current.node, elementIndex, true);
}, [listRef, conversations]);
if (last && last.get('last_status')) { const handleMoveDown = useCallback(id => {
this.props.onLoadMore(last.get('last_status')); const elementIndex = conversations.findIndex(x => x.get('id') === id) + 1;
focusChild(listRef.current.node, elementIndex, false);
}, [listRef, conversations]);
const debouncedLoadMore = useMemo(() => debounce(id => {
dispatch(expandConversations({ maxId: id }));
}, 300, { leading: true }), [dispatch]);
const handleLoadMore = useCallback(() => {
if (lastStatusId) {
debouncedLoadMore(lastStatusId);
} }
}, 300, { leading: true }); }, [debouncedLoadMore, lastStatusId]);
render () { return (
const { conversations, isLoading, onLoadMore, ...other } = this.props; <ScrollableList {...other} scrollKey={scrollKey} isLoading={isLoading} showLoading={isLoading && conversations.isEmpty()} hasMore={hasMore} onLoadMore={handleLoadMore} ref={listRef}>
{conversations.map(item => (
<Conversation
key={item.get('id')}
conversation={item}
onMoveUp={handleMoveUp}
onMoveDown={handleMoveDown}
scrollKey={scrollKey}
/>
))}
</ScrollableList>
);
};
return ( ConversationsList.propTypes = {
<ScrollableList {...other} isLoading={isLoading} showLoading={isLoading && conversations.isEmpty()} onLoadMore={onLoadMore && this.handleLoadOlder} ref={this.setRef}> scrollKey: PropTypes.string.isRequired,
{conversations.map(item => ( };
<ConversationContainer
key={item.get('id')}
conversationId={item.get('id')}
onMoveUp={this.handleMoveUp}
onMoveDown={this.handleMoveDown}
scrollKey={this.props.scrollKey}
/>
))}
</ScrollableList>
);
}
}

View file

@ -1,80 +0,0 @@
import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { replyCompose } from 'mastodon/actions/compose';
import { markConversationRead, deleteConversation } from 'mastodon/actions/conversations';
import { openModal } from 'mastodon/actions/modal';
import { muteStatus, unmuteStatus, hideStatus, revealStatus } from 'mastodon/actions/statuses';
import { makeGetStatus } from 'mastodon/selectors';
import Conversation from '../components/conversation';
const messages = defineMessages({
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
});
const mapStateToProps = () => {
const getStatus = makeGetStatus();
return (state, { conversationId }) => {
const conversation = state.getIn(['conversations', 'items']).find(x => x.get('id') === conversationId);
const lastStatusId = conversation.get('last_status', null);
return {
accounts: conversation.get('accounts').map(accountId => state.getIn(['accounts', accountId], null)),
unread: conversation.get('unread'),
lastStatus: lastStatusId && getStatus(state, { id: lastStatusId }),
};
};
};
const mapDispatchToProps = (dispatch, { intl, conversationId }) => ({
markRead () {
dispatch(markConversationRead(conversationId));
},
reply (status, router) {
dispatch((_, getState) => {
let state = getState();
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: intl.formatMessage(messages.replyMessage),
confirm: intl.formatMessage(messages.replyConfirm),
onConfirm: () => dispatch(replyCompose(status, router)),
},
}));
} else {
dispatch(replyCompose(status, router));
}
});
},
delete () {
dispatch(deleteConversation(conversationId));
},
onMute (status) {
if (status.get('muted')) {
dispatch(unmuteStatus(status.get('id')));
} else {
dispatch(muteStatus(status.get('id')));
}
},
onToggleHidden (status) {
if (status.get('hidden')) {
dispatch(revealStatus(status.get('id')));
} else {
dispatch(hideStatus(status.get('id')));
}
},
});
export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(Conversation));

View file

@ -1,16 +0,0 @@
import { connect } from 'react-redux';
import { expandConversations } from '../../../actions/conversations';
import ConversationsList from '../components/conversations_list';
const mapStateToProps = state => ({
conversations: state.getIn(['conversations', 'items']),
isLoading: state.getIn(['conversations', 'isLoading'], true),
hasMore: state.getIn(['conversations', 'hasMore'], false),
});
const mapDispatchToProps = dispatch => ({
onLoadMore: maxId => dispatch(expandConversations({ maxId })),
});
export default connect(mapStateToProps, mapDispatchToProps)(ConversationsList);

View file

@ -1,11 +1,11 @@
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { PureComponent } from 'react'; import { useRef, useCallback, useEffect } from 'react';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import { connect } from 'react-redux'; import { useDispatch } from 'react-redux';
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react'; import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns'; import { addColumn, removeColumn, moveColumn } from 'mastodon/actions/columns';
@ -14,103 +14,79 @@ import { connectDirectStream } from 'mastodon/actions/streaming';
import Column from 'mastodon/components/column'; import Column from 'mastodon/components/column';
import ColumnHeader from 'mastodon/components/column_header'; import ColumnHeader from 'mastodon/components/column_header';
import ConversationsListContainer from './containers/conversations_list_container'; import { ConversationsList } from './components/conversations_list';
const messages = defineMessages({ const messages = defineMessages({
title: { id: 'column.direct', defaultMessage: 'Private mentions' }, title: { id: 'column.direct', defaultMessage: 'Private mentions' },
}); });
class DirectTimeline extends PureComponent { const DirectTimeline = ({ columnId, multiColumn }) => {
const columnRef = useRef();
static propTypes = { const intl = useIntl();
dispatch: PropTypes.func.isRequired, const dispatch = useDispatch();
columnId: PropTypes.string, const pinned = !!columnId;
intl: PropTypes.object.isRequired,
hasUnread: PropTypes.bool,
multiColumn: PropTypes.bool,
};
handlePin = () => {
const { columnId, dispatch } = this.props;
const handlePin = useCallback(() => {
if (columnId) { if (columnId) {
dispatch(removeColumn(columnId)); dispatch(removeColumn(columnId));
} else { } else {
dispatch(addColumn('DIRECT', {})); dispatch(addColumn('DIRECT', {}));
} }
}; }, [dispatch, columnId]);
handleMove = (dir) => { const handleMove = useCallback((dir) => {
const { columnId, dispatch } = this.props;
dispatch(moveColumn(columnId, dir)); dispatch(moveColumn(columnId, dir));
}; }, [dispatch, columnId]);
handleHeaderClick = () => { const handleHeaderClick = useCallback(() => {
this.column.scrollTop(); columnRef.current.scrollTop();
}; }, [columnRef]);
componentDidMount () {
const { dispatch } = this.props;
useEffect(() => {
dispatch(mountConversations()); dispatch(mountConversations());
dispatch(expandConversations()); dispatch(expandConversations());
this.disconnect = dispatch(connectDirectStream());
}
componentWillUnmount () { const disconnect = dispatch(connectDirectStream());
this.props.dispatch(unmountConversations());
if (this.disconnect) { return () => {
this.disconnect(); dispatch(unmountConversations());
this.disconnect = null; disconnect();
} };
} }, [dispatch]);
setRef = c => { return (
this.column = c; <Column bindToDocument={!multiColumn} ref={columnRef} label={intl.formatMessage(messages.title)}>
}; <ColumnHeader
icon='at'
iconComponent={AlternateEmailIcon}
title={intl.formatMessage(messages.title)}
onPin={handlePin}
onMove={handleMove}
onClick={handleHeaderClick}
pinned={pinned}
multiColumn={multiColumn}
/>
handleLoadMore = maxId => { <ConversationsList
this.props.dispatch(expandConversations({ maxId })); trackScroll={!pinned}
}; scrollKey={`direct_timeline-${columnId}`}
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any private mentions yet. When you send or receive one, it will show up here." />}
bindToDocument={!multiColumn}
prepend={<div className='follow_requests-unlocked_explanation'><span><FormattedMessage id='compose_form.encryption_warning' defaultMessage='Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.' /> <a href='/terms' target='_blank'><FormattedMessage id='compose_form.direct_message_warning_learn_more' defaultMessage='Learn more' /></a></span></div>}
alwaysPrepend
/>
render () { <Helmet>
const { intl, hasUnread, columnId, multiColumn } = this.props; <title>{intl.formatMessage(messages.title)}</title>
const pinned = !!columnId; <meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};
return ( DirectTimeline.propTypes = {
<Column bindToDocument={!multiColumn} ref={this.setRef} label={intl.formatMessage(messages.title)}> columnId: PropTypes.string,
<ColumnHeader multiColumn: PropTypes.bool,
icon='at' };
iconComponent={AlternateEmailIcon}
active={hasUnread}
title={intl.formatMessage(messages.title)}
onPin={this.handlePin}
onMove={this.handleMove}
onClick={this.handleHeaderClick}
pinned={pinned}
multiColumn={multiColumn}
/>
<ConversationsListContainer export default DirectTimeline;
trackScroll={!pinned}
scrollKey={`direct_timeline-${columnId}`}
timelineId='direct'
bindToDocument={!multiColumn}
onLoadMore={this.handleLoadMore}
prepend={<div className='follow_requests-unlocked_explanation'><span><FormattedMessage id='compose_form.encryption_warning' defaultMessage='Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.' /> <a href='/terms' target='_blank'><FormattedMessage id='compose_form.direct_message_warning_learn_more' defaultMessage='Learn more' /></a></span></div>}
alwaysPrepend
emptyMessage={<FormattedMessage id='empty_column.direct' defaultMessage="You don't have any private mentions yet. When you send or receive one, it will show up here." />}
/>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
}
}
export default connect()(injectIntl(DirectTimeline));

View file

@ -26,7 +26,7 @@ import ColumnHeader from 'mastodon/components/column_header';
import LinkFooter from 'mastodon/features/ui/components/link_footer'; import LinkFooter from 'mastodon/features/ui/components/link_footer';
import { me, showTrends } from '../../initial_state'; import { me, showTrends } from '../../initial_state';
import NavigationContainer from '../compose/containers/navigation_container'; import { NavigationBar } from '../compose/components/navigation_bar';
import ColumnLink from '../ui/components/column_link'; import ColumnLink from '../ui/components/column_link';
import ColumnSubheading from '../ui/components/column_subheading'; import ColumnSubheading from '../ui/components/column_subheading';
@ -143,7 +143,7 @@ class GettingStarted extends ImmutablePureComponent {
return ( return (
<Column> <Column>
{(signedIn && !multiColumn) ? <NavigationContainer /> : <ColumnHeader title={intl.formatMessage(messages.menu)} icon='bars' iconComponent={MenuIcon} multiColumn={multiColumn} />} {(signedIn && !multiColumn) ? <NavigationBar /> : <ColumnHeader title={intl.formatMessage(messages.menu)} icon='bars' iconComponent={MenuIcon} multiColumn={multiColumn} />}
<div className='getting-started scrollable scrollable--flex'> <div className='getting-started scrollable scrollable--flex'>
<div className='getting-started__wrapper'> <div className='getting-started__wrapper'>

View file

@ -1,21 +1,15 @@
import { PureComponent } from 'react'; import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container';
import LoadingBarContainer from 'mastodon/features/ui/containers/loading_bar_container';
import ModalContainer from 'mastodon/features/ui/containers/modal_container';
import NotificationsContainer from 'mastodon/features/ui/containers/notifications_container';
import ComposeFormContainer from '../../compose/containers/compose_form_container'; const Compose = () => (
import LoadingBarContainer from '../../ui/containers/loading_bar_container'; <>
import ModalContainer from '../../ui/containers/modal_container'; <ComposeFormContainer autoFocus withoutNavigation />
import NotificationsContainer from '../../ui/containers/notifications_container'; <NotificationsContainer />
<ModalContainer />
<LoadingBarContainer className='loading-bar' />
</>
);
export default class Compose extends PureComponent { export default Compose;
render () {
return (
<div>
<ComposeFormContainer autoFocus />
<NotificationsContainer />
<ModalContainer />
<LoadingBarContainer className='loading-bar' />
</div>
);
}
}

View file

@ -17,8 +17,10 @@ import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react'; import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react';
import StarIcon from '@/material-icons/400-24px/star-fill.svg?react'; import StarIcon from '@/material-icons/400-24px/star-fill.svg?react';
import StarBorderIcon from '@/material-icons/400-24px/star.svg?react'; import StarBorderIcon from '@/material-icons/400-24px/star.svg?react';
import RepeatActiveIcon from '@/svg-icons/repeat_active.svg?react';
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react'; import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react'; import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
import RepeatPrivateActiveIcon from '@/svg-icons/repeat_private_active.svg?react';
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions'; import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
import { WithRouterPropTypes } from 'mastodon/utils/react_router'; import { WithRouterPropTypes } from 'mastodon/utils/react_router';
@ -296,7 +298,7 @@ class ActionBar extends PureComponent {
if (status.get('reblogged')) { if (status.get('reblogged')) {
reblogTitle = intl.formatMessage(messages.cancel_reblog_private); reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon; reblogIconComponent = publicStatus ? RepeatActiveIcon : RepeatPrivateActiveIcon;
} else if (publicStatus) { } else if (publicStatus) {
reblogTitle = intl.formatMessage(messages.reblog); reblogTitle = intl.formatMessage(messages.reblog);
reblogIconComponent = RepeatIcon; reblogIconComponent = RepeatIcon;

View file

@ -6,7 +6,6 @@ import { connect } from 'react-redux';
import { changeComposing, mountCompose, unmountCompose } from 'mastodon/actions/compose'; import { changeComposing, mountCompose, unmountCompose } from 'mastodon/actions/compose';
import ServerBanner from 'mastodon/components/server_banner'; import ServerBanner from 'mastodon/components/server_banner';
import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container'; import ComposeFormContainer from 'mastodon/features/compose/containers/compose_form_container';
import NavigationContainer from 'mastodon/features/compose/containers/navigation_container';
import SearchContainer from 'mastodon/features/compose/containers/search_container'; import SearchContainer from 'mastodon/features/compose/containers/search_container';
import LinkFooter from './link_footer'; import LinkFooter from './link_footer';
@ -56,10 +55,7 @@ class ComposePanel extends PureComponent {
)} )}
{signedIn && ( {signedIn && (
<> <ComposeFormContainer singleColumn />
<NavigationContainer onClose={this.onBlur} />
<ComposeFormContainer singleColumn />
</>
)} )}
<LinkFooter /> <LinkFooter />

View file

@ -21,7 +21,7 @@ import { Button } from 'mastodon/components/button';
import { GIFV } from 'mastodon/components/gifv'; import { GIFV } from 'mastodon/components/gifv';
import { IconButton } from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import Audio from 'mastodon/features/audio'; import Audio from 'mastodon/features/audio';
import CharacterCounter from 'mastodon/features/compose/components/character_counter'; 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 { Tesseract as fetchTesseract } from 'mastodon/features/ui/util/async-components';
import { me } from 'mastodon/initial_state'; import { me } from 'mastodon/initial_state';

View file

@ -108,7 +108,6 @@ class MuteModal extends PureComponent {
<div> <div>
<span><FormattedMessage id='mute_modal.duration' defaultMessage='Duration' />: </span> <span><FormattedMessage id='mute_modal.duration' defaultMessage='Duration' />: </span>
{/* eslint-disable-next-line jsx-a11y/no-onchange */}
<select value={muteDuration} onChange={this.changeMuteDuration}> <select value={muteDuration} onChange={this.changeMuteDuration}>
<option value={0}>{intl.formatMessage(messages.indefinite)}</option> <option value={0}>{intl.formatMessage(messages.indefinite)}</option>
<option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option> <option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>

View file

@ -79,7 +79,6 @@ class NavigationPanel extends Component {
<div className='navigation-panel'> <div className='navigation-panel'>
<div className='navigation-panel__logo'> <div className='navigation-panel__logo'>
<Link to='/' className='column-link column-link--logo'><WordmarkLogo /></Link> <Link to='/' className='column-link column-link--logo'><WordmarkLogo /></Link>
{!banner && <hr />}
</div> </div>
{banner && {banner &&

View file

@ -3,6 +3,7 @@
"about.contact": "Kontak:", "about.contact": "Kontak:",
"about.disclaimer": "Mastodon is gratis oopbronsagteware en n handelsmerk van Mastodon gGmbH.", "about.disclaimer": "Mastodon is gratis oopbronsagteware en n handelsmerk van Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Rede nie beskikbaar nie", "about.domain_blocks.no_reason_available": "Rede nie beskikbaar nie",
"about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.",
"about.domain_blocks.silenced.title": "Beperk", "about.domain_blocks.silenced.title": "Beperk",
"about.domain_blocks.suspended.title": "Opgeskort", "about.domain_blocks.suspended.title": "Opgeskort",
"about.not_available": "Hierdie inligting is nie op hierdie bediener beskikbaar gestel nie.", "about.not_available": "Hierdie inligting is nie op hierdie bediener beskikbaar gestel nie.",
@ -65,7 +66,6 @@
"alert.unexpected.message": "Iets het skeefgeloop.", "alert.unexpected.message": "Iets het skeefgeloop.",
"alert.unexpected.title": "Oeps!", "alert.unexpected.title": "Oeps!",
"announcement.announcement": "Aankondiging", "announcement.announcement": "Aankondiging",
"autosuggest_hashtag.per_week": "{count} per week",
"boost_modal.combo": "Druk {combo} om dit volgende keer oor te slaan", "boost_modal.combo": "Druk {combo} om dit volgende keer oor te slaan",
"bundle_column_error.error.title": "Ag nee!", "bundle_column_error.error.title": "Ag nee!",
"bundle_column_error.network.title": "Netwerkfout", "bundle_column_error.network.title": "Netwerkfout",
@ -110,19 +110,12 @@
"compose_form.lock_disclaimer": "Jou rekening is nie {locked} nie. Enigiemand kan jou volg en sien wat jy vir jou volgers plaas.", "compose_form.lock_disclaimer": "Jou rekening is nie {locked} nie. Enigiemand kan jou volg en sien wat jy vir jou volgers plaas.",
"compose_form.lock_disclaimer.lock": "gesluit", "compose_form.lock_disclaimer.lock": "gesluit",
"compose_form.placeholder": "Wat wil jy deel?", "compose_form.placeholder": "Wat wil jy deel?",
"compose_form.poll.add_option": "Voeg n keuse by",
"compose_form.poll.duration": "Duur van peiling", "compose_form.poll.duration": "Duur van peiling",
"compose_form.poll.option_placeholder": "Keuse {number}",
"compose_form.poll.remove_option": "Verwyder hierdie keuse",
"compose_form.poll.switch_to_multiple": "Verander peiling om meer as een keuse toe te laat", "compose_form.poll.switch_to_multiple": "Verander peiling om meer as een keuse toe te laat",
"compose_form.poll.switch_to_single": "Verander die peiling om slegs een keuse toe te laat", "compose_form.poll.switch_to_single": "Verander die peiling om slegs een keuse toe te laat",
"compose_form.publish": "Publiseer",
"compose_form.publish_form": "Publiseer", "compose_form.publish_form": "Publiseer",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Stoor veranderinge",
"compose_form.spoiler.marked": "Verwyder inhoudswaarskuwing", "compose_form.spoiler.marked": "Verwyder inhoudswaarskuwing",
"compose_form.spoiler.unmarked": "Voeg inhoudswaarskuwing by", "compose_form.spoiler.unmarked": "Voeg inhoudswaarskuwing by",
"compose_form.spoiler_placeholder": "Skryf jou waarskuwing hier",
"confirmation_modal.cancel": "Kanselleer", "confirmation_modal.cancel": "Kanselleer",
"confirmations.block.block_and_report": "Blokkeer en rapporteer", "confirmations.block.block_and_report": "Blokkeer en rapporteer",
"confirmations.block.confirm": "Blokkeer", "confirmations.block.confirm": "Blokkeer",
@ -233,7 +226,6 @@
"navigation_bar.community_timeline": "Plaaslike tydlyn", "navigation_bar.community_timeline": "Plaaslike tydlyn",
"navigation_bar.compose": "Skep nuwe plasing", "navigation_bar.compose": "Skep nuwe plasing",
"navigation_bar.domain_blocks": "Geblokkeerde domeine", "navigation_bar.domain_blocks": "Geblokkeerde domeine",
"navigation_bar.edit_profile": "Redigeer profiel",
"navigation_bar.lists": "Lyste", "navigation_bar.lists": "Lyste",
"navigation_bar.logout": "Teken uit", "navigation_bar.logout": "Teken uit",
"navigation_bar.personal": "Persoonlik", "navigation_bar.personal": "Persoonlik",
@ -266,14 +258,7 @@
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "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": "Share your profile",
"privacy.change": "Verander privaatheid van plasing", "privacy.change": "Verander privaatheid van plasing",
"privacy.direct.long": "Slegs sigbaar vir genoemde gebruikers",
"privacy.direct.short": "Slegs genoemde persone",
"privacy.private.long": "Slegs sigbaar vir volgelinge",
"privacy.private.short": "Slegs volgelinge",
"privacy.public.long": "Sigbaar vir almal",
"privacy.public.short": "Publiek", "privacy.public.short": "Publiek",
"privacy.unlisted.long": "Sigbaar vir almal, maar onttrek uit verkennings-kenmerke",
"privacy.unlisted.short": "Ongelys",
"privacy_policy.last_updated": "Laaste bywerking op {date}", "privacy_policy.last_updated": "Laaste bywerking op {date}",
"privacy_policy.title": "Privaatheidsbeleid", "privacy_policy.title": "Privaatheidsbeleid",
"regeneration_indicator.sublabel": "Jou tuis-voer word voorberei!", "regeneration_indicator.sublabel": "Jou tuis-voer word voorberei!",

View file

@ -75,7 +75,6 @@
"announcement.announcement": "Anuncio", "announcement.announcement": "Anuncio",
"attachments_list.unprocessed": "(sin procesar)", "attachments_list.unprocessed": "(sin procesar)",
"audio.hide": "Amagar audio", "audio.hide": "Amagar audio",
"autosuggest_hashtag.per_week": "{count} per semana",
"boost_modal.combo": "Puetz fer clic en {combo} pa blincar este aviso la proxima vegada", "boost_modal.combo": "Puetz fer clic en {combo} pa blincar este aviso la proxima vegada",
"bundle_column_error.copy_stacktrace": "Copiar informe d'error", "bundle_column_error.copy_stacktrace": "Copiar informe d'error",
"bundle_column_error.error.body": "La pachina solicitada no podió estar renderizada. Podría deber-se a una error en o nuestro codigo u a un problema de compatibilidat con o navegador.", "bundle_column_error.error.body": "La pachina solicitada no podió estar renderizada. Podría deber-se a una error en o nuestro codigo u a un problema de compatibilidat con o navegador.",
@ -126,22 +125,12 @@
"compose_form.lock_disclaimer": "La tuya cuenta no ye {locked}. Totz pueden seguir-te pa veyer las tuyas publicacions nomás pa seguidores.", "compose_form.lock_disclaimer": "La tuya cuenta no ye {locked}. Totz pueden seguir-te pa veyer las tuyas publicacions nomás pa seguidores.",
"compose_form.lock_disclaimer.lock": "blocau", "compose_form.lock_disclaimer.lock": "blocau",
"compose_form.placeholder": "En qué yes pensando?", "compose_form.placeholder": "En qué yes pensando?",
"compose_form.poll.add_option": "Anyadir una opción",
"compose_form.poll.duration": "Duración d'a enqüesta", "compose_form.poll.duration": "Duración d'a enqüesta",
"compose_form.poll.option_placeholder": "Elección {number}",
"compose_form.poll.remove_option": "Eliminar esta opción",
"compose_form.poll.switch_to_multiple": "Modificar enqüesta pa permitir multiples opcions", "compose_form.poll.switch_to_multiple": "Modificar enqüesta pa permitir multiples opcions",
"compose_form.poll.switch_to_single": "Modificar enqüesta pa permitir una sola opción", "compose_form.poll.switch_to_single": "Modificar enqüesta pa permitir una sola opción",
"compose_form.publish": "Publicar",
"compose_form.publish_form": "Publicar", "compose_form.publish_form": "Publicar",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Alzar cambios",
"compose_form.sensitive.hide": "{count, plural, one {Marcar material como sensible} other {Marcar material como sensible}}",
"compose_form.sensitive.marked": "{count, plural, one {Material marcau como sensible} other {Material marcau como sensible}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Material no marcau como sensible} other {Material no marcau como sensible}}",
"compose_form.spoiler.marked": "Texto amagau dimpués de l'alvertencia", "compose_form.spoiler.marked": "Texto amagau dimpués de l'alvertencia",
"compose_form.spoiler.unmarked": "Texto no amagau", "compose_form.spoiler.unmarked": "Texto no amagau",
"compose_form.spoiler_placeholder": "Alvertencia de conteniu",
"confirmation_modal.cancel": "Cancelar", "confirmation_modal.cancel": "Cancelar",
"confirmations.block.block_and_report": "Blocar y Denunciar", "confirmations.block.block_and_report": "Blocar y Denunciar",
"confirmations.block.confirm": "Blocar", "confirmations.block.confirm": "Blocar",
@ -345,7 +334,6 @@
"navigation_bar.compose": "Escribir nueva publicación", "navigation_bar.compose": "Escribir nueva publicación",
"navigation_bar.discover": "Descubrir", "navigation_bar.discover": "Descubrir",
"navigation_bar.domain_blocks": "Dominios amagaus", "navigation_bar.domain_blocks": "Dominios amagaus",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.explore": "Explorar", "navigation_bar.explore": "Explorar",
"navigation_bar.filters": "Parolas silenciadas", "navigation_bar.filters": "Parolas silenciadas",
"navigation_bar.follow_requests": "Solicitutz pa seguir-te", "navigation_bar.follow_requests": "Solicitutz pa seguir-te",
@ -429,14 +417,7 @@
"poll_button.add_poll": "Anyadir una enqüesta", "poll_button.add_poll": "Anyadir una enqüesta",
"poll_button.remove_poll": "Eliminar enqüesta", "poll_button.remove_poll": "Eliminar enqüesta",
"privacy.change": "Achustar privacidat", "privacy.change": "Achustar privacidat",
"privacy.direct.long": "Nomás amostrar a los usuarios mencionaus",
"privacy.direct.short": "Nomás contas mencionadas",
"privacy.private.long": "Nomás amostrar a seguidores",
"privacy.private.short": "Solo seguidores",
"privacy.public.long": "Visible pa totz",
"privacy.public.short": "Publico", "privacy.public.short": "Publico",
"privacy.unlisted.long": "Visible pa totz, pero excluyiu d'as funcions d'escubrimiento",
"privacy.unlisted.short": "No listau",
"privacy_policy.last_updated": "Ultima vegada actualizau {date}", "privacy_policy.last_updated": "Ultima vegada actualizau {date}",
"privacy_policy.title": "Politica de Privacidat", "privacy_policy.title": "Politica de Privacidat",
"refresh": "Actualizar", "refresh": "Actualizar",
@ -590,10 +571,8 @@
"upload_error.poll": "Puyada de fichers no permitida con enqüestas.", "upload_error.poll": "Puyada de fichers no permitida con enqüestas.",
"upload_form.audio_description": "Describir pa personas con problemas auditivos", "upload_form.audio_description": "Describir pa personas con problemas auditivos",
"upload_form.description": "Describir pa los usuarios con dificultat visual", "upload_form.description": "Describir pa los usuarios con dificultat visual",
"upload_form.description_missing": "Garra descripción anyadida",
"upload_form.edit": "Editar", "upload_form.edit": "Editar",
"upload_form.thumbnail": "Cambiar miniatura", "upload_form.thumbnail": "Cambiar miniatura",
"upload_form.undo": "Borrar",
"upload_form.video_description": "Describir pa personas con problemas auditivos u visuals", "upload_form.video_description": "Describir pa personas con problemas auditivos u visuals",
"upload_modal.analyzing_picture": "Analisando imachen…", "upload_modal.analyzing_picture": "Analisando imachen…",
"upload_modal.apply": "Aplicar", "upload_modal.apply": "Aplicar",

View file

@ -86,7 +86,6 @@
"announcement.announcement": "إعلان", "announcement.announcement": "إعلان",
"attachments_list.unprocessed": "(غير معالَج)", "attachments_list.unprocessed": "(غير معالَج)",
"audio.hide": "إخفاء المقطع الصوتي", "audio.hide": "إخفاء المقطع الصوتي",
"autosuggest_hashtag.per_week": "{count} في الأسبوع",
"boost_modal.combo": "يُمكنك الضّغط على {combo} لتخطي هذا في المرة المُقبلة", "boost_modal.combo": "يُمكنك الضّغط على {combo} لتخطي هذا في المرة المُقبلة",
"bundle_column_error.copy_stacktrace": "انسخ تقرير الخطأ", "bundle_column_error.copy_stacktrace": "انسخ تقرير الخطأ",
"bundle_column_error.error.body": "لا يمكن تقديم الصفحة المطلوبة. قد يكون بسبب خطأ في التعليمات البرمجية، أو مشكلة توافق المتصفح.", "bundle_column_error.error.body": "لا يمكن تقديم الصفحة المطلوبة. قد يكون بسبب خطأ في التعليمات البرمجية، أو مشكلة توافق المتصفح.",
@ -143,22 +142,12 @@
"compose_form.lock_disclaimer": "حسابُك غير {locked}. يُمكن لأي شخص مُتابعتك لرؤية (منشورات المتابعين فقط).", "compose_form.lock_disclaimer": "حسابُك غير {locked}. يُمكن لأي شخص مُتابعتك لرؤية (منشورات المتابعين فقط).",
"compose_form.lock_disclaimer.lock": "مُقفَل", "compose_form.lock_disclaimer.lock": "مُقفَل",
"compose_form.placeholder": "فِيمَ تُفكِّر؟", "compose_form.placeholder": "فِيمَ تُفكِّر؟",
"compose_form.poll.add_option": "إضافة خيار",
"compose_form.poll.duration": "مُدَّة اِستطلاع الرأي", "compose_form.poll.duration": "مُدَّة اِستطلاع الرأي",
"compose_form.poll.option_placeholder": "الخيار {number}",
"compose_form.poll.remove_option": "إزالة هذا الخيار",
"compose_form.poll.switch_to_multiple": "تغيِير الاستطلاع للسماح باِخيارات مُتعدِّدة", "compose_form.poll.switch_to_multiple": "تغيِير الاستطلاع للسماح باِخيارات مُتعدِّدة",
"compose_form.poll.switch_to_single": "تغيِير الاستطلاع للسماح باِخيار واحد فقط", "compose_form.poll.switch_to_single": "تغيِير الاستطلاع للسماح باِخيار واحد فقط",
"compose_form.publish": "نشر",
"compose_form.publish_form": "منشور جديد", "compose_form.publish_form": "منشور جديد",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "احفظ التعديلات",
"compose_form.sensitive.hide": "{count, plural, one {الإشارة إلى الوَسط كمُحتوى حسّاس} two{الإشارة إلى الوسطان كمُحتويان حسّاسان} other {الإشارة إلى الوسائط كمُحتويات حسّاسة}}",
"compose_form.sensitive.marked": "{count, plural, one {تمَّ الإشارة إلى الوسط كمُحتوى حسّاس} two{تمَّ الإشارة إلى الوسطان كمُحتويان حسّاسان} other {تمَّ الإشارة إلى الوسائط كمُحتويات حسّاسة}}",
"compose_form.sensitive.unmarked": "{count, plural, one {لم تَتِمّ الإشارة إلى الوسط كمُحتوى حسّاس} two{لم تَتِمّ الإشارة إلى الوسطان كمُحتويان حسّاسان} other {لم تَتِمّ الإشارة إلى الوسائط كمُحتويات حسّاسة}}",
"compose_form.spoiler.marked": "إزالة تحذير المحتوى", "compose_form.spoiler.marked": "إزالة تحذير المحتوى",
"compose_form.spoiler.unmarked": "إضافة تحذير للمحتوى", "compose_form.spoiler.unmarked": "إضافة تحذير للمحتوى",
"compose_form.spoiler_placeholder": "اُكتُب تحذيركَ هُنا",
"confirmation_modal.cancel": "إلغاء", "confirmation_modal.cancel": "إلغاء",
"confirmations.block.block_and_report": "حظره والإبلاغ عنه", "confirmations.block.block_and_report": "حظره والإبلاغ عنه",
"confirmations.block.confirm": "حظر", "confirmations.block.confirm": "حظر",
@ -402,7 +391,6 @@
"navigation_bar.direct": "الإشارات الخاصة", "navigation_bar.direct": "الإشارات الخاصة",
"navigation_bar.discover": "اكتشف", "navigation_bar.discover": "اكتشف",
"navigation_bar.domain_blocks": "النطاقات المحظورة", "navigation_bar.domain_blocks": "النطاقات المحظورة",
"navigation_bar.edit_profile": "عدّل الملف التعريفي",
"navigation_bar.explore": "استكشف", "navigation_bar.explore": "استكشف",
"navigation_bar.favourites": "المفضلة", "navigation_bar.favourites": "المفضلة",
"navigation_bar.filters": "الكلمات المكتومة", "navigation_bar.filters": "الكلمات المكتومة",
@ -509,14 +497,7 @@
"poll_button.add_poll": "إضافة استطلاع للرأي", "poll_button.add_poll": "إضافة استطلاع للرأي",
"poll_button.remove_poll": "إزالة استطلاع الرأي", "poll_button.remove_poll": "إزالة استطلاع الرأي",
"privacy.change": "اضبط خصوصية المنشور", "privacy.change": "اضبط خصوصية المنشور",
"privacy.direct.long": "مرئي للمستخدمين المذكورين فقط",
"privacy.direct.short": "الأشخاص المشار إليهم فقط",
"privacy.private.long": "أنشر لمتابعيك فقط",
"privacy.private.short": "للمتابِعين فقط",
"privacy.public.long": "مرئي للكل",
"privacy.public.short": "للعامة", "privacy.public.short": "للعامة",
"privacy.unlisted.long": "مرئي للجميع، ولكن مِن دون ميزات الاكتشاف",
"privacy.unlisted.short": "غير مدرج",
"privacy_policy.last_updated": "آخر تحديث {date}", "privacy_policy.last_updated": "آخر تحديث {date}",
"privacy_policy.title": "سياسة الخصوصية", "privacy_policy.title": "سياسة الخصوصية",
"refresh": "أنعِش", "refresh": "أنعِش",
@ -696,10 +677,8 @@
"upload_error.poll": "لا يمكن إدراج ملفات في استطلاعات الرأي.", "upload_error.poll": "لا يمكن إدراج ملفات في استطلاعات الرأي.",
"upload_form.audio_description": "وصف للأشخاص ذي قِصر السمع", "upload_form.audio_description": "وصف للأشخاص ذي قِصر السمع",
"upload_form.description": "وصف للمعاقين بصريا", "upload_form.description": "وصف للمعاقين بصريا",
"upload_form.description_missing": "لم يُضف وصف",
"upload_form.edit": "تعديل", "upload_form.edit": "تعديل",
"upload_form.thumbnail": "غيّر الصورة المصغرة", "upload_form.thumbnail": "غيّر الصورة المصغرة",
"upload_form.undo": "حذف",
"upload_form.video_description": "وصف للمعاقين بصريا أو لِذي قِصر السمع", "upload_form.video_description": "وصف للمعاقين بصريا أو لِذي قِصر السمع",
"upload_modal.analyzing_picture": "جارٍ فحص الصورة…", "upload_modal.analyzing_picture": "جارٍ فحص الصورة…",
"upload_modal.apply": "طبّق", "upload_modal.apply": "طبّق",

View file

@ -66,7 +66,6 @@
"alert.unexpected.title": "¡Meca!", "alert.unexpected.title": "¡Meca!",
"announcement.announcement": "Anunciu", "announcement.announcement": "Anunciu",
"attachments_list.unprocessed": "(ensin procesar)", "attachments_list.unprocessed": "(ensin procesar)",
"autosuggest_hashtag.per_week": "{count} per selmana",
"bundle_column_error.error.body": "La páxina solicitada nun se pudo renderizar. Ye posible que seya pola mor d'un fallu nel códigu o por un problema de compatibilidá del restolador.", "bundle_column_error.error.body": "La páxina solicitada nun se pudo renderizar. Ye posible que seya pola mor d'un fallu nel códigu o por un problema de compatibilidá del restolador.",
"bundle_column_error.error.title": "¡Oh, non!", "bundle_column_error.error.title": "¡Oh, non!",
"bundle_column_error.network.body": "Hebo un error al tentar de cargar esta páxina. Esto pudo ser pola mor d'un problema temporal cola conexón a internet o con esti sirvidor.", "bundle_column_error.network.body": "Hebo un error al tentar de cargar esta páxina. Esto pudo ser pola mor d'un problema temporal cola conexón a internet o con esti sirvidor.",
@ -109,13 +108,9 @@
"compose_form.lock_disclaimer": "La to cuenta nun ye {locked}. Cualesquier perfil pue siguite pa ver los artículos que son namás pa siguidores.", "compose_form.lock_disclaimer": "La to cuenta nun ye {locked}. Cualesquier perfil pue siguite pa ver los artículos que son namás pa siguidores.",
"compose_form.lock_disclaimer.lock": "privada", "compose_form.lock_disclaimer.lock": "privada",
"compose_form.placeholder": "¿En qué pienses?", "compose_form.placeholder": "¿En qué pienses?",
"compose_form.poll.add_option": "Amestar una opción",
"compose_form.poll.option_placeholder": "Opción {number}", "compose_form.poll.option_placeholder": "Opción {number}",
"compose_form.poll.remove_option": "Quitar esta opción", "compose_form.poll.type": "Estilu",
"compose_form.publish": "Espublizar",
"compose_form.publish_form": "Artículu nuevu", "compose_form.publish_form": "Artículu nuevu",
"compose_form.publish_loud": "¡{publish}!",
"compose_form.save_changes": "Guardar los cambeos",
"confirmation_modal.cancel": "Encaboxar", "confirmation_modal.cancel": "Encaboxar",
"confirmations.block.block_and_report": "Bloquiar ya informar", "confirmations.block.block_and_report": "Bloquiar ya informar",
"confirmations.block.confirm": "Bloquiar", "confirmations.block.confirm": "Bloquiar",
@ -286,7 +281,6 @@
"navigation_bar.community_timeline": "Llinia de tiempu llocal", "navigation_bar.community_timeline": "Llinia de tiempu llocal",
"navigation_bar.direct": "Menciones privaes", "navigation_bar.direct": "Menciones privaes",
"navigation_bar.domain_blocks": "Dominios bloquiaos", "navigation_bar.domain_blocks": "Dominios bloquiaos",
"navigation_bar.edit_profile": "Editar el perfil",
"navigation_bar.explore": "Esploración", "navigation_bar.explore": "Esploración",
"navigation_bar.filters": "Pallabres desactivaes", "navigation_bar.filters": "Pallabres desactivaes",
"navigation_bar.follow_requests": "Solicitúes de siguimientu", "navigation_bar.follow_requests": "Solicitúes de siguimientu",
@ -346,12 +340,7 @@
"poll_button.add_poll": "Amestar una encuesta", "poll_button.add_poll": "Amestar una encuesta",
"poll_button.remove_poll": "Quitar la encuesta", "poll_button.remove_poll": "Quitar la encuesta",
"privacy.change": "Configurar la privacidá del artículu", "privacy.change": "Configurar la privacidá del artículu",
"privacy.direct.long": "Artículu visible namás pa los perfiles mentaos",
"privacy.private.long": "Artículu visible namás pa los perfiles siguidores",
"privacy.private.short": "Namás pa siguidores",
"privacy.public.long": "Tol mundu pue ver l'artículu",
"privacy.public.short": "Artículu públicu", "privacy.public.short": "Artículu públicu",
"privacy.unlisted.long": "Artículu visible pa tol mundu mas escluyíu de les funciones de descubrimientu",
"privacy_policy.last_updated": "Data del últimu anovamientu: {date}", "privacy_policy.last_updated": "Data del últimu anovamientu: {date}",
"privacy_policy.title": "Política de privacidá", "privacy_policy.title": "Política de privacidá",
"refresh": "Anovar", "refresh": "Anovar",
@ -368,6 +357,7 @@
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "güei", "relative_time.today": "güei",
"reply_indicator.cancel": "Encaboxar", "reply_indicator.cancel": "Encaboxar",
"reply_indicator.poll": "Encuesta",
"report.block": "Bloquiar", "report.block": "Bloquiar",
"report.categories.spam": "Spam", "report.categories.spam": "Spam",
"report.categories.violation": "El conteníu incumple una o más normes del sirvidor", "report.categories.violation": "El conteníu incumple una o más normes del sirvidor",
@ -492,9 +482,7 @@
"upload_button.label": "Amestar ficheros multimedia", "upload_button.label": "Amestar ficheros multimedia",
"upload_error.poll": "La xuba de ficheros nun ta permitida coles encuestes.", "upload_error.poll": "La xuba de ficheros nun ta permitida coles encuestes.",
"upload_form.audio_description": "Describi'l conteníu pa persones sordes ya/o ciegues", "upload_form.audio_description": "Describi'l conteníu pa persones sordes ya/o ciegues",
"upload_form.description_missing": "Nun s'amestó la descripción",
"upload_form.edit": "Editar", "upload_form.edit": "Editar",
"upload_form.undo": "Desaniciar",
"upload_modal.analyzing_picture": "Analizando la semeya…", "upload_modal.analyzing_picture": "Analizando la semeya…",
"upload_modal.apply": "Aplicar", "upload_modal.apply": "Aplicar",
"upload_modal.applying": "Aplicando…", "upload_modal.applying": "Aplicando…",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Аб'ява", "announcement.announcement": "Аб'ява",
"attachments_list.unprocessed": "(неапрацаваны)", "attachments_list.unprocessed": "(неапрацаваны)",
"audio.hide": "Схаваць аўдыя", "audio.hide": "Схаваць аўдыя",
"autosuggest_hashtag.per_week": "{count} за тыдзень",
"boost_modal.combo": "Націсніце {combo}, каб прапусціць наступным разам", "boost_modal.combo": "Націсніце {combo}, каб прапусціць наступным разам",
"bundle_column_error.copy_stacktrace": "Скапіраваць справаздачу пра памылку", "bundle_column_error.copy_stacktrace": "Скапіраваць справаздачу пра памылку",
"bundle_column_error.error.body": "Запытаная старонка не можа быць адлюстраваная. Гэта магло стацца праз хібу ў нашым кодзе, або праз памылку сумяшчальнасці з браўзерам.", "bundle_column_error.error.body": "Запытаная старонка не можа быць адлюстраваная. Гэта магло стацца праз хібу ў нашым кодзе, або праз памылку сумяшчальнасці з браўзерам.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Ваш уліковы запіс не {locked}. Усе могуць падпісацца на вас, каб бачыць допісы толькі для падпісчыкаў.", "compose_form.lock_disclaimer": "Ваш уліковы запіс не {locked}. Усе могуць падпісацца на вас, каб бачыць допісы толькі для падпісчыкаў.",
"compose_form.lock_disclaimer.lock": "закрыты", "compose_form.lock_disclaimer.lock": "закрыты",
"compose_form.placeholder": "Што здарылася?", "compose_form.placeholder": "Што здарылася?",
"compose_form.poll.add_option": "Дадаць варыянт",
"compose_form.poll.duration": "Працягласць апытання", "compose_form.poll.duration": "Працягласць апытання",
"compose_form.poll.option_placeholder": "Варыянт {number}",
"compose_form.poll.remove_option": "Выдаліць гэты варыянт",
"compose_form.poll.switch_to_multiple": "Змяніце апытанне, каб дазволіць некалькі варыянтаў адказу", "compose_form.poll.switch_to_multiple": "Змяніце апытанне, каб дазволіць некалькі варыянтаў адказу",
"compose_form.poll.switch_to_single": "Змяніце апытанне, каб дазволіць адзіны варыянт адказу", "compose_form.poll.switch_to_single": "Змяніце апытанне, каб дазволіць адзіны варыянт адказу",
"compose_form.publish": "Апублікаваць",
"compose_form.publish_form": "Апублікаваць", "compose_form.publish_form": "Апублікаваць",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Захаваць змены",
"compose_form.sensitive.hide": "{count, plural, one {Пазначыць кантэнт як далікатны} other {Пазначыць кантэнт як далікатны}}",
"compose_form.sensitive.marked": "{count, plural, one {Кантэнт пазначаны як далікатны} other {Кантэнт пазначаны як далікатны}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Кантэнт не пазначаны як далікатны} other {Кантэнт не пазначаны як далікатны}}",
"compose_form.spoiler.marked": "Выдаліць папярэджанне аб змесціве", "compose_form.spoiler.marked": "Выдаліць папярэджанне аб змесціве",
"compose_form.spoiler.unmarked": "Дадаць папярэджанне аб змесціве", "compose_form.spoiler.unmarked": "Дадаць папярэджанне аб змесціве",
"compose_form.spoiler_placeholder": "Напішыце сваё папярэджанне тут",
"confirmation_modal.cancel": "Скасаваць", "confirmation_modal.cancel": "Скасаваць",
"confirmations.block.block_and_report": "Заблакіраваць і паскардзіцца", "confirmations.block.block_and_report": "Заблакіраваць і паскардзіцца",
"confirmations.block.confirm": "Заблакіраваць", "confirmations.block.confirm": "Заблакіраваць",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Асабістыя згадванні", "navigation_bar.direct": "Асабістыя згадванні",
"navigation_bar.discover": "Даведайцесь", "navigation_bar.discover": "Даведайцесь",
"navigation_bar.domain_blocks": "Заблакіраваныя дамены", "navigation_bar.domain_blocks": "Заблакіраваныя дамены",
"navigation_bar.edit_profile": "Рэдагаваць профіль",
"navigation_bar.explore": "Агляд", "navigation_bar.explore": "Агляд",
"navigation_bar.favourites": "Упадабанае", "navigation_bar.favourites": "Упадабанае",
"navigation_bar.filters": "Ігнараваныя словы", "navigation_bar.filters": "Ігнараваныя словы",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Дадаць апытанне", "poll_button.add_poll": "Дадаць апытанне",
"poll_button.remove_poll": "Выдаліць апытанне", "poll_button.remove_poll": "Выдаліць апытанне",
"privacy.change": "Змяніць прыватнасць допісу", "privacy.change": "Змяніць прыватнасць допісу",
"privacy.direct.long": "Паказаць толькі згаданым карыстальнікам",
"privacy.direct.short": "Толькі згаданыя людзі",
"privacy.private.long": "Паказаць толькі падпісчыкам",
"privacy.private.short": "Толькі для падпісчыкаў",
"privacy.public.long": "Бачны для ўсіх",
"privacy.public.short": "Публічны", "privacy.public.short": "Публічны",
"privacy.unlisted.long": "Бачна для ўсіх, але не праз магчымасці агляду",
"privacy.unlisted.short": "Не ў стужках",
"privacy_policy.last_updated": "Адноўлена {date}", "privacy_policy.last_updated": "Адноўлена {date}",
"privacy_policy.title": "Палітыка канфідэнцыйнасці", "privacy_policy.title": "Палітыка канфідэнцыйнасці",
"recommended": "Рэкамендуем", "recommended": "Рэкамендуем",
@ -715,10 +696,8 @@
"upload_error.poll": "Немагчыма прымацаваць файл да апытання.", "upload_error.poll": "Немагчыма прымацаваць файл да апытання.",
"upload_form.audio_description": "Апісанне для людзей з парушэннямі слыху", "upload_form.audio_description": "Апісанне для людзей з парушэннямі слыху",
"upload_form.description": "Апісаць для людзей са слабым зрокам", "upload_form.description": "Апісаць для людзей са слабым зрокам",
"upload_form.description_missing": "Апісанне адсутнічае",
"upload_form.edit": "Рэдагаваць", "upload_form.edit": "Рэдагаваць",
"upload_form.thumbnail": "Змяніць мініяцюру", "upload_form.thumbnail": "Змяніць мініяцюру",
"upload_form.undo": "Выдаліць",
"upload_form.video_description": "Апісанне для людзей з парушэннямі зроку і слыху", "upload_form.video_description": "Апісанне для людзей з парушэннямі зроку і слыху",
"upload_modal.analyzing_picture": "Аналіз выявы…", "upload_modal.analyzing_picture": "Аналіз выявы…",
"upload_modal.apply": "Ужыць", "upload_modal.apply": "Ужыць",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Оповестяване", "announcement.announcement": "Оповестяване",
"attachments_list.unprocessed": "(необработено)", "attachments_list.unprocessed": "(необработено)",
"audio.hide": "Скриване на звука", "audio.hide": "Скриване на звука",
"autosuggest_hashtag.per_week": "{count} на седмица",
"boost_modal.combo": "Можете да натиснете {combo}, за да пропуснете това следващия път", "boost_modal.combo": "Можете да натиснете {combo}, за да пропуснете това следващия път",
"bundle_column_error.copy_stacktrace": "Копиране на доклада за грешката", "bundle_column_error.copy_stacktrace": "Копиране на доклада за грешката",
"bundle_column_error.error.body": "Заявената страница не може да се изобрази. Това може да е заради грешка в кода ни или проблем със съвместимостта на браузъра.", "bundle_column_error.error.body": "Заявената страница не може да се изобрази. Това може да е заради грешка в кода ни или проблем със съвместимостта на браузъра.",
@ -148,20 +147,20 @@
"compose_form.placeholder": "Какво мислите?", "compose_form.placeholder": "Какво мислите?",
"compose_form.poll.add_option": "Добавяне на избор", "compose_form.poll.add_option": "Добавяне на избор",
"compose_form.poll.duration": "Времетраене на анкетата", "compose_form.poll.duration": "Времетраене на анкетата",
"compose_form.poll.multiple": "Множествен избор",
"compose_form.poll.option_placeholder": "Избор {number}", "compose_form.poll.option_placeholder": "Избор {number}",
"compose_form.poll.remove_option": "Премахване на този избор", "compose_form.poll.remove_option": "Премахване на тази възможност",
"compose_form.poll.single": "Подберете нещо",
"compose_form.poll.switch_to_multiple": "Промяна на анкетата, за да се позволят множество възможни избора", "compose_form.poll.switch_to_multiple": "Промяна на анкетата, за да се позволят множество възможни избора",
"compose_form.poll.switch_to_single": "Промяна на анкетата, за да се позволи един възможен избор", "compose_form.poll.switch_to_single": "Промяна на анкетата, за да се позволи един възможен избор",
"compose_form.publish": "Публикуване", "compose_form.poll.type": "Стил",
"compose_form.publish": "Публикация",
"compose_form.publish_form": "Публикуване", "compose_form.publish_form": "Публикуване",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Отговор",
"compose_form.save_changes": "Запазване на промените", "compose_form.save_changes": "Обновяване",
"compose_form.sensitive.hide": "{count, plural, one {Маркиране на мултимедията като деликатна} other {Маркиране на мултимедиите като деликатни}}",
"compose_form.sensitive.marked": "{count, plural, one {мултимедия е означена като деликатна} other {мултимедии са означени като деликатни}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Мултимедията не е маркирана като деликатна} other {Мултимедиите не са маркирани като деликатни}}",
"compose_form.spoiler.marked": "Отстраняване на предупреждение за съдържание", "compose_form.spoiler.marked": "Отстраняване на предупреждение за съдържание",
"compose_form.spoiler.unmarked": "Добавяне на предупреждение за съдържание", "compose_form.spoiler.unmarked": "Добавяне на предупреждение за съдържание",
"compose_form.spoiler_placeholder": "Тук напишете предупреждението си", "compose_form.spoiler_placeholder": "Предупреждение за съдържание (по избор)",
"confirmation_modal.cancel": "Отказ", "confirmation_modal.cancel": "Отказ",
"confirmations.block.block_and_report": "Блокиране и докладване", "confirmations.block.block_and_report": "Блокиране и докладване",
"confirmations.block.confirm": "Блокиране", "confirmations.block.confirm": "Блокиране",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Частни споменавания", "navigation_bar.direct": "Частни споменавания",
"navigation_bar.discover": "Откриване", "navigation_bar.discover": "Откриване",
"navigation_bar.domain_blocks": "Блокирани домейни", "navigation_bar.domain_blocks": "Блокирани домейни",
"navigation_bar.edit_profile": "Редактиране на профила",
"navigation_bar.explore": "Изследване", "navigation_bar.explore": "Изследване",
"navigation_bar.favourites": "Любими", "navigation_bar.favourites": "Любими",
"navigation_bar.filters": "Заглушени думи", "navigation_bar.filters": "Заглушени думи",
@ -526,14 +524,14 @@
"poll_button.add_poll": "Анкетиране", "poll_button.add_poll": "Анкетиране",
"poll_button.remove_poll": "Премахване на анкета", "poll_button.remove_poll": "Премахване на анкета",
"privacy.change": "Промяна на поверителността на публикация", "privacy.change": "Промяна на поверителността на публикация",
"privacy.direct.long": "Видимо само за споменатите потребители", "privacy.direct.long": "Всеки споменат в публикацията",
"privacy.direct.short": "Само споменатите хора", "privacy.direct.short": "Определени хора",
"privacy.private.long": "Видимо само за последователите", "privacy.private.long": "Само последователите ви",
"privacy.private.short": "Само последователи", "privacy.private.short": "Последователи",
"privacy.public.long": "Видимо за всички", "privacy.public.long": "Всеки във и извън Mastodon",
"privacy.public.short": "Публично", "privacy.public.short": "Публично",
"privacy.unlisted.long": "Видимо за всички, но не чрез възможността за откриване", "privacy.unlisted.long": "По-малко алгоритмични фанфари",
"privacy.unlisted.short": "Несписъчно", "privacy.unlisted.short": "Тиха публика",
"privacy_policy.last_updated": "Последно осъвременяване на {date}", "privacy_policy.last_updated": "Последно осъвременяване на {date}",
"privacy_policy.title": "Политика за поверителност", "privacy_policy.title": "Политика за поверителност",
"recommended": "Препоръчано", "recommended": "Препоръчано",
@ -551,7 +549,9 @@
"relative_time.minutes": "{number}м.", "relative_time.minutes": "{number}м.",
"relative_time.seconds": "{number}с.", "relative_time.seconds": "{number}с.",
"relative_time.today": "днес", "relative_time.today": "днес",
"reply_indicator.attachments": "{count, plural, one {# прикаване} other {# прикачвания}}",
"reply_indicator.cancel": "Отказ", "reply_indicator.cancel": "Отказ",
"reply_indicator.poll": "Анкета",
"report.block": "Блокиране", "report.block": "Блокиране",
"report.block_explanation": "Няма да им виждате публикациите. Те няма да могат да виждат публикациите ви или да ви последват. Те ще могат да казват, че са били блокирани.", "report.block_explanation": "Няма да им виждате публикациите. Те няма да могат да виждат публикациите ви или да ви последват. Те ще могат да казват, че са били блокирани.",
"report.categories.legal": "Правни въпроси", "report.categories.legal": "Правни въпроси",
@ -715,10 +715,8 @@
"upload_error.poll": "Качването на файлове не е позволено с анкети.", "upload_error.poll": "Качването на файлове не е позволено с анкети.",
"upload_form.audio_description": "Опишете за хора, които са глухи или трудно чуват", "upload_form.audio_description": "Опишете за хора, които са глухи или трудно чуват",
"upload_form.description": "Опишете за хора, които са слепи или имат слабо зрение", "upload_form.description": "Опишете за хора, които са слепи или имат слабо зрение",
"upload_form.description_missing": "Няма добавен опис",
"upload_form.edit": "Редактиране", "upload_form.edit": "Редактиране",
"upload_form.thumbnail": "Промяна на миниобраза", "upload_form.thumbnail": "Промяна на миниобраза",
"upload_form.undo": "Изтриване",
"upload_form.video_description": "Опишете за хора, които са глухи или трудно чуват, слепи или имат слабо зрение", "upload_form.video_description": "Опишете за хора, които са глухи или трудно чуват, слепи или имат слабо зрение",
"upload_modal.analyzing_picture": "Снимков анализ…", "upload_modal.analyzing_picture": "Снимков анализ…",
"upload_modal.apply": "Прилагане", "upload_modal.apply": "Прилагане",

View file

@ -85,7 +85,6 @@
"announcement.announcement": "ঘোষণা", "announcement.announcement": "ঘোষণা",
"attachments_list.unprocessed": "(প্রক্রিয়া করা যায়নি)", "attachments_list.unprocessed": "(প্রক্রিয়া করা যায়নি)",
"audio.hide": "অডিও লুকান", "audio.hide": "অডিও লুকান",
"autosuggest_hashtag.per_week": "প্রতি সপ্তাহে {count}",
"boost_modal.combo": "পরেরবার আপনি {combo} টিপলে এটি আর আসবে না", "boost_modal.combo": "পরেরবার আপনি {combo} টিপলে এটি আর আসবে না",
"bundle_column_error.copy_stacktrace": "এরর রিপোর্ট কপি করুন", "bundle_column_error.copy_stacktrace": "এরর রিপোর্ট কপি করুন",
"bundle_column_error.error.body": "অনুরোধ করা পৃষ্ঠাটি রেন্ডার করা যায়নি। এটি আমাদের কোডে একটি বাগ বা ব্রাউজার সামঞ্জস্যের সমস্যার কারণে হতে পারে।", "bundle_column_error.error.body": "অনুরোধ করা পৃষ্ঠাটি রেন্ডার করা যায়নি। এটি আমাদের কোডে একটি বাগ বা ব্রাউজার সামঞ্জস্যের সমস্যার কারণে হতে পারে।",
@ -142,22 +141,12 @@
"compose_form.lock_disclaimer": "আপনার নিবন্ধনে তালা দেওয়া নেই, যে কেও আপনাকে অনুসরণ করতে পারবে এবং অনুশারকদের জন্য লেখা দেখতে পারবে।", "compose_form.lock_disclaimer": "আপনার নিবন্ধনে তালা দেওয়া নেই, যে কেও আপনাকে অনুসরণ করতে পারবে এবং অনুশারকদের জন্য লেখা দেখতে পারবে।",
"compose_form.lock_disclaimer.lock": "তালা দেওয়া", "compose_form.lock_disclaimer.lock": "তালা দেওয়া",
"compose_form.placeholder": "আপনি কি ভাবছেন ?", "compose_form.placeholder": "আপনি কি ভাবছেন ?",
"compose_form.poll.add_option": "আরেকটি বিকল্প যোগ করুন",
"compose_form.poll.duration": "ভোটগ্রহনের সময়", "compose_form.poll.duration": "ভোটগ্রহনের সময়",
"compose_form.poll.option_placeholder": "বিকল্প {number}",
"compose_form.poll.remove_option": "এই বিকল্পটি মুছে ফেলুন",
"compose_form.poll.switch_to_multiple": "একাধিক পছন্দ অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন", "compose_form.poll.switch_to_multiple": "একাধিক পছন্দ অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন",
"compose_form.poll.switch_to_single": "একটি একক পছন্দের অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন", "compose_form.poll.switch_to_single": "একটি একক পছন্দের অনুমতি দেওয়ার জন্য পোল পরিবর্তন করুন",
"compose_form.publish": "প্রকাশ করুন",
"compose_form.publish_form": "প্রকাশ করুন", "compose_form.publish_form": "প্রকাশ করুন",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "পরিবর্তনগুলো প্রকাশ করুন",
"compose_form.sensitive.hide": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করতে",
"compose_form.sensitive.marked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়েছে",
"compose_form.sensitive.unmarked": "এই ছবি বা ভিডিওটি সংবেদনশীল হিসেবে চিহ্নিত করা হয়নি",
"compose_form.spoiler.marked": "সতর্কতার পিছনে লেখানটি লুকানো আছে", "compose_form.spoiler.marked": "সতর্কতার পিছনে লেখানটি লুকানো আছে",
"compose_form.spoiler.unmarked": "লেখাটি লুকানো নেই", "compose_form.spoiler.unmarked": "লেখাটি লুকানো নেই",
"compose_form.spoiler_placeholder": "আপনার লেখা দেখার সাবধানবাণী লিখুন",
"confirmation_modal.cancel": "বাতিল করুন", "confirmation_modal.cancel": "বাতিল করুন",
"confirmations.block.block_and_report": "ব্লক করুন এবং রিপোর্ট করুন", "confirmations.block.block_and_report": "ব্লক করুন এবং রিপোর্ট করুন",
"confirmations.block.confirm": "ব্লক করুন", "confirmations.block.confirm": "ব্লক করুন",
@ -324,7 +313,6 @@
"navigation_bar.compose": "নতুন টুট লিখুন", "navigation_bar.compose": "নতুন টুট লিখুন",
"navigation_bar.discover": "ঘুরে দেখুন", "navigation_bar.discover": "ঘুরে দেখুন",
"navigation_bar.domain_blocks": "লুকানো ডোমেনগুলি", "navigation_bar.domain_blocks": "লুকানো ডোমেনগুলি",
"navigation_bar.edit_profile": "নিজের পাতা সম্পাদনা করতে",
"navigation_bar.explore": "পরিব্রাজন", "navigation_bar.explore": "পরিব্রাজন",
"navigation_bar.favourites": "পছন্দসমূহ", "navigation_bar.favourites": "পছন্দসমূহ",
"navigation_bar.filters": "বন্ধ করা শব্দ", "navigation_bar.filters": "বন্ধ করা শব্দ",
@ -395,12 +383,7 @@
"poll_button.add_poll": "একটা নির্বাচন যোগ করতে", "poll_button.add_poll": "একটা নির্বাচন যোগ করতে",
"poll_button.remove_poll": "নির্বাচন বাদ দিতে", "poll_button.remove_poll": "নির্বাচন বাদ দিতে",
"privacy.change": "লেখার গোপনীয়তা অবস্থা ঠিক করতে", "privacy.change": "লেখার গোপনীয়তা অবস্থা ঠিক করতে",
"privacy.direct.long": "শুধুমাত্র উল্লেখিত ব্যবহারকারীদের কাছে লিখতে",
"privacy.direct.short": "Direct",
"privacy.private.long": "শুধুমাত্র আপনার অনুসরণকারীদের লিখতে",
"privacy.private.short": "Followers-only",
"privacy.public.short": "সর্বজনীন প্রকাশ্য", "privacy.public.short": "সর্বজনীন প্রকাশ্য",
"privacy.unlisted.short": "প্রকাশ্য নয়",
"refresh": "সতেজ করা", "refresh": "সতেজ করা",
"regeneration_indicator.label": "আসছে…", "regeneration_indicator.label": "আসছে…",
"regeneration_indicator.sublabel": "আপনার বাড়ির-সময়রেখা প্রস্তূত করা হচ্ছে!", "regeneration_indicator.sublabel": "আপনার বাড়ির-সময়রেখা প্রস্তূত করা হচ্ছে!",
@ -506,7 +489,6 @@
"upload_form.description": "যারা দেখতে পায়না তাদের জন্য এটা বর্ণনা করতে", "upload_form.description": "যারা দেখতে পায়না তাদের জন্য এটা বর্ণনা করতে",
"upload_form.edit": "সম্পাদন", "upload_form.edit": "সম্পাদন",
"upload_form.thumbnail": "থাম্বনেল পরিবর্তন করুন", "upload_form.thumbnail": "থাম্বনেল পরিবর্তন করুন",
"upload_form.undo": "মুছে ফেলতে",
"upload_form.video_description": "শ্রবণশক্তি হ্রাস বা চাক্ষুষ প্রতিবন্ধী ব্যক্তিদের জন্য বর্ণনা করুন", "upload_form.video_description": "শ্রবণশক্তি হ্রাস বা চাক্ষুষ প্রতিবন্ধী ব্যক্তিদের জন্য বর্ণনা করুন",
"upload_modal.analyzing_picture": "চিত্র বিশ্লেষণ করা হচ্ছে…", "upload_modal.analyzing_picture": "চিত্র বিশ্লেষণ করা হচ্ছে…",
"upload_modal.apply": "প্রয়োগ করুন", "upload_modal.apply": "প্রয়োগ করুন",

View file

@ -87,7 +87,6 @@
"announcement.announcement": "Kemennad", "announcement.announcement": "Kemennad",
"attachments_list.unprocessed": "(ket meret)", "attachments_list.unprocessed": "(ket meret)",
"audio.hide": "Kuzhat ar c'hleved", "audio.hide": "Kuzhat ar c'hleved",
"autosuggest_hashtag.per_week": "{count} bep sizhun",
"boost_modal.combo": "Ar wezh kentañ e c'halliot gwaskañ war {combo} evit tremen hebiou", "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.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.", "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.",
@ -143,22 +142,12 @@
"compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.", "compose_form.lock_disclaimer": "N'eo ket {locked} ho kont. An holl a c'hal ho heuliañ evit gwelet ho toudoù prevez.",
"compose_form.lock_disclaimer.lock": "prennet", "compose_form.lock_disclaimer.lock": "prennet",
"compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?", "compose_form.placeholder": "Petra emaoc'h o soñjal e-barzh ?",
"compose_form.poll.add_option": "Ouzhpenniñ un dibab",
"compose_form.poll.duration": "Pad ar sontadeg", "compose_form.poll.duration": "Pad ar sontadeg",
"compose_form.poll.option_placeholder": "Dibab {number}",
"compose_form.poll.remove_option": "Lemel an dibab-mañ",
"compose_form.poll.switch_to_multiple": "Kemmañ ar sontadeg evit aotren meur a zibab", "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", "compose_form.poll.switch_to_single": "Kemmañ ar sontadeg evit aotren un dibab hepken",
"compose_form.publish": "Embann",
"compose_form.publish_form": "Embann", "compose_form.publish_form": "Embann",
"compose_form.publish_loud": "{publish} !",
"compose_form.save_changes": "Enrollañ ar cheñchamantoù",
"compose_form.sensitive.hide": "Merkañ ar media evel kizidik",
"compose_form.sensitive.marked": "Merket eo ar media evel kizidik",
"compose_form.sensitive.unmarked": "N'eo ket merket ar media evel kizidik",
"compose_form.spoiler.marked": "Kuzhet eo an destenn a-dreñv ur c'hemenn", "compose_form.spoiler.marked": "Kuzhet eo an destenn a-dreñv ur c'hemenn",
"compose_form.spoiler.unmarked": "N'eo ket kuzhet an destenn", "compose_form.spoiler.unmarked": "N'eo ket kuzhet an destenn",
"compose_form.spoiler_placeholder": "Skrivit ho kemenn diwall amañ",
"confirmation_modal.cancel": "Nullañ", "confirmation_modal.cancel": "Nullañ",
"confirmations.block.block_and_report": "Berzañ ha Disklêriañ", "confirmations.block.block_and_report": "Berzañ ha Disklêriañ",
"confirmations.block.confirm": "Stankañ", "confirmations.block.confirm": "Stankañ",
@ -383,7 +372,6 @@
"navigation_bar.direct": "Menegoù prevez", "navigation_bar.direct": "Menegoù prevez",
"navigation_bar.discover": "Dizoleiñ", "navigation_bar.discover": "Dizoleiñ",
"navigation_bar.domain_blocks": "Domanioù kuzhet", "navigation_bar.domain_blocks": "Domanioù kuzhet",
"navigation_bar.edit_profile": "Kemmañ ar profil",
"navigation_bar.explore": "Furchal", "navigation_bar.explore": "Furchal",
"navigation_bar.favourites": "Muiañ-karet", "navigation_bar.favourites": "Muiañ-karet",
"navigation_bar.filters": "Gerioù kuzhet", "navigation_bar.filters": "Gerioù kuzhet",
@ -487,14 +475,7 @@
"poll_button.add_poll": "Ouzhpennañ ur sontadeg", "poll_button.add_poll": "Ouzhpennañ ur sontadeg",
"poll_button.remove_poll": "Dilemel ar sontadeg", "poll_button.remove_poll": "Dilemel ar sontadeg",
"privacy.change": "Cheñch prevezded an toud", "privacy.change": "Cheñch prevezded an toud",
"privacy.direct.long": "Embann evit an implijer·ezed·ien meneget hepken",
"privacy.direct.short": "Tud meneget hepken",
"privacy.private.long": "Embann evit ar re a heuilh ac'hanon hepken",
"privacy.private.short": "Tud koumanantet hepken",
"privacy.public.long": "Gwelus d'an holl",
"privacy.public.short": "Publik", "privacy.public.short": "Publik",
"privacy.unlisted.long": "Gwelus gant an holl, met hep arc'hweladur dizoleiñ",
"privacy.unlisted.short": "Anlistennet",
"privacy_policy.last_updated": "Hizivadenn ziwezhañ {date}", "privacy_policy.last_updated": "Hizivadenn ziwezhañ {date}",
"privacy_policy.title": "Reolennoù Prevezded", "privacy_policy.title": "Reolennoù Prevezded",
"recommended": "Erbedet", "recommended": "Erbedet",
@ -667,10 +648,8 @@
"upload_error.poll": "Pellgargañ restroù n'eo ket aotreet gant sontadegoù.", "upload_error.poll": "Pellgargañ restroù n'eo ket aotreet gant sontadegoù.",
"upload_form.audio_description": "Diskrivañ evit tud a zo kollet o c'hlev", "upload_form.audio_description": "Diskrivañ evit tud a zo kollet o c'hlev",
"upload_form.description": "Diskrivañ evit tud a zo kollet o gweled", "upload_form.description": "Diskrivañ evit tud a zo kollet o gweled",
"upload_form.description_missing": "Deskrivadur diank",
"upload_form.edit": "Kemmañ", "upload_form.edit": "Kemmañ",
"upload_form.thumbnail": "Kemmañ ar velvenn", "upload_form.thumbnail": "Kemmañ ar velvenn",
"upload_form.undo": "Dilemel",
"upload_form.video_description": "Diskrivañ evit tud a zo kollet o gweled pe o c'hlev", "upload_form.video_description": "Diskrivañ evit tud a zo kollet o gweled pe o c'hlev",
"upload_modal.analyzing_picture": "O tielfennañ ar skeudenn…", "upload_modal.analyzing_picture": "O tielfennañ ar skeudenn…",
"upload_modal.apply": "Arloañ", "upload_modal.apply": "Arloañ",

View file

@ -66,8 +66,6 @@
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "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": "Share your profile",
"privacy.change": "Adjust status privacy", "privacy.change": "Adjust status privacy",
"privacy.direct.short": "Direct",
"privacy.private.short": "Followers-only",
"report.placeholder": "Type or paste additional comments", "report.placeholder": "Type or paste additional comments",
"report.submit": "Submit report", "report.submit": "Submit report",
"report.target": "Report {target}", "report.target": "Report {target}",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Anunci", "announcement.announcement": "Anunci",
"attachments_list.unprocessed": "(sense processar)", "attachments_list.unprocessed": "(sense processar)",
"audio.hide": "Amaga l'àudio", "audio.hide": "Amaga l'àudio",
"autosuggest_hashtag.per_week": "{count} per setmana",
"boost_modal.combo": "Pots prémer {combo} per a evitar-ho el pròxim cop", "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.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.", "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.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure els tuts de només per a seguidors.", "compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure els tuts de només per a seguidors.",
"compose_form.lock_disclaimer.lock": "blocat", "compose_form.lock_disclaimer.lock": "blocat",
"compose_form.placeholder": "Què tens al cap?", "compose_form.placeholder": "Què tens al cap?",
"compose_form.poll.add_option": "Afegeix una opció", "compose_form.poll.add_option": "Afegiu una opció",
"compose_form.poll.duration": "Durada de l'enquesta", "compose_form.poll.duration": "Durada de l'enquesta",
"compose_form.poll.multiple": "Opcions múltiples",
"compose_form.poll.option_placeholder": "Opció {number}", "compose_form.poll.option_placeholder": "Opció {number}",
"compose_form.poll.remove_option": "Elimina aquesta opció", "compose_form.poll.remove_option": "Treu aquesta opció",
"compose_form.poll.single": "Trieu-ne una",
"compose_form.poll.switch_to_multiple": "Canvia lenquesta per a permetre múltiples opcions", "compose_form.poll.switch_to_multiple": "Canvia lenquesta per a permetre múltiples opcions",
"compose_form.poll.switch_to_single": "Canvia lenquesta per a permetre una única opció", "compose_form.poll.switch_to_single": "Canvia lenquesta per a permetre una única opció",
"compose_form.publish": "Tut", "compose_form.poll.type": "Estil",
"compose_form.publish": "Publica",
"compose_form.publish_form": "Nou tut", "compose_form.publish_form": "Nou tut",
"compose_form.publish_loud": "Tut!", "compose_form.reply": "Responeu",
"compose_form.save_changes": "Desa els canvis", "compose_form.save_changes": "Actualitza",
"compose_form.sensitive.hide": "{count, plural, one {Marca mèdia com a sensible} other {Marca mèdia com a sensible}}",
"compose_form.sensitive.marked": "{count, plural, one {Contingut marcat com a sensible} other {Contingut marcat com a sensible}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Contingut no marcat com a sensible} other {Contingut no marcat com a sensible}}",
"compose_form.spoiler.marked": "Elimina l'avís de contingut", "compose_form.spoiler.marked": "Elimina l'avís de contingut",
"compose_form.spoiler.unmarked": "Afegeix avís de contingut", "compose_form.spoiler.unmarked": "Afegeix avís de contingut",
"compose_form.spoiler_placeholder": "Escriu l'avís aquí", "compose_form.spoiler_placeholder": "Avís de contingut (opcional)",
"confirmation_modal.cancel": "Cancel·la", "confirmation_modal.cancel": "Cancel·la",
"confirmations.block.block_and_report": "Bloca i denuncia", "confirmations.block.block_and_report": "Bloca i denuncia",
"confirmations.block.confirm": "Bloca", "confirmations.block.confirm": "Bloca",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Mencions privades", "navigation_bar.direct": "Mencions privades",
"navigation_bar.discover": "Descobreix", "navigation_bar.discover": "Descobreix",
"navigation_bar.domain_blocks": "Dominis blocats", "navigation_bar.domain_blocks": "Dominis blocats",
"navigation_bar.edit_profile": "Edita el perfil",
"navigation_bar.explore": "Explora", "navigation_bar.explore": "Explora",
"navigation_bar.favourites": "Favorits", "navigation_bar.favourites": "Favorits",
"navigation_bar.filters": "Paraules silenciades", "navigation_bar.filters": "Paraules silenciades",
@ -521,19 +519,17 @@
"poll.total_people": "{count, plural, one {# persona} other {# persones}}", "poll.total_people": "{count, plural, one {# persona} other {# persones}}",
"poll.total_votes": "{count, plural, one {# vot} other {# vots}}", "poll.total_votes": "{count, plural, one {# vot} other {# vots}}",
"poll.vote": "Vota", "poll.vote": "Vota",
"poll.voted": "Vas votar per aquesta resposta", "poll.voted": "Vau votar aquesta resposta",
"poll.votes": "{votes, plural, one {# vot} other {# vots}}", "poll.votes": "{votes, plural, one {# vot} other {# vots}}",
"poll_button.add_poll": "Afegeix una enquesta", "poll_button.add_poll": "Afegeix una enquesta",
"poll_button.remove_poll": "Elimina l'enquesta", "poll_button.remove_poll": "Elimina l'enquesta",
"privacy.change": "Canvia la privacitat del tut", "privacy.change": "Canvia la privacitat del tut",
"privacy.direct.long": "Visible només per als usuaris esmentats", "privacy.direct.long": "Tothom mencionat en aquesta publicació",
"privacy.direct.short": "Només gent mencionada", "privacy.direct.short": "Persones concretes",
"privacy.private.long": "Visible només per als seguidors", "privacy.private.long": "Només els vostres seguidors",
"privacy.private.short": "Només seguidors", "privacy.private.short": "Seguidors",
"privacy.public.long": "Visible per a tothom", "privacy.public.long": "Tothom dins o fora Mastodon",
"privacy.public.short": "Públic", "privacy.public.short": "Públic",
"privacy.unlisted.long": "Visible per a tothom però exclosa de les funcions de descobriment",
"privacy.unlisted.short": "No llistada",
"privacy_policy.last_updated": "Darrera actualització {date}", "privacy_policy.last_updated": "Darrera actualització {date}",
"privacy_policy.title": "Política de Privacitat", "privacy_policy.title": "Política de Privacitat",
"recommended": "Recomanat", "recommended": "Recomanat",
@ -715,10 +711,8 @@
"upload_error.poll": "No es permet carregar fitxers a les enquestes.", "upload_error.poll": "No es permet carregar fitxers a les enquestes.",
"upload_form.audio_description": "Descriu-ho per a persones amb problemes d'audició", "upload_form.audio_description": "Descriu-ho per a persones amb problemes d'audició",
"upload_form.description": "Descriu-ho per a persones amb problemes de visió", "upload_form.description": "Descriu-ho per a persones amb problemes de visió",
"upload_form.description_missing": "No s'hi ha afegit cap descripció",
"upload_form.edit": "Edita", "upload_form.edit": "Edita",
"upload_form.thumbnail": "Canvia la miniatura", "upload_form.thumbnail": "Canvia la miniatura",
"upload_form.undo": "Elimina",
"upload_form.video_description": "Descriu-ho per a persones amb problemes de visió o audició", "upload_form.video_description": "Descriu-ho per a persones amb problemes de visió o audició",
"upload_modal.analyzing_picture": "S'analitza la imatge…", "upload_modal.analyzing_picture": "S'analitza la imatge…",
"upload_modal.apply": "Aplica", "upload_modal.apply": "Aplica",

View file

@ -76,7 +76,6 @@
"announcement.announcement": "بانگەواز", "announcement.announcement": "بانگەواز",
"attachments_list.unprocessed": "(unprocessed)", "attachments_list.unprocessed": "(unprocessed)",
"audio.hide": "شاردنەوەی دەنگ", "audio.hide": "شاردنەوەی دەنگ",
"autosuggest_hashtag.per_week": "{count} هەرهەفتە",
"boost_modal.combo": "دەتوانیت دەست بنێی بە سەر {combo} بۆ بازدان لە جاری داهاتوو", "boost_modal.combo": "دەتوانیت دەست بنێی بە سەر {combo} بۆ بازدان لە جاری داهاتوو",
"bundle_column_error.copy_stacktrace": "ڕاپۆرتی هەڵەی کۆپی بکە", "bundle_column_error.copy_stacktrace": "ڕاپۆرتی هەڵەی کۆپی بکە",
"bundle_column_error.error.body": "لاپەڕەی داواکراو نەتوانرا ڕەندەر بکرێت. دەکرێت بەهۆی هەڵەیەکی کۆدەکەمانەوە بێت، یان کێشەی گونجانی وێبگەڕ.", "bundle_column_error.error.body": "لاپەڕەی داواکراو نەتوانرا ڕەندەر بکرێت. دەکرێت بەهۆی هەڵەیەکی کۆدەکەمانەوە بێت، یان کێشەی گونجانی وێبگەڕ.",
@ -128,22 +127,12 @@
"compose_form.lock_disclaimer": "هەژمێرەکەی لە حاڵەتی {locked}. هەر کەسێک دەتوانێت شوێنت بکەوێت بۆ پیشاندانی بابەتەکانی تەنها دوایخۆی.", "compose_form.lock_disclaimer": "هەژمێرەکەی لە حاڵەتی {locked}. هەر کەسێک دەتوانێت شوێنت بکەوێت بۆ پیشاندانی بابەتەکانی تەنها دوایخۆی.",
"compose_form.lock_disclaimer.lock": "قفڵ دراوە", "compose_form.lock_disclaimer.lock": "قفڵ دراوە",
"compose_form.placeholder": "چی لە مێشکتدایە?", "compose_form.placeholder": "چی لە مێشکتدایە?",
"compose_form.poll.add_option": "زیادکردنی هەڵبژاردەیەک",
"compose_form.poll.duration": "ماوەی ڕاپرسی", "compose_form.poll.duration": "ماوەی ڕاپرسی",
"compose_form.poll.option_placeholder": "هەڵبژاردن {number}",
"compose_form.poll.remove_option": "لابردنی ئەم هەڵبژاردەیە",
"compose_form.poll.switch_to_multiple": "ڕاپرسی بگۆڕە بۆ ڕێگەدان بە چەند هەڵبژاردنێک", "compose_form.poll.switch_to_multiple": "ڕاپرسی بگۆڕە بۆ ڕێگەدان بە چەند هەڵبژاردنێک",
"compose_form.poll.switch_to_single": "گۆڕینی ڕاپرسی بۆ ڕێگەدان بە تاکە هەڵبژاردنێک", "compose_form.poll.switch_to_single": "گۆڕینی ڕاپرسی بۆ ڕێگەدان بە تاکە هەڵبژاردنێک",
"compose_form.publish": "بڵاوی بکەوە",
"compose_form.publish_form": "بڵاوی بکەوە", "compose_form.publish_form": "بڵاوی بکەوە",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "پاشکەوتی گۆڕانکاریەکان",
"compose_form.sensitive.hide": "نیشانکردنی میدیا وەک هەستیار",
"compose_form.sensitive.marked": "وادەی کۆتایی",
"compose_form.sensitive.unmarked": "میدیا وەک هەستیار نیشان نەکراوە",
"compose_form.spoiler.marked": "دەق لە پشت ئاگاداریدا شاراوەتەوە", "compose_form.spoiler.marked": "دەق لە پشت ئاگاداریدا شاراوەتەوە",
"compose_form.spoiler.unmarked": "دەق شاراوە نییە", "compose_form.spoiler.unmarked": "دەق شاراوە نییە",
"compose_form.spoiler_placeholder": "ئاگاداریەکەت لێرە بنووسە",
"confirmation_modal.cancel": "هەڵوەشاندنەوه", "confirmation_modal.cancel": "هەڵوەشاندنەوه",
"confirmations.block.block_and_report": "بلۆک & گوزارشت", "confirmations.block.block_and_report": "بلۆک & گوزارشت",
"confirmations.block.confirm": "بلۆک", "confirmations.block.confirm": "بلۆک",
@ -354,7 +343,6 @@
"navigation_bar.direct": "ئاماژەی تایبەت", "navigation_bar.direct": "ئاماژەی تایبەت",
"navigation_bar.discover": "دۆزینەوە", "navigation_bar.discover": "دۆزینەوە",
"navigation_bar.domain_blocks": "دۆمەینە بلۆک کراوەکان", "navigation_bar.domain_blocks": "دۆمەینە بلۆک کراوەکان",
"navigation_bar.edit_profile": "دەستکاری پرۆفایل بکە",
"navigation_bar.explore": "گەڕان", "navigation_bar.explore": "گەڕان",
"navigation_bar.filters": "وشە کپەکان", "navigation_bar.filters": "وشە کپەکان",
"navigation_bar.follow_requests": "بەدواداچوی داواکاریەکان بکە", "navigation_bar.follow_requests": "بەدواداچوی داواکاریەکان بکە",
@ -439,14 +427,7 @@
"poll_button.add_poll": "ڕاپرسییەک زیاد بکە", "poll_button.add_poll": "ڕاپرسییەک زیاد بکە",
"poll_button.remove_poll": "ده‌نگدان بسڕه‌وه‌‌", "poll_button.remove_poll": "ده‌نگدان بسڕه‌وه‌‌",
"privacy.change": "ڕێکخستنی تایبەتمەندی توت", "privacy.change": "ڕێکخستنی تایبەتمەندی توت",
"privacy.direct.long": "تەنیا بۆ بەکارهێنەرانی ناوبراو",
"privacy.direct.short": "تەنها کەسانی باس کراو",
"privacy.private.long": "بینراو تەنها بۆ شوێنکەوتوان",
"privacy.private.short": "تەنیا شوێنکەوتووان",
"privacy.public.long": "بۆ هەمووان دیارە",
"privacy.public.short": "گشتی", "privacy.public.short": "گشتی",
"privacy.unlisted.long": "بۆ هەمووان دیارە، بەڵام لە تایبەتمەندییەکانی دۆزینەوە دەرچووە",
"privacy.unlisted.short": "لە لیست نەکراو",
"privacy_policy.last_updated": "دوایین نوێکردنەوە {date}", "privacy_policy.last_updated": "دوایین نوێکردنەوە {date}",
"privacy_policy.title": "سیاسەتی تایبەتێتی", "privacy_policy.title": "سیاسەتی تایبەتێتی",
"refresh": "نوێکردنەوە", "refresh": "نوێکردنەوە",
@ -610,10 +591,8 @@
"upload_error.poll": "فایل و ڕاپرسی پێکەوە ڕێپێنەدراون.", "upload_error.poll": "فایل و ڕاپرسی پێکەوە ڕێپێنەدراون.",
"upload_form.audio_description": "پەیامەکەت بۆ نابیستەکان", "upload_form.audio_description": "پەیامەکەت بۆ نابیستەکان",
"upload_form.description": "پەیامەکەت بۆ نابیناکان", "upload_form.description": "پەیامەکەت بۆ نابیناکان",
"upload_form.description_missing": "هیچ وەسفێک زیاد نەکراوە",
"upload_form.edit": "دەستکاری", "upload_form.edit": "دەستکاری",
"upload_form.thumbnail": "گۆڕانی وینۆچکە", "upload_form.thumbnail": "گۆڕانی وینۆچکە",
"upload_form.undo": "بیسڕەوە",
"upload_form.video_description": "پەیامەکەت بۆ نابیست و نابیناکان", "upload_form.video_description": "پەیامەکەت بۆ نابیست و نابیناکان",
"upload_modal.analyzing_picture": "وێنەکە شی دەکرێتەوە…", "upload_modal.analyzing_picture": "وێنەکە شی دەکرێتەوە…",
"upload_modal.apply": "بیسەپێنە", "upload_modal.apply": "بیسەپێنە",

View file

@ -45,7 +45,6 @@
"alert.unexpected.title": "Uups!", "alert.unexpected.title": "Uups!",
"announcement.announcement": "Annunziu", "announcement.announcement": "Annunziu",
"attachments_list.unprocessed": "(micca trattata)", "attachments_list.unprocessed": "(micca trattata)",
"autosuggest_hashtag.per_week": "{count} per settimana",
"boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta", "boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta",
"bundle_column_error.retry": "Pruvà torna", "bundle_column_error.retry": "Pruvà torna",
"bundle_modal_error.close": "Chjudà", "bundle_modal_error.close": "Chjudà",
@ -80,20 +79,12 @@
"compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.", "compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.",
"compose_form.lock_disclaimer.lock": "privatu", "compose_form.lock_disclaimer.lock": "privatu",
"compose_form.placeholder": "À chè pensate?", "compose_form.placeholder": "À chè pensate?",
"compose_form.poll.add_option": "Aghjunghje scelta",
"compose_form.poll.duration": "Durata di u scandagliu", "compose_form.poll.duration": "Durata di u scandagliu",
"compose_form.poll.option_placeholder": "Scelta {number}",
"compose_form.poll.remove_option": "Toglie sta scelta",
"compose_form.poll.switch_to_multiple": "Cambià u scandagliu per accittà parechje scelte", "compose_form.poll.switch_to_multiple": "Cambià u scandagliu per accittà parechje scelte",
"compose_form.poll.switch_to_single": "Cambià u scandagliu per ùn accittà ch'una scelta", "compose_form.poll.switch_to_single": "Cambià u scandagliu per ùn accittà ch'una scelta",
"compose_form.publish_form": "Publish", "compose_form.publish_form": "Publish",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.hide": "{count, plural, one {Indicà u media cum'è sensibile} other {Indicà i media cum'è sensibili}}",
"compose_form.sensitive.marked": "{count, plural, one {Media indicatu cum'è sensibile} other {Media indicati cum'è sensibili}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Media micca indicatu cum'è sensibile} other {Media micca indicati cum'è sensibili}}",
"compose_form.spoiler.marked": "Testu piattatu daret'à un'avertimentu", "compose_form.spoiler.marked": "Testu piattatu daret'à un'avertimentu",
"compose_form.spoiler.unmarked": "Testu micca piattatu", "compose_form.spoiler.unmarked": "Testu micca piattatu",
"compose_form.spoiler_placeholder": "Scrive u vostr'avertimentu quì",
"confirmation_modal.cancel": "Annullà", "confirmation_modal.cancel": "Annullà",
"confirmations.block.block_and_report": "Bluccà è signalà", "confirmations.block.block_and_report": "Bluccà è signalà",
"confirmations.block.confirm": "Bluccà", "confirmations.block.confirm": "Bluccà",
@ -245,7 +236,6 @@
"navigation_bar.compose": "Scrive un novu statutu", "navigation_bar.compose": "Scrive un novu statutu",
"navigation_bar.discover": "Scopre", "navigation_bar.discover": "Scopre",
"navigation_bar.domain_blocks": "Duminii piattati", "navigation_bar.domain_blocks": "Duminii piattati",
"navigation_bar.edit_profile": "Mudificà u prufile",
"navigation_bar.filters": "Parolle silenzate", "navigation_bar.filters": "Parolle silenzate",
"navigation_bar.follow_requests": "Dumande d'abbunamentu", "navigation_bar.follow_requests": "Dumande d'abbunamentu",
"navigation_bar.follows_and_followers": "Abbunati è abbunamenti", "navigation_bar.follows_and_followers": "Abbunati è abbunamenti",
@ -318,12 +308,7 @@
"poll_button.add_poll": "Aghjunghje", "poll_button.add_poll": "Aghjunghje",
"poll_button.remove_poll": "Toglie u scandagliu", "poll_button.remove_poll": "Toglie u scandagliu",
"privacy.change": "Mudificà a cunfidenzialità di u statutu", "privacy.change": "Mudificà a cunfidenzialità di u statutu",
"privacy.direct.long": "Mandà solu à quelli chì so mintuvati",
"privacy.direct.short": "Direct",
"privacy.private.long": "Mustrà solu à l'abbunati",
"privacy.private.short": "Followers-only",
"privacy.public.short": "Pubblicu", "privacy.public.short": "Pubblicu",
"privacy.unlisted.short": "Micca listatu",
"refresh": "Attualizà", "refresh": "Attualizà",
"regeneration_indicator.label": "Caricamentu…", "regeneration_indicator.label": "Caricamentu…",
"regeneration_indicator.sublabel": "Priparazione di a vostra pagina d'accolta!", "regeneration_indicator.sublabel": "Priparazione di a vostra pagina d'accolta!",
@ -409,7 +394,6 @@
"upload_form.description": "Discrizzione per i malvistosi", "upload_form.description": "Discrizzione per i malvistosi",
"upload_form.edit": "Mudificà", "upload_form.edit": "Mudificà",
"upload_form.thumbnail": "Cambià vignetta", "upload_form.thumbnail": "Cambià vignetta",
"upload_form.undo": "Sguassà",
"upload_form.video_description": "Discrizzione per i ciochi o cechi", "upload_form.video_description": "Discrizzione per i ciochi o cechi",
"upload_modal.analyzing_picture": "Analisi di u ritrattu…", "upload_modal.analyzing_picture": "Analisi di u ritrattu…",
"upload_modal.apply": "Affettà", "upload_modal.apply": "Affettà",

View file

@ -87,7 +87,6 @@
"announcement.announcement": "Oznámení", "announcement.announcement": "Oznámení",
"attachments_list.unprocessed": "(nezpracováno)", "attachments_list.unprocessed": "(nezpracováno)",
"audio.hide": "Skrýt zvuk", "audio.hide": "Skrýt zvuk",
"autosuggest_hashtag.per_week": "{count} za týden",
"boost_modal.combo": "Příště můžete pro přeskočení stisknout {combo}", "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.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.", "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.",
@ -144,22 +143,12 @@
"compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky učené pouze pro sledující.", "compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky učené pouze pro sledující.",
"compose_form.lock_disclaimer.lock": "zamčený", "compose_form.lock_disclaimer.lock": "zamčený",
"compose_form.placeholder": "Co se vám honí hlavou?", "compose_form.placeholder": "Co se vám honí hlavou?",
"compose_form.poll.add_option": "Přidat volbu",
"compose_form.poll.duration": "Doba trvání ankety", "compose_form.poll.duration": "Doba trvání ankety",
"compose_form.poll.option_placeholder": "Volba {number}",
"compose_form.poll.remove_option": "Odebrat tuto volbu",
"compose_form.poll.switch_to_multiple": "Povolit u ankety výběr více voleb", "compose_form.poll.switch_to_multiple": "Povolit u ankety výběr více voleb",
"compose_form.poll.switch_to_single": "Povolit u ankety výběr pouze jedné volby", "compose_form.poll.switch_to_single": "Povolit u ankety výběr pouze jedné volby",
"compose_form.publish": "Zveřejnit",
"compose_form.publish_form": "Zveřejnit", "compose_form.publish_form": "Zveřejnit",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Uložit změny",
"compose_form.sensitive.hide": "{count, plural, one {Označit média za citlivá} few {Označit média za citlivá} many {Označit média za citlivá} other {Označit média za citlivá}}",
"compose_form.sensitive.marked": "{count, plural, one {Média jsou označena za citlivá} few {Média jsou označena za citlivá} many {Média jsou označena za citlivá} other {Média jsou označena za citlivá}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Média nejsou označena za citlivá} few {Média nejsou označena za citlivá} many {Média nejsou označena za citlivá} other {Média nejsou označena za citlivá}}",
"compose_form.spoiler.marked": "Odebrat varování o obsahu", "compose_form.spoiler.marked": "Odebrat varování o obsahu",
"compose_form.spoiler.unmarked": "Přidat varování o obsahu", "compose_form.spoiler.unmarked": "Přidat varování o obsahu",
"compose_form.spoiler_placeholder": "Sem napište vaše varování",
"confirmation_modal.cancel": "Zrušit", "confirmation_modal.cancel": "Zrušit",
"confirmations.block.block_and_report": "Blokovat a nahlásit", "confirmations.block.block_and_report": "Blokovat a nahlásit",
"confirmations.block.confirm": "Blokovat", "confirmations.block.confirm": "Blokovat",
@ -401,7 +390,6 @@
"navigation_bar.direct": "Soukromé zmínky", "navigation_bar.direct": "Soukromé zmínky",
"navigation_bar.discover": "Objevit", "navigation_bar.discover": "Objevit",
"navigation_bar.domain_blocks": "Blokované domény", "navigation_bar.domain_blocks": "Blokované domény",
"navigation_bar.edit_profile": "Upravit profil",
"navigation_bar.explore": "Prozkoumat", "navigation_bar.explore": "Prozkoumat",
"navigation_bar.favourites": "Oblíbené", "navigation_bar.favourites": "Oblíbené",
"navigation_bar.filters": "Skrytá slova", "navigation_bar.filters": "Skrytá slova",
@ -508,14 +496,7 @@
"poll_button.add_poll": "Přidat anketu", "poll_button.add_poll": "Přidat anketu",
"poll_button.remove_poll": "Odebrat anketu", "poll_button.remove_poll": "Odebrat anketu",
"privacy.change": "Změnit soukromí příspěvku", "privacy.change": "Změnit soukromí příspěvku",
"privacy.direct.long": "Viditelný pouze pro zmíněné uživatele",
"privacy.direct.short": "Pouze zmínění lidé",
"privacy.private.long": "Viditelný pouze pro sledující",
"privacy.private.short": "Pouze sledující",
"privacy.public.long": "Viditelný pro všechny",
"privacy.public.short": "Veřejné", "privacy.public.short": "Veřejné",
"privacy.unlisted.long": "Viditelný pro všechny, ale vyňat z funkcí objevování",
"privacy.unlisted.short": "Neveřejný",
"privacy_policy.last_updated": "Naposledy aktualizováno {date}", "privacy_policy.last_updated": "Naposledy aktualizováno {date}",
"privacy_policy.title": "Zásady ochrany osobních údajů", "privacy_policy.title": "Zásady ochrany osobních údajů",
"refresh": "Obnovit", "refresh": "Obnovit",
@ -695,10 +676,8 @@
"upload_error.poll": "Nahrávání souborů není povoleno s anketami.", "upload_error.poll": "Nahrávání souborů není povoleno s anketami.",
"upload_form.audio_description": "Popis pro sluchově postižené", "upload_form.audio_description": "Popis pro sluchově postižené",
"upload_form.description": "Popis pro zrakově postižené", "upload_form.description": "Popis pro zrakově postižené",
"upload_form.description_missing": "Nebyl přidán popis",
"upload_form.edit": "Upravit", "upload_form.edit": "Upravit",
"upload_form.thumbnail": "Změnit miniaturu", "upload_form.thumbnail": "Změnit miniaturu",
"upload_form.undo": "Smazat",
"upload_form.video_description": "Popis pro sluchově či zrakově postižené", "upload_form.video_description": "Popis pro sluchově či zrakově postižené",
"upload_modal.analyzing_picture": "Analyzuji obrázek…", "upload_modal.analyzing_picture": "Analyzuji obrázek…",
"upload_modal.apply": "Použít", "upload_modal.apply": "Použít",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Cyhoeddiad", "announcement.announcement": "Cyhoeddiad",
"attachments_list.unprocessed": "(heb eu prosesu)", "attachments_list.unprocessed": "(heb eu prosesu)",
"audio.hide": "Cuddio sain", "audio.hide": "Cuddio sain",
"autosuggest_hashtag.per_week": "{count} yr wythnos",
"boost_modal.combo": "Mae modd pwyso {combo} er mwyn hepgor hyn tro nesa", "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.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.", "bundle_column_error.error.body": "Nid oedd modd cynhyrchu'r dudalen honno. Gall fod oherwydd gwall yn ein cod neu fater cydnawsedd porwr.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich postiadau dilynwyr-yn-unig.", "compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich postiadau dilynwyr-yn-unig.",
"compose_form.lock_disclaimer.lock": "wedi ei gloi", "compose_form.lock_disclaimer.lock": "wedi ei gloi",
"compose_form.placeholder": "Beth sydd ar eich meddwl?", "compose_form.placeholder": "Beth sydd ar eich meddwl?",
"compose_form.poll.add_option": "Ychwanegu dewis",
"compose_form.poll.duration": "Cyfnod pleidlais", "compose_form.poll.duration": "Cyfnod pleidlais",
"compose_form.poll.option_placeholder": "Dewis {number}",
"compose_form.poll.remove_option": "Tynnu'r dewis",
"compose_form.poll.switch_to_multiple": "Newid pleidlais i adael mwy nag un dewis", "compose_form.poll.switch_to_multiple": "Newid pleidlais i adael mwy nag un dewis",
"compose_form.poll.switch_to_single": "Newid pleidlais i gyfyngu i un dewis", "compose_form.poll.switch_to_single": "Newid pleidlais i gyfyngu i un dewis",
"compose_form.publish": "Cyhoeddi",
"compose_form.publish_form": "Cyhoeddi", "compose_form.publish_form": "Cyhoeddi",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Cadw newidiadau",
"compose_form.sensitive.hide": "Marcio cyfryngau fel eu bod yn sensitif",
"compose_form.sensitive.marked": "Cyfryngau wedi'u marcio'n sensitif",
"compose_form.sensitive.unmarked": "Nid yw'r cyfryngau wedi'u marcio'n sensitif",
"compose_form.spoiler.marked": "Dileu rhybudd cynnwys", "compose_form.spoiler.marked": "Dileu rhybudd cynnwys",
"compose_form.spoiler.unmarked": "Ychwanegu rhybudd cynnwys", "compose_form.spoiler.unmarked": "Ychwanegu rhybudd cynnwys",
"compose_form.spoiler_placeholder": "Ysgrifenwch eich rhybudd yma",
"confirmation_modal.cancel": "Diddymu", "confirmation_modal.cancel": "Diddymu",
"confirmations.block.block_and_report": "Rhwystro ac Adrodd", "confirmations.block.block_and_report": "Rhwystro ac Adrodd",
"confirmations.block.confirm": "Blocio", "confirmations.block.confirm": "Blocio",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Crybwylliadau preifat", "navigation_bar.direct": "Crybwylliadau preifat",
"navigation_bar.discover": "Darganfod", "navigation_bar.discover": "Darganfod",
"navigation_bar.domain_blocks": "Parthau wedi'u blocio", "navigation_bar.domain_blocks": "Parthau wedi'u blocio",
"navigation_bar.edit_profile": "Golygu proffil",
"navigation_bar.explore": "Darganfod", "navigation_bar.explore": "Darganfod",
"navigation_bar.favourites": "Ffefrynnau", "navigation_bar.favourites": "Ffefrynnau",
"navigation_bar.filters": "Geiriau wedi'u tewi", "navigation_bar.filters": "Geiriau wedi'u tewi",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Ychwanegu pleidlais", "poll_button.add_poll": "Ychwanegu pleidlais",
"poll_button.remove_poll": "Tynnu pleidlais", "poll_button.remove_poll": "Tynnu pleidlais",
"privacy.change": "Addasu preifatrwdd y post", "privacy.change": "Addasu preifatrwdd y post",
"privacy.direct.long": "Dim ond yn weladwy i ddefnyddwyr a grybwyllwyd",
"privacy.direct.short": "Dim ond pobl sy wedi'u crybwyll",
"privacy.private.long": "Dim ond pobl sy'n ddilynwyr",
"privacy.private.short": "Dilynwyr yn unig",
"privacy.public.long": "Gweladwy i bawb",
"privacy.public.short": "Cyhoeddus", "privacy.public.short": "Cyhoeddus",
"privacy.unlisted.long": "Gweladwy i bawb, ond wedi optio allan o nodweddion darganfod",
"privacy.unlisted.short": "Heb ei restru",
"privacy_policy.last_updated": "Diweddarwyd ddiwethaf ar {date}", "privacy_policy.last_updated": "Diweddarwyd ddiwethaf ar {date}",
"privacy_policy.title": "Polisi Preifatrwydd", "privacy_policy.title": "Polisi Preifatrwydd",
"recommended": "Argymhellwyd", "recommended": "Argymhellwyd",
@ -715,10 +696,8 @@
"upload_error.poll": "Nid oes modd llwytho ffeiliau â phleidleisiau.", "upload_error.poll": "Nid oes modd llwytho ffeiliau â phleidleisiau.",
"upload_form.audio_description": "Disgrifio ar gyfer pobl sydd â cholled clyw", "upload_form.audio_description": "Disgrifio ar gyfer pobl sydd â cholled clyw",
"upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg", "upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
"upload_form.description_missing": "Dim disgrifiad wedi'i ychwanegu",
"upload_form.edit": "Golygu", "upload_form.edit": "Golygu",
"upload_form.thumbnail": "Newid llun bach", "upload_form.thumbnail": "Newid llun bach",
"upload_form.undo": "Dileu",
"upload_form.video_description": "Disgrifio ar gyfer pobl sydd â cholled clyw neu amhariad golwg", "upload_form.video_description": "Disgrifio ar gyfer pobl sydd â cholled clyw neu amhariad golwg",
"upload_modal.analyzing_picture": "Yn dadansoddi llun…", "upload_modal.analyzing_picture": "Yn dadansoddi llun…",
"upload_modal.apply": "Gosod", "upload_modal.apply": "Gosod",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Bekendtgørelse", "announcement.announcement": "Bekendtgørelse",
"attachments_list.unprocessed": "(ubehandlet)", "attachments_list.unprocessed": "(ubehandlet)",
"audio.hide": "Skjul lyd", "audio.hide": "Skjul lyd",
"autosuggest_hashtag.per_week": "{count} pr. uge",
"boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang", "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.copy_stacktrace": "Kopiér fejlrapport",
"bundle_column_error.error.body": "Den anmodede side kunne ikke gengives. Dette kan skyldes flere typer fejl.", "bundle_column_error.error.body": "Den anmodede side kunne ikke gengives. Dette kan skyldes flere typer fejl.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Enhver kan følge dig og se indlæg kun beregnet for følgere.", "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Enhver kan følge dig og se indlæg kun beregnet for følgere.",
"compose_form.lock_disclaimer.lock": "låst", "compose_form.lock_disclaimer.lock": "låst",
"compose_form.placeholder": "Hvad tænker du på?", "compose_form.placeholder": "Hvad tænker du på?",
"compose_form.poll.add_option": "Tilføj valgmulighed", "compose_form.poll.add_option": "Tilføj mulighed",
"compose_form.poll.duration": "Afstemningens varighed", "compose_form.poll.duration": "Afstemningens varighed",
"compose_form.poll.multiple": "Multivalg",
"compose_form.poll.option_placeholder": "Valgmulighed {number}", "compose_form.poll.option_placeholder": "Valgmulighed {number}",
"compose_form.poll.remove_option": "Fjern denne valgmulighed", "compose_form.poll.remove_option": "Fjern denne valgmulighed",
"compose_form.poll.single": "Vælg én",
"compose_form.poll.switch_to_multiple": "Ændr afstemning til flervalgstype", "compose_form.poll.switch_to_multiple": "Ændr afstemning til flervalgstype",
"compose_form.poll.switch_to_single": "Ændr afstemning til enkeltvalgstype", "compose_form.poll.switch_to_single": "Ændr afstemning til enkeltvalgstype",
"compose_form.publish": "Publicér", "compose_form.poll.type": "Stil",
"compose_form.publish": "Indsend",
"compose_form.publish_form": "Publicér", "compose_form.publish_form": "Publicér",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Svar",
"compose_form.save_changes": "Gem ændringer", "compose_form.save_changes": "Opdatér",
"compose_form.sensitive.hide": "{count, plural, one {Markér medie som følsomt} other {Markér medier som følsomme}}",
"compose_form.sensitive.marked": "{count, plural, one {Medie er markeret som sensitivt} other {Medier er markerede som sensitive}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Medie er ikke market som sensitivt} other {Medier er ikke markerede som sensitive}}",
"compose_form.spoiler.marked": "Fjern indholdsadvarsel", "compose_form.spoiler.marked": "Fjern indholdsadvarsel",
"compose_form.spoiler.unmarked": "Tilføj indholdsadvarsel", "compose_form.spoiler.unmarked": "Tilføj indholdsadvarsel",
"compose_form.spoiler_placeholder": "Skriv din advarsel hér", "compose_form.spoiler_placeholder": "Indholdsadvarsel (valgfri)",
"confirmation_modal.cancel": "Afbryd", "confirmation_modal.cancel": "Afbryd",
"confirmations.block.block_and_report": "Blokér og Anmeld", "confirmations.block.block_and_report": "Blokér og Anmeld",
"confirmations.block.confirm": "Blokér", "confirmations.block.confirm": "Blokér",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Private omtaler", "navigation_bar.direct": "Private omtaler",
"navigation_bar.discover": "Opdag", "navigation_bar.discover": "Opdag",
"navigation_bar.domain_blocks": "Blokerede domæner", "navigation_bar.domain_blocks": "Blokerede domæner",
"navigation_bar.edit_profile": "Redigér profil",
"navigation_bar.explore": "Udforsk", "navigation_bar.explore": "Udforsk",
"navigation_bar.favourites": "Favoritter", "navigation_bar.favourites": "Favoritter",
"navigation_bar.filters": "Skjulte ord (mutede)", "navigation_bar.filters": "Skjulte ord (mutede)",
@ -526,14 +524,15 @@
"poll_button.add_poll": "Tilføj en afstemning", "poll_button.add_poll": "Tilføj en afstemning",
"poll_button.remove_poll": "Fjern afstemning", "poll_button.remove_poll": "Fjern afstemning",
"privacy.change": "Tilpas indlægsfortrolighed", "privacy.change": "Tilpas indlægsfortrolighed",
"privacy.direct.long": "Kun synlig for nævnte brugere", "privacy.direct.long": "Alle nævnt i indlægget",
"privacy.direct.short": "Kun omtalte personer", "privacy.direct.short": "Bestemte personer",
"privacy.private.long": "Kun synlig for følgere", "privacy.private.long": "Kun dine følgere",
"privacy.private.short": "Kun følgere", "privacy.private.short": "Følgere",
"privacy.public.long": "Synlig for alle", "privacy.public.long": "Alle på og udenfor Mastodon",
"privacy.public.short": "Offentlig", "privacy.public.short": "Offentlig",
"privacy.unlisted.long": "Synlig for alle, men med fravalgt visning i opdagelsesfunktioner", "privacy.unlisted.additional": "Dette er præcis som offentlig adfærd, dog vises indlægget ikke i live feeds/hashtags, udforsk eller Mastodon-søgning, selv hvis valget gælder hele kontoen.",
"privacy.unlisted.short": "Diskret", "privacy.unlisted.long": "Færre algoritmiske fanfarer",
"privacy.unlisted.short": "Tavsgøre offentligt",
"privacy_policy.last_updated": "Senest opdateret {date}", "privacy_policy.last_updated": "Senest opdateret {date}",
"privacy_policy.title": "Privatlivspolitik", "privacy_policy.title": "Privatlivspolitik",
"recommended": "Anbefalet", "recommended": "Anbefalet",
@ -551,7 +550,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "i dag", "relative_time.today": "i dag",
"reply_indicator.attachments": "{count, plural, one {# vedhæftning} other {# vedhæftninger}}",
"reply_indicator.cancel": "Afbryd", "reply_indicator.cancel": "Afbryd",
"reply_indicator.poll": "Afstemning",
"report.block": "Blokér", "report.block": "Blokér",
"report.block_explanation": "Du vil ikke se vedkommendes indlæg. Vedkommende vil ikke kunne se dine indlæg eller følge dig. Vedkommende vil kunne se, at de er blokeret.", "report.block_explanation": "Du vil ikke se vedkommendes indlæg. Vedkommende vil ikke kunne se dine indlæg eller følge dig. Vedkommende vil kunne se, at de er blokeret.",
"report.categories.legal": "Juridisk", "report.categories.legal": "Juridisk",
@ -715,10 +716,8 @@
"upload_error.poll": "Filupload ikke tilladt for afstemninger.", "upload_error.poll": "Filupload ikke tilladt for afstemninger.",
"upload_form.audio_description": "Beskrivelse til hørehæmmede", "upload_form.audio_description": "Beskrivelse til hørehæmmede",
"upload_form.description": "Beskrivelse til svagtseende", "upload_form.description": "Beskrivelse til svagtseende",
"upload_form.description_missing": "Ingen beskrivelse tilføjet",
"upload_form.edit": "Redigér", "upload_form.edit": "Redigér",
"upload_form.thumbnail": "Skift miniature", "upload_form.thumbnail": "Skift miniature",
"upload_form.undo": "Slet",
"upload_form.video_description": "Beskrivelse for hørehæmmede eller synshandicappede personer", "upload_form.video_description": "Beskrivelse for hørehæmmede eller synshandicappede personer",
"upload_modal.analyzing_picture": "Analyserer billede…", "upload_modal.analyzing_picture": "Analyserer billede…",
"upload_modal.apply": "Anvend", "upload_modal.apply": "Anvend",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Ankündigung", "announcement.announcement": "Ankündigung",
"attachments_list.unprocessed": "(ausstehend)", "attachments_list.unprocessed": "(ausstehend)",
"audio.hide": "Audio ausblenden", "audio.hide": "Audio ausblenden",
"autosuggest_hashtag.per_week": "{count} pro Woche",
"boost_modal.combo": "Mit {combo} wird dieses Fenster beim nächsten Mal nicht mehr angezeigt", "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.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.", "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.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Andere können dir folgen und deine Beiträge sehen, die nur für Follower bestimmt sind.", "compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Andere können dir folgen und deine Beiträge sehen, die nur für Follower bestimmt sind.",
"compose_form.lock_disclaimer.lock": "geschützt", "compose_form.lock_disclaimer.lock": "geschützt",
"compose_form.placeholder": "Was gibts Neues?", "compose_form.placeholder": "Was gibts Neues?",
"compose_form.poll.add_option": "Auswahl", "compose_form.poll.add_option": "Auswahl hinzufügen",
"compose_form.poll.duration": "Umfragedauer", "compose_form.poll.duration": "Umfragedauer",
"compose_form.poll.option_placeholder": "{number}. Auswahl", "compose_form.poll.multiple": "Mehrfachauswahl",
"compose_form.poll.remove_option": "Auswahlfeld entfernen", "compose_form.poll.option_placeholder": "{number}. Auswahlmöglichkeit",
"compose_form.poll.remove_option": "Dieses Auswahlfeld entfernen",
"compose_form.poll.single": "Einfachauswahl",
"compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben", "compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben",
"compose_form.poll.switch_to_single": "Nur Einzelauswahl erlauben", "compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben",
"compose_form.poll.type": "Art",
"compose_form.publish": "Veröffentlichen", "compose_form.publish": "Veröffentlichen",
"compose_form.publish_form": "Neuer Beitrag", "compose_form.publish_form": "Neuer Beitrag",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Antworten",
"compose_form.save_changes": "Änderungen speichern", "compose_form.save_changes": "Aktualisieren",
"compose_form.sensitive.hide": "{count, plural, one {Mit einer Inhaltswarnung versehen} other {Mit einer Inhaltswarnung versehen}}",
"compose_form.sensitive.marked": "{count, plural, one {Medien-Datei ist mit einer Inhaltswarnung versehen} other {Medien-Dateien sind mit einer Inhaltswarnung versehen}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Medien-Datei ist nicht mit einer Inhaltswarnung versehen} other {Medien-Dateien sind nicht mit einer Inhaltswarnung versehen}}",
"compose_form.spoiler.marked": "Inhaltswarnung entfernen", "compose_form.spoiler.marked": "Inhaltswarnung entfernen",
"compose_form.spoiler.unmarked": "Inhaltswarnung hinzufügen", "compose_form.spoiler.unmarked": "Inhaltswarnung hinzufügen",
"compose_form.spoiler_placeholder": "Inhaltswarnung", "compose_form.spoiler_placeholder": "Inhaltswarnung (optional)",
"confirmation_modal.cancel": "Abbrechen", "confirmation_modal.cancel": "Abbrechen",
"confirmations.block.block_and_report": "Blockieren und melden", "confirmations.block.block_and_report": "Blockieren und melden",
"confirmations.block.confirm": "Blockieren", "confirmations.block.confirm": "Blockieren",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Private Erwähnungen", "navigation_bar.direct": "Private Erwähnungen",
"navigation_bar.discover": "Entdecken", "navigation_bar.discover": "Entdecken",
"navigation_bar.domain_blocks": "Blockierte Domains", "navigation_bar.domain_blocks": "Blockierte Domains",
"navigation_bar.edit_profile": "Profil bearbeiten",
"navigation_bar.explore": "Entdecken", "navigation_bar.explore": "Entdecken",
"navigation_bar.favourites": "Favoriten", "navigation_bar.favourites": "Favoriten",
"navigation_bar.filters": "Stummgeschaltete Wörter", "navigation_bar.filters": "Stummgeschaltete Wörter",
@ -526,14 +524,15 @@
"poll_button.add_poll": "Umfrage erstellen", "poll_button.add_poll": "Umfrage erstellen",
"poll_button.remove_poll": "Umfrage entfernen", "poll_button.remove_poll": "Umfrage entfernen",
"privacy.change": "Sichtbarkeit anpassen", "privacy.change": "Sichtbarkeit anpassen",
"privacy.direct.long": "Nur für die erwähnten Profile sichtbar", "privacy.direct.long": "Alle in diesem Beitrag erwähnten Profile",
"privacy.direct.short": "Nur erwähnte Profile", "privacy.direct.short": "Bestimmte Profile",
"privacy.private.long": "Nur für deine Follower sichtbar", "privacy.private.long": "Nur deine Follower",
"privacy.private.short": "Nur Follower", "privacy.private.short": "Follower",
"privacy.public.long": "Für alle sichtbar", "privacy.public.long": "Alle auf und außerhalb von Mastodon",
"privacy.public.short": "Öffentlich", "privacy.public.short": "Öffentlich",
"privacy.unlisted.long": "Für alle sichtbar, aber nicht über die Suche zu finden", "privacy.unlisted.additional": "Das Verhalten ist wie bei „Öffentlich“, jedoch erscheint dieser Beitrag nicht in „Live-Feeds“, „Erkunden“, Hashtags oder über die Mastodon-Suchfunktion selbst wenn du das in den Einstellungen aktiviert hast.",
"privacy.unlisted.short": "Nicht gelistet", "privacy.unlisted.long": "Weniger im Algorithmus berücksichtigt",
"privacy.unlisted.short": "Öffentlich (eingeschränkt)",
"privacy_policy.last_updated": "Stand: {date}", "privacy_policy.last_updated": "Stand: {date}",
"privacy_policy.title": "Datenschutzerklärung", "privacy_policy.title": "Datenschutzerklärung",
"recommended": "Empfohlen", "recommended": "Empfohlen",
@ -551,7 +550,9 @@
"relative_time.minutes": "{number} Min.", "relative_time.minutes": "{number} Min.",
"relative_time.seconds": "{number} Sek.", "relative_time.seconds": "{number} Sek.",
"relative_time.today": "heute", "relative_time.today": "heute",
"reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}",
"reply_indicator.cancel": "Abbrechen", "reply_indicator.cancel": "Abbrechen",
"reply_indicator.poll": "Umfrage",
"report.block": "Blockieren", "report.block": "Blockieren",
"report.block_explanation": "Du wirst keine Beiträge mehr von diesem Konto sehen. Das blockierte Konto wird deine Beiträge nicht mehr sehen oder dir folgen können. Die Person könnte mitbekommen, dass du sie blockiert hast.", "report.block_explanation": "Du wirst keine Beiträge mehr von diesem Konto sehen. Das blockierte Konto wird deine Beiträge nicht mehr sehen oder dir folgen können. Die Person könnte mitbekommen, dass du sie blockiert hast.",
"report.categories.legal": "Rechtlich", "report.categories.legal": "Rechtlich",
@ -715,10 +716,8 @@
"upload_error.poll": "Medien-Anhänge sind zusammen mit Umfragen nicht erlaubt.", "upload_error.poll": "Medien-Anhänge sind zusammen mit Umfragen nicht erlaubt.",
"upload_form.audio_description": "Beschreibe für Menschen mit Hörbehinderung", "upload_form.audio_description": "Beschreibe für Menschen mit Hörbehinderung",
"upload_form.description": "Beschreibe für Menschen mit Sehbehinderung", "upload_form.description": "Beschreibe für Menschen mit Sehbehinderung",
"upload_form.description_missing": "Keine Beschreibung hinzugefügt",
"upload_form.edit": "Bearbeiten", "upload_form.edit": "Bearbeiten",
"upload_form.thumbnail": "Vorschaubild ändern", "upload_form.thumbnail": "Vorschaubild ändern",
"upload_form.undo": "Löschen",
"upload_form.video_description": "Beschreibe für Menschen mit einer Hör- oder Sehbehinderung", "upload_form.video_description": "Beschreibe für Menschen mit einer Hör- oder Sehbehinderung",
"upload_modal.analyzing_picture": "Bild wird analysiert …", "upload_modal.analyzing_picture": "Bild wird analysiert …",
"upload_modal.apply": "Übernehmen", "upload_modal.apply": "Übernehmen",

View file

@ -85,7 +85,6 @@
"announcement.announcement": "Ανακοίνωση", "announcement.announcement": "Ανακοίνωση",
"attachments_list.unprocessed": "(μη επεξεργασμένο)", "attachments_list.unprocessed": "(μη επεξεργασμένο)",
"audio.hide": "Απόκρυψη αρχείου ήχου", "audio.hide": "Απόκρυψη αρχείου ήχου",
"autosuggest_hashtag.per_week": "{count} ανά εβδομάδα",
"boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις την επόμενη φορά", "boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις την επόμενη φορά",
"bundle_column_error.copy_stacktrace": "Αντιγραφή αναφοράς σφάλματος", "bundle_column_error.copy_stacktrace": "Αντιγραφή αναφοράς σφάλματος",
"bundle_column_error.error.body": "Δεν ήταν δυνατή η απόδοση της σελίδας που ζήτησες. Μπορεί να οφείλεται σε σφάλμα στον κώδικά μας ή σε πρόβλημα συμβατότητας του προγράμματος περιήγησης.", "bundle_column_error.error.body": "Δεν ήταν δυνατή η απόδοση της σελίδας που ζήτησες. Μπορεί να οφείλεται σε σφάλμα στον κώδικά μας ή σε πρόβλημα συμβατότητας του προγράμματος περιήγησης.",
@ -111,6 +110,7 @@
"column.direct": "Ιδιωτικές αναφορές", "column.direct": "Ιδιωτικές αναφορές",
"column.directory": "Περιήγηση στα προφίλ", "column.directory": "Περιήγηση στα προφίλ",
"column.domain_blocks": "Αποκλεισμένοι τομείς", "column.domain_blocks": "Αποκλεισμένοι τομείς",
"column.favourites": "Αγαπημένα",
"column.follow_requests": "Αιτήματα ακολούθησης", "column.follow_requests": "Αιτήματα ακολούθησης",
"column.home": "Αρχική", "column.home": "Αρχική",
"column.lists": "Λίστες", "column.lists": "Λίστες",
@ -131,6 +131,9 @@
"community.column_settings.remote_only": "Απομακρυσμένα μόνο", "community.column_settings.remote_only": "Απομακρυσμένα μόνο",
"compose.language.change": "Αλλαγή γλώσσας", "compose.language.change": "Αλλαγή γλώσσας",
"compose.language.search": "Αναζήτηση γλωσσών...", "compose.language.search": "Αναζήτηση γλωσσών...",
"compose.published.body": "Η ανάρτηση δημοσιεύτηκε.",
"compose.published.open": "Άνοιγμα",
"compose.saved.body": "Η ανάρτηση αποθηκεύτηκε.",
"compose_form.direct_message_warning_learn_more": "Μάθε περισσότερα", "compose_form.direct_message_warning_learn_more": "Μάθε περισσότερα",
"compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μη μοιράζεσαι ευαίσθητες πληροφορίες μέσω του Mastodon.", "compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μη μοιράζεσαι ευαίσθητες πληροφορίες μέσω του Mastodon.",
"compose_form.hashtag_warning": "Αυτή η δημοσίευση δεν θα εμφανίζεται κάτω από οποιαδήποτε ετικέτα καθώς δεν είναι δημόσια. Μόνο οι δημόσιες δημοσιεύσεις μπορούν να αναζητηθούν με ετικέτα.", "compose_form.hashtag_warning": "Αυτή η δημοσίευση δεν θα εμφανίζεται κάτω από οποιαδήποτε ετικέτα καθώς δεν είναι δημόσια. Μόνο οι δημόσιες δημοσιεύσεις μπορούν να αναζητηθούν με ετικέτα.",
@ -139,20 +142,19 @@
"compose_form.placeholder": "Τι σκέφτεσαι;", "compose_form.placeholder": "Τι σκέφτεσαι;",
"compose_form.poll.add_option": "Προσθήκη επιλογής", "compose_form.poll.add_option": "Προσθήκη επιλογής",
"compose_form.poll.duration": "Διάρκεια δημοσκόπησης", "compose_form.poll.duration": "Διάρκεια δημοσκόπησης",
"compose_form.poll.multiple": "Πολλαπλή επιλογή",
"compose_form.poll.option_placeholder": "Επιλογή {number}", "compose_form.poll.option_placeholder": "Επιλογή {number}",
"compose_form.poll.remove_option": "Αφαίρεση επιλογής", "compose_form.poll.remove_option": "Αφαίρεση επιλογής",
"compose_form.poll.switch_to_multiple": "Ενημέρωση δημοσκόπησης με πολλαπλές επιλογές", "compose_form.poll.switch_to_multiple": "Ενημέρωση δημοσκόπησης με πολλαπλές επιλογές",
"compose_form.poll.switch_to_single": "Ενημέρωση δημοσκόπησης με μοναδική επιλογή", "compose_form.poll.switch_to_single": "Ενημέρωση δημοσκόπησης με μοναδική επιλογή",
"compose_form.publish": "Δημοσίευση", "compose_form.poll.type": "Στυλ",
"compose_form.publish": "Ανάρτηση",
"compose_form.publish_form": "Δημοσίευση", "compose_form.publish_form": "Δημοσίευση",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Απάντηση",
"compose_form.save_changes": "Αποθήκευση αλλαγών", "compose_form.save_changes": "Ενημέρωση",
"compose_form.sensitive.hide": "{count, plural, one {Επισήμανση πολυμέσου ως ευαίσθητο} other {Επισήμανση πολυμέσων ως ευαίσθητα}}",
"compose_form.sensitive.marked": "{count, plural, one {Το πολυμέσο έχει σημειωθεί ως ευαίσθητο} other {Τα πολυμέσα έχουν σημειωθεί ως ευαίσθητα}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Το πολυμέσο δεν έχει σημειωθεί ως ευαίσθητο} other {Τα πολυμέσα δεν έχουν σημειωθεί ως ευαίσθητα}}",
"compose_form.spoiler.marked": "Αφαίρεση προειδοποίηση περιεχομένου", "compose_form.spoiler.marked": "Αφαίρεση προειδοποίηση περιεχομένου",
"compose_form.spoiler.unmarked": "Προσθήκη προειδοποίησης περιεχομένου", "compose_form.spoiler.unmarked": "Προσθήκη προειδοποίησης περιεχομένου",
"compose_form.spoiler_placeholder": "Γράψε την προειδοποίησή σου εδώ", "compose_form.spoiler_placeholder": "Προειδοποίηση περιεχομένου (προαιρετική)",
"confirmation_modal.cancel": "Άκυρο", "confirmation_modal.cancel": "Άκυρο",
"confirmations.block.block_and_report": "Αποκλεισμός & Αναφορά", "confirmations.block.block_and_report": "Αποκλεισμός & Αναφορά",
"confirmations.block.confirm": "Αποκλεισμός", "confirmations.block.confirm": "Αποκλεισμός",
@ -184,6 +186,7 @@
"conversation.mark_as_read": "Σήμανση ως αναγνωσμένο", "conversation.mark_as_read": "Σήμανση ως αναγνωσμένο",
"conversation.open": "Προβολή συνομιλίας", "conversation.open": "Προβολή συνομιλίας",
"conversation.with": "Με {names}", "conversation.with": "Με {names}",
"copy_icon_button.copied": "Αντιγράφηκε στο πρόχειρο",
"copypaste.copied": "Αντιγράφηκε", "copypaste.copied": "Αντιγράφηκε",
"copypaste.copy_to_clipboard": "Αντιγραφή στο πρόχειρο", "copypaste.copy_to_clipboard": "Αντιγραφή στο πρόχειρο",
"directory.federated": "Από το γνωστό fediverse", "directory.federated": "Από το γνωστό fediverse",
@ -380,7 +383,6 @@
"navigation_bar.direct": "Ιδιωτικές επισημάνσεις", "navigation_bar.direct": "Ιδιωτικές επισημάνσεις",
"navigation_bar.discover": "Ανακάλυψη", "navigation_bar.discover": "Ανακάλυψη",
"navigation_bar.domain_blocks": "Αποκλεισμένοι τομείς", "navigation_bar.domain_blocks": "Αποκλεισμένοι τομείς",
"navigation_bar.edit_profile": "Επεξεργασία προφίλ",
"navigation_bar.explore": "Εξερεύνηση", "navigation_bar.explore": "Εξερεύνηση",
"navigation_bar.filters": "Αποσιωπημένες λέξεις", "navigation_bar.filters": "Αποσιωπημένες λέξεις",
"navigation_bar.follow_requests": "Αιτήματα ακολούθησης", "navigation_bar.follow_requests": "Αιτήματα ακολούθησης",
@ -450,6 +452,12 @@
"onboarding.actions.go_to_home": "Πηγαίνετε στην αρχική σας ροή", "onboarding.actions.go_to_home": "Πηγαίνετε στην αρχική σας ροή",
"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": "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": "Δημοφιλή στο Mastodon", "onboarding.follows.title": "Δημοφιλή στο Mastodon",
"onboarding.profile.note": "Βιογραφικό",
"onboarding.profile.note_hint": "Μπορείτε να @αναφέρετε άλλα άτομα ή #hashtags…",
"onboarding.profile.save_and_continue": "Αποθήκευση και συνέχεια",
"onboarding.profile.title": "Ρύθμιση προφίλ",
"onboarding.profile.upload_avatar": "Μεταφόρτωση εικόνας προφίλ",
"onboarding.profile.upload_header": "Μεταφόρτωση κεφαλίδας προφίλ",
"onboarding.share.lead": "Let people know how they can find you on Mastodon!\nΕνημερώστε άλλα άτομα πώς μπορούν να σας βρουν στο Mastodon!", "onboarding.share.lead": "Let people know how they can find you on Mastodon!\nΕνημερώστε άλλα άτομα πώς μπορούν να σας βρουν στο Mastodon!",
"onboarding.share.next_steps": "Πιθανά επόμενα βήματα:", "onboarding.share.next_steps": "Πιθανά επόμενα βήματα:",
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
@ -458,6 +466,7 @@
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.", "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.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": "Say hello to the world.",
"onboarding.steps.publish_status.title": "Κάντε την πρώτη σας δημοσίευση",
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.", "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.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.body": "Let your friends know how to find you on Mastodon!",
@ -467,6 +476,7 @@
"picture_in_picture.restore": "Βάλε το πίσω", "picture_in_picture.restore": "Βάλε το πίσω",
"poll.closed": "Κλειστή", "poll.closed": "Κλειστή",
"poll.refresh": "Ανανέωση", "poll.refresh": "Ανανέωση",
"poll.reveal": "Δείτε τα αποτελέσματα",
"poll.total_people": "{count, plural, one {# άτομο} other {# άτομα}}", "poll.total_people": "{count, plural, one {# άτομο} other {# άτομα}}",
"poll.total_votes": "{count, plural, one {# ψήφος} other {# ψήφοι}}", "poll.total_votes": "{count, plural, one {# ψήφος} other {# ψήφοι}}",
"poll.vote": "Ψήφισε", "poll.vote": "Ψήφισε",
@ -475,16 +485,14 @@
"poll_button.add_poll": "Προσθήκη δημοσκόπησης", "poll_button.add_poll": "Προσθήκη δημοσκόπησης",
"poll_button.remove_poll": "Αφαίρεση δημοσκόπησης", "poll_button.remove_poll": "Αφαίρεση δημοσκόπησης",
"privacy.change": "Προσαρμογή ιδιωτικότητας ανάρτησης", "privacy.change": "Προσαρμογή ιδιωτικότητας ανάρτησης",
"privacy.direct.long": "Δημοσίευση μόνο σε όσους επισημαίνονται", "privacy.direct.long": "Όλοι όσοι αναφέρθηκαν στη δημοσίευση",
"privacy.direct.short": "Αναφερόμενα άτομα μόνο", "privacy.direct.short": "Συγκεκριμένα άτομα",
"privacy.private.long": "Ορατό μόνο για τους ακολούθους", "privacy.private.long": "Μόνο οι ακόλουθοί σας",
"privacy.private.short": "Μόνο ακόλουθοι", "privacy.private.short": "Ακόλουθοι",
"privacy.public.long": "Ορατό σε όλους",
"privacy.public.short": "Δημόσιο", "privacy.public.short": "Δημόσιο",
"privacy.unlisted.long": "Ορατό για όλους, εκτός αυτών που δεν συμμετέχουν σε δυνατότητες ανακάλυψης",
"privacy.unlisted.short": "Μη καταχωρημένα",
"privacy_policy.last_updated": "Τελευταία ενημέρωση {date}", "privacy_policy.last_updated": "Τελευταία ενημέρωση {date}",
"privacy_policy.title": "Πολιτική Απορρήτου", "privacy_policy.title": "Πολιτική Απορρήτου",
"recommended": "Προτεινόμενα",
"refresh": "Ανανέωση", "refresh": "Ανανέωση",
"regeneration_indicator.label": "Φορτώνει…", "regeneration_indicator.label": "Φορτώνει…",
"regeneration_indicator.sublabel": "Η αρχική σου ροή ετοιμάζεται!", "regeneration_indicator.sublabel": "Η αρχική σου ροή ετοιμάζεται!",
@ -500,8 +508,10 @@
"relative_time.seconds": "{number}δ", "relative_time.seconds": "{number}δ",
"relative_time.today": "σήμερα", "relative_time.today": "σήμερα",
"reply_indicator.cancel": "Άκυρο", "reply_indicator.cancel": "Άκυρο",
"reply_indicator.poll": "Δημοσκόπηση",
"report.block": "Αποκλεισμός", "report.block": "Αποκλεισμός",
"report.block_explanation": "Δεν θα βλέπεις τις αναρτήσεις του. Δεν θα μπορεί να δει τις αναρτήσεις σου ή να σε ακολουθήσει. Θα μπορεί να δει ότι έχει αποκλειστεί.", "report.block_explanation": "Δεν θα βλέπεις τις αναρτήσεις του. Δεν θα μπορεί να δει τις αναρτήσεις σου ή να σε ακολουθήσει. Θα μπορεί να δει ότι έχει αποκλειστεί.",
"report.categories.legal": "Νομικό περιεχόμενο",
"report.categories.other": "Άλλες", "report.categories.other": "Άλλες",
"report.categories.spam": "Ανεπιθύμητα", "report.categories.spam": "Ανεπιθύμητα",
"report.categories.violation": "Το περιεχόμενο παραβιάζει έναν ή περισσότερους κανόνες διακομιστή", "report.categories.violation": "Το περιεχόμενο παραβιάζει έναν ή περισσότερους κανόνες διακομιστή",
@ -519,6 +529,8 @@
"report.placeholder": "Επιπλέον σχόλια", "report.placeholder": "Επιπλέον σχόλια",
"report.reasons.dislike": "Δεν μου αρέσει", "report.reasons.dislike": "Δεν μου αρέσει",
"report.reasons.dislike_description": "Δεν είναι κάτι που θα ήθελες να δεις", "report.reasons.dislike_description": "Δεν είναι κάτι που θα ήθελες να δεις",
"report.reasons.legal": "Είναι παράνομο",
"report.reasons.legal_description": "Πιστεύετε ότι παραβιάζει το νόμο της χώρας σας ή της χώρας του διακομιστή",
"report.reasons.other": "Είναι κάτι άλλο", "report.reasons.other": "Είναι κάτι άλλο",
"report.reasons.other_description": "Το ζήτημα δεν ταιριάζει σε άλλες κατηγορίες", "report.reasons.other_description": "Το ζήτημα δεν ταιριάζει σε άλλες κατηγορίες",
"report.reasons.spam": "Είναι σπαμ", "report.reasons.spam": "Είναι σπαμ",
@ -552,10 +564,12 @@
"search.search_or_paste": "Αναζήτηση ή εισαγωγή URL", "search.search_or_paste": "Αναζήτηση ή εισαγωγή URL",
"search_popout.quick_actions": "Γρήγορες ενέργειες", "search_popout.quick_actions": "Γρήγορες ενέργειες",
"search_popout.recent": "Πρόσφατες αναζητήσεις", "search_popout.recent": "Πρόσφατες αναζητήσεις",
"search_popout.user": "χρήστης",
"search_results.accounts": "Προφίλ", "search_results.accounts": "Προφίλ",
"search_results.all": "Όλα", "search_results.all": "Όλα",
"search_results.hashtags": "Ετικέτες", "search_results.hashtags": "Ετικέτες",
"search_results.nothing_found": "Δεν βρέθηκε τίποτα με αυτούς τους όρους αναζήτησης", "search_results.nothing_found": "Δεν βρέθηκε τίποτα με αυτούς τους όρους αναζήτησης",
"search_results.see_all": "Δες τα όλα",
"search_results.statuses": "Αναρτήσεις", "search_results.statuses": "Αναρτήσεις",
"search_results.title": "Αναζήτηση για {q}", "search_results.title": "Αναζήτηση για {q}",
"server_banner.about_active_users": "Άτομα που χρησιμοποιούν αυτόν τον διακομιστή κατά τις τελευταίες 30 ημέρες (Μηνιαία Ενεργοί Χρήστες)", "server_banner.about_active_users": "Άτομα που χρησιμοποιούν αυτόν τον διακομιστή κατά τις τελευταίες 30 ημέρες (Μηνιαία Ενεργοί Χρήστες)",
@ -566,6 +580,8 @@
"server_banner.server_stats": "Στατιστικά διακομιστή:", "server_banner.server_stats": "Στατιστικά διακομιστή:",
"sign_in_banner.create_account": "Δημιουργία λογαριασμού", "sign_in_banner.create_account": "Δημιουργία λογαριασμού",
"sign_in_banner.sign_in": "Σύνδεση", "sign_in_banner.sign_in": "Σύνδεση",
"sign_in_banner.sso_redirect": "Συνδεθείτε ή Εγγραφείτε",
"sign_in_banner.text": "Συνδεθείτε για να ακολουθήσετε προφίλ ή ετικέτες, αγαπήστε, μοιραστείτε και απαντήστε σε δημοσιεύσεις. Μπορείτε επίσης να αλληλεπιδράσετε από τον λογαριασμό σας σε διαφορετικό διακομιστή.",
"status.admin_account": "Άνοιγμα διεπαφής συντονισμού για τον/την @{name}", "status.admin_account": "Άνοιγμα διεπαφής συντονισμού για τον/την @{name}",
"status.admin_domain": "Άνοιγμα λειτουργίας διαμεσολάβησης για {domain}", "status.admin_domain": "Άνοιγμα λειτουργίας διαμεσολάβησης για {domain}",
"status.admin_status": "Άνοιγμα αυτής της ανάρτησης σε διεπαφή συντονισμού", "status.admin_status": "Άνοιγμα αυτής της ανάρτησης σε διεπαφή συντονισμού",
@ -582,6 +598,7 @@
"status.edited": "Επεξεργάστηκε στις {date}", "status.edited": "Επεξεργάστηκε στις {date}",
"status.edited_x_times": "Επεξεργάστηκε {count, plural, one {{count} φορά} other {{count} φορές}}", "status.edited_x_times": "Επεξεργάστηκε {count, plural, one {{count} φορά} other {{count} φορές}}",
"status.embed": "Ενσωμάτωσε", "status.embed": "Ενσωμάτωσε",
"status.favourite": "Αγαπημένα",
"status.filter": "Φιλτράρισμα αυτής της ανάρτησης", "status.filter": "Φιλτράρισμα αυτής της ανάρτησης",
"status.filtered": "Φιλτραρισμένα", "status.filtered": "Φιλτραρισμένα",
"status.hide": "Απόκρυψη ανάρτησης", "status.hide": "Απόκρυψη ανάρτησης",
@ -646,10 +663,8 @@
"upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.", "upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.",
"upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής", "upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής",
"upload_form.description": "Περιγραφή για άτομα με προβλήματα όρασης", "upload_form.description": "Περιγραφή για άτομα με προβλήματα όρασης",
"upload_form.description_missing": "Δεν προστέθηκε περιγραφή",
"upload_form.edit": "Επεξεργασία", "upload_form.edit": "Επεξεργασία",
"upload_form.thumbnail": "Αλλαγή μικρογραφίας", "upload_form.thumbnail": "Αλλαγή μικρογραφίας",
"upload_form.undo": "Διαγραφή",
"upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης", "upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης",
"upload_modal.analyzing_picture": "Ανάλυση εικόνας…", "upload_modal.analyzing_picture": "Ανάλυση εικόνας…",
"upload_modal.apply": "Εφαρμογή", "upload_modal.apply": "Εφαρμογή",

View file

@ -87,7 +87,6 @@
"announcement.announcement": "Announcement", "announcement.announcement": "Announcement",
"attachments_list.unprocessed": "(unprocessed)", "attachments_list.unprocessed": "(unprocessed)",
"audio.hide": "Hide audio", "audio.hide": "Hide audio",
"autosuggest_hashtag.per_week": "{count} per week",
"boost_modal.combo": "You can press {combo} to skip this next time", "boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.copy_stacktrace": "Copy error report", "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.", "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.",
@ -144,22 +143,12 @@
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "locked", "compose_form.lock_disclaimer.lock": "locked",
"compose_form.placeholder": "What's on your mind?", "compose_form.placeholder": "What's on your mind?",
"compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish",
"compose_form.publish_form": "New post", "compose_form.publish_form": "New post",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Save changes",
"compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
"compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
"compose_form.spoiler.marked": "Remove content warning", "compose_form.spoiler.marked": "Remove content warning",
"compose_form.spoiler.unmarked": "Add content warning", "compose_form.spoiler.unmarked": "Add content warning",
"compose_form.spoiler_placeholder": "Write your warning here",
"confirmation_modal.cancel": "Cancel", "confirmation_modal.cancel": "Cancel",
"confirmations.block.block_and_report": "Block & Report", "confirmations.block.block_and_report": "Block & Report",
"confirmations.block.confirm": "Block", "confirmations.block.confirm": "Block",
@ -406,7 +395,6 @@
"navigation_bar.direct": "Private mentions", "navigation_bar.direct": "Private mentions",
"navigation_bar.discover": "Discover", "navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Blocked domains", "navigation_bar.domain_blocks": "Blocked domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.explore": "Explore", "navigation_bar.explore": "Explore",
"navigation_bar.favourites": "Favourites", "navigation_bar.favourites": "Favourites",
"navigation_bar.filters": "Muted words", "navigation_bar.filters": "Muted words",
@ -524,14 +512,7 @@
"poll_button.add_poll": "Add a poll", "poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll", "poll_button.remove_poll": "Remove poll",
"privacy.change": "Change post privacy", "privacy.change": "Change post privacy",
"privacy.direct.long": "Visible for mentioned users only",
"privacy.direct.short": "Mentioned people only",
"privacy.private.long": "Visible for followers only",
"privacy.private.short": "Followers-only",
"privacy.public.long": "Visible for all",
"privacy.public.short": "Public", "privacy.public.short": "Public",
"privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
"privacy.unlisted.short": "Unlisted",
"privacy_policy.last_updated": "Last updated {date}", "privacy_policy.last_updated": "Last updated {date}",
"privacy_policy.title": "Privacy Policy", "privacy_policy.title": "Privacy Policy",
"recommended": "Recommended", "recommended": "Recommended",
@ -713,10 +694,8 @@
"upload_error.poll": "File upload not allowed with polls.", "upload_error.poll": "File upload not allowed with polls.",
"upload_form.audio_description": "Describe for people who are deaf or hard of hearing", "upload_form.audio_description": "Describe for people who are deaf or hard of hearing",
"upload_form.description": "Describe for people who are blind or have low vision", "upload_form.description": "Describe for people who are blind or have low vision",
"upload_form.description_missing": "No description added",
"upload_form.edit": "Edit", "upload_form.edit": "Edit",
"upload_form.thumbnail": "Change thumbnail", "upload_form.thumbnail": "Change thumbnail",
"upload_form.undo": "Delete",
"upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision", "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
"upload_modal.analyzing_picture": "Analysing picture…", "upload_modal.analyzing_picture": "Analysing picture…",
"upload_modal.apply": "Apply", "upload_modal.apply": "Apply",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Announcement", "announcement.announcement": "Announcement",
"attachments_list.unprocessed": "(unprocessed)", "attachments_list.unprocessed": "(unprocessed)",
"audio.hide": "Hide audio", "audio.hide": "Hide audio",
"autosuggest_hashtag.per_week": "{count} per week",
"boost_modal.combo": "You can press {combo} to skip this next time", "boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.copy_stacktrace": "Copy error report", "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.", "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.",
@ -146,22 +145,20 @@
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "locked", "compose_form.lock_disclaimer.lock": "locked",
"compose_form.placeholder": "What's on your mind?", "compose_form.placeholder": "What's on your mind?",
"compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.multiple": "Multiple choice",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.option_placeholder": "Option {number}",
"compose_form.poll.single": "Pick one",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.poll.type": "Style",
"compose_form.publish": "Post",
"compose_form.publish_form": "New post", "compose_form.publish_form": "New post",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Reply",
"compose_form.save_changes": "Save changes", "compose_form.save_changes": "Update",
"compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",
"compose_form.sensitive.marked": "{count, plural, one {Media is marked as sensitive} other {Media is marked as sensitive}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Media is not marked as sensitive} other {Media is not marked as sensitive}}",
"compose_form.spoiler.marked": "Remove content warning", "compose_form.spoiler.marked": "Remove content warning",
"compose_form.spoiler.unmarked": "Add content warning", "compose_form.spoiler.unmarked": "Add content warning",
"compose_form.spoiler_placeholder": "Write your warning here", "compose_form.spoiler_placeholder": "Content warning (optional)",
"confirmation_modal.cancel": "Cancel", "confirmation_modal.cancel": "Cancel",
"confirmations.block.block_and_report": "Block & Report", "confirmations.block.block_and_report": "Block & Report",
"confirmations.block.confirm": "Block", "confirmations.block.confirm": "Block",
@ -408,7 +405,6 @@
"navigation_bar.direct": "Private mentions", "navigation_bar.direct": "Private mentions",
"navigation_bar.discover": "Discover", "navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Blocked domains", "navigation_bar.domain_blocks": "Blocked domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.explore": "Explore", "navigation_bar.explore": "Explore",
"navigation_bar.favourites": "Favorites", "navigation_bar.favourites": "Favorites",
"navigation_bar.filters": "Muted words", "navigation_bar.filters": "Muted words",
@ -526,14 +522,15 @@
"poll_button.add_poll": "Add a poll", "poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll", "poll_button.remove_poll": "Remove poll",
"privacy.change": "Change post privacy", "privacy.change": "Change post privacy",
"privacy.direct.long": "Visible for mentioned users only", "privacy.direct.long": "Everyone mentioned in the post",
"privacy.direct.short": "Mentioned people only", "privacy.direct.short": "Specific people",
"privacy.private.long": "Visible for followers only", "privacy.private.long": "Only your followers",
"privacy.private.short": "Followers only", "privacy.private.short": "Followers",
"privacy.public.long": "Visible for all", "privacy.public.long": "Anyone on and off Mastodon",
"privacy.public.short": "Public", "privacy.public.short": "Public",
"privacy.unlisted.long": "Visible for all, but opted-out of discovery features", "privacy.unlisted.additional": "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.",
"privacy.unlisted.short": "Unlisted", "privacy.unlisted.long": "Fewer algorithmic fanfares",
"privacy.unlisted.short": "Quiet public",
"privacy_policy.last_updated": "Last updated {date}", "privacy_policy.last_updated": "Last updated {date}",
"privacy_policy.title": "Privacy Policy", "privacy_policy.title": "Privacy Policy",
"recommended": "Recommended", "recommended": "Recommended",
@ -551,7 +548,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "today", "relative_time.today": "today",
"reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}",
"reply_indicator.cancel": "Cancel", "reply_indicator.cancel": "Cancel",
"reply_indicator.poll": "Poll",
"report.block": "Block", "report.block": "Block",
"report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.",
"report.categories.legal": "Legal", "report.categories.legal": "Legal",
@ -715,10 +714,8 @@
"upload_error.poll": "File upload not allowed with polls.", "upload_error.poll": "File upload not allowed with polls.",
"upload_form.audio_description": "Describe for people who are deaf or hard of hearing", "upload_form.audio_description": "Describe for people who are deaf or hard of hearing",
"upload_form.description": "Describe for people who are blind or have low vision", "upload_form.description": "Describe for people who are blind or have low vision",
"upload_form.description_missing": "No description added",
"upload_form.edit": "Edit", "upload_form.edit": "Edit",
"upload_form.thumbnail": "Change thumbnail", "upload_form.thumbnail": "Change thumbnail",
"upload_form.undo": "Delete",
"upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision", "upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
"upload_modal.analyzing_picture": "Analyzing picture…", "upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.apply": "Apply", "upload_modal.apply": "Apply",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Anoncoj", "announcement.announcement": "Anoncoj",
"attachments_list.unprocessed": "(neprilaborita)", "attachments_list.unprocessed": "(neprilaborita)",
"audio.hide": "Kaŝi aŭdion", "audio.hide": "Kaŝi aŭdion",
"autosuggest_hashtag.per_week": "po {count} por semajno",
"boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje", "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
"bundle_column_error.copy_stacktrace": "Kopii la eraran raporton", "bundle_column_error.copy_stacktrace": "Kopii la eraran raporton",
"bundle_column_error.error.body": "La petita paĝo ne povas redonitis. Eble estas eraro.", "bundle_column_error.error.body": "La petita paĝo ne povas redonitis. Eble estas eraro.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Via konto ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn afiŝojn nur al la sekvantoj.", "compose_form.lock_disclaimer": "Via konto ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn afiŝojn nur al la sekvantoj.",
"compose_form.lock_disclaimer.lock": "ŝlosita", "compose_form.lock_disclaimer.lock": "ŝlosita",
"compose_form.placeholder": "Kion vi pensas?", "compose_form.placeholder": "Kion vi pensas?",
"compose_form.poll.add_option": "Aldoni elekteblon",
"compose_form.poll.duration": "Daŭro de la balotenketo", "compose_form.poll.duration": "Daŭro de la balotenketo",
"compose_form.poll.option_placeholder": "Elekteblo {number}",
"compose_form.poll.remove_option": "Forigi ĉi tiu elekteblon",
"compose_form.poll.switch_to_multiple": "Ŝanĝi la balotenketon por permesi multajn elektojn", "compose_form.poll.switch_to_multiple": "Ŝanĝi la balotenketon por permesi multajn elektojn",
"compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton", "compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton",
"compose_form.publish": "Afiŝi",
"compose_form.publish_form": "Afiŝi", "compose_form.publish_form": "Afiŝi",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Konservi ŝanĝojn",
"compose_form.sensitive.hide": "{count, plural, one {Marki la plurmedio kiel tikla} other {Marki la plurmedioj kiel tiklaj}}",
"compose_form.sensitive.marked": "{count, plural, one {La plurmedio estas markita kiel tikla} other {La plurmedioj estas markitaj kiel tiklaj}}",
"compose_form.sensitive.unmarked": "{count, plural, one {La plurmedio ne estas markita kiel tikla} other {La plurmedioj ne estas markitaj kiel tiklaj}}",
"compose_form.spoiler.marked": "Forigi la averton de enhavo", "compose_form.spoiler.marked": "Forigi la averton de enhavo",
"compose_form.spoiler.unmarked": "Aldoni averton de enhavo", "compose_form.spoiler.unmarked": "Aldoni averton de enhavo",
"compose_form.spoiler_placeholder": "Skribu vian averton ĉi tie",
"confirmation_modal.cancel": "Nuligi", "confirmation_modal.cancel": "Nuligi",
"confirmations.block.block_and_report": "Bloki kaj raporti", "confirmations.block.block_and_report": "Bloki kaj raporti",
"confirmations.block.confirm": "Bloki", "confirmations.block.confirm": "Bloki",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Privataj mencioj", "navigation_bar.direct": "Privataj mencioj",
"navigation_bar.discover": "Esplori", "navigation_bar.discover": "Esplori",
"navigation_bar.domain_blocks": "Blokitaj domajnoj", "navigation_bar.domain_blocks": "Blokitaj domajnoj",
"navigation_bar.edit_profile": "Redakti profilon",
"navigation_bar.explore": "Esplori", "navigation_bar.explore": "Esplori",
"navigation_bar.favourites": "Stelumoj", "navigation_bar.favourites": "Stelumoj",
"navigation_bar.filters": "Silentigitaj vortoj", "navigation_bar.filters": "Silentigitaj vortoj",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Aldoni balotenketon", "poll_button.add_poll": "Aldoni balotenketon",
"poll_button.remove_poll": "Forigi balotenketon", "poll_button.remove_poll": "Forigi balotenketon",
"privacy.change": "Agordi mesaĝan privatecon", "privacy.change": "Agordi mesaĝan privatecon",
"privacy.direct.long": "Videbla nur al menciitaj uzantoj",
"privacy.direct.short": "Nur menciitaj personoj",
"privacy.private.long": "Videbla nur al viaj sekvantoj",
"privacy.private.short": "Nur abonantoj",
"privacy.public.long": "Videbla por ĉiuj",
"privacy.public.short": "Publika", "privacy.public.short": "Publika",
"privacy.unlisted.long": "Videbla por ĉiuj, sed ekskluzive el la funkcio de esploro",
"privacy.unlisted.short": "Nelistigita",
"privacy_policy.last_updated": "Laste ĝisdatigita en {date}", "privacy_policy.last_updated": "Laste ĝisdatigita en {date}",
"privacy_policy.title": "Politiko de privateco", "privacy_policy.title": "Politiko de privateco",
"recommended": "Rekomendita", "recommended": "Rekomendita",
@ -715,10 +696,8 @@
"upload_error.poll": "Alŝuto de dosiero ne permesita kun balotenketo.", "upload_error.poll": "Alŝuto de dosiero ne permesita kun balotenketo.",
"upload_form.audio_description": "Priskribi por homoj kiuj malfacile aŭdi", "upload_form.audio_description": "Priskribi por homoj kiuj malfacile aŭdi",
"upload_form.description": "Priskribi por personoj, kiuj estas blindaj aŭ havas vidmalsufiĉon", "upload_form.description": "Priskribi por personoj, kiuj estas blindaj aŭ havas vidmalsufiĉon",
"upload_form.description_missing": "Neniu priskribo aldonita",
"upload_form.edit": "Redakti", "upload_form.edit": "Redakti",
"upload_form.thumbnail": "Ŝanĝi etigita bildo", "upload_form.thumbnail": "Ŝanĝi etigita bildo",
"upload_form.undo": "Forigi",
"upload_form.video_description": "Priskribi por homoj kiuj malfacile aŭdi aŭ vidi", "upload_form.video_description": "Priskribi por homoj kiuj malfacile aŭdi aŭ vidi",
"upload_modal.analyzing_picture": "Bilda analizado…", "upload_modal.analyzing_picture": "Bilda analizado…",
"upload_modal.apply": "Apliki", "upload_modal.apply": "Apliki",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Anuncio", "announcement.announcement": "Anuncio",
"attachments_list.unprocessed": "[sin procesar]", "attachments_list.unprocessed": "[sin procesar]",
"audio.hide": "Ocultar audio", "audio.hide": "Ocultar audio",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Podés hacer clic en {combo} para saltar esto la próxima vez", "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.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.", "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.",
@ -146,22 +145,21 @@
"compose_form.lock_disclaimer": "Tu cuenta no es {locked}. Todos pueden seguirte para ver tus mensajes marcados como \"Sólo para seguidores\".", "compose_form.lock_disclaimer": "Tu cuenta no es {locked}. Todos pueden seguirte para ver tus mensajes marcados como \"Sólo para seguidores\".",
"compose_form.lock_disclaimer.lock": "privada", "compose_form.lock_disclaimer.lock": "privada",
"compose_form.placeholder": "¿Qué onda?", "compose_form.placeholder": "¿Qué onda?",
"compose_form.poll.add_option": "Agregá una opción",
"compose_form.poll.duration": "Duración de la encuesta", "compose_form.poll.duration": "Duración de la encuesta",
"compose_form.poll.multiple": "Selección múltiple",
"compose_form.poll.option_placeholder": "Opción {number}", "compose_form.poll.option_placeholder": "Opción {number}",
"compose_form.poll.remove_option": "Quitar esta opción", "compose_form.poll.remove_option": "Quitar esta opción",
"compose_form.poll.single": "Elige uno",
"compose_form.poll.switch_to_multiple": "Cambiar encuesta para permitir opciones múltiples", "compose_form.poll.switch_to_multiple": "Cambiar encuesta para permitir opciones múltiples",
"compose_form.poll.switch_to_single": "Cambiar encuesta para permitir una sola opción", "compose_form.poll.switch_to_single": "Cambiar encuesta para permitir una sola opción",
"compose_form.poll.type": "Estilo",
"compose_form.publish": "Publicar", "compose_form.publish": "Publicar",
"compose_form.publish_form": "Nuevo mensaje", "compose_form.publish_form": "Nuevo mensaje",
"compose_form.publish_loud": "¡{publish}!", "compose_form.reply": "Responder",
"compose_form.save_changes": "Guardar cambios", "compose_form.save_changes": "Actualizar",
"compose_form.sensitive.hide": "Marcar medio como sensible",
"compose_form.sensitive.marked": "{count, plural, one {El medio está marcado como sensible} other {Los medios están marcados como sensibles}}",
"compose_form.sensitive.unmarked": "El medio no está marcado como sensible",
"compose_form.spoiler.marked": "Quitar advertencia de contenido", "compose_form.spoiler.marked": "Quitar advertencia de contenido",
"compose_form.spoiler.unmarked": "Agregar advertencia de contenido", "compose_form.spoiler.unmarked": "Agregar advertencia de contenido",
"compose_form.spoiler_placeholder": "Escribí tu advertencia acá", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)",
"confirmation_modal.cancel": "Cancelar", "confirmation_modal.cancel": "Cancelar",
"confirmations.block.block_and_report": "Bloquear y denunciar", "confirmations.block.block_and_report": "Bloquear y denunciar",
"confirmations.block.confirm": "Bloquear", "confirmations.block.confirm": "Bloquear",
@ -408,7 +406,6 @@
"navigation_bar.direct": "Menciones privadas", "navigation_bar.direct": "Menciones privadas",
"navigation_bar.discover": "Descubrir", "navigation_bar.discover": "Descubrir",
"navigation_bar.domain_blocks": "Dominios bloqueados", "navigation_bar.domain_blocks": "Dominios bloqueados",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.explore": "Explorá", "navigation_bar.explore": "Explorá",
"navigation_bar.favourites": "Favoritos", "navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Palabras silenciadas", "navigation_bar.filters": "Palabras silenciadas",
@ -526,14 +523,10 @@
"poll_button.add_poll": "Agregar encuesta", "poll_button.add_poll": "Agregar encuesta",
"poll_button.remove_poll": "Quitar encuesta", "poll_button.remove_poll": "Quitar encuesta",
"privacy.change": "Configurar privacidad del mensaje", "privacy.change": "Configurar privacidad del mensaje",
"privacy.direct.long": "Visible sólo para los usuarios mencionados", "privacy.direct.short": "Personas específicas",
"privacy.direct.short": "Sólo cuentas mencionadas", "privacy.private.long": "Solo tus seguidores",
"privacy.private.long": "Visible sólo para los seguidores", "privacy.private.short": "Seguidores",
"privacy.private.short": "Sólo para seguidores",
"privacy.public.long": "Visible para todos",
"privacy.public.short": "Público", "privacy.public.short": "Público",
"privacy.unlisted.long": "Visible para todos, pero excluido de las características de descubrimiento",
"privacy.unlisted.short": "No listado",
"privacy_policy.last_updated": "Última actualización: {date}", "privacy_policy.last_updated": "Última actualización: {date}",
"privacy_policy.title": "Política de privacidad", "privacy_policy.title": "Política de privacidad",
"recommended": "Opción recomendada", "recommended": "Opción recomendada",
@ -715,10 +708,8 @@
"upload_error.poll": "No se permite la subida de archivos en encuestas.", "upload_error.poll": "No se permite la subida de archivos en encuestas.",
"upload_form.audio_description": "Agregá una descripción para personas con dificultades auditivas", "upload_form.audio_description": "Agregá una descripción para personas con dificultades auditivas",
"upload_form.description": "Agregá una descripción para personas con dificultades visuales", "upload_form.description": "Agregá una descripción para personas con dificultades visuales",
"upload_form.description_missing": "No se agregó descripción",
"upload_form.edit": "Editar", "upload_form.edit": "Editar",
"upload_form.thumbnail": "Cambiar miniatura", "upload_form.thumbnail": "Cambiar miniatura",
"upload_form.undo": "Eliminar",
"upload_form.video_description": "Agregá una descripción para personas con dificultades auditivas o visuales", "upload_form.video_description": "Agregá una descripción para personas con dificultades auditivas o visuales",
"upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.analyzing_picture": "Analizando imagen…",
"upload_modal.apply": "Aplicar", "upload_modal.apply": "Aplicar",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Anuncio", "announcement.announcement": "Anuncio",
"attachments_list.unprocessed": "(sin procesar)", "attachments_list.unprocessed": "(sin procesar)",
"audio.hide": "Ocultar audio", "audio.hide": "Ocultar audio",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez", "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.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.", "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.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.", "compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
"compose_form.lock_disclaimer.lock": "bloqueado", "compose_form.lock_disclaimer.lock": "bloqueado",
"compose_form.placeholder": "¿En qué estás pensando?", "compose_form.placeholder": "¿En qué estás pensando?",
"compose_form.poll.add_option": "Añadir una opción", "compose_form.poll.add_option": "Agregar opción",
"compose_form.poll.duration": "Duración de la encuesta", "compose_form.poll.duration": "Duración de la encuesta",
"compose_form.poll.option_placeholder": "Elección {number}", "compose_form.poll.multiple": "Selección múltiple",
"compose_form.poll.option_placeholder": "Opción {number}",
"compose_form.poll.remove_option": "Eliminar esta opción", "compose_form.poll.remove_option": "Eliminar esta opción",
"compose_form.poll.single": "Seleccione uno",
"compose_form.poll.switch_to_multiple": "Modificar encuesta para permitir múltiples opciones", "compose_form.poll.switch_to_multiple": "Modificar encuesta para permitir múltiples opciones",
"compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción", "compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción",
"compose_form.publish": "Publicar", "compose_form.poll.type": "Estilo",
"compose_form.publish": "Publicación",
"compose_form.publish_form": "Publicar", "compose_form.publish_form": "Publicar",
"compose_form.publish_loud": "¡{publish}!", "compose_form.reply": "Respuesta",
"compose_form.save_changes": "Guardar cambios", "compose_form.save_changes": "Actualización",
"compose_form.sensitive.hide": "Marcar multimedia como sensible",
"compose_form.sensitive.marked": "Material marcado como sensible",
"compose_form.sensitive.unmarked": "Material no marcado como sensible",
"compose_form.spoiler.marked": "Texto oculto tras la advertencia", "compose_form.spoiler.marked": "Texto oculto tras la advertencia",
"compose_form.spoiler.unmarked": "Texto no oculto", "compose_form.spoiler.unmarked": "Texto no oculto",
"compose_form.spoiler_placeholder": "Advertencia de contenido", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)",
"confirmation_modal.cancel": "Cancelar", "confirmation_modal.cancel": "Cancelar",
"confirmations.block.block_and_report": "Bloquear y Denunciar", "confirmations.block.block_and_report": "Bloquear y Denunciar",
"confirmations.block.confirm": "Bloquear", "confirmations.block.confirm": "Bloquear",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Menciones privadas", "navigation_bar.direct": "Menciones privadas",
"navigation_bar.discover": "Descubrir", "navigation_bar.discover": "Descubrir",
"navigation_bar.domain_blocks": "Dominios ocultos", "navigation_bar.domain_blocks": "Dominios ocultos",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.explore": "Explorar", "navigation_bar.explore": "Explorar",
"navigation_bar.favourites": "Favoritos", "navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Palabras silenciadas", "navigation_bar.filters": "Palabras silenciadas",
@ -526,14 +524,15 @@
"poll_button.add_poll": "Añadir una encuesta", "poll_button.add_poll": "Añadir una encuesta",
"poll_button.remove_poll": "Eliminar encuesta", "poll_button.remove_poll": "Eliminar encuesta",
"privacy.change": "Ajustar privacidad", "privacy.change": "Ajustar privacidad",
"privacy.direct.long": "Sólo mostrar a los usuarios mencionados", "privacy.direct.long": "Todos los mencionados en la publicación",
"privacy.direct.short": "Solo personas mencionadas", "privacy.direct.short": "Personas específicas",
"privacy.private.long": "Sólo mostrar a seguidores", "privacy.private.long": "Sólo tus seguidores",
"privacy.private.short": "Solo seguidores", "privacy.private.short": "Seguidores",
"privacy.public.long": "Visible para todos", "privacy.public.long": "Cualquiera dentro y fuera de Mastodon",
"privacy.public.short": "Público", "privacy.public.short": "Público",
"privacy.unlisted.long": "Visible para todos, pero excluido de las funciones de descubrimiento", "privacy.unlisted.additional": "Esto se comporta exactamente igual que el público, excepto que el post no aparecerá en las cronologías en directo o en los hashtags, la exploración o busquedas en Mastodon, incluso si está optado por activar la cuenta de usuario.",
"privacy.unlisted.short": "No listado", "privacy.unlisted.long": "Menos fanfares algorítmicos",
"privacy.unlisted.short": "Público silencioso",
"privacy_policy.last_updated": "Actualizado por última vez {date}", "privacy_policy.last_updated": "Actualizado por última vez {date}",
"privacy_policy.title": "Política de Privacidad", "privacy_policy.title": "Política de Privacidad",
"recommended": "Recomendado", "recommended": "Recomendado",
@ -551,7 +550,9 @@
"relative_time.minutes": "{number} m", "relative_time.minutes": "{number} m",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "hoy", "relative_time.today": "hoy",
"reply_indicator.attachments": "{count, plural, one {# adjunto} other {# adjuntos}}",
"reply_indicator.cancel": "Cancelar", "reply_indicator.cancel": "Cancelar",
"reply_indicator.poll": "Encuesta",
"report.block": "Bloquear", "report.block": "Bloquear",
"report.block_explanation": "No veras sus publicaciones. No podrán ver tus publicaciones ni seguirte. Podrán saber que están bloqueados.", "report.block_explanation": "No veras sus publicaciones. No podrán ver tus publicaciones ni seguirte. Podrán saber que están bloqueados.",
"report.categories.legal": "Legal", "report.categories.legal": "Legal",
@ -715,10 +716,8 @@
"upload_error.poll": "Subida de archivos no permitida con encuestas.", "upload_error.poll": "Subida de archivos no permitida con encuestas.",
"upload_form.audio_description": "Describir para personas con problemas auditivos", "upload_form.audio_description": "Describir para personas con problemas auditivos",
"upload_form.description": "Describir para los usuarios con dificultad visual", "upload_form.description": "Describir para los usuarios con dificultad visual",
"upload_form.description_missing": "Sin descripción añadida",
"upload_form.edit": "Editar", "upload_form.edit": "Editar",
"upload_form.thumbnail": "Cambiar miniatura", "upload_form.thumbnail": "Cambiar miniatura",
"upload_form.undo": "Borrar",
"upload_form.video_description": "Describir para personas con problemas auditivos o visuales", "upload_form.video_description": "Describir para personas con problemas auditivos o visuales",
"upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.analyzing_picture": "Analizando imagen…",
"upload_modal.apply": "Aplicar", "upload_modal.apply": "Aplicar",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Anuncio", "announcement.announcement": "Anuncio",
"attachments_list.unprocessed": "(sin procesar)", "attachments_list.unprocessed": "(sin procesar)",
"audio.hide": "Ocultar audio", "audio.hide": "Ocultar audio",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez", "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.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.", "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.",
@ -146,22 +145,21 @@
"compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus publicaciones solo para seguidores.", "compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus publicaciones solo para seguidores.",
"compose_form.lock_disclaimer.lock": "bloqueado", "compose_form.lock_disclaimer.lock": "bloqueado",
"compose_form.placeholder": "¿En qué estás pensando?", "compose_form.placeholder": "¿En qué estás pensando?",
"compose_form.poll.add_option": "Añadir una opción",
"compose_form.poll.duration": "Duración de la encuesta", "compose_form.poll.duration": "Duración de la encuesta",
"compose_form.poll.option_placeholder": "Elección {number}", "compose_form.poll.multiple": "Selección múltiple",
"compose_form.poll.remove_option": "Eliminar esta opción", "compose_form.poll.option_placeholder": "Opción {number}",
"compose_form.poll.remove_option": "Quitar esta opción",
"compose_form.poll.single": "Elige uno",
"compose_form.poll.switch_to_multiple": "Modificar encuesta para permitir múltiples opciones", "compose_form.poll.switch_to_multiple": "Modificar encuesta para permitir múltiples opciones",
"compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción", "compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción",
"compose_form.poll.type": "Estilo",
"compose_form.publish": "Publicar", "compose_form.publish": "Publicar",
"compose_form.publish_form": "Publicar", "compose_form.publish_form": "Publicar",
"compose_form.publish_loud": "¡{publish}!", "compose_form.reply": "Responder",
"compose_form.save_changes": "Guardar cambios", "compose_form.save_changes": "Actualizar",
"compose_form.sensitive.hide": "{count, plural, one {Marcar material como sensible} other {Marcar material como sensible}}",
"compose_form.sensitive.marked": "{count, plural, one {Material marcado como sensible} other {Material marcado como sensible}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Material no marcado como sensible} other {Material no marcado como sensible}}",
"compose_form.spoiler.marked": "Quitar advertencia de contenido", "compose_form.spoiler.marked": "Quitar advertencia de contenido",
"compose_form.spoiler.unmarked": "Añadir advertencia de contenido", "compose_form.spoiler.unmarked": "Añadir advertencia de contenido",
"compose_form.spoiler_placeholder": "Escribe aquí tu advertencia", "compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)",
"confirmation_modal.cancel": "Cancelar", "confirmation_modal.cancel": "Cancelar",
"confirmations.block.block_and_report": "Bloquear y Reportar", "confirmations.block.block_and_report": "Bloquear y Reportar",
"confirmations.block.confirm": "Bloquear", "confirmations.block.confirm": "Bloquear",
@ -408,7 +406,6 @@
"navigation_bar.direct": "Menciones privadas", "navigation_bar.direct": "Menciones privadas",
"navigation_bar.discover": "Descubrir", "navigation_bar.discover": "Descubrir",
"navigation_bar.domain_blocks": "Dominios ocultos", "navigation_bar.domain_blocks": "Dominios ocultos",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.explore": "Explorar", "navigation_bar.explore": "Explorar",
"navigation_bar.favourites": "Favoritos", "navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Palabras silenciadas", "navigation_bar.filters": "Palabras silenciadas",
@ -526,14 +523,10 @@
"poll_button.add_poll": "Añadir una encuesta", "poll_button.add_poll": "Añadir una encuesta",
"poll_button.remove_poll": "Eliminar encuesta", "poll_button.remove_poll": "Eliminar encuesta",
"privacy.change": "Ajustar privacidad", "privacy.change": "Ajustar privacidad",
"privacy.direct.long": "Visible solo para usuarios mencionados", "privacy.direct.short": "Personas específicas",
"privacy.direct.short": "Sólo cuentas mencionadas", "privacy.private.long": "Solo tus seguidores",
"privacy.private.long": "Sólo mostrar a seguidores", "privacy.private.short": "Seguidores",
"privacy.private.short": "Solo seguidores",
"privacy.public.long": "Visible para todos",
"privacy.public.short": "Público", "privacy.public.short": "Público",
"privacy.unlisted.long": "Visible para todos, pero excluido de las funciones de descubrimiento",
"privacy.unlisted.short": "No listado",
"privacy_policy.last_updated": "Actualizado por última vez {date}", "privacy_policy.last_updated": "Actualizado por última vez {date}",
"privacy_policy.title": "Política de Privacidad", "privacy_policy.title": "Política de Privacidad",
"recommended": "Recomendado", "recommended": "Recomendado",
@ -715,10 +708,8 @@
"upload_error.poll": "No se permite la subida de archivos con encuestas.", "upload_error.poll": "No se permite la subida de archivos con encuestas.",
"upload_form.audio_description": "Describir para personas con problemas auditivos", "upload_form.audio_description": "Describir para personas con problemas auditivos",
"upload_form.description": "Describir para personas con discapacidad visual", "upload_form.description": "Describir para personas con discapacidad visual",
"upload_form.description_missing": "No se ha añadido ninguna descripción",
"upload_form.edit": "Editar", "upload_form.edit": "Editar",
"upload_form.thumbnail": "Cambiar miniatura", "upload_form.thumbnail": "Cambiar miniatura",
"upload_form.undo": "Eliminar",
"upload_form.video_description": "Describir para personas con problemas auditivos o visuales", "upload_form.video_description": "Describir para personas con problemas auditivos o visuales",
"upload_modal.analyzing_picture": "Analizando imagen…", "upload_modal.analyzing_picture": "Analizando imagen…",
"upload_modal.apply": "Aplicar", "upload_modal.apply": "Aplicar",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Teadaanne", "announcement.announcement": "Teadaanne",
"attachments_list.unprocessed": "(töötlemata)", "attachments_list.unprocessed": "(töötlemata)",
"audio.hide": "Peida audio", "audio.hide": "Peida audio",
"autosuggest_hashtag.per_week": "{count} nädalas",
"boost_modal.combo": "Vajutades {combo}, saab selle edaspidi vahele jätta", "boost_modal.combo": "Vajutades {combo}, saab selle edaspidi vahele jätta",
"bundle_column_error.copy_stacktrace": "Kopeeri veateade", "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.", "bundle_column_error.error.body": "Soovitud lehte ei õnnestunud esitada. See võib olla meie koodiviga või probleem brauseri ühilduvusega.",
@ -148,20 +147,20 @@
"compose_form.placeholder": "Millest mõtled?", "compose_form.placeholder": "Millest mõtled?",
"compose_form.poll.add_option": "Lisa valik", "compose_form.poll.add_option": "Lisa valik",
"compose_form.poll.duration": "Küsitluse kestus", "compose_form.poll.duration": "Küsitluse kestus",
"compose_form.poll.multiple": "Valikvastustega",
"compose_form.poll.option_placeholder": "Valik {number}", "compose_form.poll.option_placeholder": "Valik {number}",
"compose_form.poll.remove_option": "Eemalda see valik", "compose_form.poll.remove_option": "Eemalda see valik",
"compose_form.poll.single": "Vali üks",
"compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks", "compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks",
"compose_form.poll.switch_to_single": "Muuda küsitlust ainult ühe valiku lubamiseks", "compose_form.poll.switch_to_single": "Muuda küsitlust ainult ühe valiku lubamiseks",
"compose_form.poll.type": "Stiil",
"compose_form.publish": "Postita", "compose_form.publish": "Postita",
"compose_form.publish_form": "Postita", "compose_form.publish_form": "Postita",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Vasta",
"compose_form.save_changes": "Salvesta muudatused", "compose_form.save_changes": "Uuenda",
"compose_form.sensitive.hide": "{count, plural, one {Märgi meedia tundlikuks} other {Märgi meediad tundlikuks}}",
"compose_form.sensitive.marked": "{count, plural, one {Meedia on märgitud tundlikuks} other {Meediad on märgitud tundlikuks}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Meedia ei ole tundlikuks märgitud} other {Meediad ei ole märgitud tundlikuks}}",
"compose_form.spoiler.marked": "Tekst on hoiatuse taha peidetud", "compose_form.spoiler.marked": "Tekst on hoiatuse taha peidetud",
"compose_form.spoiler.unmarked": "Märgi sisu tundlikuks", "compose_form.spoiler.unmarked": "Märgi sisu tundlikuks",
"compose_form.spoiler_placeholder": "Kirjuta hoiatus siia", "compose_form.spoiler_placeholder": "Sisuhoiatus (valikuline)",
"confirmation_modal.cancel": "Katkesta", "confirmation_modal.cancel": "Katkesta",
"confirmations.block.block_and_report": "Blokeeri ja teata", "confirmations.block.block_and_report": "Blokeeri ja teata",
"confirmations.block.confirm": "Blokeeri", "confirmations.block.confirm": "Blokeeri",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Privaatsed mainimised", "navigation_bar.direct": "Privaatsed mainimised",
"navigation_bar.discover": "Avasta", "navigation_bar.discover": "Avasta",
"navigation_bar.domain_blocks": "Peidetud domeenid", "navigation_bar.domain_blocks": "Peidetud domeenid",
"navigation_bar.edit_profile": "Muuda profiili",
"navigation_bar.explore": "Avasta", "navigation_bar.explore": "Avasta",
"navigation_bar.favourites": "Lemmikud", "navigation_bar.favourites": "Lemmikud",
"navigation_bar.filters": "Vaigistatud sõnad", "navigation_bar.filters": "Vaigistatud sõnad",
@ -526,14 +524,14 @@
"poll_button.add_poll": "Lisa küsitlus", "poll_button.add_poll": "Lisa küsitlus",
"poll_button.remove_poll": "Eemalda küsitlus", "poll_button.remove_poll": "Eemalda küsitlus",
"privacy.change": "Muuda postituse nähtavust", "privacy.change": "Muuda postituse nähtavust",
"privacy.direct.long": "Postita ainult mainitud kasutajatele", "privacy.direct.long": "Kõik postituses mainitud",
"privacy.direct.short": "Mainitud inimesed ainult", "privacy.direct.short": "Määratud kasutajad",
"privacy.private.long": "Postita ainult jälgijatele", "privacy.private.long": "Ainult jälgijad",
"privacy.private.short": "Jälgijad ainult", "privacy.private.short": "Jälgijad",
"privacy.public.long": "Kõigile nähtav", "privacy.public.long": "Nii kasutajad kui mittekasutajad",
"privacy.public.short": "Avalik", "privacy.public.short": "Avalik",
"privacy.unlisted.long": "Kõigile nähtav, aga ei ilmu avastamise vaadetes", "privacy.unlisted.long": "Vähem algoritmilisi teavitusi",
"privacy.unlisted.short": "Määramata", "privacy.unlisted.short": "Vaikselt avalik",
"privacy_policy.last_updated": "Viimati uuendatud {date}", "privacy_policy.last_updated": "Viimati uuendatud {date}",
"privacy_policy.title": "Isikuandmete kaitse", "privacy_policy.title": "Isikuandmete kaitse",
"recommended": "Soovitatud", "recommended": "Soovitatud",
@ -551,7 +549,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "täna", "relative_time.today": "täna",
"reply_indicator.attachments": "{count, plural, one {# lisa} other {# lisa}}",
"reply_indicator.cancel": "Tühista", "reply_indicator.cancel": "Tühista",
"reply_indicator.poll": "Küsitlus",
"report.block": "Blokeeri", "report.block": "Blokeeri",
"report.block_explanation": "Sa ei näe tema postitusi. Tema ei saa näha sinu postitusi ega sind jälgida. Talle on näha, et ta on blokeeritud.", "report.block_explanation": "Sa ei näe tema postitusi. Tema ei saa näha sinu postitusi ega sind jälgida. Talle on näha, et ta on blokeeritud.",
"report.categories.legal": "Juriidiline", "report.categories.legal": "Juriidiline",
@ -715,10 +715,8 @@
"upload_error.poll": "Küsitlustes pole faili üleslaadimine lubatud.", "upload_error.poll": "Küsitlustes pole faili üleslaadimine lubatud.",
"upload_form.audio_description": "Kirjelda kuulmispuudega inimeste jaoks", "upload_form.audio_description": "Kirjelda kuulmispuudega inimeste jaoks",
"upload_form.description": "Kirjelda vaegnägijatele", "upload_form.description": "Kirjelda vaegnägijatele",
"upload_form.description_missing": "Kirjeldus puudub",
"upload_form.edit": "Muuda", "upload_form.edit": "Muuda",
"upload_form.thumbnail": "Muuda pisipilti", "upload_form.thumbnail": "Muuda pisipilti",
"upload_form.undo": "Kustuta",
"upload_form.video_description": "Kirjelda kuulmis- või nägemispuudega inimeste jaoks", "upload_form.video_description": "Kirjelda kuulmis- või nägemispuudega inimeste jaoks",
"upload_modal.analyzing_picture": "Analüüsime pilti…", "upload_modal.analyzing_picture": "Analüüsime pilti…",
"upload_modal.apply": "Rakenda", "upload_modal.apply": "Rakenda",

View file

@ -25,7 +25,7 @@
"account.direct": "Aipatu pribatuki @{name}", "account.direct": "Aipatu pribatuki @{name}",
"account.disable_notifications": "Utzi jakinarazteari @{name} erabiltzaileak argitaratzean", "account.disable_notifications": "Utzi jakinarazteari @{name} erabiltzaileak argitaratzean",
"account.domain_blocked": "Ezkutatutako domeinua", "account.domain_blocked": "Ezkutatutako domeinua",
"account.edit_profile": "Aldatu profila", "account.edit_profile": "Editatu profila",
"account.enable_notifications": "Jakinarazi @{name} erabiltzaileak argitaratzean", "account.enable_notifications": "Jakinarazi @{name} erabiltzaileak argitaratzean",
"account.endorse": "Nabarmendu profilean", "account.endorse": "Nabarmendu profilean",
"account.featured_tags.last_status_at": "Azken bidalketa {date} datan", "account.featured_tags.last_status_at": "Azken bidalketa {date} datan",
@ -89,7 +89,6 @@
"announcement.announcement": "Iragarpena", "announcement.announcement": "Iragarpena",
"attachments_list.unprocessed": "(prozesatu gabe)", "attachments_list.unprocessed": "(prozesatu gabe)",
"audio.hide": "Ezkutatu audioa", "audio.hide": "Ezkutatu audioa",
"autosuggest_hashtag.per_week": "{count} asteko",
"boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko", "boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko",
"bundle_column_error.copy_stacktrace": "Kopiatu errore-txostena", "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.", "bundle_column_error.error.body": "Eskatutako orria ezin izan da bistaratu. Kodeko errore bategatik izan daiteke edo nabigatzailearen bateragarritasun arazo bategatik.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren bidalketak ikusteko.", "compose_form.lock_disclaimer": "Zure kontua ez dago {locked}. Edonork jarraitu zaitzake zure jarraitzaileentzako soilik diren bidalketak ikusteko.",
"compose_form.lock_disclaimer.lock": "giltzapetuta", "compose_form.lock_disclaimer.lock": "giltzapetuta",
"compose_form.placeholder": "Zer duzu buruan?", "compose_form.placeholder": "Zer duzu buruan?",
"compose_form.poll.add_option": "Gehitu aukera bat", "compose_form.poll.add_option": "Gehitu aukera",
"compose_form.poll.duration": "Inkestaren iraupena", "compose_form.poll.duration": "Inkestaren iraupena",
"compose_form.poll.multiple": "Aukera aniza",
"compose_form.poll.option_placeholder": "{number}. aukera", "compose_form.poll.option_placeholder": "{number}. aukera",
"compose_form.poll.remove_option": "Kendu aukera hau", "compose_form.poll.remove_option": "Kendu aukera hau",
"compose_form.poll.single": "Hautatu bat",
"compose_form.poll.switch_to_multiple": "Aldatu inkesta hainbat aukera onartzeko", "compose_form.poll.switch_to_multiple": "Aldatu inkesta hainbat aukera onartzeko",
"compose_form.poll.switch_to_single": "Aldatu inkesta aukera bakarra onartzeko", "compose_form.poll.switch_to_single": "Aldatu inkesta aukera bakarra onartzeko",
"compose_form.poll.type": "Estiloa",
"compose_form.publish": "Argitaratu", "compose_form.publish": "Argitaratu",
"compose_form.publish_form": "Argitaratu", "compose_form.publish_form": "Argitaratu",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Erantzun",
"compose_form.save_changes": "Gorde aldaketak", "compose_form.save_changes": "Eguneratu",
"compose_form.sensitive.hide": "Markatu multimedia hunkigarri gisa",
"compose_form.sensitive.marked": "Multimedia edukia hunkigarri gisa markatu da",
"compose_form.sensitive.unmarked": "Multimedia edukia ez da hunkigarri gisa markatu",
"compose_form.spoiler.marked": "Testua abisu batek ezkutatzen du", "compose_form.spoiler.marked": "Testua abisu batek ezkutatzen du",
"compose_form.spoiler.unmarked": "Testua ez dago ezkutatuta", "compose_form.spoiler.unmarked": "Testua ez dago ezkutatuta",
"compose_form.spoiler_placeholder": "Idatzi zure abisua hemen", "compose_form.spoiler_placeholder": "Edukiaren abisua (aukerakoa)",
"confirmation_modal.cancel": "Utzi", "confirmation_modal.cancel": "Utzi",
"confirmations.block.block_and_report": "Blokeatu eta salatu", "confirmations.block.block_and_report": "Blokeatu eta salatu",
"confirmations.block.confirm": "Blokeatu", "confirmations.block.confirm": "Blokeatu",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Aipamen pribatuak", "navigation_bar.direct": "Aipamen pribatuak",
"navigation_bar.discover": "Aurkitu", "navigation_bar.discover": "Aurkitu",
"navigation_bar.domain_blocks": "Ezkutatutako domeinuak", "navigation_bar.domain_blocks": "Ezkutatutako domeinuak",
"navigation_bar.edit_profile": "Aldatu profila",
"navigation_bar.explore": "Arakatu", "navigation_bar.explore": "Arakatu",
"navigation_bar.favourites": "Gogokoak", "navigation_bar.favourites": "Gogokoak",
"navigation_bar.filters": "Mutututako hitzak", "navigation_bar.filters": "Mutututako hitzak",
@ -526,14 +524,15 @@
"poll_button.add_poll": "Gehitu inkesta bat", "poll_button.add_poll": "Gehitu inkesta bat",
"poll_button.remove_poll": "Kendu inkesta", "poll_button.remove_poll": "Kendu inkesta",
"privacy.change": "Aldatu bidalketaren pribatutasuna", "privacy.change": "Aldatu bidalketaren pribatutasuna",
"privacy.direct.long": "Bidali aipatutako erabiltzaileei besterik ez", "privacy.direct.long": "Argitalpen honetan aipatutako denak",
"privacy.direct.short": "Aipatutako jendea soilik", "privacy.direct.short": "Jende jakina",
"privacy.private.long": "Bidali jarraitzaileei besterik ez", "privacy.private.long": "Soilik jarraitzaileak",
"privacy.private.short": "Jarraitzaileak soilik", "privacy.private.short": "Jarraitzaileak",
"privacy.public.long": "Guztientzat ikusgai", "privacy.public.long": "Mastodonen dagoen edo ez dagoen edonor",
"privacy.public.short": "Publikoa", "privacy.public.short": "Publikoa",
"privacy.unlisted.long": "Guztientzat ikusgai, baina ez aurkitzeko ezaugarrietan", "privacy.unlisted.additional": "Aukera honek publiko modua bezala funtzionatzen du, baina argitalpena ez da agertuko zuzeneko jarioetan edo traoletan, \"Arakatu\" atalean edo Mastodonen bilaketan, nahiz eta kontua zabaltzeko onartu duzun.",
"privacy.unlisted.short": "Zerrendatu gabea", "privacy.unlisted.long": "Tontakeria algoritmiko gutxiago",
"privacy.unlisted.short": "Deiadar urrikoa",
"privacy_policy.last_updated": "Azkenengo eguneraketa {date}", "privacy_policy.last_updated": "Azkenengo eguneraketa {date}",
"privacy_policy.title": "Pribatutasun politika", "privacy_policy.title": "Pribatutasun politika",
"recommended": "Gomendatua", "recommended": "Gomendatua",
@ -551,7 +550,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "gaur", "relative_time.today": "gaur",
"reply_indicator.attachments": "{count, plural, one {# eranskin} other {# eranskin}}",
"reply_indicator.cancel": "Utzi", "reply_indicator.cancel": "Utzi",
"reply_indicator.poll": "Inkesta",
"report.block": "Blokeatu", "report.block": "Blokeatu",
"report.block_explanation": "Ez dituzu bere bidalketak ikusiko. Ezingo dituzte zure bidalketak ikusi eta ez jarraitu. Blokeatu dituzula jakin dezakete.", "report.block_explanation": "Ez dituzu bere bidalketak ikusiko. Ezingo dituzte zure bidalketak ikusi eta ez jarraitu. Blokeatu dituzula jakin dezakete.",
"report.categories.legal": "Juridikoa", "report.categories.legal": "Juridikoa",
@ -715,10 +716,8 @@
"upload_error.poll": "Ez da inkestetan fitxategiak igotzea onartzen.", "upload_error.poll": "Ez da inkestetan fitxategiak igotzea onartzen.",
"upload_form.audio_description": "Deskribatu entzumen galera duten pertsonentzat", "upload_form.audio_description": "Deskribatu entzumen galera duten pertsonentzat",
"upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat", "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat",
"upload_form.description_missing": "Ez da deskribapenik gehitu",
"upload_form.edit": "Editatu", "upload_form.edit": "Editatu",
"upload_form.thumbnail": "Aldatu koadro txikia", "upload_form.thumbnail": "Aldatu koadro txikia",
"upload_form.undo": "Ezabatu",
"upload_form.video_description": "Deskribatu entzumen galera edo ikusmen urritasuna duten pertsonentzat", "upload_form.video_description": "Deskribatu entzumen galera edo ikusmen urritasuna duten pertsonentzat",
"upload_modal.analyzing_picture": "Irudia aztertzen…", "upload_modal.analyzing_picture": "Irudia aztertzen…",
"upload_modal.apply": "Aplikatu", "upload_modal.apply": "Aplikatu",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "اعلامیه", "announcement.announcement": "اعلامیه",
"attachments_list.unprocessed": "(پردازش نشده)", "attachments_list.unprocessed": "(پردازش نشده)",
"audio.hide": "نهفتن صدا", "audio.hide": "نهفتن صدا",
"autosuggest_hashtag.per_week": "{count} در هفته",
"boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید", "boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید",
"bundle_column_error.copy_stacktrace": "رونوشت از گزارش خطا", "bundle_column_error.copy_stacktrace": "رونوشت از گزارش خطا",
"bundle_column_error.error.body": "صفحهٔ درخواستی نتوانست پرداخت شود. ممکن است به خاطر اشکالی در کدمان یا مشکل سازگاری مرورگر باشد.", "bundle_column_error.error.body": "صفحهٔ درخواستی نتوانست پرداخت شود. ممکن است به خاطر اشکالی در کدمان یا مشکل سازگاری مرورگر باشد.",
@ -148,20 +147,20 @@
"compose_form.placeholder": "تازه چه خبر؟", "compose_form.placeholder": "تازه چه خبر؟",
"compose_form.poll.add_option": "افزودن گزینه", "compose_form.poll.add_option": "افزودن گزینه",
"compose_form.poll.duration": "مدت نظرسنجی", "compose_form.poll.duration": "مدت نظرسنجی",
"compose_form.poll.multiple": "چند گزینه‌ای",
"compose_form.poll.option_placeholder": "گزینهٔ {number}", "compose_form.poll.option_placeholder": "گزینهٔ {number}",
"compose_form.poll.remove_option": "برداشتن این گزینه", "compose_form.poll.remove_option": "برداشتن این گزینه",
"compose_form.poll.single": "گزینش یکی",
"compose_form.poll.switch_to_multiple": "تغییر نظرسنجی برای اجازه به چندین گزینه", "compose_form.poll.switch_to_multiple": "تغییر نظرسنجی برای اجازه به چندین گزینه",
"compose_form.poll.switch_to_single": "تبدیل به نظرسنجی تک‌گزینه‌ای", "compose_form.poll.switch_to_single": "تبدیل به نظرسنجی تک‌گزینه‌ای",
"compose_form.publish": "انتشار", "compose_form.poll.type": "سبک",
"compose_form.publish": "فرستادن",
"compose_form.publish_form": "انتشار", "compose_form.publish_form": "انتشار",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "پاسخ",
"compose_form.save_changes": "ذخیرهٔ تغییرات", "compose_form.save_changes": "به‌روز رسانی",
"compose_form.sensitive.hide": "{count, plural, one {علامت‌گذاری رسانه به عنوان حساس} other {علامت‌گذاری رسانه‌ها به عنوان حساس}}",
"compose_form.sensitive.marked": "{count, plural, one {رسانه به عنوان حساس علامت‌گذاری شد} other {رسانه‌ها به عنوان حساس علامت‌گذاری شدند}}",
"compose_form.sensitive.unmarked": "{count, plural, one {رسانه به عنوان حساس علامت‌گذاری نشد} other {رسانه‌ها به عنوان حساس علامت‌گذاری نشدند}}",
"compose_form.spoiler.marked": "برداشتن هشدار محتوا", "compose_form.spoiler.marked": "برداشتن هشدار محتوا",
"compose_form.spoiler.unmarked": "افزودن هشدار محتوا", "compose_form.spoiler.unmarked": "افزودن هشدار محتوا",
"compose_form.spoiler_placeholder": "هشدارتان را این‌جا بنویسید", "compose_form.spoiler_placeholder": "هشدار محتوا (اختیاری)",
"confirmation_modal.cancel": "لغو", "confirmation_modal.cancel": "لغو",
"confirmations.block.block_and_report": "انسداد و گزارش", "confirmations.block.block_and_report": "انسداد و گزارش",
"confirmations.block.confirm": "انسداد", "confirmations.block.confirm": "انسداد",
@ -408,7 +407,6 @@
"navigation_bar.direct": "اشاره‌های خصوصی", "navigation_bar.direct": "اشاره‌های خصوصی",
"navigation_bar.discover": "گشت و گذار", "navigation_bar.discover": "گشت و گذار",
"navigation_bar.domain_blocks": "دامنه‌های مسدود شده", "navigation_bar.domain_blocks": "دامنه‌های مسدود شده",
"navigation_bar.edit_profile": "ویرایش نمایه",
"navigation_bar.explore": "کاوش", "navigation_bar.explore": "کاوش",
"navigation_bar.favourites": "برگزیده‌ها", "navigation_bar.favourites": "برگزیده‌ها",
"navigation_bar.filters": "واژه‌های خموش", "navigation_bar.filters": "واژه‌های خموش",
@ -524,14 +522,14 @@
"poll_button.add_poll": "افزودن نظرسنجی", "poll_button.add_poll": "افزودن نظرسنجی",
"poll_button.remove_poll": "برداشتن نظرسنجی", "poll_button.remove_poll": "برداشتن نظرسنجی",
"privacy.change": "تغییر محرمانگی فرسته", "privacy.change": "تغییر محرمانگی فرسته",
"privacy.direct.long": "نمایان فقط برای کاربران اشاره شده", "privacy.direct.long": "هرکسی که در فرسته نام برده شده",
"privacy.direct.short": "فقط افراد اشاره شده", "privacy.direct.short": "افراد مشخّص",
"privacy.private.long": "نمایان فقط برای پی‌گیرندگان", "privacy.private.long": "تنها پی‌گیرندگانتان",
"privacy.private.short": "فقط پی‌گیرندگان", "privacy.private.short": "پی‌گیرندگان",
"privacy.public.long": "نمایان برای همه", "privacy.public.long": "هرکسی در و بیرون از ماستودون",
"privacy.public.short": "عمومی", "privacy.public.short": "عمومی",
"privacy.unlisted.long": "نمایان برای همه، ولی خارج از قابلیت‌های کشف", "privacy.unlisted.long": "سروصدای الگوریتمی کم‌تر",
"privacy.unlisted.short": "فهرست نشده", "privacy.unlisted.short": "عمومی ساکت",
"privacy_policy.last_updated": "آخرین به‌روز رسانی در {date}", "privacy_policy.last_updated": "آخرین به‌روز رسانی در {date}",
"privacy_policy.title": "سیاست محرمانگی", "privacy_policy.title": "سیاست محرمانگی",
"recommended": "پیشنهادشده", "recommended": "پیشنهادشده",
@ -550,6 +548,7 @@
"relative_time.seconds": "{number} ثانیه", "relative_time.seconds": "{number} ثانیه",
"relative_time.today": "امروز", "relative_time.today": "امروز",
"reply_indicator.cancel": "لغو", "reply_indicator.cancel": "لغو",
"reply_indicator.poll": "نظرسنجی",
"report.block": "انسداد", "report.block": "انسداد",
"report.block_explanation": "شما فرسته‌هایشان را نخواهید دید. آن‌ها نمی‌توانند فرسته‌هایتان را ببینند یا شما را پی‌بگیرند. آنها می‌توانند بگویند که مسدود شده‌اند.", "report.block_explanation": "شما فرسته‌هایشان را نخواهید دید. آن‌ها نمی‌توانند فرسته‌هایتان را ببینند یا شما را پی‌بگیرند. آنها می‌توانند بگویند که مسدود شده‌اند.",
"report.categories.legal": "حقوقی", "report.categories.legal": "حقوقی",
@ -713,10 +712,8 @@
"upload_error.poll": "بارگذاری پرونده در نظرسنجی‌ها مجاز نیست.", "upload_error.poll": "بارگذاری پرونده در نظرسنجی‌ها مجاز نیست.",
"upload_form.audio_description": "برای ناشنوایان توصیفش کنید", "upload_form.audio_description": "برای ناشنوایان توصیفش کنید",
"upload_form.description": "برای کم‌بینایان توصیفش کنید", "upload_form.description": "برای کم‌بینایان توصیفش کنید",
"upload_form.description_missing": "شرحی افزوده نشده",
"upload_form.edit": "ویرایش", "upload_form.edit": "ویرایش",
"upload_form.thumbnail": "تغییر بندانگشتی", "upload_form.thumbnail": "تغییر بندانگشتی",
"upload_form.undo": "حذف",
"upload_form.video_description": "برای کم‌بینایان یا ناشنوایان توصیفش کنید", "upload_form.video_description": "برای کم‌بینایان یا ناشنوایان توصیفش کنید",
"upload_modal.analyzing_picture": "در حال پردازش تصویر…", "upload_modal.analyzing_picture": "در حال پردازش تصویر…",
"upload_modal.apply": "اعمال", "upload_modal.apply": "اعمال",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Ilmoitus", "announcement.announcement": "Ilmoitus",
"attachments_list.unprocessed": "(käsittelemätön)", "attachments_list.unprocessed": "(käsittelemätön)",
"audio.hide": "Piilota ääni", "audio.hide": "Piilota ääni",
"autosuggest_hashtag.per_week": "{count} viikossa",
"boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}", "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}",
"bundle_column_error.copy_stacktrace": "Kopioi virheraportti", "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.", "bundle_column_error.error.body": "Pyydettyä sivua ei voitu hahmontaa. Se voi johtua virheestä koodissamme tai selaimen yhteensopivuudessa.",
@ -146,22 +145,22 @@
"compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.", "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.",
"compose_form.lock_disclaimer.lock": "lukittu", "compose_form.lock_disclaimer.lock": "lukittu",
"compose_form.placeholder": "Mitä mietit?", "compose_form.placeholder": "Mitä mietit?",
"compose_form.poll.add_option": "Lisää valinta", "compose_form.poll.add_option": "Lisää vaihtoehto",
"compose_form.poll.duration": "Äänestyksen kesto", "compose_form.poll.duration": "Äänestyksen kesto",
"compose_form.poll.option_placeholder": "Valinta {number}", "compose_form.poll.multiple": "Monivalinta",
"compose_form.poll.remove_option": "Poista tämä valinta", "compose_form.poll.option_placeholder": "Vaihtoehto {number}",
"compose_form.poll.remove_option": "Poista tämä vaihtoehto",
"compose_form.poll.single": "Valitse yksi",
"compose_form.poll.switch_to_multiple": "Muuta äänestys monivalinnaksi", "compose_form.poll.switch_to_multiple": "Muuta äänestys monivalinnaksi",
"compose_form.poll.switch_to_single": "Muuta äänestys sallimaan vain yksi valinta", "compose_form.poll.switch_to_single": "Muuta äänestys sallimaan vain yksi valinta",
"compose_form.poll.type": "Tyyli",
"compose_form.publish": "Julkaise", "compose_form.publish": "Julkaise",
"compose_form.publish_form": "Uusi julkaisu", "compose_form.publish_form": "Uusi julkaisu",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Vastaa",
"compose_form.save_changes": "Tallenna muutokset", "compose_form.save_changes": "Päivitä",
"compose_form.sensitive.hide": "{count, plural, one {Merkitse media arkaluonteiseksi} other {Merkitse mediat arkaluonteisiksi}}",
"compose_form.sensitive.marked": "{count, plural, one {Media on merkitty arkaluonteiseksi} other {Mediat on merkitty arkaluonteisiksi}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Mediaa ei ole merkitty arkaluonteiseksi} other {Medioita ei ole merkitty arkaluonteisiksi}}",
"compose_form.spoiler.marked": "Poista sisältövaroitus", "compose_form.spoiler.marked": "Poista sisältövaroitus",
"compose_form.spoiler.unmarked": "Lisää sisältövaroitus", "compose_form.spoiler.unmarked": "Lisää sisältövaroitus",
"compose_form.spoiler_placeholder": "Kirjoita varoituksesi tähän", "compose_form.spoiler_placeholder": "Sisältövaroitus (valinnainen)",
"confirmation_modal.cancel": "Peruuta", "confirmation_modal.cancel": "Peruuta",
"confirmations.block.block_and_report": "Estä ja raportoi", "confirmations.block.block_and_report": "Estä ja raportoi",
"confirmations.block.confirm": "Estä", "confirmations.block.confirm": "Estä",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Yksityiset maininnat", "navigation_bar.direct": "Yksityiset maininnat",
"navigation_bar.discover": "Löydä uutta", "navigation_bar.discover": "Löydä uutta",
"navigation_bar.domain_blocks": "Estetyt verkkotunnukset", "navigation_bar.domain_blocks": "Estetyt verkkotunnukset",
"navigation_bar.edit_profile": "Muokkaa profiilia",
"navigation_bar.explore": "Selaa", "navigation_bar.explore": "Selaa",
"navigation_bar.favourites": "Suosikit", "navigation_bar.favourites": "Suosikit",
"navigation_bar.filters": "Mykistetyt sanat", "navigation_bar.filters": "Mykistetyt sanat",
@ -526,14 +524,13 @@
"poll_button.add_poll": "Lisää äänestys", "poll_button.add_poll": "Lisää äänestys",
"poll_button.remove_poll": "Poista äänestys", "poll_button.remove_poll": "Poista äänestys",
"privacy.change": "Muuta julkaisun näkyvyyttä", "privacy.change": "Muuta julkaisun näkyvyyttä",
"privacy.direct.long": "Näkyy vain mainituille käyttäjille", "privacy.direct.long": "Kaikki tässä julkaisussa mainitut",
"privacy.direct.short": "Vain mainitut käyttäjät", "privacy.direct.short": "Tietyt henkilöt",
"privacy.private.long": "Näkyy vain seuraajille", "privacy.private.long": "Vain seuraajasi",
"privacy.private.short": "Vain seuraajat", "privacy.private.short": "Seuraajat",
"privacy.public.long": "Näkyy kaikille", "privacy.public.long": "Kuka tahansa Mastodonissa ja sen ulkopuolella",
"privacy.public.short": "Julkinen", "privacy.public.short": "Julkinen",
"privacy.unlisted.long": "Näkyy kaikille mutta jää pois löytämisominaisuuksista", "privacy.unlisted.additional": "Tämä toimii kuten julkinen, paitsi että julkaisu ei näy livesyötteissä, aihetunnisteissa, selaa-näkymässä tai Mastodon-haussa, vaikka olisit sallinut ne käyttäjätilin laajuisesti.",
"privacy.unlisted.short": "Listaamaton",
"privacy_policy.last_updated": "Viimeksi päivitetty {date}", "privacy_policy.last_updated": "Viimeksi päivitetty {date}",
"privacy_policy.title": "Tietosuojakäytäntö", "privacy_policy.title": "Tietosuojakäytäntö",
"recommended": "Suositeltu", "recommended": "Suositeltu",
@ -551,7 +548,9 @@
"relative_time.minutes": "{number} min", "relative_time.minutes": "{number} min",
"relative_time.seconds": "{number} s", "relative_time.seconds": "{number} s",
"relative_time.today": "tänään", "relative_time.today": "tänään",
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
"reply_indicator.cancel": "Peruuta", "reply_indicator.cancel": "Peruuta",
"reply_indicator.poll": "Kysely",
"report.block": "Estä", "report.block": "Estä",
"report.block_explanation": "Et näe hänen viestejään, eikä hän voi nähdä viestejäsi tai seurata sinua. Hän näkee, että olet estänyt hänet.", "report.block_explanation": "Et näe hänen viestejään, eikä hän voi nähdä viestejäsi tai seurata sinua. Hän näkee, että olet estänyt hänet.",
"report.categories.legal": "Lakiasiat", "report.categories.legal": "Lakiasiat",
@ -715,10 +714,8 @@
"upload_error.poll": "Tiedoston lataaminen ei ole sallittua äänestyksissä.", "upload_error.poll": "Tiedoston lataaminen ei ole sallittua äänestyksissä.",
"upload_form.audio_description": "Kuvaile sisältöä kuuroille ja kuulorajoitteisille", "upload_form.audio_description": "Kuvaile sisältöä kuuroille ja kuulorajoitteisille",
"upload_form.description": "Kuvaile sisältöä sokeille ja näkörajoitteisille", "upload_form.description": "Kuvaile sisältöä sokeille ja näkörajoitteisille",
"upload_form.description_missing": "Kuvausta ei ole lisätty",
"upload_form.edit": "Muokkaa", "upload_form.edit": "Muokkaa",
"upload_form.thumbnail": "Vaihda pikkukuva", "upload_form.thumbnail": "Vaihda pikkukuva",
"upload_form.undo": "Poista",
"upload_form.video_description": "Kuvaile sisältöä kuuroille, kuulorajoitteisille, sokeille tai näkörajoitteisille", "upload_form.video_description": "Kuvaile sisältöä kuuroille, kuulorajoitteisille, sokeille tai näkörajoitteisille",
"upload_modal.analyzing_picture": "Analysoidaan kuvaa…", "upload_modal.analyzing_picture": "Analysoidaan kuvaa…",
"upload_modal.apply": "Käytä", "upload_modal.apply": "Käytä",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Kunngerð", "announcement.announcement": "Kunngerð",
"attachments_list.unprocessed": "(óviðgjørt)", "attachments_list.unprocessed": "(óviðgjørt)",
"audio.hide": "Fjal ljóð", "audio.hide": "Fjal ljóð",
"autosuggest_hashtag.per_week": "{count} um vikuna",
"boost_modal.combo": "Tú kanst trýsta á {combo} fyri at loypa uppum hetta næstu ferð", "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.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.", "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.",
@ -148,20 +147,20 @@
"compose_form.placeholder": "Hvat hevur tú í huga?", "compose_form.placeholder": "Hvat hevur tú í huga?",
"compose_form.poll.add_option": "Legg valmøguleika afturat", "compose_form.poll.add_option": "Legg valmøguleika afturat",
"compose_form.poll.duration": "Atkvøðugreiðslutíð", "compose_form.poll.duration": "Atkvøðugreiðslutíð",
"compose_form.poll.multiple": "Fleiri valmøguleikar",
"compose_form.poll.option_placeholder": "Valmøguleiki {number}", "compose_form.poll.option_placeholder": "Valmøguleiki {number}",
"compose_form.poll.remove_option": "Strika valmøguleikan", "compose_form.poll.remove_option": "Strika hendan valmøguleikan",
"compose_form.poll.single": "Vel ein",
"compose_form.poll.switch_to_multiple": "Broyt atkvøðugreiðslu til at loyva fleiri svarum", "compose_form.poll.switch_to_multiple": "Broyt atkvøðugreiðslu til at loyva fleiri svarum",
"compose_form.poll.switch_to_single": "Broyt atkvøðugreiðslu til einstakt svar", "compose_form.poll.switch_to_single": "Broyt atkvøðugreiðslu til einstakt svar",
"compose_form.publish": "Legg út", "compose_form.poll.type": "Stílur",
"compose_form.publish": "Posta",
"compose_form.publish_form": "Legg út", "compose_form.publish_form": "Legg út",
"compose_form.publish_loud": "{publish}!", "compose_form.reply": "Svara",
"compose_form.save_changes": "Goym broytingar", "compose_form.save_changes": "Dagfør",
"compose_form.sensitive.hide": "{count, plural, one {Frámerk tilfar sum viðkvæmt} other {Frámerk tilfar sum viðkvæmt}}",
"compose_form.sensitive.marked": "{count, plural, one {Tilfarið er frámerkt sum viðkvæmt} other {Tilfarið er frámerkt sum viðkvæmt}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Tilfarið er ikki merkt sum viðkvæmt} other {Tilfarið er ikki merkt sum viðkvæmt}}",
"compose_form.spoiler.marked": "Ávaring um at strika innihald", "compose_form.spoiler.marked": "Ávaring um at strika innihald",
"compose_form.spoiler.unmarked": "Skriva ávaring um innihald", "compose_form.spoiler.unmarked": "Skriva ávaring um innihald",
"compose_form.spoiler_placeholder": "Skriva tína ávaring her", "compose_form.spoiler_placeholder": "Innihaldsávaring (valfrí)",
"confirmation_modal.cancel": "Strika", "confirmation_modal.cancel": "Strika",
"confirmations.block.block_and_report": "Banna og melda", "confirmations.block.block_and_report": "Banna og melda",
"confirmations.block.confirm": "Banna", "confirmations.block.confirm": "Banna",
@ -408,7 +407,6 @@
"navigation_bar.direct": "Privatar umrøður", "navigation_bar.direct": "Privatar umrøður",
"navigation_bar.discover": "Uppdaga", "navigation_bar.discover": "Uppdaga",
"navigation_bar.domain_blocks": "Bannað økisnøvn", "navigation_bar.domain_blocks": "Bannað økisnøvn",
"navigation_bar.edit_profile": "Broyt vanga",
"navigation_bar.explore": "Rannsaka", "navigation_bar.explore": "Rannsaka",
"navigation_bar.favourites": "Dámdir postar", "navigation_bar.favourites": "Dámdir postar",
"navigation_bar.filters": "Doyvd orð", "navigation_bar.filters": "Doyvd orð",
@ -526,14 +524,15 @@
"poll_button.add_poll": "Legg atkvøðugreiðslu afturat", "poll_button.add_poll": "Legg atkvøðugreiðslu afturat",
"poll_button.remove_poll": "Strika atkvøðugreiðslu", "poll_button.remove_poll": "Strika atkvøðugreiðslu",
"privacy.change": "Broyt privatverju av posti", "privacy.change": "Broyt privatverju av posti",
"privacy.direct.long": "Bert sjónligt hjá nevndum brúkarum", "privacy.direct.long": "Øll, sum eru nevnd í postinum",
"privacy.direct.short": "Bert nevnd fólk", "privacy.direct.short": "Ávís fólk",
"privacy.private.long": "Bert sjónligt hjá fylgjarum", "privacy.private.long": "Einans tey, ið fylgja tær",
"privacy.private.short": "Einans fylgjarar", "privacy.private.short": "Fylgjarar",
"privacy.public.long": "Sjónligt hjá øllum", "privacy.public.long": "Øll í og uttanfyri Mastodon",
"privacy.public.short": "Alment", "privacy.public.short": "Alment",
"privacy.unlisted.long": "Sjónligur fyri øll, men ikki gjøgnum uppdagingarhentleikarnar", "privacy.unlisted.additional": "Hetta er júst sum almenn, tó verður posturin ikki vístur í samtíðarrásum ella frámerkjum, rannsakan ella Mastodon leitingum, sjálvt um valið er galdandi fyri alla kontuna.",
"privacy.unlisted.short": "Ikki listað", "privacy.unlisted.long": "Færri algoritmiskar fanfarur",
"privacy.unlisted.short": "Stillur almenningur",
"privacy_policy.last_updated": "Seinast dagført {date}", "privacy_policy.last_updated": "Seinast dagført {date}",
"privacy_policy.title": "Privatlívspolitikkur", "privacy_policy.title": "Privatlívspolitikkur",
"recommended": "Viðmælt", "recommended": "Viðmælt",
@ -551,7 +550,9 @@
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"relative_time.today": "í dag", "relative_time.today": "í dag",
"reply_indicator.attachments": "{count, plural, one {# viðfesti} other {# viðfesti}}",
"reply_indicator.cancel": "Ógilda", "reply_indicator.cancel": "Ógilda",
"reply_indicator.poll": "Atkvøðugreiðsla",
"report.block": "Blokera", "report.block": "Blokera",
"report.block_explanation": "Tú fer ikki at síggja postarnar hjá teimum. Tey kunnu ikki síggja tínar postar ella fylgja tær. Tey síggja, at tey eru blokeraði.", "report.block_explanation": "Tú fer ikki at síggja postarnar hjá teimum. Tey kunnu ikki síggja tínar postar ella fylgja tær. Tey síggja, at tey eru blokeraði.",
"report.categories.legal": "Løgfrøðisligt", "report.categories.legal": "Løgfrøðisligt",
@ -715,10 +716,8 @@
"upload_error.poll": "Ikki loyvt at leggja fílur upp í spurnarkanningum.", "upload_error.poll": "Ikki loyvt at leggja fílur upp í spurnarkanningum.",
"upload_form.audio_description": "Lýs fyri teimum, sum eru deyv ella hava ringa hoyrn", "upload_form.audio_description": "Lýs fyri teimum, sum eru deyv ella hava ringa hoyrn",
"upload_form.description": "Lýs fyri teimum, sum eru blind ella eru sjónveik", "upload_form.description": "Lýs fyri teimum, sum eru blind ella eru sjónveik",
"upload_form.description_missing": "Lýsing vantar",
"upload_form.edit": "Rætta", "upload_form.edit": "Rætta",
"upload_form.thumbnail": "Broyt smámynd", "upload_form.thumbnail": "Broyt smámynd",
"upload_form.undo": "Strika",
"upload_form.video_description": "Lýs fyri teimum, sum eru deyv, hava ringa hoyrn, eru blind ella eru sjónveik", "upload_form.video_description": "Lýs fyri teimum, sum eru deyv, hava ringa hoyrn, eru blind ella eru sjónveik",
"upload_modal.analyzing_picture": "Greini mynd…", "upload_modal.analyzing_picture": "Greini mynd…",
"upload_modal.apply": "Ger virkið", "upload_modal.apply": "Ger virkið",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Annonce", "announcement.announcement": "Annonce",
"attachments_list.unprocessed": "(non traité)", "attachments_list.unprocessed": "(non traité)",
"audio.hide": "Masquer l'audio", "audio.hide": "Masquer l'audio",
"autosuggest_hashtag.per_week": "{count} par semaine",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour sauter ceci la prochaine fois", "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.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.", "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.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre et voir vos publications privés.", "compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre et voir vos publications privés.",
"compose_form.lock_disclaimer.lock": "verrouillé", "compose_form.lock_disclaimer.lock": "verrouillé",
"compose_form.placeholder": "À quoi pensez-vous?", "compose_form.placeholder": "À quoi pensez-vous?",
"compose_form.poll.add_option": "Ajouter un choix",
"compose_form.poll.duration": "Durée du sondage", "compose_form.poll.duration": "Durée du sondage",
"compose_form.poll.option_placeholder": "Choix {number}",
"compose_form.poll.remove_option": "Supprimer ce choix",
"compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "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.switch_to_single": "Changer le sondage pour n'autoriser qu'un seul choix",
"compose_form.publish": "Publier",
"compose_form.publish_form": "Publier", "compose_form.publish_form": "Publier",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Enregistrer les modifications",
"compose_form.sensitive.hide": "{count, plural, one {Marquer média comme sensible} other {Marquer médias comme sensibles}}",
"compose_form.sensitive.marked": "{count, plural, one {Le média est marqué comme sensible} other {Les médias sont marqués comme sensibles}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Le média nest pas marqué comme sensible} other {Les médias ne sont pas marqués comme sensibles}}",
"compose_form.spoiler.marked": "Enlever l'avertissement de contenu", "compose_form.spoiler.marked": "Enlever l'avertissement de contenu",
"compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu", "compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu",
"compose_form.spoiler_placeholder": "Écrivez votre avertissement ici",
"confirmation_modal.cancel": "Annuler", "confirmation_modal.cancel": "Annuler",
"confirmations.block.block_and_report": "Bloquer et signaler", "confirmations.block.block_and_report": "Bloquer et signaler",
"confirmations.block.confirm": "Bloquer", "confirmations.block.confirm": "Bloquer",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Mention privée", "navigation_bar.direct": "Mention privée",
"navigation_bar.discover": "Découvrir", "navigation_bar.discover": "Découvrir",
"navigation_bar.domain_blocks": "Domaines bloqués", "navigation_bar.domain_blocks": "Domaines bloqués",
"navigation_bar.edit_profile": "Modifier le profil",
"navigation_bar.explore": "Explorer", "navigation_bar.explore": "Explorer",
"navigation_bar.favourites": "Favoris", "navigation_bar.favourites": "Favoris",
"navigation_bar.filters": "Mots masqués", "navigation_bar.filters": "Mots masqués",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Ajouter un sondage", "poll_button.add_poll": "Ajouter un sondage",
"poll_button.remove_poll": "Supprimer le sondage", "poll_button.remove_poll": "Supprimer le sondage",
"privacy.change": "Changer la confidentialité des messages", "privacy.change": "Changer la confidentialité des messages",
"privacy.direct.long": "Visible uniquement par les comptes mentionnés",
"privacy.direct.short": "Personnes mentionnées uniquement",
"privacy.private.long": "Visible uniquement pour vos abonné·e·s",
"privacy.private.short": "Abonné·e·s seulement",
"privacy.public.long": "Visible pour tous",
"privacy.public.short": "Public", "privacy.public.short": "Public",
"privacy.unlisted.long": "Visible pour tous, mais sans fonctionnalités de découverte",
"privacy.unlisted.short": "Non listé",
"privacy_policy.last_updated": "Dernière mise à jour {date}", "privacy_policy.last_updated": "Dernière mise à jour {date}",
"privacy_policy.title": "Politique de confidentialité", "privacy_policy.title": "Politique de confidentialité",
"recommended": "Recommandé", "recommended": "Recommandé",
@ -715,10 +696,8 @@
"upload_error.poll": "Lenvoi de fichiers nest pas autorisé avec les sondages.", "upload_error.poll": "Lenvoi de fichiers nest pas autorisé avec les sondages.",
"upload_form.audio_description": "Décrire pour les personnes ayant des difficultés daudition", "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés daudition",
"upload_form.description": "Décrire pour les malvoyants", "upload_form.description": "Décrire pour les malvoyants",
"upload_form.description_missing": "Description manquante",
"upload_form.edit": "Modifier", "upload_form.edit": "Modifier",
"upload_form.thumbnail": "Changer la vignette", "upload_form.thumbnail": "Changer la vignette",
"upload_form.undo": "Supprimer",
"upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition", "upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition",
"upload_modal.analyzing_picture": "Analyse de limage en cours…", "upload_modal.analyzing_picture": "Analyse de limage en cours…",
"upload_modal.apply": "Appliquer", "upload_modal.apply": "Appliquer",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Annonce", "announcement.announcement": "Annonce",
"attachments_list.unprocessed": "(non traité)", "attachments_list.unprocessed": "(non traité)",
"audio.hide": "Masquer l'audio", "audio.hide": "Masquer l'audio",
"autosuggest_hashtag.per_week": "{count} par semaine",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois", "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.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.", "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.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre pour voir vos messages réservés à vos abonné⋅e⋅s.", "compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre pour voir vos messages réservés à vos abonné⋅e⋅s.",
"compose_form.lock_disclaimer.lock": "verrouillé", "compose_form.lock_disclaimer.lock": "verrouillé",
"compose_form.placeholder": "Quavez-vous en tête?", "compose_form.placeholder": "Quavez-vous en tête?",
"compose_form.poll.add_option": "Ajouter un choix",
"compose_form.poll.duration": "Durée du sondage", "compose_form.poll.duration": "Durée du sondage",
"compose_form.poll.option_placeholder": "Choix {number}",
"compose_form.poll.remove_option": "Supprimer ce choix",
"compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix", "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.switch_to_single": "Modifier le sondage pour autoriser qu'un seul choix",
"compose_form.publish": "Publier",
"compose_form.publish_form": "Nouvelle publication", "compose_form.publish_form": "Nouvelle publication",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Enregistrer les modifications",
"compose_form.sensitive.hide": "{count, plural, one {Marquer le média comme sensible} other {Marquer les médias comme sensibles}}",
"compose_form.sensitive.marked": "{count, plural, one {Le média est marqué comme sensible} other {Les médias sont marqués comme sensibles}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Le média nest pas marqué comme sensible} other {Les médias ne sont pas marqués comme sensibles}}",
"compose_form.spoiler.marked": "Enlever lavertissement de contenu", "compose_form.spoiler.marked": "Enlever lavertissement de contenu",
"compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu", "compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu",
"compose_form.spoiler_placeholder": "Écrivez votre avertissement ici",
"confirmation_modal.cancel": "Annuler", "confirmation_modal.cancel": "Annuler",
"confirmations.block.block_and_report": "Bloquer et signaler", "confirmations.block.block_and_report": "Bloquer et signaler",
"confirmations.block.confirm": "Bloquer", "confirmations.block.confirm": "Bloquer",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Mention privée", "navigation_bar.direct": "Mention privée",
"navigation_bar.discover": "Découvrir", "navigation_bar.discover": "Découvrir",
"navigation_bar.domain_blocks": "Domaines bloqués", "navigation_bar.domain_blocks": "Domaines bloqués",
"navigation_bar.edit_profile": "Modifier le profil",
"navigation_bar.explore": "Explorer", "navigation_bar.explore": "Explorer",
"navigation_bar.favourites": "Favoris", "navigation_bar.favourites": "Favoris",
"navigation_bar.filters": "Mots masqués", "navigation_bar.filters": "Mots masqués",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Ajouter un sondage", "poll_button.add_poll": "Ajouter un sondage",
"poll_button.remove_poll": "Supprimer le sondage", "poll_button.remove_poll": "Supprimer le sondage",
"privacy.change": "Ajuster la confidentialité du message", "privacy.change": "Ajuster la confidentialité du message",
"privacy.direct.long": "Visible uniquement par les comptes mentionnés",
"privacy.direct.short": "Personnes mentionnées uniquement",
"privacy.private.long": "Visible uniquement par vos abonnés",
"privacy.private.short": "Abonnés uniquement",
"privacy.public.long": "Visible pour tous",
"privacy.public.short": "Public", "privacy.public.short": "Public",
"privacy.unlisted.long": "Visible pour tous, mais sans fonctionnalités de découverte",
"privacy.unlisted.short": "Non listé",
"privacy_policy.last_updated": "Dernière mise à jour {date}", "privacy_policy.last_updated": "Dernière mise à jour {date}",
"privacy_policy.title": "Politique de confidentialité", "privacy_policy.title": "Politique de confidentialité",
"recommended": "Recommandé", "recommended": "Recommandé",
@ -715,10 +696,8 @@
"upload_error.poll": "Lenvoi de fichiers nest pas autorisé avec les sondages.", "upload_error.poll": "Lenvoi de fichiers nest pas autorisé avec les sondages.",
"upload_form.audio_description": "Décrire pour les personnes ayant des difficultés daudition", "upload_form.audio_description": "Décrire pour les personnes ayant des difficultés daudition",
"upload_form.description": "Décrire pour les malvoyant·e·s", "upload_form.description": "Décrire pour les malvoyant·e·s",
"upload_form.description_missing": "Description manquante",
"upload_form.edit": "Modifier", "upload_form.edit": "Modifier",
"upload_form.thumbnail": "Changer la vignette", "upload_form.thumbnail": "Changer la vignette",
"upload_form.undo": "Supprimer",
"upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition", "upload_form.video_description": "Décrire pour les personnes ayant des problèmes de vue ou d'audition",
"upload_modal.analyzing_picture": "Analyse de limage en cours…", "upload_modal.analyzing_picture": "Analyse de limage en cours…",
"upload_modal.apply": "Appliquer", "upload_modal.apply": "Appliquer",

View file

@ -89,7 +89,6 @@
"announcement.announcement": "Oankundiging", "announcement.announcement": "Oankundiging",
"attachments_list.unprocessed": "(net ferwurke)", "attachments_list.unprocessed": "(net ferwurke)",
"audio.hide": "Audio ferstopje", "audio.hide": "Audio ferstopje",
"autosuggest_hashtag.per_week": "{count} yn e wike",
"boost_modal.combo": "Jo kinne op {combo} drukke om dit de folgjende kear oer te slaan", "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.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.", "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.",
@ -146,22 +145,12 @@
"compose_form.lock_disclaimer": "Jo account is net {locked}. Elkenien kin jo folgje en kin de berjochten sjen dyt jo allinnich oan jo folgers rjochte hawwe.", "compose_form.lock_disclaimer": "Jo account is net {locked}. Elkenien kin jo folgje en kin de berjochten sjen dyt jo allinnich oan jo folgers rjochte hawwe.",
"compose_form.lock_disclaimer.lock": "beskoattele", "compose_form.lock_disclaimer.lock": "beskoattele",
"compose_form.placeholder": "Wat wolle jo kwyt?", "compose_form.placeholder": "Wat wolle jo kwyt?",
"compose_form.poll.add_option": "Kar tafoegje",
"compose_form.poll.duration": "Doer fan de enkête", "compose_form.poll.duration": "Doer fan de enkête",
"compose_form.poll.option_placeholder": "Kar {number}",
"compose_form.poll.remove_option": "Dizze kar fuortsmite",
"compose_form.poll.switch_to_multiple": "Enkête wizigje om meardere karren ta te stean", "compose_form.poll.switch_to_multiple": "Enkête wizigje om meardere karren ta te stean",
"compose_form.poll.switch_to_single": "Enkête wizigje om in inkelde kar ta te stean", "compose_form.poll.switch_to_single": "Enkête wizigje om in inkelde kar ta te stean",
"compose_form.publish": "Publisearje",
"compose_form.publish_form": "Publisearje", "compose_form.publish_form": "Publisearje",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Wizigingen bewarje",
"compose_form.sensitive.hide": "{count, plural, one {Media as gefoelich markearje} other {Media as gefoelich markearje}}",
"compose_form.sensitive.marked": "{count, plural, one {Media as gefoelich markearre} other {Media as gefoelich markearre}}",
"compose_form.sensitive.unmarked": "{count, plural, one {Media is net as gefoelich markearre} other {Media is net as gefoelich markearre}}",
"compose_form.spoiler.marked": "Ynhâldswarskôging fuortsmite", "compose_form.spoiler.marked": "Ynhâldswarskôging fuortsmite",
"compose_form.spoiler.unmarked": "Ynhâldswarskôging tafoegje", "compose_form.spoiler.unmarked": "Ynhâldswarskôging tafoegje",
"compose_form.spoiler_placeholder": "Warskôgingstekst",
"confirmation_modal.cancel": "Annulearje", "confirmation_modal.cancel": "Annulearje",
"confirmations.block.block_and_report": "Blokkearje en rapportearje", "confirmations.block.block_and_report": "Blokkearje en rapportearje",
"confirmations.block.confirm": "Blokkearje", "confirmations.block.confirm": "Blokkearje",
@ -408,7 +397,6 @@
"navigation_bar.direct": "Priveefermeldingen", "navigation_bar.direct": "Priveefermeldingen",
"navigation_bar.discover": "Untdekke", "navigation_bar.discover": "Untdekke",
"navigation_bar.domain_blocks": "Blokkearre domeinen", "navigation_bar.domain_blocks": "Blokkearre domeinen",
"navigation_bar.edit_profile": "Profyl bewurkje",
"navigation_bar.explore": "Ferkenne", "navigation_bar.explore": "Ferkenne",
"navigation_bar.favourites": "Favoriten", "navigation_bar.favourites": "Favoriten",
"navigation_bar.filters": "Negearre wurden", "navigation_bar.filters": "Negearre wurden",
@ -526,14 +514,7 @@
"poll_button.add_poll": "Poll tafoegje", "poll_button.add_poll": "Poll tafoegje",
"poll_button.remove_poll": "Enkête fuortsmite", "poll_button.remove_poll": "Enkête fuortsmite",
"privacy.change": "Sichtberheid fan berjocht oanpasse", "privacy.change": "Sichtberheid fan berjocht oanpasse",
"privacy.direct.long": "Allinnich sichtber foar fermelde brûkers",
"privacy.direct.short": "Allinnich fermelde minsken",
"privacy.private.long": "Allinnich sichtber foar folgers",
"privacy.private.short": "Allinnich folgers",
"privacy.public.long": "Sichtber foar elkenien",
"privacy.public.short": "Iepenbier", "privacy.public.short": "Iepenbier",
"privacy.unlisted.long": "Foar elkenien sichtber, mar net ûnder trends, hashtags en op iepenbiere tiidlinen",
"privacy.unlisted.short": "Minder iepenbier",
"privacy_policy.last_updated": "Lêst bywurke op {date}", "privacy_policy.last_updated": "Lêst bywurke op {date}",
"privacy_policy.title": "Privacybelied", "privacy_policy.title": "Privacybelied",
"recommended": "Oanrekommandearre", "recommended": "Oanrekommandearre",
@ -715,10 +696,8 @@
"upload_error.poll": "It opladen fan bestannen is yn enkêten net tastien.", "upload_error.poll": "It opladen fan bestannen is yn enkêten net tastien.",
"upload_form.audio_description": "Describe for people with hearing loss", "upload_form.audio_description": "Describe for people with hearing loss",
"upload_form.description": "Describe for the visually impaired", "upload_form.description": "Describe for the visually impaired",
"upload_form.description_missing": "Gjin omskriuwing tafoege",
"upload_form.edit": "Bewurkje", "upload_form.edit": "Bewurkje",
"upload_form.thumbnail": "Miniatuerôfbylding wizigje", "upload_form.thumbnail": "Miniatuerôfbylding wizigje",
"upload_form.undo": "Fuortsmite",
"upload_form.video_description": "Describe for people with hearing loss or visual impairment", "upload_form.video_description": "Describe for people with hearing loss or visual impairment",
"upload_modal.analyzing_picture": "Ofbylding analysearje…", "upload_modal.analyzing_picture": "Ofbylding analysearje…",
"upload_modal.apply": "Tapasse", "upload_modal.apply": "Tapasse",

Some files were not shown because too many files have changed in this diff Show more