Compare commits

...

127 Commits
main ... v4.5.6

Author SHA1 Message Date
Claire
e8045de79b
Bump version to v4.5.6 (#37715)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2026-02-03 15:26:52 +01:00
Claire
5f30206c5e
Merge commit from fork 2026-02-03 14:59:53 +01:00
Claire
68a26ce7c6 Fix connection recycling pushing symbols to connection pool (#37674)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2026-01-30 12:18:36 +01:00
Claire
ff20ce9acf Clear affected relationship cache on Move activities (#37664) 2026-01-30 12:18:36 +01:00
PGray
1ba2b1cdc1 Fix quote cancel button not appearing after edit then delete-and-redraft (#37066)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
JavaScript Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
2026-01-29 14:55:25 +01:00
Claire
4c1fbe4e2e Fix followers with profile subscription (bell icon) being notified of post edits (#37646) 2026-01-29 14:55:25 +01:00
Claire
569ff6c8ad Fix error when encountering invalid tag in updated object (#37635) 2026-01-29 14:55:25 +01:00
Claire
81716f7e27 Fix quote cache invalidation (#37592) 2026-01-29 14:55:25 +01:00
Claire
8935137526 Shorten caching of quote posts pending approval (#37570) 2026-01-29 14:55:25 +01:00
Claire
dcc5c2b6f6 Fix cross-server conversation tracking (#37559) 2026-01-29 14:55:25 +01:00
Shlee
f1c32f6a11 Unclosed connection leak when replacing pooled connection in SharedTimedStack.try_create (#37335) 2026-01-29 14:55:25 +01:00
Claire
db943c43c8
Bump version to v4.5.5 (#37546)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
CSS Linting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2026-01-20 15:53:37 +01:00
Claire
1a74b74a40
Merge commit from fork
* Add limit on inbox payload size

The 1MB limit is consistent with the limit we use when fetching remote resources

* Add limit to number of options from federated polls

* Add a limit to the number of federated profile fields

* Add limit on federated username length

* Add hard limits for federated display name and account bio

* Add hard limits for `alsoKnownAs` and `attributionDomains`

* Add hard limit on federated custom emoji shortcode

* Highlight most destructive limits and expand on their reasoning
2026-01-20 15:14:45 +01:00
Claire
9a25b12f0c
Merge commit from fork 2026-01-20 15:13:42 +01:00
Claire
6f9b32b137
Merge commit from fork 2026-01-20 15:13:10 +01:00
Claire
1b3ef035b9
Merge commit from fork 2026-01-20 15:10:38 +01:00
Claire
6698901d57 Fix potential duplicate handling of quote accept/reject/delete (#37537) 2026-01-20 08:57:46 +01:00
Claire
ba0609bbaf Skip tombstone creation on deleting from 404 (#37533) 2026-01-20 08:57:46 +01:00
Claire
ded7f50f2c Fix FeedManager#filter_from_home error when handling a reblog of a deleted status (#37486) 2026-01-19 11:37:34 +01:00
Claire
85eda5b46f Simplify status batch removal SQL query (#37469) 2026-01-19 11:37:34 +01:00
Matt Jankowski
f1c9c89c39 Add spec for quote policy update change (#37474) 2026-01-19 11:37:34 +01:00
Shlee
57e0c6562f Fix quote_approval_policy being reset to user defaults when omitted in status update (#37436) 2026-01-19 11:37:34 +01:00
Joshua Rogers
f7b6e57151 Fix Vary parsing in cache control enforcement (#37426) 2026-01-19 11:37:34 +01:00
Joshua Rogers
57f658dc5c Fix arg order for non_matching_uri_hosts? call in QuoteRequest (#37425) 2026-01-19 11:37:34 +01:00
Joshua Rogers
0cda068918 Fix thread-unsafe ActivityPub activity dispatch (#37423) 2026-01-19 11:37:34 +01:00
David Roetzel
deeaf50472 Fix URI generation for reblogs by accounts with numerical AP ids (#37415) 2026-01-19 11:37:34 +01:00
Shlee
adea0b7b31 Fix SignatureParser accepting duplicate parameters in HTTP Signature header (#37375)
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
2026-01-19 11:37:34 +01:00
Shlee
1eb8d1b967 SharedConnectionPool - NoMethodError: undefined method 'site' for Integer (#37374) 2026-01-19 11:37:34 +01:00
Echo
f354bbe8aa Remove trailing variation selector code for legacy emojis (#37320) 2026-01-19 11:37:34 +01:00
diondiondion
53437c4653 Fix mobile admin sidebar displaying under batch table toolbar (#37307) 2026-01-19 11:37:34 +01:00
Claire
617926742c
Update SECURITY.md (#37505) 2026-01-15 14:17:38 +01:00
Claire
55a7b1ea58
Bump version to v4.5.4 (#37409) 2026-01-07 14:23:34 +01:00
Claire
c1fb6893c5
Merge commit from fork 2026-01-07 14:15:14 +01:00
Claire
71ae4cf2cf
Merge commit from fork 2026-01-07 14:14:42 +01:00
Claire
a846ed17ff Fix custom emojis not being rendered in profile fields (#37365) 2026-01-06 14:11:56 +01:00
Claire
3013039720 Fix serialization of context pages (#37376) 2026-01-06 14:11:56 +01:00
Claire
ad4ba5aa00 Fix quotes with CWs but no text not having fallback link (#37361) 2026-01-06 14:11:56 +01:00
Claire
1c5461fffe Fix outdated link target for “locked” warning (#37366) 2026-01-06 14:11:56 +01:00
ChaosExAnima
3de59a9344 Remove rendering of custom emoji using the database (#37284)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
CSS Linting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-12-19 11:02:32 +01:00
Echo
32c3376d84 Fixes CDN domain loading (#37310) 2025-12-19 11:02:32 +01:00
Claire
962ae88caf Fix custom emojis not displaying in CWs and fav/boost notifications (#37306) 2025-12-19 11:02:32 +01:00
diondiondion
7d9d3de972 Fix notifications page error in Tor browser (#37285) 2025-12-19 11:02:32 +01:00
Echo
546a95349e Emojis: Show in embedded statuses (#37272) 2025-12-19 11:02:32 +01:00
Claire
df1ab0ab90 Fix default Admin role not including view_feeds permission (#37301) 2025-12-19 11:02:32 +01:00
Claire
8d1ea4c531 Fix hashtag autocomplete replacing suggestion's first characters with input (#37281) 2025-12-19 11:02:32 +01:00
Claire
8233295e3b Fix mentions of domain-blocked users being processed (#37257) 2025-12-19 11:02:32 +01:00
Claire
4eb0a506d3 Change HTTP Signature verification status from 401 to 503 on temporary failure to get remote actor (#37221) 2025-12-19 11:02:32 +01:00
Claire
75739a5a9b Change build-releases workflow to tag images latest based on latest stable-x.y branch (#37179)
Co-authored-by: emilweth <7402764+emilweth@users.noreply.github.com>
2025-12-19 11:02:32 +01:00
Claire
86cff1abca
Bump version to v4.5.3 (#37142)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-12-08 16:20:15 +01:00
Claire
e6d2fc869b
Merge commit from fork 2025-12-08 15:44:08 +01:00
github-actions[bot]
a9f8268a75
New Crowdin Translations for stable-4.5 (automated) (#37158)
Some checks are pending
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Co-authored-by: GitHub Actions <noreply@github.com>
2025-12-08 12:56:49 +01:00
Claire
dfe269439a Fix “Delete and Redraft” on a non-quote being treated as a quote post in some cases (#37140)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-12-05 16:50:07 +01:00
Echo
9bc9ebc59e Fixes YouTube embeds (#37126)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
2025-12-05 11:15:16 +01:00
Claire
a6d31c0ccf Fix streamed quoted polls not being hydrated correctly (#37118) 2025-12-05 11:15:16 +01:00
David Roetzel
1e2cf6c964 Fix creation of duplicate conversations (#37108) 2025-12-05 11:15:16 +01:00
Echo
c42c71c90a Remove noreferrer from external links (#37107) 2025-12-05 11:15:16 +01:00
Claire
782e410719 Make settings-related database migrations more robust (#37079) 2025-12-05 11:15:16 +01:00
Claire
b0c141e658 Fix error handling when re-fetching already-known statuses (#37077) 2025-12-05 11:15:16 +01:00
diondiondion
1ef4bbd88d Fix post navigation in single-column mode when Advanced UI is enabled (#37044) 2025-12-05 11:15:16 +01:00
Claire
240d38b7c0 Fix tootctl status remove removing quoted posts and remote quotes of local posts (#37009) 2025-12-05 11:15:16 +01:00
Claire
770d1212bb Increase HTTP read timeout for expensive S3 batch delete operation (#37004) 2025-12-05 11:15:16 +01:00
Claire
86e463c0e8 Fix compose autosuggest always lowercasing token (#36995) 2025-12-05 11:15:16 +01:00
Matt Jankowski
a04a210e14 Suggest ES image version 7.17.29 in docker compose (#36972) 2025-12-05 11:15:16 +01:00
Claire
19588756ef
Bump version to v4.5.2 (#36944)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-11-20 14:41:09 +01:00
github-actions[bot]
e398ff40b2
New Crowdin Translations for stable-4.5 (automated) (#36945)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-11-20 13:40:31 +01:00
Claire
96eb687524 Fix missing fallback link in CW-only quote posts (#36963)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
JavaScript Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
2025-11-20 12:56:41 +01:00
Claire
05c624cfa7 Fix statuses without text disappearing on reload (#36962) 2025-11-20 12:56:41 +01:00
Claire
5fe316b2e9
Update dependency glob (#36941)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
CSS Linting / lint (push) Has been cancelled
2025-11-19 16:29:35 +01:00
diondiondion
1dbf10198d Fix g + h keyboard shortcut not working when a post is focused (#36935) 2025-11-19 15:20:01 +01:00
Claire
c6ccacdf7b Fix quoting overwriting current content warning (#36934) 2025-11-19 15:20:01 +01:00
Claire
6ccd9c2f1f Fix scroll-to-status in threaded view being unreliable (#36927) 2025-11-19 15:20:01 +01:00
Claire
261d9b33fe Change private quote education modal to not show up on self-quotes (#36926) 2025-11-19 15:20:01 +01:00
Claire
4ee21c2e29 Fix double encoding in links (#36925) 2025-11-19 15:20:01 +01:00
Echo
c08cd6d62a Emoji: Fix path resolution for emoji worker (#36897) 2025-11-19 15:20:01 +01:00
Shugo Maeda
44d45e5705 Fix ArgumentError of tootctl upgrade storage-schema (#36914) 2025-11-19 15:20:01 +01:00
Claire
27c67f1750 Fix cross-origin handling of CSS modules (#36890) 2025-11-19 15:20:01 +01:00
renovate[bot]
bb28552859 chore(deps): update dependency js-yaml to v4.1.1 [security] (#36891)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-19 15:20:01 +01:00
Echo
6486c092f6 Fix error with remote tags including percent signs (#36886) 2025-11-19 15:20:01 +01:00
Claire
a7b45682a6 Fix bogus quote approval policy not always being replaced correctly (#36885) 2025-11-19 15:20:01 +01:00
Claire
5a57c0844a Fix hashtag completion not being inserted correctly (#36884) 2025-11-19 15:20:01 +01:00
diondiondion
1d081250f4 Fix Cmd/Ctrl + Enter in the composer triggering confirmation dialog action (#36870) 2025-11-19 15:20:01 +01:00
Claire
bb6093c315 Bump version to v4.5.1
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
CSS Linting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-11-13 17:12:07 +01:00
Claire
058f704c21 Fix error when sending new posts (#36869) 2025-11-13 17:12:07 +01:00
diondiondion
6baa8f2466 Fix Cmd/Ctrl + Enter not submitting Alt text modal on some browsers (#36866) 2025-11-13 17:12:07 +01:00
github-actions[bot]
e742eff044
New Crowdin Translations for stable-4.5 (automated) (#36864)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-11-13 15:46:34 +01:00
Claire
55b9d21537 Fix posts coming from public/hashtag streaming being marked as unquotable (#36860) 2025-11-13 15:24:58 +01:00
Claire
59f0134578 Fix Update importing old previously-unknown activities and treating them as recent ones (#36848) 2025-11-13 15:24:58 +01:00
Echo
28b9e9087a Fix deprecation warning in Vite (#36849) 2025-11-13 15:24:58 +01:00
diondiondion
fa2cc409ce Fixes blank screen in browsers that don't support Intl.DisplayNames (#36847) 2025-11-13 15:24:58 +01:00
Claire
8a100d84c5 Fix filters not being applied to quotes in detailed view (#36843) 2025-11-13 15:24:58 +01:00
Echo
9ae0464e8f Emoji: Load emoji with hash in URL (#36808) 2025-11-13 15:24:58 +01:00
diondiondion
9eea4479e1 Fix scroll shift caused by fetch-all-replies alerts (#36807) 2025-11-13 15:24:58 +01:00
diondiondion
30103fd2c8 Fix dropdown menu not focusing first item when opened via keyboard (#36804) 2025-11-13 15:24:58 +01:00
Claire
a9a7ad62f1 Update dependency rollup from 4.46.2 to 4.46.4 (#36781) 2025-11-13 15:24:58 +01:00
Claire
ea663cf7c7 Fix /api/v1/statuses/:id/context sometimes returing Mastodon-Async-Refresh without result_count (#36779) 2025-11-13 15:24:58 +01:00
Claire
fbe05d42fb Fix prepared quote not being discarded with contents when replying (#36778) 2025-11-13 15:24:58 +01:00
Claire
29ae9c9c4b
Add 4.5.x to the list of supported branches (#36761)
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-11-06 17:12:41 +01:00
Claire
26c78392f8
Bump version to v4.5.0 (#36732)
Some checks failed
Check i18n / check-i18n (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
CSS Linting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
2025-11-06 12:39:07 +01:00
github-actions[bot]
048430f4e8
New Crowdin Translations for stable-4.5 (automated) (#36745)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-11-06 11:37:54 +01:00
Echo
d45b4db1d7 Fix: correctly dismisses announcement when viewed (#36750) 2025-11-06 11:23:46 +01:00
Echo
ef3a95affc Add default visualizer for audio upload without poster (#36734) 2025-11-06 10:34:12 +01:00
diondiondion
3e6a9371b0 Fix spoiler toggle button being able to submit compose form (#36736) 2025-11-06 10:34:12 +01:00
Claire
e91c764590 Bump version to v4.5.0-rc.3
Some checks failed
CodeQL / Analyze (javascript) (push) Waiting to run
CodeQL / Analyze (ruby) (push) Waiting to run
Check formatting / lint (push) Waiting to run
CSS Linting / lint (push) Waiting to run
JavaScript Linting / lint (push) Waiting to run
Ruby Linting / lint (push) Waiting to run
JavaScript Testing / test (push) Waiting to run
Historical data migration test / test (14-alpine) (push) Waiting to run
Historical data migration test / test (15-alpine) (push) Waiting to run
Historical data migration test / test (16-alpine) (push) Waiting to run
Historical data migration test / test (17-alpine) (push) Waiting to run
Ruby Testing / build (production) (push) Waiting to run
Ruby Testing / build (test) (push) Waiting to run
Ruby Testing / test (.ruby-version) (push) Blocked by required conditions
Ruby Testing / test (3.2) (push) Blocked by required conditions
Ruby Testing / test (3.3) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (.ruby-version) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.2) (push) Blocked by required conditions
Ruby Testing / ImageMagick tests (3.3) (push) Blocked by required conditions
Ruby Testing / End to End testing (.ruby-version) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.2) (push) Blocked by required conditions
Ruby Testing / End to End testing (3.3) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Blocked by required conditions
Bundler Audit / security (push) Has been cancelled
Crowdin / Upload translations / upload-translations (push) Has been cancelled
Haml Linting / lint (push) Has been cancelled
2025-11-05 09:59:00 +01:00
Claire
cfdd9396c0 Change paste-link-to-quote loading state from generic loading bar to compose placeholder (#36695) 2025-11-05 09:59:00 +01:00
Claire
ba498ae779 Change quote action to error instead of insert link in Private Mentions (#36721) 2025-11-05 09:59:00 +01:00
Echo
5bae08d1ff Quote Posts: Add notifications for DMs and private posts (#36696) 2025-11-05 09:59:00 +01:00
Echo
5253527ec4 Add CSS Module support (#36637) 2025-11-05 09:59:00 +01:00
Claire
0b50789c5b Fix Skeleton placeholders being animated when setting to reduce animations is enabled (#36716) 2025-11-05 09:59:00 +01:00
Claire
a978e37f4c Fix quote dropdown menu item in detailed status view (#36704) 2025-11-05 09:59:00 +01:00
Claire
dd708298a8 Remove option to disable access to local topic feeds for logged-in users (#36703) 2025-11-05 09:59:00 +01:00
renovate[bot]
449eb03f11 chore(deps): update dependency sidekiq to v8.0.9 (#36699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 09:59:00 +01:00
renovate[bot]
1baede0a7c chore(deps): update dependency brakeman to v7.1.1 (#35434)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 09:59:00 +01:00
renovate[bot]
a7ecfc1ca5 fix(deps): update dependency @rails/ujs to v7.1.600 (#36634)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 09:59:00 +01:00
Claire
e62baacfc1 Increase number of quote approval job retries (#36698) 2025-11-05 09:59:00 +01:00
Rachael Wright-Munn
b5a6feb3bf Move "Privacy and reach" from "Public profile" to top-level navigation (#27294) 2025-11-05 09:59:00 +01:00
Claire
05964f571b Prevent creation of Private Mentions quoting someone who is not mentioned (#36689) 2025-11-05 09:59:00 +01:00
Claire
16a54f7158 Fix issuance of quote approval for remote private statuses (#36693) 2025-11-05 09:59:00 +01:00
Claire
6d53ca63d6 Disable paste-link-to-quote flow when composing Private Mentions (#36690) 2025-11-05 09:59:00 +01:00
renovate[bot]
93acfdd7d3 chore(deps): update dependency irb to v1.15.3 (#36682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 09:59:00 +01:00
renovate[bot]
a209b8e544 chore(deps): update dependency rubyzip to v3.2.2 (#36687)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-05 09:59:00 +01:00
Claire
af4c372ab2 Bump version to v4.5.0-rc.2
Some checks failed
Check i18n / check-i18n (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript) (push) Has been cancelled
CodeQL / Analyze (ruby) (push) Has been cancelled
Crowdin / Upload translations / upload-translations (push) Has been cancelled
Check formatting / lint (push) Has been cancelled
CSS Linting / lint (push) Has been cancelled
JavaScript Linting / lint (push) Has been cancelled
Ruby Linting / lint (push) Has been cancelled
JavaScript Testing / test (push) Has been cancelled
Historical data migration test / test (14-alpine) (push) Has been cancelled
Historical data migration test / test (15-alpine) (push) Has been cancelled
Historical data migration test / test (16-alpine) (push) Has been cancelled
Historical data migration test / test (17-alpine) (push) Has been cancelled
Ruby Testing / build (production) (push) Has been cancelled
Ruby Testing / build (test) (push) Has been cancelled
Ruby Testing / test (.ruby-version) (push) Has been cancelled
Ruby Testing / test (3.2) (push) Has been cancelled
Ruby Testing / test (3.3) (push) Has been cancelled
Ruby Testing / ImageMagick tests (.ruby-version) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.2) (push) Has been cancelled
Ruby Testing / ImageMagick tests (3.3) (push) Has been cancelled
Ruby Testing / End to End testing (.ruby-version) (push) Has been cancelled
Ruby Testing / End to End testing (3.2) (push) Has been cancelled
Ruby Testing / End to End testing (3.3) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, docker.elastic.co/elasticsearch/elasticsearch:8.10.2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (.ruby-version, opensearchproject/opensearch:2) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.2, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
Ruby Testing / Elastic Search integration testing (3.3, docker.elastic.co/elasticsearch/elasticsearch:7.17.13) (push) Has been cancelled
2025-10-31 16:01:06 +01:00
diondiondion
aa579ce286 Fix initially selected language in Rules panel, hide selector when no alternative translations exist (#36672) 2025-10-31 16:01:06 +01:00
github-actions[bot]
adfabf8c80
New Crowdin Translations for stable-4.5 (automated) (#36670)
Co-authored-by: GitHub Actions <noreply@github.com>
2025-10-31 14:51:18 +01:00
renovate[bot]
ea710df180 chore(deps): update dependency axios to v1.13.1 (#36633)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-31 14:09:36 +01:00
renovate[bot]
e1b6e28829 chore(deps): update dependency libvips to v8.17.3 (#36654)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-31 14:09:36 +01:00
diondiondion
214d59bd37 Show error when submitting empty post rather than failing silently (#36650) 2025-10-31 14:09:36 +01:00
Claire
e4291e9b05 Fix SMTP configuration with mail 2.9.0 (#36646) 2025-10-31 14:09:36 +01:00
315 changed files with 6466 additions and 2207 deletions

View File

@ -9,7 +9,44 @@ permissions:
packages: write
jobs:
check-latest-stable:
runs-on: ubuntu-latest
outputs:
latest: ${{ steps.check.outputs.is_latest_stable }}
steps:
# Repository needs to be cloned to list branches
- name: Clone repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Check latest stable
shell: bash
id: check
run: |
ref="${GITHUB_REF#refs/tags/}"
if [[ "$ref" =~ ^v([0-9]+)\.([0-9]+)(\.[0-9]+)?$ ]]; then
current="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
else
echo "tag $ref is not semver"
echo "is_latest_stable=false" >> "$GITHUB_OUTPUT"
exit 0
fi
latest=$(git for-each-ref --format='%(refname:short)' "refs/remotes/origin/stable-*.*" \
| sed -E 's#^origin/stable-##' \
| sort -Vr \
| head -n1)
if [[ "$current" == "$latest" ]]; then
echo "is_latest_stable=true" >> "$GITHUB_OUTPUT"
else
echo "is_latest_stable=false" >> "$GITHUB_OUTPUT"
fi
build-image:
needs: check-latest-stable
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: Dockerfile
@ -21,13 +58,14 @@ jobs:
# Only tag with latest when ran against the latest stable branch
# This needs to be updated after each minor version release
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
latest=${{ needs.check-latest-stable.outputs.latest }}
tags: |
type=pep440,pattern={{raw}}
type=pep440,pattern=v{{major}}.{{minor}}
secrets: inherit
build-image-streaming:
needs: check-latest-stable
uses: ./.github/workflows/build-container-image.yml
with:
file_to_build: streaming/Dockerfile
@ -39,7 +77,7 @@ jobs:
# Only tag with latest when ran against the latest stable branch
# This needs to be updated after each minor version release
flavor: |
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
latest=${{ needs.check-latest-stable.outputs.latest }}
tags: |
type=pep440,pattern={{raw}}
type=pep440,pattern=v{{major}}.{{minor}}

View File

@ -2,17 +2,145 @@
All notable changes to this project will be documented in this file.
## [4.5.0] - UNRELEASED
## [4.5.6] - 2026-02-03
### Security
- Fix ActivityPub collection caching logic for pinned posts and featured tags not checking blocked accounts ([GHSA-ccpr-m53r-mfwr](https://github.com/mastodon/mastodon/security/advisories/GHSA-ccpr-m53r-mfwr))
### Changed
- Shorten caching of quote posts pending approval (#37570 and #37592 by @ClearlyClaire)
### Fixed
- Fix relationship cache not being cleared when handling account migrations (#37664 by @ClearlyClaire)
- Fix quote cancel button not appearing after edit then delete-and-redraft (#37066 by @PGrayCS)
- Fix followers with profile subscription (bell icon) being notified of post edits (#37646 by @ClearlyClaire)
- Fix error when encountering invalid tag in updated object (#37635 by @ClearlyClaire)
- Fix cross-server conversation tracking (#37559 by @ClearlyClaire)
- Fix recycled connections not being immediately closed (#37335 and #37674 by @ClearlyClaire and @shleeable)
## [4.5.5] - 2026-01-20
### Security
- Fix missing limits on various federated properties [GHSA-gg8q-rcg7-p79g](https://github.com/mastodon/mastodon/security/advisories/GHSA-gg8q-rcg7-p79g)
- Fix remote user suspension bypass [GHSA-5h2f-wg8j-xqwp](https://github.com/mastodon/mastodon/security/advisories/GHSA-5h2f-wg8j-xqwp)
- Fix missing length limits on some user-provided fields [GHSA-6x3w-9g92-gvf3](https://github.com/mastodon/mastodon/security/advisories/GHSA-6x3w-9g92-gvf3)
- Fix missing access check for push notification settings update [GHSA-f3q8-7vw3-69v4](https://github.com/mastodon/mastodon/security/advisories/GHSA-f3q8-7vw3-69v4)
### Changed
- Skip tombstone creation on deleting from 404 (#37533 by @ClearlyClaire)
### Fixed
- Fix potential duplicate handling of quote accept/reject/delete (#37537 by @ClearlyClaire)
- Fix `FeedManager#filter_from_home` error when handling a reblog of a deleted status (#37486 by @ClearlyClaire)
- Fix needlessly complicated SQL query in status batch removal (#37469 by @ClearlyClaire)
- Fix `quote_approval_policy` being reset to user defaults when omitted in status update (#37436 and #37474 by @mjankowski and @shleeable)
- Fix `Vary` parsing in cache control enforcement (#37426 by @MegaManSec)
- Fix missing URI scheme test in `QuoteRequest` handling (#37425 by @MegaManSec)
- Fix thread-unsafe ActivityPub activity dispatch (#37423 by @MegaManSec)
- Fix URI generation for reblogs by accounts with numerical ActivityPub identifiers (#37415 by @oneiros)
- Fix SignatureParser accepting duplicate parameters in HTTP Signature header (#37375 by @shleeable)
- Fix emoji with variant selector not being rendered properly (#37320 by @ChaosExAnima)
- Fix mobile admin sidebar displaying under batch table toolbar (#37307 by @diondiondion)
## [4.5.4] - 2026-01-07
### Security
- Fix SSRF protection bypass ([GHSA](https://github.com/mastodon/mastodon/security/advisories/GHSA-xfrj-c749-jxxq))
- Fix missing ownership check in severed relationships controller ([GHSA](https://github.com/mastodon/mastodon/security/advisories/GHSA-ww85-x9cp-5v24))
### Changed
- Change HTTP Signature verification status from 401 to 503 on temporary failure to get remote actor (#37221 by @ClearlyClaire)
### Fixed
- Fix custom emojis not being rendered in profile fields (#37365 by @ClearlyClaire)
- Fix serialization of context pages (#37376 by @ClearlyClaire)
- Fix quotes with CWs but no text not having fallback link (#37361 by @ClearlyClaire)
- Fix outdated link target for “locked” warning (#37366 by @ClearlyClaire)
- Fix local custom emojis sometimes being rendered in remote posts (#37284 by @ChaosExAnima)
- Fix some assets not being loaded from configured CDN (#37310 by @ChaosExAnima)
- Fix notifications page error in Tor browser (#37285 by @diondiondion)
- Fix custom emojis not being displayed in CWs and fav/boost notifications (#37272 and #37306 by @ChaosExAnima and @ClearlyClaire)
- Fix default `Admin` role not including `view_feeds` permission (#37301 by @ClearlyClaire)
- Fix hashtag autocomplete replacing suggestion's first characters with input (#37281 by @ClearlyClaire)
- Fix mentions of domain-blocked users being processed (#37257 by @ClearlyClaire)
## [4.5.3] - 2025-12-08
### Security
- Fix inconsistent error handling leaking information on existence of private posts ([GHSA-gwhw-gcjx-72v8](https://github.com/mastodon/mastodon/security/advisories/GHSA-gwhw-gcjx-72v8))
### Fixed
- Fix “Delete and Redraft” on a non-quote being treated as a quote post in some cases (#37140 by @ClearlyClaire)
- Fix YouTube embeds by sending referer (#37126 by @ChaosExAnima)
- Fix streamed quoted polls not being hydrated correctly (#37118 by @ClearlyClaire)
- Fix creation of duplicate conversations (#37108 by @oneiros)
- Fix extraneous `noreferrer` in external links (#37107 by @ChaosExAnima)
- Fix edge case error handling in some database migrations (#37079 by @ClearlyClaire)
- Fix error handling when re-fetching already-known statuses (#37077 by @ClearlyClaire)
- Fix post navigation in single-column mode when Advanced UI is enabled (#37044 by @diondiondion)
- Fix `tootctl status remove` removing quoted posts and remote quotes of local posts (#37009 by @ClearlyClaire)
- Fix known expensive S3 batch delete operation failing because of short timeouts (#37004 by @ClearlyClaire)
- Fix compose autosuggest always lowercasing input token (#36995 by @ClearlyClaire)
## [4.5.2] - 2025-11-20
### Changed
- Change private quote education modal to not show up on self-quotes (#36926 by @ClearlyClaire)
### Fixed
- Fix missing fallback link in CW-only quote posts (#36963 by @ClearlyClaire)
- Fix statuses without text being hidden while loading (#36962 by @ClearlyClaire)
- Fix `g` + `h` keyboard shortcut not working when a post is focused (#36935 by @diondiondion)
- Fix quoting overwriting current content warning (#36934 by @ClearlyClaire)
- Fix scroll-to-status in threaded view being unreliable (#36927 by @ClearlyClaire)
- Fix path resolution for emoji worker (#36897 by @ChaosExAnima)
- Fix `tootctl upgrade storage-schema` failing with `ArgumentError` (#36914 by @shugo)
- Fix cross-origin handling of CSS modules (#36890 by @ClearlyClaire)
- Fix error with remote tags including percent signs (#36886 and #36925 by @ChaosExAnima and @ClearlyClaire)
- Fix bogus quote approval policy not always being replaced correctly (#36885 by @ClearlyClaire)
- Fix hashtag completion not being inserted correctly (#36884 by @ClearlyClaire)
- Fix Cmd/Ctrl + Enter in the composer triggering confirmation dialog action (#36870 by @diondiondion)
## [4.5.1] - 2025-11-13
### Fixed
- Fix Cmd/Ctrl + Enter not submitting Alt text modal on some browsers (#36866 by @diondiondion)
- Fix posts coming from public/hashtag streaming being marked as unquotable (#36860 and #36869 by @ClearlyClaire)
- Fix old previously-undiscovered posts being treated as new when receiving an `Update` (#36848 by @ClearlyClaire)
- Fix blank screen in browsers that don't support `Intl.DisplayNames` (#36847 by @diondiondion)
- Fix filters not being applied to quotes in detailed view (#36843 by @ClearlyClaire)
- Fix scroll shift caused by fetch-all-replies alerts (#36807 by @diondiondion)
- Fix dropdown menu not focusing first item when opened via keyboard (#36804 by @diondiondion)
- Fix assets build issue on arch64 (#36781 by @ClearlyClaire)
- Fix `/api/v1/statuses/:id/context` sometimes returing `Mastodon-Async-Refresh` without `result_count` (#36779 by @ClearlyClaire)
- Fix prepared quote not being discarded with contents when replying (#36778 by @ClearlyClaire)
## [4.5.0] - 2025-11-06
### Added
- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516, #36528, #36549, #36550 and #36559 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\
- **Add support for allowing and authoring quotes** (#35355, #35578, #35614, #35618, #35624, #35626, #35652, #35629, #35665, #35653, #35670, #35677, #35690, #35697, #35689, #35699, #35700, #35701, #35709, #35714, #35713, #35715, #35725, #35749, #35769, #35780, #35762, #35804, #35808, #35805, #35819, #35824, #35828, #35822, #35835, #35865, #35860, #35832, #35891, #35894, #35895, #35820, #35917, #35924, #35925, #35914, #35930, #35941, #35939, #35948, #35955, #35967, #35990, #35991, #35975, #35971, #36002, #35986, #36031, #36034, #36038, #36054, #36052, #36055, #36065, #36068, #36083, #36087, #36080, #36091, #36090, #36118, #36119, #36128, #36094, #36129, #36138, #36132, #36151, #36158, #36171, #36194, #36220, #36169, #36130, #36249, #36153, #36299, #36291, #36301, #36315, #36317, #36364, #36383, #36381, #36459, #36464, #36461, #36516, #36528, #36549, #36550, #36559, #36693, #36704, #36690, #36689, #36696, #36721, #36695 and #36736 by @ChaosExAnima, @ClearlyClaire, @Lycolia, @diondiondion, and @tribela)\
This includes a revamp of the composer interface.\
See https://blog.joinmastodon.org/2025/09/introducing-quote-posts/ for a user-centric overview of the feature, and https://docs.joinmastodon.org/client/quotes/ for API documentation.
- **Add support for fetching and refreshing replies to the web UI** (#35210, #35496, #35575, #35500, #35577, #35602, #35603, #35654, #36141, #36237, #36172, #36256, #36271, #36334, #36382, #36239, #36484, #36481, #36583, #36627 and #36547 by @ClearlyClaire, @diondiondion, @Gargron and @renchap)
- **Add ability to block words in usernames** (#35407, #35655, and #35806 by @ClearlyClaire and @Gargron)
- Add ability to individually disable local or remote feeds for visitors or logged-in users `disabled` value to server setting for live and topic feeds, as well as user permission to bypass that (#36338, #36467, #36497, #36563, #36577, #36585, and #36607 by @ClearlyClaire)\
This splits the `timeline_preview` setting into four more granular settings controlling live feeds and topic (hashtag, trending link) feeds, with 3 values each: `public`, `authenticated`, `disabled`.\
- Add ability to individually disable local or remote feeds for visitors or logged-in users `disabled` value to server setting for live and topic feeds, as well as user permission to bypass that (#36338, #36467, #36497, #36563, #36577, #36585, #36607 and #36703 by @ClearlyClaire)\
This splits the `timeline_preview` setting into four more granular settings controlling live feeds and topic (hashtag, trending link) feeds.\
The setting for local topic feeds has 2 values: `public` and `authenticated`. Every other setting has 3 values: `public`, `authenticated`, `disabled`.\
When `disabled`, users with the “View live and topic feeds” will still be able to view them.
- Add support for displaying of quote posts in Moderator UI (#35964 by @ThisIsMissEm)
- Add support for displaying link previews for Admin UI (#35958 by @ThisIsMissEm)
@ -20,21 +148,22 @@ All notable changes to this project will be documented in this file.
- Add support for `Update` activities on converted object types (#36322 by @ClearlyClaire)
- Add support for dynamic viewport height (#36272 by @e1berd)
- Add support for numeric-based URIs for new local accounts (#32724, #36304, #36316, and #36365 by @ClearlyClaire)
- Add default visualizer for audio upload without poster (#36734 by @ChaosExAnima)
- Add Traditional Mongolian to posting languages (#36196 by @shimon1024)
- Add example post with manual quote approval policy to `dev:populate_sample_data` (#36099 by @ClearlyClaire)
- Add server-side support for handling posts with a quote policy allowing followers to quote (#36093 and #36127 by @ClearlyClaire)
- Add schema.org markup to SEO-enabled posts (#36075 by @Gargron)
- Add migration to fill unset default quote policy based on default post privacy (#36041 by @ClearlyClaire)
- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion)
- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima)
- Add feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502, #36532, #36603, #36409, #36638 and #36750 by @ChaosExAnima, @ClearlyClaire and @braddunbar)\
This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places.
- Add support for exposing conversation context for new public conversations according to FEP-7888 (#35959 and #36064 by @ClearlyClaire and @jesseplusplus)
- Add digest re-check before removing followers in synchronization mechanism (#34273 by @ClearlyClaire)
- Add “Posting defaults” setting page, moving existing settings from “Other” (#35896, #36033, #35966, #35969, and #36084 by @ClearlyClaire and @diondiondion)
- Add support for displaying Valkey version on admin dashboard (#35785 by @ykzts)
- Add delivery failure tracking and handling to FASP jobs (#35625, #35628, and #35723 by @oneiros)
- Add example of quote post with a preview card to development sample data (#35616 by @ClearlyClaire)
- Add second set of blocked text that applies to accounts regardless of account age for spam-blocking (#35563 by @ClearlyClaire)
- Added emoji from Twemoji v16 (#36501 and #36530 by @ChaosExAnima)
- Add feature to select custom emoji rendering (#35229, #35282, #35253, #35424, #35473, #35483, #35505, #35568, #35605, #35659, #35664, #35739, #35985, #36051, #36071, #36137, #36165, #36248, #36262, #36275, #36293, #36341, #36342, #36366, #36377, #36378, #36385, #36393, #36397, #36403, #36413, #36410, #36454, #36402, #36503, #36502, #36532, #36603, #36409 and #36638 by @ChaosExAnima, @ClearlyClaire and @braddunbar)\
This also completely reworks the processing and rendering of emojis and server-rendered HTML in statuses and other places.
### Changed
@ -43,6 +172,9 @@ All notable changes to this project will be documented in this file.
- Change appearance settings to introduce new Advanced settings section (#36496 and #36506 by @diondiondion)
- Change display of blocked and muted quoted users (#36619 by @ClearlyClaire)\
This adds `blocked_account`, `blocked_domain` and `muted_account` values to the `state` attribute of `Quote` and `ShallowQuote` REST API entities.
- Change submitting an empty post to show an error rather than failing silently (#36650 by @diondiondion)
- Change "Privacy and reach" settings from "Public profile" to their own top-level category (#27294 by @ChaelCodes)
- Change number of times quote verification is retried to better deal with temporary failures (#36698 by @ClearlyClaire)
- Change display of content warnings in Admin UI (#35935 by @ThisIsMissEm)
- Change styling of column banners (#36531 by @ClearlyClaire)
- Change recommended Node version to 24 (LTS) (#36539 by @renchap)
@ -70,9 +202,11 @@ All notable changes to this project will be documented in this file.
- Fix relationship not being fetched to evaluate whether to show a quote post (#36517 by @ClearlyClaire)
- Fix rendering of poll options in status history modal (#35633 by @ThisIsMissEm)
- Fix “mute” button being displayed to unauthenticated visitors in hashtag dropdown (#36353 by @mkljczk)
- Fix initially selected language in Rules panel, hide selector when no alternative translations exist (#36672 by @diondiondion)
- Fix URL comparison for mentions in case of empty path (#36613 and #36626 by @ClearlyClaire)
- Fix hashtags not being picked up when full-width hash sign is used (#36103 and #36625 by @ClearlyClaire and @Gargron)
- Fix layout of severed relationships when purged events are listed (#36593 by @mejofi)
- Fix Skeleton placeholders being animated when setting to reduce animations is enabled (#36716 by @ClearlyClaire)
- Fix vacuum tasks being interrupted by a single batch failure (#36606 by @Gargron)
- Fix handling of unreachable network error for search services (#36587 by @mjankowski)
- Fix bookmarks export when a bookmarked status is soft-deleted (#36576 by @ClearlyClaire)

View File

@ -183,7 +183,7 @@ FROM build AS libvips
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
ARG VIPS_VERSION=8.17.2
ARG VIPS_VERSION=8.17.3
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download

View File

@ -48,3 +48,22 @@ Mastodon requires all `POST` requests to be signed, and MAY require `GET` reques
### Additional documentation
- [Mastodon documentation](https://docs.joinmastodon.org/)
## Size limits
Mastodon imposes a few hard limits on federated content.
These limits are intended to be very generous and way above what the Mastodon user experience is optimized for, so as to accomodate future changes and unusual or unforeseen usage patterns, while still providing some limits for performance reasons.
The following table attempts to summary those limits.
| Limited property | Size limit | Consequence of exceeding the limit |
| ------------------------------------------------------------- | ---------- | ---------------------------------- |
| Serialized JSON-LD | 1MB | **Activity is rejected/dropped** |
| Profile fields (actor `PropertyValue` attachments) name/value | 2047 | Field name/value is truncated |
| Number of profile fields (actor `PropertyValue` attachments) | 50 | Fields list is truncated |
| Poll options (number of `anyOf`/`oneOf` in a `Question`) | 500 | Items list is truncated |
| Account username (actor `preferredUsername`) length | 2048 | **Actor will be rejected** |
| Account display name (actor `name`) length | 2048 | Display name will be truncated |
| Account note (actor `summary`) length | 20kB | Account note will be truncated |
| Account `attributionDomains` | 256 | List will be truncated |
| Account aliases (actor `alsoKnownAs`) | 256 | List will be truncated |
| Custom emoji shortcode (`Emoji` `name`) | 2048 | Emoji will be rejected |

View File

@ -128,7 +128,7 @@ GEM
blurhash (0.1.8)
bootsnap (1.18.6)
msgpack (~> 1.2)
brakeman (7.0.2)
brakeman (7.1.1)
racc
browser (6.2.0)
builder (3.3.0)
@ -224,7 +224,7 @@ GEM
mail (~> 2.7)
email_validator (2.2.4)
activemodel
erb (5.1.1)
erb (5.1.3)
erubi (1.13.1)
et-orbi (1.4.0)
tzinfo
@ -337,7 +337,7 @@ GEM
activesupport (>= 3.0)
nokogiri (>= 1.6)
io-console (0.8.1)
irb (1.15.2)
irb (1.15.3)
pp (>= 0.6.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
@ -621,7 +621,7 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
rack (3.2.3)
rack (3.2.4)
rack-attack (6.8.0)
rack (>= 1.0, < 4)
rack-cors (3.0.0)
@ -691,7 +691,7 @@ GEM
readline (~> 0.0)
rdf-normalize (0.7.0)
rdf (~> 3.3)
rdoc (6.15.0)
rdoc (6.15.1)
erb
psych (>= 4.0.0)
tsort
@ -791,7 +791,7 @@ GEM
ruby-vips (2.2.5)
ffi (~> 1.12)
logger
rubyzip (3.2.1)
rubyzip (3.2.2)
rufus-scheduler (3.9.2)
fugit (~> 1.1, >= 1.11.1)
safety_net_attestation (0.5.0)
@ -805,7 +805,7 @@ GEM
securerandom (0.4.1)
shoulda-matchers (6.5.0)
activesupport (>= 5.2.0)
sidekiq (8.0.8)
sidekiq (8.0.9)
connection_pool (>= 2.5.0)
json (>= 2.9.0)
logger (>= 1.6.2)

View File

@ -15,7 +15,7 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
| Version | Supported |
| ------- | ---------------- |
| 4.5.x | Yes |
| 4.4.x | Yes |
| 4.3.x | Yes |
| 4.2.x | Until 2026-01-08 |
| < 4.2 | No |
| 4.3.x | Until 2026-05-06 |
| < 4.3 | No |

View File

@ -4,17 +4,31 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
vary_by -> { 'Signature' if authorized_fetch_mode? }
before_action :require_account_signature!, if: :authorized_fetch_mode?
before_action :check_authorization
before_action :set_items
before_action :set_size
before_action :set_type
def show
expires_in 3.minutes, public: public_fetch_mode?
render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter
if @unauthorized
render json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter
else
render_with_cache json: collection_presenter, content_type: 'application/activity+json', serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter
end
end
private
def check_authorization
# Because in public fetch mode we cache the response, there would be no
# benefit from performing the check below, since a blocked account or domain
# would likely be served the cache from the reverse proxy anyway
@unauthorized = authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
end
def set_items
case params[:id]
when 'featured'
@ -57,11 +71,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
end
def for_signed_account
# Because in public fetch mode we cache the response, there would be no
# benefit from performing the check below, since a blocked account or domain
# would likely be served the cache from the reverse proxy anyway
if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
if @unauthorized
[]
else
yield

View File

@ -36,9 +36,8 @@ class ActivityPub::ContextsController < ActivityPub::BaseController
def context_presenter
first_page = ActivityPub::CollectionPresenter.new(
id: items_context_url(@conversation, page_params),
type: :unordered,
part_of: items_context_url(@conversation),
part_of: context_url(@conversation),
next: next_page,
items: @items.map { |status| status.local? ? ActivityPub::TagManager.instance.uri_for(status) : status.uri }
)
@ -52,7 +51,7 @@ class ActivityPub::ContextsController < ActivityPub::BaseController
page = ActivityPub::CollectionPresenter.new(
id: items_context_url(@conversation, page_params),
type: :unordered,
part_of: items_context_url(@conversation),
part_of: context_url(@conversation),
next: next_page,
items: @items.map { |status| status.local? ? ActivityPub::TagManager.instance.uri_for(status) : status.uri }
)

View File

@ -3,6 +3,7 @@
class ActivityPub::InboxesController < ActivityPub::BaseController
include JsonLdHelper
before_action :skip_large_payload
before_action :skip_unknown_actor_activity
before_action :require_actor_signature!
skip_before_action :authenticate_user!
@ -16,6 +17,10 @@ class ActivityPub::InboxesController < ActivityPub::BaseController
private
def skip_large_payload
head 413 if request.content_length > ActivityPub::Activity::MAX_JSON_SIZE
end
def skip_unknown_actor_activity
head 202 if unknown_affected_account?
end

View File

@ -22,7 +22,7 @@ class ActivityPub::LikesController < ActivityPub::BaseController
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -9,7 +9,7 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController
before_action :set_quote_authorization
def show
expires_in 30.seconds, public: true if @quote.status.distributable? && public_fetch_mode?
expires_in 30.seconds, public: true if @quote.quoted_status.distributable? && public_fetch_mode?
render json: @quote, serializer: ActivityPub::QuoteAuthorizationSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
end
@ -23,8 +23,8 @@ class ActivityPub::QuoteAuthorizationsController < ActivityPub::BaseController
@quote = Quote.accepted.where(quoted_account: @account).find(params[:id])
return not_found unless @quote.status.present? && @quote.quoted_status.present?
authorize @quote.status, :show?
rescue Mastodon::NotPermittedError
authorize @quote.quoted_status, :show?
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
end

View File

@ -25,7 +25,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -22,7 +22,7 @@ class ActivityPub::SharesController < ActivityPub::BaseController
def set_status
@status = @account.statuses.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -17,7 +17,7 @@ class Api::V1::Polls::VotesController < Api::BaseController
def set_poll
@poll = Poll.find(params[:poll_id])
authorize @poll.status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -17,7 +17,7 @@ class Api::V1::PollsController < Api::BaseController
def set_poll
@poll = Poll.find(params[:id])
authorize @poll.status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -10,7 +10,7 @@ class Api::V1::Statuses::BaseController < Api::BaseController
def set_status
@status = Status.find(params[:status_id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
end

View File

@ -23,7 +23,7 @@ class Api::V1::Statuses::BookmarksController < Api::V1::Statuses::BaseController
bookmark&.destroy!
render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_account.id, bookmarks_map: { @status.id => false })
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
end

View File

@ -25,7 +25,7 @@ class Api::V1::Statuses::FavouritesController < Api::V1::Statuses::BaseControlle
relationships = StatusRelationshipsPresenter.new([@status], current_account.id, favourites_map: { @status.id => false }, attributes_map: { @status.id => { favourites_count: count } })
render json: @status, serializer: REST::StatusSerializer, relationships: relationships
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
end

View File

@ -36,7 +36,7 @@ class Api::V1::Statuses::ReblogsController < Api::V1::Statuses::BaseController
relationships = StatusRelationshipsPresenter.new([@status], current_account.id, reblogs_map: { @reblog.id => false }, attributes_map: { @reblog.id => { reblogs_count: count } })
render json: @reblog, serializer: REST::StatusSerializer, relationships: relationships
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
@ -45,7 +45,7 @@ class Api::V1::Statuses::ReblogsController < Api::V1::Statuses::BaseController
def set_reblog
@reblog = Status.find(params[:status_id])
authorize @reblog, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -66,7 +66,7 @@ class Api::V1::StatusesController < Api::BaseController
if async_refresh.running?
add_async_refresh_header(async_refresh)
elsif !current_account.nil? && @status.should_fetch_replies?
add_async_refresh_header(AsyncRefresh.create(refresh_key))
add_async_refresh_header(AsyncRefresh.create(refresh_key, count_results: true))
WorkerBatch.new.within do |batch|
batch.connect(refresh_key, threshold: 1.0)
@ -106,9 +106,7 @@ class Api::V1::StatusesController < Api::BaseController
@status = Status.where(account: current_account).find(params[:id])
authorize @status, :update?
UpdateStatusService.new.call(
@status,
current_account.id,
update_options = {
text: status_params[:status],
media_ids: status_params[:media_ids],
media_attributes: status_params[:media_attributes],
@ -116,8 +114,11 @@ class Api::V1::StatusesController < Api::BaseController
language: status_params[:language],
spoiler_text: status_params[:spoiler_text],
poll: status_params[:poll],
quote_approval_policy: quote_approval_policy
)
}
update_options[:quote_approval_policy] = quote_approval_policy if status_params[:quote_approval_policy].present?
UpdateStatusService.new.call(@status, current_account.id, update_options)
render json: @status, serializer: REST::StatusSerializer
end
@ -145,7 +146,7 @@ class Api::V1::StatusesController < Api::BaseController
def set_status
@status = Status.find(params[:id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -30,7 +30,7 @@ class Api::Web::EmbedsController < Api::Web::BaseController
def set_status
@status = Status.find(params[:id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end
end

View File

@ -62,7 +62,7 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
end
def set_push_subscription
@push_subscription = ::Web::PushSubscription.find(params[:id])
@push_subscription = ::Web::PushSubscription.where(user_id: active_session.user_id).find(params[:id])
end
def subscription_params

View File

@ -21,7 +21,7 @@ class AuthorizeInteractionsController < ApplicationController
def set_resource
@resource = located_resource
authorize(@resource, :show?) if @resource.is_a?(Status)
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -19,7 +19,7 @@ module CacheConcern
# from being used as cache keys, while allowing to `Vary` on them (to not serve
# anonymous cached data to authenticated requests when authentication matters)
def enforce_cache_control!
vary = response.headers['Vary']&.split&.map { |x| x.strip.downcase }
vary = response.headers['Vary'].to_s.split(',').map { |x| x.strip.downcase }.reject(&:empty?)
return unless vary.present? && %w(cookie authorization signature).any? { |header| vary.include?(header) && request.headers[header].present? }
response.cache_control.replace(private: true, no_store: true)

View File

@ -72,10 +72,13 @@ module SignatureVerification
rescue Mastodon::SignatureVerificationError => e
fail_with! e.message
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
@signature_verification_failure_code ||= 503
fail_with! "Failed to fetch remote data: #{e.message}"
rescue Mastodon::UnexpectedResponseError
@signature_verification_failure_code ||= 503
fail_with! 'Failed to fetch remote data (got unexpected reply from server)'
rescue Stoplight::Error::RedLight
@signature_verification_failure_code ||= 503
fail_with! 'Fetching attempt skipped because of recent connection failure'
end

View File

@ -34,7 +34,7 @@ class MediaController < ApplicationController
def verify_permitted_status!
authorize @media_attachment.status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -26,7 +26,7 @@ class SeveredRelationshipsController < ApplicationController
private
def set_event
@event = AccountRelationshipSeveranceEvent.find(params[:id])
@event = AccountRelationshipSeveranceEvent.where(account: current_account).find(params[:id])
end
def following_data

View File

@ -29,7 +29,7 @@ class StatusesController < ApplicationController
end
format.json do
expires_in 3.minutes, public: true if @status.distributable? && public_fetch_mode?
expires_in @status.quote&.pending? ? 5.seconds : 3.minutes, public: true if @status.distributable? && public_fetch_mode?
render_with_cache json: @status, content_type: 'application/activity+json', serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter
end
end
@ -62,7 +62,7 @@ class StatusesController < ApplicationController
def set_status
@status = @account.statuses.find(params[:id])
authorize @status, :show?
rescue Mastodon::NotPermittedError
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
not_found
end

View File

@ -5,6 +5,7 @@ import { throttle } from 'lodash';
import api from 'mastodon/api';
import { browserHistory } from 'mastodon/components/router';
import { countableText } from 'mastodon/features/compose/util/counter';
import { search as emojiSearch } from 'mastodon/features/emoji/emoji_mart_search_light';
import { tagHistory } from 'mastodon/settings';
@ -55,7 +56,6 @@ export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
export const COMPOSE_VISIBILITY_CHANGE = 'COMPOSE_VISIBILITY_CHANGE';
export const COMPOSE_COMPOSING_CHANGE = 'COMPOSE_COMPOSING_CHANGE';
export const COMPOSE_LANGUAGE_CHANGE = 'COMPOSE_LANGUAGE_CHANGE';
@ -88,6 +88,7 @@ const messages = defineMessages({
open: { id: 'compose.published.open', defaultMessage: 'Open' },
published: { id: 'compose.published.body', defaultMessage: 'Post published.' },
saved: { id: 'compose.saved.body', defaultMessage: 'Post saved.' },
blankPostError: { id: 'compose.error.blank_post', defaultMessage: 'Post can\'t be blank.' },
});
export const ensureComposeIsVisible = (getState) => {
@ -197,7 +198,15 @@ export function submitCompose(successCallback) {
const hasQuote = !!getState().getIn(['compose', 'quoted_status_id']);
const spoiler_text = getState().getIn(['compose', 'spoiler']) ? getState().getIn(['compose', 'spoiler_text'], '') : '';
if (!(status?.length || media.size !== 0 || (hasQuote && spoiler_text?.length))) {
const fulltext = `${spoiler_text ?? ''}${countableText(status ?? '')}`;
const hasText = fulltext.trim().length > 0;
if (!(hasText || media.size !== 0 || (hasQuote && spoiler_text?.length))) {
dispatch(showAlert({
message: messages.blankPostError,
}));
dispatch(focusCompose());
return;
}
@ -664,8 +673,17 @@ export function selectComposeSuggestion(position, token, suggestion, path) {
dispatch(useEmoji(suggestion));
} else if (suggestion.type === 'hashtag') {
completion = suggestion.name.slice(token.length - 1);
startPosition = position + token.length;
// TODO: it could make sense to keep the “most capitalized” of the two
const tokenName = token.slice(1); // strip leading '#'
const suggestionPrefix = suggestion.name.slice(0, tokenName.length);
const prefixMatchesSuggestion = suggestionPrefix.localeCompare(tokenName, undefined, { sensitivity: 'accent' }) === 0;
if (prefixMatchesSuggestion) {
completion = token + suggestion.name.slice(tokenName.length);
} else {
completion = `${token.slice(0, 1)}${suggestion.name}`;
}
startPosition = position - 1;
} else if (suggestion.type === 'account') {
completion = `@${getState().getIn(['accounts', suggestion.id, 'acct'])}`;
startPosition = position - 1;
@ -784,13 +802,6 @@ export function changeComposeSpoilerText(text) {
};
}
export function changeComposeVisibility(value) {
return {
type: COMPOSE_VISIBILITY_CHANGE,
value,
};
}
export function insertEmojiCompose(position, emoji, needsSpace) {
return {
type: COMPOSE_EMOJI_INSERT,

View File

@ -13,10 +13,11 @@ import {
} from 'mastodon/store/typed_functions';
import type { ApiQuotePolicy } from '../api_types/quotes';
import type { Status } from '../models/status';
import type { Status, StatusVisibility } from '../models/status';
import type { RootState } from '../store';
import { showAlert } from './alerts';
import { focusCompose } from './compose';
import { changeCompose, focusCompose } from './compose';
import { importFetchedStatuses } from './importer';
import { openModal } from './modal';
@ -41,6 +42,10 @@ const messages = defineMessages({
id: 'quote_error.unauthorized',
defaultMessage: 'You are not authorized to quote this post.',
},
quoteErrorPrivateMention: {
id: 'quote_error.private_mentions',
defaultMessage: 'Quoting is not allowed with direct mentions.',
},
});
type SimulatedMediaAttachmentJSON = ApiMediaAttachmentJSON & {
@ -67,6 +72,39 @@ const simulateModifiedApiResponse = (
return data;
};
export const changeComposeVisibility = createAppThunk(
'compose/visibility_change',
(visibility: StatusVisibility, { dispatch, getState }) => {
if (visibility !== 'direct') {
return visibility;
}
const state = getState();
const quotedStatusId = state.compose.get('quoted_status_id') as
| string
| null;
if (!quotedStatusId) {
return visibility;
}
// Remove the quoted status
dispatch(quoteComposeCancel());
const quotedStatus = state.statuses.get(quotedStatusId) as Status | null;
if (!quotedStatus) {
return visibility;
}
// Append the quoted status URL to the compose text
const url = quotedStatus.get('url') as string;
const text = state.compose.get('text') as string;
if (!text.includes(url)) {
const newText = text.trim() ? `${text}\n\n${url}` : url;
dispatch(changeCompose(newText));
}
return visibility;
},
);
export const changeUploadCompose = createDataLoadingThunk(
'compose/changeUpload',
async (
@ -130,6 +168,8 @@ export const quoteComposeByStatus = createAppThunk(
if (composeState.get('id')) {
dispatch(showAlert({ message: messages.quoteErrorEdit }));
} else if (composeState.get('privacy') === 'direct') {
dispatch(showAlert({ message: messages.quoteErrorPrivateMention }));
} else if (composeState.get('poll')) {
dispatch(showAlert({ message: messages.quoteErrorPoll }));
} else if (
@ -173,6 +213,17 @@ export const quoteComposeById = createAppThunk(
},
);
const composeStateForbidsLink = (composeState: RootState['compose']) => {
return (
composeState.get('quoted_status_id') ||
composeState.get('is_submitting') ||
composeState.get('poll') ||
composeState.get('is_uploading') ||
composeState.get('id') ||
composeState.get('privacy') === 'direct'
);
};
export const pasteLinkCompose = createDataLoadingThunk(
'compose/pasteLink',
async ({ url }: { url: string }) => {
@ -183,15 +234,12 @@ export const pasteLinkCompose = createDataLoadingThunk(
limit: 2,
});
},
(data, { dispatch, getState }) => {
(data, { dispatch, getState, requestId }) => {
const composeState = getState().compose;
if (
composeState.get('quoted_status_id') ||
composeState.get('is_submitting') ||
composeState.get('poll') ||
composeState.get('is_uploading') ||
composeState.get('id')
composeStateForbidsLink(composeState) ||
composeState.get('fetching_link') !== requestId // Request has been cancelled
)
return;
@ -207,6 +255,17 @@ export const pasteLinkCompose = createDataLoadingThunk(
dispatch(quoteComposeById(data.statuses[0].id));
}
},
{
useLoadingBar: false,
condition: (_, { getState }) =>
!getState().compose.get('fetching_link') &&
!composeStateForbidsLink(getState().compose),
},
);
// Ideally this would cancel the action and the HTTP request, but this is good enough
export const cancelPasteLinkCompose = createAction(
'compose/cancelPasteLinkCompose',
);
export const quoteComposeCancel = createAction('compose/quoteComposeCancel');

View File

@ -46,11 +46,11 @@ export function importFetchedAccounts(accounts) {
return importAccounts({ accounts: normalAccounts });
}
export function importFetchedStatus(status) {
return importFetchedStatuses([status]);
export function importFetchedStatus(status, options = {}) {
return importFetchedStatuses([status], options);
}
export function importFetchedStatuses(statuses) {
export function importFetchedStatuses(statuses, options = {}) {
return (dispatch, getState) => {
const accounts = [];
const normalStatuses = [];
@ -58,7 +58,7 @@ export function importFetchedStatuses(statuses) {
const filters = [];
function processStatus(status) {
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id]), options));
pushUnique(accounts, status.account);
if (status.filtered) {

View File

@ -27,9 +27,12 @@ function stripQuoteFallback(text) {
return wrapper.innerHTML;
}
export function normalizeStatus(status, normalOldStatus) {
export function normalizeStatus(status, normalOldStatus, { bogusQuotePolicy = false }) {
const normalStatus = { ...status };
if (bogusQuotePolicy)
normalStatus.quote_approval = null;
normalStatus.account = status.account.id;
if (status.reblog && status.reblog.id) {
@ -109,6 +112,8 @@ export function normalizeStatus(status, normalOldStatus) {
}
if (normalOldStatus) {
normalStatus.quote_approval ||= normalOldStatus.get('quote_approval');
const list = normalOldStatus.get('media_attachments');
if (normalStatus.media_attachments && list) {
normalStatus.media_attachments.forEach(item => {

View File

@ -85,6 +85,8 @@ export function fetchStatus(id, {
dispatch(fetchStatusSuccess(skipLoading));
}).catch(error => {
dispatch(fetchStatusFail(id, error, skipLoading, parentQuotePostId));
if (error.status === 404)
dispatch(deleteFromTimelines(id));
});
};
}
@ -203,8 +205,8 @@ export function deleteStatusFail(id, error) {
};
}
export const updateStatus = status => dispatch =>
dispatch(importFetchedStatus(status));
export const updateStatus = (status, { bogusQuotePolicy }) => dispatch =>
dispatch(importFetchedStatus(status, { bogusQuotePolicy }));
export function muteStatus(id) {
return (dispatch) => {

View File

@ -52,6 +52,9 @@ const randomUpTo = max =>
export const connectTimelineStream = (timelineId, channelName, params = {}, options = {}) => {
const { messages } = getLocale();
// Public streams are currently not returning personalized quote policies
const bogusQuotePolicy = channelName.startsWith('public') || channelName.startsWith('hashtag');
return connectStream(channelName, params, (dispatch, getState) => {
// @ts-ignore
const locale = getState().getIn(['meta', 'locale']);
@ -97,11 +100,11 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
switch (data.event) {
case 'update':
// @ts-expect-error
dispatch(updateTimeline(timelineId, JSON.parse(data.payload), options.accept));
dispatch(updateTimeline(timelineId, JSON.parse(data.payload), { accept: options.accept, bogusQuotePolicy }));
break;
case 'status.update':
// @ts-expect-error
dispatch(updateStatus(JSON.parse(data.payload)));
dispatch(updateStatus(JSON.parse(data.payload), { bogusQuotePolicy }));
break;
case 'delete':
dispatch(deleteFromTimelines(data.payload));

View File

@ -32,7 +32,7 @@ export const loadPending = timeline => ({
timeline,
});
export function updateTimeline(timeline, status, accept) {
export function updateTimeline(timeline, status, { accept = undefined, bogusQuotePolicy = false } = {}) {
return (dispatch, getState) => {
if (typeof accept === 'function' && !accept(status)) {
return;
@ -45,7 +45,7 @@ export function updateTimeline(timeline, status, accept) {
return;
}
dispatch(importFetchedStatus(status));
dispatch(importFetchedStatus(status, { bogusQuotePolicy }));
dispatch({
type: TIMELINE_UPDATE,

View File

@ -6,7 +6,6 @@ import CheckIcon from '@/material-icons/400-24px/check.svg?react';
import { Icon } from 'mastodon/components/icon';
import type { Account } from 'mastodon/models/account';
import { CustomEmojiProvider } from './emoji/context';
import { EmojiHTML } from './emoji/html';
import { useElementHandledLink } from './status/handled_link';
@ -22,12 +21,13 @@ export const AccountFields: React.FC<Pick<Account, 'fields' | 'emojis'>> = ({
}
return (
<CustomEmojiProvider emojis={emojis}>
<>
{fields.map((pair, i) => (
<dl key={i} className={classNames({ verified: pair.verified_at })}>
<EmojiHTML
as='dt'
htmlString={pair.name_emojified}
extraEmojis={emojis}
className='translate'
{...htmlHandlers}
/>
@ -52,12 +52,13 @@ export const AccountFields: React.FC<Pick<Account, 'fields' | 'emojis'>> = ({
<EmojiHTML
as='span'
htmlString={pair.value_emojified}
extraEmojis={emojis}
{...htmlHandlers}
/>
</dd>
</dl>
))}
</CustomEmojiProvider>
</>
);
};

View File

@ -28,7 +28,7 @@ const textAtCursorMatchesToken = (str, caretPosition, searchTokens) => {
return [null, null];
}
word = word.trim().toLowerCase();
word = word.trim();
if (word.length > 0) {
return [left + 1, word];

View File

@ -29,7 +29,7 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
return [null, null];
}
word = word.trim().toLowerCase();
word = word.trim();
if (word.length > 0) {
return [left + 1, word];

View File

@ -31,7 +31,7 @@ export const ContentWarning: React.FC<{
<EmojiHTML
as='span'
htmlString={text}
extraEmojis={status.get('emoji') as List<CustomEmoji>}
extraEmojis={status.get('emojis') as List<CustomEmoji>}
/>
</StatusBanner>
);

View File

@ -26,6 +26,7 @@ import {
closeDropdownMenu,
} from 'mastodon/actions/dropdown_menu';
import { openModal, closeModal } from 'mastodon/actions/modal';
import { fetchStatus } from 'mastodon/actions/statuses';
import { CircularProgress } from 'mastodon/components/circular_progress';
import { isUserTouching } from 'mastodon/is_mobile';
import {
@ -42,16 +43,10 @@ import { IconButton } from './icon_button';
let id = 0;
export interface RenderItemFnHandlers {
onClick: React.MouseEventHandler;
onKeyUp: React.KeyboardEventHandler;
}
export type RenderItemFn<Item = MenuItem> = (
item: Item,
index: number,
handlers: RenderItemFnHandlers,
focusRefCallback?: (c: HTMLAnchorElement | HTMLButtonElement | null) => void,
onClick: React.MouseEventHandler,
) => React.ReactNode;
type ItemClickFn<Item = MenuItem> = (item: Item, index: number) => void;
@ -101,7 +96,6 @@ export const DropdownMenu = <Item = MenuItem,>({
onItemClick,
}: DropdownMenuProps<Item>) => {
const nodeRef = useRef<HTMLDivElement>(null);
const focusedItemRef = useRef<HTMLElement | null>(null);
useEffect(() => {
const handleDocumentClick = (e: MouseEvent) => {
@ -163,8 +157,11 @@ export const DropdownMenu = <Item = MenuItem,>({
document.addEventListener('click', handleDocumentClick, { capture: true });
document.addEventListener('keydown', handleKeyDown, { capture: true });
if (focusedItemRef.current && openedViaKeyboard) {
focusedItemRef.current.focus({ preventScroll: true });
if (openedViaKeyboard) {
const firstMenuItem = nodeRef.current?.querySelector<
HTMLAnchorElement | HTMLButtonElement
>('li:first-child > :is(a, button)');
firstMenuItem?.focus({ preventScroll: true });
}
return () => {
@ -175,13 +172,6 @@ export const DropdownMenu = <Item = MenuItem,>({
};
}, [onClose, openedViaKeyboard]);
const handleFocusedItemRef = useCallback(
(c: HTMLAnchorElement | HTMLButtonElement | null) => {
focusedItemRef.current = c as HTMLElement;
},
[],
);
const handleItemClick = useCallback(
(e: React.MouseEvent | React.KeyboardEvent) => {
const i = Number(e.currentTarget.getAttribute('data-index'));
@ -207,15 +197,6 @@ export const DropdownMenu = <Item = MenuItem,>({
[onClose, onItemClick, items],
);
const handleItemKeyUp = useCallback(
(e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
handleItemClick(e);
}
},
[handleItemClick],
);
const nativeRenderItem = (option: Item, i: number) => {
if (!isMenuItem(option)) {
return null;
@ -232,9 +213,7 @@ export const DropdownMenu = <Item = MenuItem,>({
if (isActionItem(option)) {
element = (
<button
ref={i === 0 ? handleFocusedItemRef : undefined}
onClick={handleItemClick}
onKeyUp={handleItemKeyUp}
data-index={i}
aria-disabled={disabled}
>
@ -248,9 +227,7 @@ export const DropdownMenu = <Item = MenuItem,>({
target={option.target ?? '_target'}
data-method={option.method}
rel='noopener'
ref={i === 0 ? handleFocusedItemRef : undefined}
onClick={handleItemClick}
onKeyUp={handleItemKeyUp}
data-index={i}
>
<DropdownMenuItemContent item={option} />
@ -258,13 +235,7 @@ export const DropdownMenu = <Item = MenuItem,>({
);
} else {
element = (
<Link
to={option.to}
ref={i === 0 ? handleFocusedItemRef : undefined}
onClick={handleItemClick}
onKeyUp={handleItemKeyUp}
data-index={i}
>
<Link to={option.to} onClick={handleItemClick} data-index={i}>
<DropdownMenuItemContent item={option} />
</Link>
);
@ -307,15 +278,7 @@ export const DropdownMenu = <Item = MenuItem,>({
})}
>
{items.map((option, i) =>
renderItemMethod(
option,
i,
{
onClick: handleItemClick,
onKeyUp: handleItemKeyUp,
},
i === 0 ? handleFocusedItemRef : undefined,
),
renderItemMethod(option, i, handleItemClick),
)}
</ul>
)}
@ -340,6 +303,7 @@ interface DropdownProps<Item extends object | null = MenuItem> {
*/
scrollKey?: string;
status?: ImmutableMap<string, unknown>;
needsStatusRefresh?: boolean;
forceDropdown?: boolean;
renderItem?: RenderItemFn<Item>;
renderHeader?: RenderHeaderFn<Item>;
@ -363,6 +327,7 @@ export const Dropdown = <Item extends object | null = MenuItem>({
placement = 'bottom',
offset = [5, 5],
status,
needsStatusRefresh,
forceDropdown = false,
renderItem,
renderHeader,
@ -382,6 +347,7 @@ export const Dropdown = <Item extends object | null = MenuItem>({
const prefetchAccountId = status
? status.getIn(['account', 'id'])
: undefined;
const statusId = status?.get('id') as string | undefined;
const handleClose = useCallback(() => {
if (buttonRef.current) {
@ -399,7 +365,7 @@ export const Dropdown = <Item extends object | null = MenuItem>({
}, [dispatch, currentId]);
const handleItemClick = useCallback(
(e: React.MouseEvent | React.KeyboardEvent) => {
(e: React.MouseEvent) => {
const i = Number(e.currentTarget.getAttribute('data-index'));
const item = items?.[i];
@ -420,10 +386,20 @@ export const Dropdown = <Item extends object | null = MenuItem>({
[handleClose, onItemClick, items],
);
const toggleDropdown = useCallback(
(e: React.MouseEvent | React.KeyboardEvent) => {
const { type } = e;
const isKeypressRef = useRef(false);
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
if (e.key === ' ' || e.key === 'Enter') {
isKeypressRef.current = true;
}
}, []);
const unsetIsKeypress = useCallback(() => {
isKeypressRef.current = false;
}, []);
const toggleDropdown = useCallback(
(e: React.MouseEvent) => {
if (open) {
handleClose();
} else {
@ -436,6 +412,15 @@ export const Dropdown = <Item extends object | null = MenuItem>({
dispatch(fetchRelationships([prefetchAccountId]));
}
if (needsStatusRefresh && statusId) {
dispatch(
fetchStatus(statusId, {
forceFetch: true,
alsoFetchContext: false,
}),
);
}
if (isUserTouching() && !forceDropdown) {
dispatch(
openModal({
@ -450,10 +435,11 @@ export const Dropdown = <Item extends object | null = MenuItem>({
dispatch(
openDropdownMenu({
id: currentId,
keyboard: type !== 'click',
keyboard: isKeypressRef.current,
scrollKey,
}),
);
isKeypressRef.current = false;
}
}
},
@ -468,6 +454,8 @@ export const Dropdown = <Item extends object | null = MenuItem>({
items,
forceDropdown,
handleClose,
statusId,
needsStatusRefresh,
],
);
@ -484,6 +472,9 @@ export const Dropdown = <Item extends object | null = MenuItem>({
const buttonProps = {
disabled,
onClick: toggleDropdown,
onKeyDown: handleKeyDown,
onKeyUp: unsetIsKeypress,
onBlur: unsetIsKeypress,
'aria-expanded': open,
'aria-controls': menuId,
ref: buttonRef,

View File

@ -58,17 +58,7 @@ export const EditedTimestamp: React.FC<{
}, []);
const renderItem = useCallback(
(
item: HistoryItem,
index: number,
{
onClick,
onKeyUp,
}: {
onClick: React.MouseEventHandler;
onKeyUp: React.KeyboardEventHandler;
},
) => {
(item: HistoryItem, index: number, onClick: React.MouseEventHandler) => {
const formattedDate = (
<RelativeTimestamp
timestamp={item.get('created_at') as string}
@ -98,7 +88,7 @@ export const EditedTimestamp: React.FC<{
className='dropdown-menu__item edited-timestamp__history__item'
key={item.get('created_at') as string}
>
<button data-index={index} onClick={onClick} onKeyUp={onKeyUp}>
<button data-index={index} onClick={onClick} type='button'>
{label}
</button>
</li>

View File

@ -180,25 +180,24 @@ export function useHotkeys<T extends HTMLElement>(handlers: HandlerMap) {
if (shouldHandleEvent) {
const matchCandidates: {
handler: (event: KeyboardEvent) => void;
// A candidate will be have an undefined handler if it's matched,
// but handled in a parent component rather than this one.
handler: ((event: KeyboardEvent) => void) | undefined;
priority: number;
}[] = [];
(Object.keys(hotkeyMatcherMap) as HotkeyName[]).forEach(
(handlerName) => {
const handler = handlersRef.current[handlerName];
const hotkeyMatcher = hotkeyMatcherMap[handlerName];
if (handler) {
const hotkeyMatcher = hotkeyMatcherMap[handlerName];
const { isMatch, priority } = hotkeyMatcher(
event,
bufferedKeys.current,
);
const { isMatch, priority } = hotkeyMatcher(
event,
bufferedKeys.current,
);
if (isMatch) {
matchCandidates.push({ handler, priority });
}
if (isMatch) {
matchCandidates.push({ handler, priority });
}
},
);

View File

@ -145,6 +145,7 @@ class Status extends ImmutablePureComponent {
'hidden',
'unread',
'pictureInPicture',
'onQuoteCancel',
];
state = {

View File

@ -8,13 +8,14 @@ import classNames from 'classnames';
import { quoteComposeById } from '@/mastodon/actions/compose_typed';
import { toggleReblog } from '@/mastodon/actions/interactions';
import { openModal } from '@/mastodon/actions/modal';
import { fetchStatus } from '@/mastodon/actions/statuses';
import { quickBoosting } from '@/mastodon/initial_state';
import type { ActionMenuItem } from '@/mastodon/models/dropdown_menu';
import type { Status } from '@/mastodon/models/status';
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
import type { SomeRequired } from '@/mastodon/utils/types';
import type { RenderItemFn, RenderItemFnHandlers } from '../dropdown_menu';
import type { RenderItemFn } from '../dropdown_menu';
import { Dropdown, DropdownMenuItemContent } from '../dropdown_menu';
import { IconButton } from '../icon_button';
@ -74,18 +75,12 @@ const StandaloneBoostButton: FC<ReblogButtonProps> = ({ status, counters }) => {
);
};
const renderMenuItem: RenderItemFn<ActionMenuItem> = (
item,
index,
handlers,
focusRefCallback,
) => (
const renderMenuItem: RenderItemFn<ActionMenuItem> = (item, index, onClick) => (
<ReblogMenuItem
index={index}
item={item}
handlers={handlers}
onClick={onClick}
key={`${item.text}-${index}`}
focusRefCallback={focusRefCallback}
/>
);
@ -117,6 +112,7 @@ const BoostOrQuoteMenu: FC<ReblogButtonProps> = ({ status, counters }) => {
const statusId = status.get('id') as string;
const wasBoosted = !!status.get('reblogged');
const quoteApproval = status.get('quote_approval');
const showLoginPrompt = useCallback(() => {
dispatch(
@ -173,9 +169,16 @@ const BoostOrQuoteMenu: FC<ReblogButtonProps> = ({ status, counters }) => {
dispatch(toggleReblog(status.get('id'), true));
return false;
}
if (quoteApproval === null) {
dispatch(
fetchStatus(statusId, { forceFetch: true, alsoFetchContext: false }),
);
}
return true;
},
[dispatch, isLoggedIn, showLoginPrompt, status],
[dispatch, isLoggedIn, showLoginPrompt, status, quoteApproval, statusId],
);
return (
@ -208,16 +211,10 @@ const BoostOrQuoteMenu: FC<ReblogButtonProps> = ({ status, counters }) => {
interface ReblogMenuItemProps {
item: ActionMenuItem;
index: number;
handlers: RenderItemFnHandlers;
focusRefCallback?: (c: HTMLAnchorElement | HTMLButtonElement | null) => void;
onClick: React.MouseEventHandler;
}
const ReblogMenuItem: FC<ReblogMenuItemProps> = ({
index,
item,
handlers,
focusRefCallback,
}) => {
const ReblogMenuItem: FC<ReblogMenuItemProps> = ({ index, item, onClick }) => {
const { text, highlighted, disabled } = item;
return (
@ -227,12 +224,7 @@ const ReblogMenuItem: FC<ReblogMenuItemProps> = ({
})}
key={`${text}-${index}`}
>
<button
{...handlers}
ref={focusRefCallback}
aria-disabled={disabled}
data-index={index}
>
<button onClick={onClick} aria-disabled={disabled} data-index={index}>
<DropdownMenuItemContent item={item} />
</button>
</li>

View File

@ -27,16 +27,18 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
}) => {
// Handle hashtags
if (
text.startsWith('#') ||
prevText?.endsWith('#') ||
text.startsWith('') ||
prevText?.endsWith('')
(text.startsWith('#') ||
prevText?.endsWith('#') ||
text.startsWith('') ||
prevText?.endsWith('')) &&
!text.includes('%')
) {
const hashtag = text.slice(1).trim();
return (
<Link
className={classNames('mention hashtag', className)}
to={`/tags/${hashtag}`}
to={`/tags/${encodeURIComponent(hashtag)}`}
rel='tag'
data-menu-hashtag={hashtagAccountId}
>
@ -73,7 +75,7 @@ export const HandledLink: FC<HandledLinkProps & ComponentProps<'a'>> = ({
title={href}
className={classNames('unhandled-link', className)}
target='_blank'
rel='noreferrer noopener'
rel='noopener'
translate='no'
>
{children}

View File

@ -404,6 +404,7 @@ class StatusActionBar extends ImmutablePureComponent {
<Dropdown
scrollKey={scrollKey}
status={status}
needsStatusRefresh={quickBoosting && status.get('quote_approval') === null}
items={menu}
icon='ellipsis-h'
iconComponent={MoreHorizIcon}

View File

@ -0,0 +1,3 @@
.inlineIcon {
vertical-align: middle;
}

View File

@ -12,6 +12,8 @@ import { Button } from '../button';
import { useDismissableBannerState } from '../dismissable_banner';
import { Icon } from '../icon';
import classes from './remove_quote_hint.module.css';
const DISMISSABLE_BANNER_ID = 'notifications/remove_quote_hint';
/**
@ -93,7 +95,7 @@ export const RemoveQuoteHint: React.FC<{
id: 'status.more',
defaultMessage: 'More',
})}
style={{ verticalAlign: 'middle' }}
className={classes.inlineIcon}
/>
),
}}

View File

@ -49,6 +49,7 @@ export const StatusBanner: React.FC<{
<button
ref={buttonRef}
type='button'
className='link-button'
onClick={onClick}
aria-describedby={descriptionId}

View File

@ -32,16 +32,38 @@ interface Rule extends BaseRule {
translations?: Record<string, BaseRule>;
}
function getDefaultSelectedLocale(
currentUiLocale: string,
localeOptions: SelectItem[],
) {
const preciseMatch = localeOptions.find(
(option) => option.value === currentUiLocale,
);
if (preciseMatch) {
return preciseMatch.value;
}
const partialLocale = currentUiLocale.split('-')[0];
const partialMatch = localeOptions.find(
(option) => option.value.split('-')[0] === partialLocale,
);
return partialMatch?.value ?? 'default';
}
export const RulesSection: FC<RulesSectionProps> = ({ isLoading = false }) => {
const intl = useIntl();
const [locale, setLocale] = useState(intl.locale);
const rules = useAppSelector((state) => rulesSelector(state, locale));
const localeOptions = useAppSelector((state) =>
localeOptionsSelector(state, intl),
);
const [selectedLocale, setSelectedLocale] = useState(() =>
getDefaultSelectedLocale(intl.locale, localeOptions),
);
const rules = useAppSelector((state) => rulesSelector(state, selectedLocale));
const handleLocaleChange: ChangeEventHandler<HTMLSelectElement> = useCallback(
(e) => {
setLocale(e.currentTarget.value);
setSelectedLocale(e.currentTarget.value);
},
[],
);
@ -74,25 +96,27 @@ export const RulesSection: FC<RulesSectionProps> = ({ isLoading = false }) => {
))}
</ol>
<div className='rules-languages'>
<label htmlFor='language-select'>
<FormattedMessage
id='about.language_label'
defaultMessage='Language'
/>
</label>
<select onChange={handleLocaleChange} id='language-select'>
{localeOptions.map((option) => (
<option
key={option.value}
value={option.value}
selected={option.value === locale}
>
{option.text}
</option>
))}
</select>
</div>
{localeOptions.length > 1 && (
<div className='rules-languages'>
<label htmlFor='language-select'>
<FormattedMessage
id='about.language_label'
defaultMessage='Language'
/>
</label>
<select onChange={handleLocaleChange} id='language-select'>
{localeOptions.map((option) => (
<option
key={option.value}
value={option.value}
selected={option.value === selectedLocale}
>
{option.text}
</option>
))}
</select>
</div>
)}
</Section>
);
};
@ -145,9 +169,13 @@ const localeOptionsSelector = createSelector(
},
};
// Use the default locale as a target to translate language names.
const intlLocale = new Intl.DisplayNames(intl.locale, {
type: 'language',
});
const intlLocale =
// Intl.DisplayNames can be undefined in old browsers
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Intl.DisplayNames &&
(new Intl.DisplayNames(intl.locale, {
type: 'language',
}) as Intl.DisplayNames | undefined);
for (const { translations } of rules) {
for (const locale in translations) {
if (langs[locale]) {
@ -155,7 +183,7 @@ const localeOptionsSelector = createSelector(
}
langs[locale] = {
value: locale,
text: intlLocale.of(locale) ?? locale,
text: intlLocale?.of(locale) ?? locale,
};
}
}

View File

@ -330,7 +330,7 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
});
}, [dispatch, setIsSaving, mediaId, onClose, position, description]);
const handleKeyUp = useCallback(
const handleKeyDown = useCallback(
(e: React.KeyboardEvent) => {
if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
e.preventDefault();
@ -457,7 +457,7 @@ export const AltTextModal = forwardRef<ModalRef, Props & Partial<RestoreProps>>(
id='description'
value={isDetecting ? ' ' : description}
onChange={handleDescriptionChange}
onKeyUp={handleKeyUp}
onKeyDown={handleKeyDown}
lang={lang}
placeholder={intl.formatMessage(
type === 'audio'

View File

@ -1,4 +1,4 @@
import { useEffect, useRef, useCallback, useState, useId } from 'react';
import { useEffect, useRef, useCallback, useState } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
@ -22,6 +22,8 @@ import { useAudioVisualizer } from 'mastodon/hooks/useAudioVisualizer';
import { displayMedia, useBlurhash } from 'mastodon/initial_state';
import { playerSettings } from 'mastodon/settings';
import { AudioVisualizer } from './visualizer';
const messages = defineMessages({
play: { id: 'video.play', defaultMessage: 'Play' },
pause: { id: 'video.pause', defaultMessage: 'Pause' },
@ -116,7 +118,6 @@ export const Audio: React.FC<{
const seekRef = useRef<HTMLDivElement>(null);
const volumeRef = useRef<HTMLDivElement>(null);
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>();
const accessibilityId = useId();
const { audioContextRef, sourceRef, gainNodeRef, playAudio, pauseAudio } =
useAudioContext({ audioElementRef: audioRef });
@ -538,19 +539,6 @@ export const Audio: React.FC<{
[togglePlay, toggleMute],
);
const springForBand0 = useSpring({
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
config: config.wobbly,
});
const springForBand1 = useSpring({
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
config: config.wobbly,
});
const springForBand2 = useSpring({
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
config: config.wobbly,
});
const progress = Math.min((currentTime / loadedDuration) * 100, 100);
const effectivelyMuted = muted || volume === 0;
@ -641,81 +629,7 @@ export const Audio: React.FC<{
</div>
<div className='audio-player__controls__play'>
<svg
className='audio-player__visualizer'
viewBox='0 0 124 124'
xmlns='http://www.w3.org/2000/svg'
>
<animated.circle
opacity={0.5}
cx={57}
cy={62.5}
r={springForBand0.r}
fill='var(--player-accent-color)'
/>
<animated.circle
opacity={0.5}
cx={65}
cy={57.5}
r={springForBand1.r}
fill='var(--player-accent-color)'
/>
<animated.circle
opacity={0.5}
cx={63}
cy={66.5}
r={springForBand2.r}
fill='var(--player-accent-color)'
/>
<g clipPath={`url(#${accessibilityId}-clip)`}>
<rect
x={14}
y={14}
width={96}
height={96}
fill={`url(#${accessibilityId}-pattern)`}
/>
<rect
x={14}
y={14}
width={96}
height={96}
fill='var(--player-background-color'
opacity={0.45}
/>
</g>
<defs>
<pattern
id={`${accessibilityId}-pattern`}
patternContentUnits='objectBoundingBox'
width='1'
height='1'
>
<use href={`#${accessibilityId}-image`} />
</pattern>
<clipPath id={`${accessibilityId}-clip`}>
<rect
x={14}
y={14}
width={96}
height={96}
rx={48}
fill='white'
/>
</clipPath>
<image
id={`${accessibilityId}-image`}
href={poster}
width={1}
height={1}
preserveAspectRatio='none'
/>
</defs>
</svg>
<AudioVisualizer frequencyBands={frequencyBands} poster={poster} />
<button
type='button'

View File

@ -0,0 +1,100 @@
import { useId } from 'react';
import type { FC } from 'react';
import { animated, config, useSpring } from '@react-spring/web';
interface AudioVisualizerProps {
frequencyBands?: number[];
poster?: string;
}
export const AudioVisualizer: FC<AudioVisualizerProps> = ({
frequencyBands = [],
poster,
}) => {
const accessibilityId = useId();
const springForBand0 = useSpring({
to: { r: 50 + (frequencyBands[0] ?? 0) * 10 },
config: config.wobbly,
});
const springForBand1 = useSpring({
to: { r: 50 + (frequencyBands[1] ?? 0) * 10 },
config: config.wobbly,
});
const springForBand2 = useSpring({
to: { r: 50 + (frequencyBands[2] ?? 0) * 10 },
config: config.wobbly,
});
return (
<svg
className='audio-player__visualizer'
viewBox='0 0 124 124'
xmlns='http://www.w3.org/2000/svg'
>
<animated.circle
opacity={0.5}
cx={57}
cy={62.5}
r={springForBand0.r}
fill='var(--player-accent-color)'
/>
<animated.circle
opacity={0.5}
cx={65}
cy={57.5}
r={springForBand1.r}
fill='var(--player-accent-color)'
/>
<animated.circle
opacity={0.5}
cx={63}
cy={66.5}
r={springForBand2.r}
fill='var(--player-accent-color)'
/>
<g clipPath={`url(#${accessibilityId}-clip)`}>
<rect
x={14}
y={14}
width={96}
height={96}
fill={`url(#${accessibilityId}-pattern)`}
/>
<rect
x={14}
y={14}
width={96}
height={96}
fill='var(--player-background-color'
opacity={0.45}
/>
</g>
<defs>
<pattern
id={`${accessibilityId}-pattern`}
patternContentUnits='objectBoundingBox'
width='1'
height='1'
>
<use href={`#${accessibilityId}-image`} />
</pattern>
<clipPath id={`${accessibilityId}-clip`}>
<rect x={14} y={14} width={96} height={96} rx={48} fill='white' />
</clipPath>
<image
id={`${accessibilityId}-image`}
href={poster}
width={1}
height={1}
preserveAspectRatio='none'
/>
</defs>
</svg>
);
};

View File

@ -102,6 +102,7 @@ class ComposeForm extends ImmutablePureComponent {
handleKeyDownPost = (e) => {
if (e.key.toLowerCase() === 'enter' && (e.ctrlKey || e.metaKey)) {
this.handleSubmit();
e.preventDefault();
}
this.blurOnEscape(e);
};
@ -123,11 +124,10 @@ class ComposeForm extends ImmutablePureComponent {
};
canSubmit = () => {
const { isSubmitting, isChangingUpload, isUploading, anyMedia, maxChars } = this.props;
const { isSubmitting, isChangingUpload, isUploading, maxChars } = this.props;
const fulltext = this.getFulltextForCharacterCounting();
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars);
};
handleSubmit = (e) => {
@ -141,7 +141,10 @@ class ComposeForm extends ImmutablePureComponent {
return;
}
this.props.onSubmit(missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct');
this.props.onSubmit({
missingAltText: missingAltTextModal && this.props.missingAltText && this.props.privacy !== 'direct',
quoteToPrivate: this.props.quoteToPrivate,
});
if (e) {
e.preventDefault();

View File

@ -0,0 +1,48 @@
import { useCallback } from 'react';
import type { FC } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { cancelPasteLinkCompose } from '@/mastodon/actions/compose_typed';
import { useAppDispatch } from '@/mastodon/store';
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
import { DisplayName } from 'mastodon/components/display_name';
import { IconButton } from 'mastodon/components/icon_button';
import { Skeleton } from 'mastodon/components/skeleton';
const messages = defineMessages({
quote_cancel: { id: 'status.quote.cancel', defaultMessage: 'Cancel quote' },
});
export const QuotePlaceholder: FC = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const handleQuoteCancel = useCallback(() => {
dispatch(cancelPasteLinkCompose());
}, [dispatch]);
return (
<div className='status__quote'>
<div className='status'>
<div className='status__info'>
<div className='status__avatar'>
<Skeleton width='32px' height='32px' />
</div>
<div className='status__display-name'>
<DisplayName />
</div>
<IconButton
onClick={handleQuoteCancel}
className='status__quote-cancel'
title={intl.formatMessage(messages.quote_cancel)}
icon='cancel-fill'
iconComponent={CancelFillIcon}
/>
</div>
<div className='status__content'>
<Skeleton />
</div>
</div>
</div>
);
};

View File

@ -7,11 +7,17 @@ import { quoteComposeCancel } from '@/mastodon/actions/compose_typed';
import { QuotedStatus } from '@/mastodon/components/status_quoted';
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
import { QuotePlaceholder } from './quote_placeholder';
export const ComposeQuotedStatus: FC = () => {
const quotedStatusId = useAppSelector(
(state) => state.compose.get('quoted_status_id') as string | null,
);
const isFetchingLink = useAppSelector(
(state) => !!state.compose.get('fetching_link'),
);
const isEditing = useAppSelector((state) => !!state.compose.get('id'));
const quote = useMemo(
@ -30,7 +36,9 @@ export const ComposeQuotedStatus: FC = () => {
dispatch(quoteComposeCancel());
}, [dispatch]);
if (!quote) {
if (isFetchingLink && !quote) {
return <QuotePlaceholder />;
} else if (!quote) {
return null;
}

View File

@ -10,6 +10,7 @@ import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
import SoundIcon from '@/material-icons/400-24px/audio.svg?react';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
import { undoUploadCompose } from 'mastodon/actions/compose';
@ -17,7 +18,18 @@ import { openModal } from 'mastodon/actions/modal';
import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon';
import type { MediaAttachment } from 'mastodon/models/media_attachment';
import { useAppDispatch, useAppSelector } from 'mastodon/store';
import {
createAppSelector,
useAppDispatch,
useAppSelector,
} from 'mastodon/store';
import { AudioVisualizer } from '../../audio/visualizer';
const selectUserAvatar = createAppSelector(
[(state) => state.accounts, (state) => state.meta.get('me') as string],
(accounts, myId) => accounts.get(myId)?.avatar_static,
);
export const Upload: React.FC<{
id: string;
@ -38,6 +50,7 @@ export const Upload: React.FC<{
const sensitive = useAppSelector(
(state) => state.compose.get('spoiler') as boolean,
);
const userAvatar = useAppSelector(selectUserAvatar);
const handleUndoClick = useCallback(() => {
dispatch(undoUploadCompose(id));
@ -67,6 +80,8 @@ export const Upload: React.FC<{
transform: CSS.Transform.toString(transform),
transition,
};
const preview_url = media.get('preview_url') as string | null;
const blurhash = media.get('blurhash') as string | null;
return (
<div
@ -85,17 +100,19 @@ export const Upload: React.FC<{
<div
className='compose-form__upload__thumbnail'
style={{
backgroundImage: !sensitive
? `url(${media.get('preview_url') as string})`
: undefined,
backgroundImage:
!sensitive && preview_url ? `url(${preview_url})` : undefined,
backgroundPosition: `${x}% ${y}%`,
}}
>
{sensitive && (
<Blurhash
hash={media.get('blurhash') as string}
className='compose-form__upload__preview'
/>
{sensitive && blurhash && (
<Blurhash hash={blurhash} className='compose-form__upload__preview' />
)}
{!sensitive && !preview_url && (
<div className='compose-form__upload__visualizer'>
<AudioVisualizer poster={userAvatar} />
<Icon id='sound' icon={SoundIcon} />
</div>
)}
<div className='compose-form__upload__actions'>

View File

@ -5,8 +5,10 @@ import { defineMessages, useIntl } from 'react-intl';
import classNames from 'classnames';
import { changeComposeVisibility } from '@/mastodon/actions/compose';
import { setComposeQuotePolicy } from '@/mastodon/actions/compose_typed';
import {
changeComposeVisibility,
setComposeQuotePolicy,
} from '@/mastodon/actions/compose_typed';
import { openModal } from '@/mastodon/actions/modal';
import type { ApiQuotePolicy } from '@/mastodon/api_types/quotes';
import type { StatusVisibility } from '@/mastodon/api_types/statuses';

View File

@ -31,7 +31,7 @@ export const Warning = () => {
defaultMessage='Your account is not {locked}. Anyone can follow you to view your follower-only posts.'
values={{
locked: (
<a href='/settings/profile'>
<a href='/settings/privacy#account_unlocked'>
<FormattedMessage
id='compose_form.lock_disclaimer.lock'
defaultMessage='locked'

View File

@ -12,6 +12,8 @@ import {
} from 'mastodon/actions/compose';
import { pasteLinkCompose } from 'mastodon/actions/compose_typed';
import { openModal } from 'mastodon/actions/modal';
import { PRIVATE_QUOTE_MODAL_ID } from 'mastodon/features/ui/components/confirmation_modals/private_quote_notify';
import { me } from 'mastodon/initial_state';
import ComposeForm from '../components/compose_form';
@ -32,6 +34,11 @@ const mapStateToProps = state => ({
isUploading: state.getIn(['compose', 'is_uploading']),
anyMedia: state.getIn(['compose', 'media_attachments']).size > 0,
missingAltText: state.getIn(['compose', 'media_attachments']).some(media => ['image', 'gifv'].includes(media.get('type')) && (media.get('description') ?? '').length === 0),
quoteToPrivate:
!!state.getIn(['compose', 'quoted_status_id'])
&& state.getIn(['compose', 'privacy']) === 'private'
&& state.getIn(['statuses', state.getIn(['compose', 'quoted_status_id']), 'account']) !== me
&& !state.getIn(['settings', 'dismissed_banners', PRIVATE_QUOTE_MODAL_ID]),
isInReply: state.getIn(['compose', 'in_reply_to']) !== null,
lang: state.getIn(['compose', 'language']),
maxChars: state.getIn(['server', 'server', 'configuration', 'statuses', 'max_characters'], 500),
@ -43,12 +50,17 @@ const mapDispatchToProps = (dispatch, props) => ({
dispatch(changeCompose(text));
},
onSubmit (missingAltText) {
onSubmit ({ missingAltText, quoteToPrivate }) {
if (missingAltText) {
dispatch(openModal({
modalType: 'CONFIRM_MISSING_ALT_TEXT',
modalProps: {},
}));
} else if (quoteToPrivate) {
dispatch(openModal({
modalType: 'CONFIRM_PRIVATE_QUOTE_NOTIFY',
modalProps: {},
}));
} else {
dispatch(submitCompose((status) => {
if (props.redirectOnSuccess) {

View File

@ -1,8 +1,7 @@
import { connect } from 'react-redux';
import { changeComposeVisibility } from '../../../actions/compose';
import { openModal, closeModal } from '../../../actions/modal';
import { isUserTouching } from '../../../is_mobile';
import { changeComposeVisibility } from '@/mastodon/actions/compose_typed';
import PrivacyDropdown from '../components/privacy_dropdown';
const mapStateToProps = state => ({

View File

@ -1,6 +1,7 @@
import { initialState } from '@/mastodon/initial_state';
import { toSupportedLocale } from './locale';
import type { LocaleOrCustom } from './types';
import { emojiLogger } from './utils';
// eslint-disable-next-line import/default -- Importing via worker loader.
import EmojiWorker from './worker?worker&inline';
@ -24,19 +25,17 @@ export function initializeEmoji() {
}
if (worker) {
// Assign worker to const to make TS happy inside the event listener.
const thisWorker = worker;
const timeoutId = setTimeout(() => {
log('worker is not ready after timeout');
worker = null;
void fallbackLoad();
}, WORKER_TIMEOUT);
thisWorker.addEventListener('message', (event: MessageEvent<string>) => {
worker.addEventListener('message', (event: MessageEvent<string>) => {
const { data: message } = event;
if (message === 'ready') {
log('worker ready, loading data');
clearTimeout(timeoutId);
thisWorker.postMessage('custom');
messageWorker('custom');
void loadEmojiLocale(userLocale);
// Load English locale as well, because people are still used to
// using it from before we supported other locales.
@ -55,20 +54,35 @@ export function initializeEmoji() {
async function fallbackLoad() {
log('falling back to main thread for loading');
const { importCustomEmojiData } = await import('./loader');
await importCustomEmojiData();
const emojis = await importCustomEmojiData();
if (emojis) {
log('loaded %d custom emojis', emojis.length);
}
await loadEmojiLocale(userLocale);
if (userLocale !== 'en') {
await loadEmojiLocale('en');
}
}
export async function loadEmojiLocale(localeString: string) {
async function loadEmojiLocale(localeString: string) {
const locale = toSupportedLocale(localeString);
const { importEmojiData, localeToPath } = await import('./loader');
if (worker) {
worker.postMessage(locale);
const path = await localeToPath(locale);
log('asking worker to load locale %s from %s', locale, path);
messageWorker(locale, path);
} else {
const { importEmojiData } = await import('./loader');
await importEmojiData(locale);
const emojis = await importEmojiData(locale);
if (emojis) {
log('loaded %d emojis to locale %s', emojis.length, locale);
}
}
}
function messageWorker(locale: LocaleOrCustom, path?: string) {
if (!worker) {
return;
}
worker.postMessage({ locale, path });
}

View File

@ -1,5 +1,5 @@
import { flattenEmojiData } from 'emojibase';
import type { CompactEmoji, FlatCompactEmoji } from 'emojibase';
import type { CompactEmoji, FlatCompactEmoji, Locale } from 'emojibase';
import {
putEmojiData,
@ -8,45 +8,64 @@ import {
putLatestEtag,
} from './database';
import { toSupportedLocale, toSupportedLocaleOrCustom } from './locale';
import type { CustomEmojiData, LocaleOrCustom } from './types';
import { emojiLogger } from './utils';
import type { CustomEmojiData } from './types';
const log = emojiLogger('loader');
export async function importEmojiData(localeString: string) {
export async function importEmojiData(localeString: string, path?: string) {
const locale = toSupportedLocale(localeString);
const emojis = await fetchAndCheckEtag<CompactEmoji[]>(locale);
// Validate the provided path.
if (path && !/^[/a-z]*\/packs\/assets\/compact-\w+\.json$/.test(path)) {
throw new Error('Invalid path for emoji data');
} else {
// Otherwise get the path if not provided.
path ??= await localeToPath(locale);
}
const emojis = await fetchAndCheckEtag<CompactEmoji[]>(locale, path);
if (!emojis) {
return;
}
const flattenedEmojis: FlatCompactEmoji[] = flattenEmojiData(emojis);
log('loaded %d for %s locale', flattenedEmojis.length, locale);
await putEmojiData(flattenedEmojis, locale);
return flattenedEmojis;
}
export async function importCustomEmojiData() {
const emojis = await fetchAndCheckEtag<CustomEmojiData[]>('custom');
const emojis = await fetchAndCheckEtag<CustomEmojiData[]>(
'custom',
'/api/v1/custom_emojis',
);
if (!emojis) {
return;
}
log('loaded %d custom emojis', emojis.length);
await putCustomEmojiData(emojis);
return emojis;
}
async function fetchAndCheckEtag<ResultType extends object[]>(
localeOrCustom: LocaleOrCustom,
const modules = import.meta.glob<string>(
'../../../../../node_modules/emojibase-data/**/compact.json',
{
query: '?url',
import: 'default',
},
);
export function localeToPath(locale: Locale) {
const key = `../../../../../node_modules/emojibase-data/${locale}/compact.json`;
if (!modules[key] || typeof modules[key] !== 'function') {
throw new Error(`Unsupported locale: ${locale}`);
}
return modules[key]();
}
export async function fetchAndCheckEtag<ResultType extends object[]>(
localeString: string,
path: string,
): Promise<ResultType | null> {
const locale = toSupportedLocaleOrCustom(localeOrCustom);
const locale = toSupportedLocaleOrCustom(localeString);
// Use location.origin as this script may be loaded from a CDN domain.
const url = new URL(location.origin);
if (locale === 'custom') {
url.pathname = '/api/v1/custom_emojis';
} else {
// This doesn't use isDevelopment() as that module loads initial state
// which breaks workers, as they cannot access the DOM.
url.pathname = `/packs${import.meta.env.DEV ? '-dev' : ''}/emoji/${locale}.json`;
}
const url = new URL(path, location.origin);
const oldEtag = await loadLatestEtag(locale);
const response = await fetch(url, {
@ -61,21 +80,19 @@ async function fetchAndCheckEtag<ResultType extends object[]>(
}
if (!response.ok) {
throw new Error(
`Failed to fetch emoji data for ${localeOrCustom}: ${response.statusText}`,
`Failed to fetch emoji data for ${locale}: ${response.statusText}`,
);
}
const data = (await response.json()) as ResultType;
if (!Array.isArray(data)) {
throw new Error(
`Unexpected data format for ${localeOrCustom}: expected an array`,
);
throw new Error(`Unexpected data format for ${locale}: expected an array`);
}
// Store the ETag for future requests
const etag = response.headers.get('ETag');
if (etag) {
await putLatestEtag(etag, localeOrCustom);
await putLatestEtag(etag, localeString);
}
return data;

View File

@ -33,6 +33,7 @@ describe('emojiToUnicodeHex', () => {
['⚫', '26AB'],
['🖤', '1F5A4'],
['💀', '1F480'],
['❤️', '2764'], // Checks for trailing variation selector removal.
['💂‍♂️', '1F482-200D-2642-FE0F'],
] as const)(
'emojiToUnicodeHex converts %s to %s',

View File

@ -30,6 +30,12 @@ export function emojiToUnicodeHex(emoji: string): string {
codes.push(code);
}
}
// Handles how Emojibase removes the variation selector for single code emojis.
// See: https://emojibase.dev/docs/spec/#merged-variation-selectors
if (codes.at(1) === VARIATION_SELECTOR_CODE && codes.length === 2) {
codes.pop();
}
return hexNumbersToString(codes);
}

View File

@ -7,6 +7,7 @@ import {
stringToEmojiState,
tokenizeText,
} from './render';
import type { EmojiStateCustom } from './types';
describe('tokenizeText', () => {
test('returns an array of text to be a single token', () => {
@ -82,12 +83,8 @@ describe('stringToEmojiState', () => {
});
});
test('returns custom emoji state for valid custom emoji', () => {
expect(stringToEmojiState(':smile:')).toEqual({
type: 'custom',
code: 'smile',
data: undefined,
});
test('returns null for custom emoji without data', () => {
expect(stringToEmojiState(':smile:')).toBeNull();
});
test('returns custom emoji state with data when provided', () => {
@ -107,7 +104,6 @@ describe('stringToEmojiState', () => {
test('returns null for invalid emoji strings', () => {
expect(stringToEmojiState('notanemoji')).toBeNull();
expect(stringToEmojiState(':invalid-emoji:')).toBeNull();
});
});
@ -130,18 +126,13 @@ describe('loadEmojiDataToState', () => {
});
});
test('loads custom emoji data into state', async () => {
const dbCall = vi
.spyOn(db, 'loadCustomEmojiByShortcode')
.mockResolvedValueOnce(customEmojiFactory());
const customState = { type: 'custom', code: 'smile' } as const;
const result = await loadEmojiDataToState(customState, 'en');
expect(dbCall).toHaveBeenCalledWith('smile');
expect(result).toEqual({
test('returns null for custom emoji without data', async () => {
const customState = {
type: 'custom',
code: 'smile',
data: customEmojiFactory(),
});
} as const satisfies EmojiStateCustom;
const result = await loadEmojiDataToState(customState, 'en');
expect(result).toBeNull();
});
test('returns null if unicode emoji not found in database', async () => {
@ -151,18 +142,11 @@ describe('loadEmojiDataToState', () => {
expect(result).toBeNull();
});
test('returns null if custom emoji not found in database', async () => {
vi.spyOn(db, 'loadCustomEmojiByShortcode').mockResolvedValueOnce(undefined);
const customState = { type: 'custom', code: 'smile' } as const;
const result = await loadEmojiDataToState(customState, 'en');
expect(result).toBeNull();
});
test('retries loading emoji data once if initial load fails', async () => {
const dbCall = vi
.spyOn(db, 'loadEmojiByHexcode')
.mockRejectedValue(new db.LocaleNotLoadedError('en'));
vi.spyOn(loader, 'importEmojiData').mockResolvedValueOnce();
vi.spyOn(loader, 'importEmojiData').mockResolvedValueOnce(undefined);
const consoleCall = vi
.spyOn(console, 'warn')
.mockImplementationOnce(() => null);

View File

@ -4,11 +4,7 @@ import {
EMOJI_TYPE_UNICODE,
EMOJI_TYPE_CUSTOM,
} from './constants';
import {
loadCustomEmojiByShortcode,
loadEmojiByHexcode,
LocaleNotLoadedError,
} from './database';
import { loadEmojiByHexcode, LocaleNotLoadedError } from './database';
import { importEmojiData } from './loader';
import { emojiToUnicodeHex } from './normalize';
import type {
@ -79,7 +75,7 @@ export function tokenizeText(text: string): TokenizedText {
export function stringToEmojiState(
code: string,
customEmoji: ExtraCustomEmojiMap = {},
): EmojiState | null {
): EmojiStateUnicode | Required<EmojiStateCustom> | null {
if (isUnicodeEmoji(code)) {
return {
type: EMOJI_TYPE_UNICODE,
@ -89,11 +85,13 @@ export function stringToEmojiState(
if (isCustomEmoji(code)) {
const shortCode = code.slice(1, -1);
return {
type: EMOJI_TYPE_CUSTOM,
code: shortCode,
data: customEmoji[shortCode],
};
if (customEmoji[shortCode]) {
return {
type: EMOJI_TYPE_CUSTOM,
code: shortCode,
data: customEmoji[shortCode],
};
}
}
return null;
@ -114,26 +112,23 @@ export async function loadEmojiDataToState(
return state;
}
// Don't try to load data for custom emoji.
if (state.type === EMOJI_TYPE_CUSTOM) {
return null;
}
// First, try to load the data from IndexedDB.
try {
// This is duplicative, but that's because TS can't distinguish the state type easily.
if (state.type === EMOJI_TYPE_UNICODE) {
const data = await loadEmojiByHexcode(state.code, locale);
if (data) {
return {
...state,
data,
};
}
} else {
const data = await loadCustomEmojiByShortcode(state.code);
if (data) {
return {
...state,
data,
};
}
const data = await loadEmojiByHexcode(state.code, locale);
if (data) {
return {
...state,
type: EMOJI_TYPE_UNICODE,
data,
};
}
// If not found, assume it's not an emoji and return null.
log(
'Could not find emoji %s of type %s for locale %s',

View File

@ -1,18 +1,25 @@
import { importEmojiData, importCustomEmojiData } from './loader';
import { importCustomEmojiData, importEmojiData } from './loader';
addEventListener('message', handleMessage);
self.postMessage('ready'); // After the worker is ready, notify the main thread
function handleMessage(event: MessageEvent<string>) {
const { data: locale } = event;
void loadData(locale);
function handleMessage(event: MessageEvent<{ locale: string; path?: string }>) {
const {
data: { locale, path },
} = event;
void loadData(locale, path);
}
async function loadData(locale: string) {
if (locale !== 'custom') {
await importEmojiData(locale);
async function loadData(locale: string, path?: string) {
let importCount: number | undefined;
if (locale === 'custom') {
importCount = (await importCustomEmojiData())?.length;
} else if (path) {
importCount = (await importEmojiData(locale, path))?.length;
} else {
await importCustomEmojiData();
throw new Error('Path is required for loading locale emoji data');
}
if (importCount) {
self.postMessage(`loaded ${importCount} emojis into ${locale}`);
}
self.postMessage(`loaded ${locale}`);
}

View File

@ -1,11 +1,13 @@
import { useEffect, useState } from 'react';
import type { FC } from 'react';
import { useEffect, useState } from 'react';
import { FormattedDate, FormattedMessage } from 'react-intl';
import { dismissAnnouncement } from '@/mastodon/actions/announcements';
import type { ApiAnnouncementJSON } from '@/mastodon/api_types/announcements';
import { AnimateEmojiProvider } from '@/mastodon/components/emoji/context';
import { EmojiHTML } from '@/mastodon/components/emoji/html';
import { useAppDispatch } from '@/mastodon/store';
import { ReactionsBar } from './reactions';
@ -22,13 +24,23 @@ export const Announcement: FC<AnnouncementProps> = ({
announcement,
selected,
}) => {
const [unread, setUnread] = useState(!announcement.read);
const { read, id } = announcement;
// Dismiss announcement when it becomes active.
const dispatch = useAppDispatch();
useEffect(() => {
// Only update `unread` marker once the announcement is out of view
if (!selected && unread !== !announcement.read) {
setUnread(!announcement.read);
if (selected && !read) {
dispatch(dismissAnnouncement(id));
}
}, [announcement.read, selected, unread]);
}, [selected, id, dispatch, read]);
// But visually show the announcement as read only when it goes out of view.
const [unread, setUnread] = useState(!read);
useEffect(() => {
if (!selected && unread !== !read) {
setUnread(!read);
}
}, [selected, unread, read]);
return (
<AnimateEmojiProvider className='announcements__item'>

View File

@ -4,6 +4,7 @@ import type { List } from 'immutable';
import { EmojiHTML } from '@/mastodon/components/emoji/html';
import { useElementHandledLink } from '@/mastodon/components/status/handled_link';
import type { CustomEmoji } from '@/mastodon/models/custom_emoji';
import type { Status } from '@/mastodon/models/status';
import type { Mention } from './embedded_status';
@ -33,6 +34,7 @@ export const EmbeddedStatusContent: React.FC<{
className={className}
lang={status.get('language') as string}
htmlString={status.get('contentHtml') as string}
extraEmojis={status.get('emojis') as List<CustomEmoji>}
/>
);
};

View File

@ -48,7 +48,10 @@ const handleIframeUrl = (html, url, providerName) => {
iframeUrl.searchParams.set('autoplay', 1)
iframeUrl.searchParams.set('auto_play', 1)
if (startTime && providerName === "YouTube") iframeUrl.searchParams.set('start', startTime)
if (providerName === 'YouTube') {
iframeUrl.searchParams.set('start', startTime || '');
iframe.referrerPolicy = 'strict-origin-when-cross-origin';
}
iframe.src = iframeUrl.href

View File

@ -4,7 +4,7 @@
@typescript-eslint/no-unsafe-assignment */
import type { CSSProperties } from 'react';
import { useState, useRef, useCallback } from 'react';
import { useState, useRef, useCallback, useEffect } from 'react';
import { FormattedMessage } from 'react-intl';
@ -55,6 +55,8 @@ export const DetailedStatus: React.FC<{
pictureInPicture: any;
onToggleHidden?: (status: any) => void;
onToggleMediaVisibility?: () => void;
ancestors?: number;
multiColumn?: boolean;
}> = ({
status,
onOpenMedia,
@ -69,6 +71,8 @@ export const DetailedStatus: React.FC<{
pictureInPicture,
onToggleMediaVisibility,
onToggleHidden,
ancestors = 0,
multiColumn = false,
}) => {
const properStatus = status?.get('reblog') ?? status;
const [height, setHeight] = useState(0);
@ -123,6 +127,30 @@ export const DetailedStatus: React.FC<{
if (onTranslate) onTranslate(status);
}, [onTranslate, status]);
// The component is managed and will change if the status changes
// Ancestors can increase when loading a thread, in which case we want to scroll,
// or decrease if a post is deleted, in which case we don't want to mess with it
const previousAncestors = useRef(-1);
useEffect(() => {
if (nodeRef.current && previousAncestors.current < ancestors) {
nodeRef.current.scrollIntoView(true);
// In the single-column interface, `scrollIntoView` will put the post behind the header, so compensate for that.
if (!multiColumn) {
const offset = document
.querySelector('.column-header__wrapper')
?.getBoundingClientRect().bottom;
if (offset) {
const scrollingElement = document.scrollingElement ?? document.body;
scrollingElement.scrollBy(0, -offset);
}
}
}
previousAncestors.current = ancestors;
}, [ancestors, multiColumn]);
if (!properStatus) {
return null;
}
@ -417,6 +445,7 @@ export const DetailedStatus: React.FC<{
<QuotedStatus
quote={status.get('quote')}
parentQuotePostId={status.get('id')}
contextType='thread'
/>
)}
</>

View File

@ -295,7 +295,7 @@ export const RefreshController: React.FC<{
if (loadingState === 'loading') {
return (
<div
className='load-more load-gap'
className='load-more load-more--large'
aria-busy
aria-live='polite'
aria-label={intl.formatMessage(messages.loadingInitial)}

View File

@ -159,18 +159,16 @@ class Status extends ImmutablePureComponent {
};
UNSAFE_componentWillMount () {
this.props.dispatch(fetchStatus(this.props.params.statusId));
this.props.dispatch(fetchStatus(this.props.params.statusId, { forceFetch: true }));
}
componentDidMount () {
attachFullscreenListener(this.onFullScreenChange);
this._scrollStatusIntoView();
}
UNSAFE_componentWillReceiveProps (nextProps) {
if (nextProps.params.statusId !== this.props.params.statusId && nextProps.params.statusId) {
this.props.dispatch(fetchStatus(nextProps.params.statusId));
this.props.dispatch(fetchStatus(nextProps.params.statusId, { forceFetch: true }));
}
if (nextProps.status && nextProps.status.get('id') !== this.state.loadedStatusId) {
@ -299,6 +297,12 @@ class Status extends ImmutablePureComponent {
dispatch(openModal({ modalType: 'COMPOSE_PRIVACY', modalProps: { statusId, onChange: handleChange } }));
};
handleQuote = (status) => {
const { dispatch } = this.props;
dispatch(quoteComposeById(status.get('id')));
};
handleEditClick = (status) => {
const { dispatch, askReplyConfirmation } = this.props;
@ -481,35 +485,11 @@ class Status extends ImmutablePureComponent {
this.statusNode = c;
};
_scrollStatusIntoView () {
const { status, multiColumn } = this.props;
if (status) {
requestIdleCallback(() => {
this.statusNode?.scrollIntoView(true);
// In the single-column interface, `scrollIntoView` will put the post behind the header,
// so compensate for that.
if (!multiColumn) {
const offset = document.querySelector('.column-header__wrapper')?.getBoundingClientRect()?.bottom;
if (offset) {
const scrollingElement = document.scrollingElement || document.body;
scrollingElement.scrollBy(0, -offset);
}
}
});
}
}
componentDidUpdate (prevProps) {
const { status, ancestorsIds, descendantsIds } = this.props;
const { status, descendantsIds } = this.props;
const isSameStatus = status && (prevProps.status?.get('id') === status.get('id'));
if (status && (ancestorsIds.length > prevProps.ancestorsIds.length || !isSameStatus)) {
this._scrollStatusIntoView();
}
// Only highlight replies after the initial load
if (prevProps.descendantsIds.length && isSameStatus) {
const newRepliesIds = difference(descendantsIds, prevProps.descendantsIds);
@ -613,6 +593,8 @@ class Status extends ImmutablePureComponent {
showMedia={this.state.showMedia}
onToggleMediaVisibility={this.handleToggleMediaVisibility}
pictureInPicture={pictureInPicture}
ancestors={this.props.ancestorsIds.length}
multiColumn={multiColumn}
/>
<ActionBar
@ -625,6 +607,7 @@ class Status extends ImmutablePureComponent {
onDelete={this.handleDeleteClick}
onRevokeQuote={this.handleRevokeQuoteClick}
onQuotePolicyChange={this.handleQuotePolicyChange}
onQuote={this.handleQuote}
onEdit={this.handleEditClick}
onDirect={this.handleDirectClick}
onMention={this.handleMentionClick}

View File

@ -18,6 +18,7 @@ export const ConfirmationModal: React.FC<
onSecondary?: () => void;
onConfirm: () => void;
closeWhenConfirm?: boolean;
extraContent?: React.ReactNode;
} & BaseConfirmationModalProps
> = ({
title,
@ -29,6 +30,7 @@ export const ConfirmationModal: React.FC<
secondary,
onSecondary,
closeWhenConfirm = true,
extraContent,
}) => {
const handleClick = useCallback(() => {
if (closeWhenConfirm) {
@ -49,6 +51,8 @@ export const ConfirmationModal: React.FC<
<div className='safety-action-modal__confirmation'>
<h1>{title}</h1>
{message && <p>{message}</p>}
{extraContent}
</div>
</div>

View File

@ -0,0 +1,88 @@
import { forwardRef, useCallback, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { submitCompose } from '@/mastodon/actions/compose';
import { changeSetting } from '@/mastodon/actions/settings';
import { CheckBox } from '@/mastodon/components/check_box';
import { useAppDispatch } from '@/mastodon/store';
import { ConfirmationModal } from './confirmation_modal';
import type { BaseConfirmationModalProps } from './confirmation_modal';
import classes from './styles.module.css';
export const PRIVATE_QUOTE_MODAL_ID = 'quote/private_notify';
const messages = defineMessages({
title: {
id: 'confirmations.private_quote_notify.title',
defaultMessage: 'Share with followers and mentioned users?',
},
message: {
id: 'confirmations.private_quote_notify.message',
defaultMessage:
'The person you are quoting and other mentions ' +
"will be notified and will be able to view your post, even if they're not following you.",
},
confirm: {
id: 'confirmations.private_quote_notify.confirm',
defaultMessage: 'Publish post',
},
cancel: {
id: 'confirmations.private_quote_notify.cancel',
defaultMessage: 'Back to editing',
},
});
export const PrivateQuoteNotify = forwardRef<
HTMLDivElement,
BaseConfirmationModalProps
>(
(
{ onClose },
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_ref,
) => {
const intl = useIntl();
const [dismiss, setDismissed] = useState(false);
const handleDismissToggle = useCallback(() => {
setDismissed((prev) => !prev);
}, []);
const dispatch = useAppDispatch();
const handleConfirm = useCallback(() => {
dispatch(submitCompose());
if (dismiss) {
dispatch(
changeSetting(['dismissed_banners', PRIVATE_QUOTE_MODAL_ID], true),
);
}
}, [dismiss, dispatch]);
return (
<ConfirmationModal
title={intl.formatMessage(messages.title)}
message={intl.formatMessage(messages.message)}
confirm={intl.formatMessage(messages.confirm)}
cancel={intl.formatMessage(messages.cancel)}
onConfirm={handleConfirm}
onClose={onClose}
extraContent={
<label className={classes.checkbox_wrapper}>
<CheckBox
value='hide'
checked={dismiss}
onChange={handleDismissToggle}
/>{' '}
<FormattedMessage
id='confirmations.private_quote_notify.do_not_show_again'
defaultMessage="Don't show me this message again"
/>
</label>
}
/>
);
},
);
PrivateQuoteNotify.displayName = 'PrivateQuoteNotify';

View File

@ -0,0 +1,7 @@
.checkbox_wrapper {
display: flex;
align-items: center;
gap: 0.5rem;
margin: 1rem 0;
cursor: pointer;
}

View File

@ -47,6 +47,7 @@ import MediaModal from './media_modal';
import { ModalPlaceholder } from './modal_placeholder';
import VideoModal from './video_modal';
import { VisibilityModal } from './visibility_modal';
import { PrivateQuoteNotify } from './confirmation_modals/private_quote_notify';
export const MODAL_COMPONENTS = {
'MEDIA': () => Promise.resolve({ default: MediaModal }),
@ -66,6 +67,7 @@ export const MODAL_COMPONENTS = {
'CONFIRM_LOG_OUT': () => Promise.resolve({ default: ConfirmLogOutModal }),
'CONFIRM_FOLLOW_TO_LIST': () => Promise.resolve({ default: ConfirmFollowToListModal }),
'CONFIRM_MISSING_ALT_TEXT': () => Promise.resolve({ default: ConfirmMissingAltTextModal }),
'CONFIRM_PRIVATE_QUOTE_NOTIFY': () => Promise.resolve({ default: PrivateQuoteNotify }),
'CONFIRM_REVOKE_QUOTE': () => Promise.resolve({ default: ConfirmRevokeQuoteModal }),
'CONFIRM_QUIET_QUOTE': () => Promise.resolve({ default: QuietPostQuoteInfoModal }),
'MUTE': MuteModal,

View File

@ -128,9 +128,12 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
const disableVisibility = !!statusId;
const disableQuotePolicy =
visibility === 'private' || visibility === 'direct';
const disablePublicVisibilities: boolean = useAppSelector(
const disablePublicVisibilities = useAppSelector(
selectDisablePublicVisibilities,
);
const isQuotePost = useAppSelector(
(state) => state.compose.get('quoted_status_id') !== null,
);
const visibilityItems = useMemo<SelectItem<StatusVisibility>[]>(() => {
const items: SelectItem<StatusVisibility>[] = [
@ -315,6 +318,21 @@ export const VisibilityModal: FC<VisibilityModalProps> = forwardRef(
id={quoteDescriptionId}
/>
</div>
{isQuotePost && visibility === 'direct' && (
<div className='visibility-modal__quote-warning'>
<FormattedMessage
id='visibility_modal.direct_quote_warning.title'
defaultMessage="Quotes can't be embedded in private mentions"
tagName='h3'
/>
<FormattedMessage
id='visibility_modal.direct_quote_warning.text'
defaultMessage='If you save the current settings, the embedded quote will be converted to a link.'
tagName='p'
/>
</div>
)}
</div>
<div className='dialog-modal__content__actions'>
<Button onClick={onClose} secondary>

View File

@ -1,5 +1,3 @@
import { initialState } from '@/mastodon/initial_state';
interface FocusColumnOptions {
index?: number;
focusItem?: 'first' | 'first-visible';
@ -14,7 +12,10 @@ export function focusColumn({
focusItem = 'first',
}: FocusColumnOptions = {}) {
// Skip the leftmost drawer in multi-column mode
const indexOffset = initialState?.meta.advanced_layout ? 1 : 0;
const isMultiColumnLayout = !!document.querySelector(
'body.layout-multiple-columns',
);
const indexOffset = isMultiColumnLayout ? 1 : 0;
const column = document.querySelector(
`.column:nth-child(${index + indexOffset})`,

View File

@ -35,7 +35,7 @@ interface InitialStateMeta {
streaming_api_base_url: string;
local_live_feed_access: 'public' | 'authenticated' | 'disabled';
remote_live_feed_access: 'public' | 'authenticated' | 'disabled';
local_topic_feed_access: 'public' | 'authenticated' | 'disabled';
local_topic_feed_access: 'public' | 'authenticated';
remote_topic_feed_access: 'public' | 'authenticated' | 'disabled';
title: string;
show_trends: boolean;
@ -129,17 +129,21 @@ export const statusPageUrl = getMeta('status_page_url');
export const sso_redirect = getMeta('sso_redirect');
export const termsOfServiceEnabled = getMeta('terms_of_service_enabled');
const displayNames = new Intl.DisplayNames(getMeta('locale'), {
type: 'language',
fallback: 'none',
languageDisplay: 'standard',
});
const displayNames =
// Intl.DisplayNames can be undefined in old browsers
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Intl.DisplayNames &&
(new Intl.DisplayNames(getMeta('locale'), {
type: 'language',
fallback: 'none',
languageDisplay: 'standard',
}) as Intl.DisplayNames | undefined);
export const languages = initialState?.languages.map((lang) => {
// zh-YUE is not a valid CLDR unicode_language_id
return [
lang[0],
displayNames.of(lang[0].replace('zh-YUE', 'yue')) ?? lang[1],
displayNames?.of(lang[0].replace('zh-YUE', 'yue')) ?? lang[1],
lang[2],
];
});

View File

@ -24,7 +24,7 @@
"account.blocking": "Блакіраванне",
"account.cancel_follow_request": "Скасаваць запыт на падпіску",
"account.copy": "Скапіраваць спасылку на профіль",
"account.direct": "Згадаць асабіста @{name}",
"account.direct": "Згадаць прыватна @{name}",
"account.disable_notifications": "Не паведамляць мне пра публікацыі @{name}",
"account.domain_blocking": "Блакіраванне дамена",
"account.edit_profile": "Рэдагаваць профіль",
@ -194,6 +194,7 @@
"community.column_settings.local_only": "Толькі лакальныя",
"community.column_settings.media_only": "Толькі медыя",
"community.column_settings.remote_only": "Толькі дыстанцыйна",
"compose.error.blank_post": "Допіс не можа быць пустым.",
"compose.language.change": "Змяніць мову",
"compose.language.search": "Шукаць мовы...",
"compose.published.body": "Допіс апублікаваны.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Усё адно апублікаваць",
"confirmations.missing_alt_text.title": "Дадаць альтэрнатыўны тэкст?",
"confirmations.mute.confirm": "Ігнараваць",
"confirmations.private_quote_notify.cancel": "Звяртацца да рэдагавання",
"confirmations.private_quote_notify.confirm": "Апублікаваць допіс",
"confirmations.private_quote_notify.do_not_show_again": "Больш не паказваць мне гэтае паведамленне",
"confirmations.private_quote_notify.message": "Асоба, якую Вы цытуеце, і іншыя, хто быў узгаданы, атрымаюць апавяшчэнні і змогуць пабачыць Ваш допіс, нават калі яны не падпісаныя на Вас.",
"confirmations.private_quote_notify.title": "Падзяліцца з падпісчыкамі і ўзгаданымі карыстальнікамі?",
"confirmations.quiet_post_quote_info.dismiss": "Не нагадваць зноў",
"confirmations.quiet_post_quote_info.got_it": "Зразумела",
"confirmations.quiet_post_quote_info.message": "Калі будзеце цытаваць ціхі публічны допіс, Ваш допіс будзе схаваны ад трэндавых стужак.",
@ -758,6 +764,7 @@
"privacy_policy.title": "Палітыка канфідэнцыйнасці",
"quote_error.edit": "Нельга дадаваць цытаты пры рэдагаванні допісаў.",
"quote_error.poll": "Нельга цытаваць з апытаннямі.",
"quote_error.private_mentions": "Цытаванне не дазваляецца ў прамых узгадваннях.",
"quote_error.quote": "За раз дазволена рабіць толькі адну цытату.",
"quote_error.unauthorized": "Вы не ўвайшлі, каб цытаваць гэты допіс.",
"quote_error.upload": "Нельга цытаваць з медыя далучэннямі.",
@ -911,9 +918,12 @@
"status.pin": "Замацаваць у профілі",
"status.quote": "Цытаваць",
"status.quote.cancel": "Адмяніць цытаванне",
"status.quote_error.blocked_account_hint.title": "Гэты допіс схаваны, бо Вы заблакіравалі @{name}.",
"status.quote_error.blocked_domain_hint.title": "Гэты допіс схаваны, бо Вы заблакіравалі @{domain}.",
"status.quote_error.filtered": "Схавана адным з Вашых фільтраў",
"status.quote_error.limited_account_hint.action": "Усё адно паказаць",
"status.quote_error.limited_account_hint.title": "Гэты ўліковы запіс быў схаваны мадэратарамі {domain}.",
"status.quote_error.muted_account_hint.title": "Гэты допіс схаваны, бо Вы вырашылі ігнараваць @{name}.",
"status.quote_error.not_available": "Допіс недаступны",
"status.quote_error.pending_approval": "Допіс чакае пацвярджэння",
"status.quote_error.pending_approval_popout.body": "У Mastodon можна кантраляваць магчымасць іншых цытаваць Вас. Гэты допіс будзе знаходзіцца ў стане чакання, пакуль мы не атрымаем ухваленне на цытаванне ад аўтара арыгінальнага допісу.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Паменшыць гучнасць",
"video.volume_up": "Павялічыць гучнасць",
"visibility_modal.button_title": "Вызначыць бачнасць",
"visibility_modal.direct_quote_warning.text": "Калі Вы захавайце бягучыя налады, прымацаваная цытата будзе пераробленая ў спасылку.",
"visibility_modal.direct_quote_warning.title": "Цытаты нельга далучаць да прыватных узгадванняў",
"visibility_modal.header": "Бачнасць і ўзаемадзеянне",
"visibility_modal.helper.direct_quoting": "Прыватныя згадванні, створаныя на Mastodon, нельга цытаваць іншым людзям.",
"visibility_modal.helper.privacy_editing": "Бачнасць нельга змяніць у апублікаваным допісе.",

View File

@ -190,6 +190,7 @@
"community.column_settings.local_only": "Само локално",
"community.column_settings.media_only": "Само мултимедия",
"community.column_settings.remote_only": "Само отдалечено",
"compose.error.blank_post": "Публикацията не може да е празна.",
"compose.language.change": "Смяна на езика",
"compose.language.search": "Търсене на езици...",
"compose.published.body": "Публикувано.",
@ -242,6 +243,9 @@
"confirmations.missing_alt_text.secondary": "Все пак да се публикува",
"confirmations.missing_alt_text.title": "Добавяте ли алтернативен текст?",
"confirmations.mute.confirm": "Заглушаване",
"confirmations.private_quote_notify.cancel": "Назад към редактирането",
"confirmations.private_quote_notify.confirm": "Издаване на публикация",
"confirmations.private_quote_notify.do_not_show_again": "Без показване пак на това съобщение",
"confirmations.quiet_post_quote_info.dismiss": "Без друго напомняне",
"confirmations.quiet_post_quote_info.got_it": "Схванах",
"confirmations.quiet_post_quote_info.title": "Цитиране на публикации за тиха публика",

View File

@ -173,6 +173,8 @@
"column.edit_list": "Edita la llista",
"column.favourites": "Favorits",
"column.firehose": "Tuts en directe",
"column.firehose_local": "Canal en directe per a aquest servidor",
"column.firehose_singular": "Canal en directe",
"column.follow_requests": "Peticions de seguir-te",
"column.home": "Inici",
"column.list_members": "Gestiona els membres de la llista",
@ -192,6 +194,7 @@
"community.column_settings.local_only": "Només local",
"community.column_settings.media_only": "Només contingut",
"community.column_settings.remote_only": "Només remot",
"compose.error.blank_post": "La publicació no pot estar en blanc.",
"compose.language.change": "Canvia d'idioma",
"compose.language.search": "Cerca idiomes...",
"compose.published.body": "Tut publicat.",
@ -244,8 +247,15 @@
"confirmations.missing_alt_text.secondary": "Publica-la igualment",
"confirmations.missing_alt_text.title": "Hi voleu afegir text alternatiu?",
"confirmations.mute.confirm": "Silencia",
"confirmations.private_quote_notify.cancel": "Torna a l'edició",
"confirmations.private_quote_notify.confirm": "Publica la publicació",
"confirmations.private_quote_notify.do_not_show_again": "No tornis a mostrar-me aquest missatge",
"confirmations.private_quote_notify.message": "La persona que citeu i altres mencionades rebran una notificació i podran veure la vostra publicació, encara que no us segueixen.",
"confirmations.private_quote_notify.title": "Voleu compartir amb seguidors i usuaris mencionats?",
"confirmations.quiet_post_quote_info.dismiss": "No m'ho tornis a recordar",
"confirmations.quiet_post_quote_info.got_it": "Entesos",
"confirmations.quiet_post_quote_info.message": "Quan citeu una publicació pública en mode silenciós, la vostra publicació s'amagarà de les línies de temps de tendències.",
"confirmations.quiet_post_quote_info.title": "Citació d'una publicació pública en mode silenciós",
"confirmations.redraft.confirm": "Esborra i reescriu",
"confirmations.redraft.message": "Segur que vols eliminar aquest tut i tornar a escriure'l? Es perdran tots els impulsos i els favorits, i les respostes al tut original quedaran aïllades.",
"confirmations.redraft.title": "Esborrar i reescriure la publicació?",
@ -331,6 +341,7 @@
"empty_column.bookmarked_statuses": "Encara no has marcat cap tut. Quan en marquis un, apareixerà aquí.",
"empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per posar-ho tot en marxa!",
"empty_column.direct": "Encara no tens mencions privades. Quan n'enviïs o en rebis una, et sortirà aquí.",
"empty_column.disabled_feed": "L'administració del vostre servidor ha desactivat aquest canal.",
"empty_column.domain_blocks": "Encara no hi ha dominis blocats.",
"empty_column.explore_statuses": "No hi ha res en tendència ara mateix. Revisa-ho més tard!",
"empty_column.favourited_statuses": "Encara no has afavorit cap tut. Quan ho facis, apareixerà aquí.",
@ -458,6 +469,7 @@
"ignore_notifications_modal.not_following_title": "Voleu ignorar les notificacions de qui no seguiu?",
"ignore_notifications_modal.private_mentions_title": "Voleu ignorar les notificacions de mencions privades no sol·licitades?",
"info_button.label": "Ajuda",
"info_button.what_is_alt_text": "<h1>Què és el text alternatiu?</h1> <p>El text alternatiu proporciona descripcions d'imatges per a persones amb discapacitat visual, connexions de poca amplada de banda o aquelles que busquen un context addicional.</p> <p>Podeu millorar l'accessibilitat i la comprensió per a tothom escrivint un text alternatiu clar, concís i objectiu.</p> <ul> <li>Descriviu els elements importants</li> <li>Utilitzeu frases senzilles</li> <li>Resumiu el text en imatges</li> <li>Eviteu la informació redundant</li> <li>Centreu-vos en les tendències i els aspectes clau dels elements visuals complexos (com ara diagrames o mapes)</li> </ul>",
"interaction_modal.action": "Per a interactuar amb la publicació de {name} cal que inicieu la sessió en el servidor que feu servir.",
"interaction_modal.go": "Endavant",
"interaction_modal.no_account_yet": "Encara no teniu cap compte?",
@ -749,7 +761,9 @@
"privacy.unlisted.short": "Públic silenciós",
"privacy_policy.last_updated": "Darrera actualització {date}",
"privacy_policy.title": "Política de Privacitat",
"quote_error.edit": "No es poden afegir cites en editar una publicació.",
"quote_error.poll": "Amb les enquestes no es permeten cites.",
"quote_error.private_mentions": "Amb mencions directes no es permeten cites.",
"quote_error.quote": "Només es permet una cita alhora.",
"quote_error.unauthorized": "No se us permet de citar aquesta publicació.",
"quote_error.upload": "Amb media adjunts no es permeten cites.",
@ -871,6 +885,7 @@
"status.contains_quote": "Conté una cita",
"status.context.loading": "Es carreguen més respostes",
"status.context.loading_error": "No s'han pogut carregar respostes noves",
"status.context.loading_success": "S'han carregat les noves respostes",
"status.context.more_replies_found": "S'han trobat més respostes",
"status.context.retry": "Torna-ho a provar",
"status.context.show": "Mostra",
@ -902,9 +917,12 @@
"status.pin": "Fixa en el perfil",
"status.quote": "Cita",
"status.quote.cancel": "Canceŀlar la citació",
"status.quote_error.blocked_account_hint.title": "Aquesta publicació està amagada perquè heu blocat a @{name}.",
"status.quote_error.blocked_domain_hint.title": "Aquesta publicació està amagada perquè heu blocat a {domain}.",
"status.quote_error.filtered": "No es mostra a causa d'un dels vostres filtres",
"status.quote_error.limited_account_hint.action": "Mostra-la igualment",
"status.quote_error.limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
"status.quote_error.muted_account_hint.title": "Aquesta publicació està amagada perquè heu silenciat a @{name}.",
"status.quote_error.not_available": "Publicació no disponible",
"status.quote_error.pending_approval": "Publicació pendent",
"status.quote_error.pending_approval_popout.body": "A Mastodon pots controlar si algú et pot citar. Aquesta publicació està pendent mentre esperem l'aprovació de l'autor original.",
@ -999,10 +1017,15 @@
"video.volume_down": "Abaixa el volum",
"video.volume_up": "Apuja el volum",
"visibility_modal.button_title": "Establiu la visibilitat",
"visibility_modal.direct_quote_warning.text": "Si deseu la configuració actual, la cita incrustada es convertirà en un enllaç.",
"visibility_modal.direct_quote_warning.title": "Les cites no es poden incrustar a les mencions privades",
"visibility_modal.header": "Visibilitat i interacció",
"visibility_modal.helper.direct_quoting": "No es poden citar mencions privades fetes a Mastondon.",
"visibility_modal.helper.privacy_editing": "La visibilitat no es pot canviar després de publicar una publicació.",
"visibility_modal.helper.privacy_private_self_quote": "Les autocites de publicacions privades no es poden fer públiques.",
"visibility_modal.helper.private_quoting": "No es poden citar publicacions fetes a Mastodon només per a seguidors.",
"visibility_modal.helper.unlisted_quoting": "Quan la gent et citi les seves publicacions estaran amagades de les línies de temps de tendències.",
"visibility_modal.helper.unlisted_quoting": "Quan la gent us citi, les seves publicacions quedaran amagades de les línies de temps de tendències.",
"visibility_modal.instructions": "Controleu qui pot interactuar amb aquesta publicació. També podeu aplicar la configuració a totes les publicacions futures navegant a <link>Preferències > Valors per defecte de publicació</link>.",
"visibility_modal.privacy_label": "Visibilitat",
"visibility_modal.quote_followers": "Només seguidors",
"visibility_modal.quote_label": "Qui pot citar",

View File

@ -173,6 +173,8 @@
"column.edit_list": "Upravit seznam",
"column.favourites": "Oblíbené",
"column.firehose": "Živé kanály",
"column.firehose_local": "Živý kanál pro tento server",
"column.firehose_singular": "Živý kanál",
"column.follow_requests": "Žádosti o sledování",
"column.home": "Domů",
"column.list_members": "Spravovat členy seznamu",
@ -192,6 +194,7 @@
"community.column_settings.local_only": "Pouze místní",
"community.column_settings.media_only": "Pouze média",
"community.column_settings.remote_only": "Pouze vzdálené",
"compose.error.blank_post": "Příspěvek nemůže být prázdný.",
"compose.language.change": "Změnit jazyk",
"compose.language.search": "Prohledat jazyky...",
"compose.published.body": "Příspěvek zveřejněn.",
@ -244,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Přesto odeslat",
"confirmations.missing_alt_text.title": "Přidat popisek?",
"confirmations.mute.confirm": "Skrýt",
"confirmations.private_quote_notify.cancel": "Zpět k úpravám",
"confirmations.private_quote_notify.confirm": "Publikovat příspěvek",
"confirmations.private_quote_notify.do_not_show_again": "Nezobrazujte mi znovu tuto zprávu",
"confirmations.private_quote_notify.message": "Osoba, kterou citujete, a další zmínění budou upozorněni a budou moci si zobrazit váš příspěvek, i pokud vás nesledují.",
"confirmations.private_quote_notify.title": "Sdílet se sledujícími a zmíněnými uživateli?",
"confirmations.quiet_post_quote_info.dismiss": "Znovu nepřípomínat",
"confirmations.quiet_post_quote_info.got_it": "Rozumím",
"confirmations.quiet_post_quote_info.message": "Při citování ztišeného veřejného příspěvku, váš příspěvek bude skrytý z os populárních příspěvků.",
@ -756,6 +764,7 @@
"privacy_policy.title": "Zásady ochrany osobních údajů",
"quote_error.edit": "Citáty nemohou být přidány při úpravě příspěvku.",
"quote_error.poll": "Citování není u dotazníků povoleno.",
"quote_error.private_mentions": "Citování není povoleno s přímými zmínkami.",
"quote_error.quote": "Je povoleno citovat pouze jednou.",
"quote_error.unauthorized": "Nemáte oprávnění citovat tento příspěvek.",
"quote_error.upload": "Není povoleno citovat s přílohami.",
@ -909,9 +918,12 @@
"status.pin": "Připnout na profil",
"status.quote": "Citovat",
"status.quote.cancel": "Zrušit citování",
"status.quote_error.blocked_account_hint.title": "Tento příspěvek je skryt, protože jste zablokovali @{name}.",
"status.quote_error.blocked_domain_hint.title": "Tento příspěvek je skryt, protože jste zablokovali {domain}.",
"status.quote_error.filtered": "Skryté kvůli jednomu z vašich filtrů",
"status.quote_error.limited_account_hint.action": "Přesto zobrazit",
"status.quote_error.limited_account_hint.title": "Tento účet byl skryt moderátory {domain}.",
"status.quote_error.muted_account_hint.title": "Tento příspěvek je skryt, protože jste ztišili @{name}.",
"status.quote_error.not_available": "Příspěvek není dostupný",
"status.quote_error.pending_approval": "Příspěvek čeká na schválení",
"status.quote_error.pending_approval_popout.body": "Na Mastodonu můžete kontrolovat, zda vás někdo může citovat. Tento příspěvek čeká, dokud neobdržíme schválení od původního autora.",
@ -1006,6 +1018,8 @@
"video.volume_down": "Snížit hlasitost",
"video.volume_up": "Zvýšit hlasitost",
"visibility_modal.button_title": "Nastavit viditelnost",
"visibility_modal.direct_quote_warning.text": "Pokud uložíte aktuální nastavení, vložená citace bude převedena na odkaz.",
"visibility_modal.direct_quote_warning.title": "Citace nemohou být vloženy do soukromých zmínek",
"visibility_modal.header": "Viditelnost a interakce",
"visibility_modal.helper.direct_quoting": "Soukromé zmínky, které jsou vytvořeny na Mastodonu, nemohou být citovány ostatními.",
"visibility_modal.helper.privacy_editing": "Viditelnost nelze změnit po publikování příspěvku.",

View File

@ -173,6 +173,8 @@
"column.edit_list": "Golygu rhestr",
"column.favourites": "Ffefrynnau",
"column.firehose": "Ffrydiau byw",
"column.firehose_local": "Ffrwd fyw ar gyfer y gweinydd hwn",
"column.firehose_singular": "Ffrwd fyw",
"column.follow_requests": "Ceisiadau dilyn",
"column.home": "Cartref",
"column.list_members": "Rheoli aelodau rhestr",
@ -192,6 +194,7 @@
"community.column_settings.local_only": "Lleol yn unig",
"community.column_settings.media_only": "Cyfryngau yn unig",
"community.column_settings.remote_only": "Pell yn unig",
"compose.error.blank_post": "Gall postiad ddim bod yn wag.",
"compose.language.change": "Newid iaith",
"compose.language.search": "Chwilio ieithoedd...",
"compose.published.body": "Postiad wedi ei gyhoeddi.",
@ -244,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Postio beth bynnag",
"confirmations.missing_alt_text.title": "Ychwanegu testun amgen?",
"confirmations.mute.confirm": "Tewi",
"confirmations.private_quote_notify.cancel": "Nôl i olygu",
"confirmations.private_quote_notify.confirm": "Cyhoeddi postiad",
"confirmations.private_quote_notify.do_not_show_again": "Peidio dangos y neges hon i mi eto",
"confirmations.private_quote_notify.message": "Bydd y person rydych chi'n ei ddyfynnu a chrybwylliadau eraill yn cael gwybod a bydd yn gallu gweld eich postiad, hyd yn oed os nad ydyn nhw'n eich dilyn chi.",
"confirmations.private_quote_notify.title": "Rhannu gyda dilynwyr a defnyddwyr sy'n cael eu crybwyll?",
"confirmations.quiet_post_quote_info.dismiss": "Peidio fy atgoff eto",
"confirmations.quiet_post_quote_info.got_it": "Iawn",
"confirmations.quiet_post_quote_info.message": "Wrth ddyfynnu postiad cyhoeddus tawel, bydd eich postiad yn cael ei guddio rhag llinellau amser sy'n trendio.",
@ -756,6 +764,7 @@
"privacy_policy.title": "Polisi Preifatrwydd",
"quote_error.edit": "Does dim modd ychwanegu dyfyniadau wrth olygu postiad.",
"quote_error.poll": "Dyw dyfynnu ddim yn cael ei ganiatáu gyda pholau.",
"quote_error.private_mentions": "Does dim caniatâd i ddyfynnu gyda chrybwylliadau uniongyrchol.",
"quote_error.quote": "Dim ond un dyfyniad ar y tro sy'n cael ei ganiatáu.",
"quote_error.unauthorized": "Does gennych chi ddim awdurdod i ddyfynnu'r postiad hwn.",
"quote_error.upload": "Dyw dyfynnu ddim yn cael ei ganiatáu gydag atodiadau cyfryngau.",
@ -909,9 +918,12 @@
"status.pin": "Pinio ar y proffil",
"status.quote": "Dyfynnu",
"status.quote.cancel": "Diddymu'r dyfyniad",
"status.quote_error.blocked_account_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi rhwystro @{name}.",
"status.quote_error.blocked_domain_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi rhwystro {domain}.",
"status.quote_error.filtered": "Wedi'i guddio oherwydd un o'ch hidlwyr",
"status.quote_error.limited_account_hint.action": "Dangos beth bynnag",
"status.quote_error.limited_account_hint.title": "Mae'r cyfrif hwn wedi'i guddio gan gymedrolwyr {domain}.",
"status.quote_error.muted_account_hint.title": "Mae'r postiad hwn wedi'i guddio oherwydd eich bod wedi mudo @{name}.",
"status.quote_error.not_available": "Postiad ddim ar gael",
"status.quote_error.pending_approval": "Postiad yn yr arfaeth",
"status.quote_error.pending_approval_popout.body": "Ar Mastodon, gallwch reoli os yw rhywun yn gallu eich dyfynnu. Mae'r postiad hwn yn cael ei ddal nôl tra'n bod yn cael cymeradwyaeth yr awdur gwreiddiol.",
@ -1006,6 +1018,8 @@
"video.volume_down": "Lefel sain i lawr",
"video.volume_up": "Lefel sain i fyny",
"visibility_modal.button_title": "Gosod gwelededd",
"visibility_modal.direct_quote_warning.text": "Os byddwch chi'n cadw'r gosodiadau cyfredol, bydd y dyfyniad sydd wedi'i fewnosod yn cael ei drawsnewid yn ddolen.",
"visibility_modal.direct_quote_warning.title": "Does dim modd mewnblannu dyfyniadau mewn crybwylliadau preifat",
"visibility_modal.header": "Gwelededd a rhyngweithio",
"visibility_modal.helper.direct_quoting": "Does dim modd dyfynnu crybwylliadau preifat ysgrifennwyd ar Mastodon.",
"visibility_modal.helper.privacy_editing": "Does dim modd newid gwelededd ar ôl i bostiad gael ei gyhoeddi.",

View File

@ -15,7 +15,7 @@
"about.rules": "Serverregler",
"account.account_note_header": "Personligt notat",
"account.add_or_remove_from_list": "Tilføj eller fjern fra lister",
"account.badges.bot": "Bot",
"account.badges.bot": "Automatisert",
"account.badges.group": "Gruppe",
"account.block": "Blokér @{name}",
"account.block_domain": "Blokér domænet {domain}",
@ -28,7 +28,7 @@
"account.disable_notifications": "Giv mig ikke længere en notifikation, når @{name} laver indlæg",
"account.domain_blocking": "Blokerer domæne",
"account.edit_profile": "Redigér profil",
"account.edit_profile_short": "Redigér",
"account.edit_profile_short": "Rediger",
"account.enable_notifications": "Giv mig besked, når @{name} laver indlæg",
"account.endorse": "Fremhæv på profil",
"account.familiar_followers_many": "Følges af {name1}, {name2} og {othersCount, plural, one {# mere, man kender} other {# mere, du kender}}",
@ -51,7 +51,7 @@
"account.followers_counter": "{count, plural, one {{counter} følger} other {{counter} følgere}}",
"account.followers_you_know_counter": "{counter} du kender",
"account.following": "Følger",
"account.following_counter": "{count, plural, one {{counter} følger} other {{counter} følger}}",
"account.following_counter": "{count, plural, one {{counter} fulgt} other {{counter} fulgte}}",
"account.follows.empty": "Denne bruger følger ikke nogen endnu.",
"account.follows_you": "Følger dig",
"account.go_to_profile": "Gå til profil",
@ -117,20 +117,20 @@
"annual_report.summary.archetype.lurker": "Lureren",
"annual_report.summary.archetype.oracle": "Oraklet",
"annual_report.summary.archetype.pollster": "Afstemningsmageren",
"annual_report.summary.archetype.replier": "Den social sommerfugl",
"annual_report.summary.archetype.replier": "Den sociale sommerfugl",
"annual_report.summary.followers.followers": "følgere",
"annual_report.summary.followers.total": "{count} i alt",
"annual_report.summary.here_it_is": "Her er dit {year} i sammendrag:",
"annual_report.summary.highlighted_post.by_favourites": "mest favoritmarkerede indlæg",
"annual_report.summary.highlighted_post.by_reblogs": "mest fremhævede indlæg",
"annual_report.summary.highlighted_post.by_replies": "mest besvarede indlæg",
"annual_report.summary.highlighted_post.by_replies": "indlæg med flest svar",
"annual_report.summary.highlighted_post.possessive": "{name}s",
"annual_report.summary.most_used_app.most_used_app": "mest benyttede app",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "mest benyttede hashtag",
"annual_report.summary.most_used_hashtag.none": "Intet",
"annual_report.summary.new_posts.new_posts": "nye indlæg",
"annual_report.summary.percentile.text": "<topLabel>Dermed er du i top</topLabel><percentage></percentage><bottomLabel>af {domain}-brugere.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Vi fortæller det ikke til Pernille Skipper.",
"annual_report.summary.percentile.we_wont_tell_bernie": "Vi fortæller det ikke til nogen.",
"annual_report.summary.thanks": "Tak for at være en del af Mastodon!",
"attachments_list.unprocessed": "(ubehandlet)",
"audio.hide": "Skjul lyd",
@ -144,7 +144,7 @@
"block_modal.you_wont_see_mentions": "Du vil ikke se indlæg, som omtaler vedkommende.",
"boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang",
"boost_modal.reblog": "Fremhæv indlæg?",
"boost_modal.undo_reblog": "Fjern fremhævning af indlæg?",
"boost_modal.undo_reblog": "Fjern fremhævelse af indlæg?",
"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.title": "Åh nej!",
@ -152,12 +152,12 @@
"bundle_column_error.network.title": "Netværksfejl",
"bundle_column_error.retry": "Forsøg igen",
"bundle_column_error.return": "Tilbage til hjem",
"bundle_column_error.routing.body": "Den anmodede side kunne ikke findes. Er du sikker på, at URL'en er korrekt?",
"bundle_column_error.routing.body": "Den ønskede side kunne ikke findes. Er du sikker på, at URL'en i adresselinjen er korrekt?",
"bundle_column_error.routing.title": "404",
"bundle_modal_error.close": "Luk",
"bundle_modal_error.message": "Noget gik galt under indlæsningen af denne skærm.",
"bundle_modal_error.retry": "Forsøg igen",
"closed_registrations.other_server_instructions": "Da Mastodon er decentraliseret, kan du oprette en konto på en anden server og stadig interagere med denne.",
"closed_registrations.other_server_instructions": "Eftersom Mastodon er decentraliseret, kan du oprette en konto på en anden server og stadig interagere med denne.",
"closed_registrations_modal.description": "Oprettelse af en konto på {domain} er i øjeblikket ikke muligt, men husk på, at du ikke behøver en konto specifikt på {domain} for at bruge Mastodon.",
"closed_registrations_modal.find_another_server": "Find en anden server",
"closed_registrations_modal.preamble": "Mastodon er decentraliseret, så uanset hvor du opretter din konto, vil du være i stand til at følge og interagere med hvem som helst på denne server. Du kan endda selv være vært for den!",
@ -168,7 +168,7 @@
"column.community": "Lokal tidslinje",
"column.create_list": "Opret liste",
"column.direct": "Private omtaler",
"column.directory": "Tjek profiler",
"column.directory": "Gennemse profiler",
"column.domain_blocks": "Blokerede domæner",
"column.edit_list": "Redigér liste",
"column.favourites": "Favoritter",
@ -194,6 +194,7 @@
"community.column_settings.local_only": "Kun lokalt",
"community.column_settings.media_only": "Kun medier",
"community.column_settings.remote_only": "Kun udefra",
"compose.error.blank_post": "Indlæg kan ikke være tomt.",
"compose.language.change": "Skift sprog",
"compose.language.search": "Søg efter sprog...",
"compose.published.body": "Indlæg udgivet.",
@ -204,7 +205,7 @@
"compose_form.hashtag_warning": "Da indlægget ikke er offentligt, vises det ikke under noget hashtag, da kun offentlige indlæg er søgbare via hashtags.",
"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.placeholder": "Hvad har du på hjertet?",
"compose_form.placeholder": "Hvad har du på hjerte?",
"compose_form.poll.duration": "Afstemningens varighed",
"compose_form.poll.multiple": "Multivalg",
"compose_form.poll.option_placeholder": "Valgmulighed {number}",
@ -228,7 +229,7 @@
"confirmations.delete_list.title": "Slet liste?",
"confirmations.discard_draft.confirm": "Kassér og fortsæt",
"confirmations.discard_draft.edit.cancel": "Fortsæt redigering",
"confirmations.discard_draft.edit.message": "Hvis du fortsætter, kasseres alle ændringer, du har foretaget i det indlæg, du er i gang med at redigere.",
"confirmations.discard_draft.edit.message": "Hvis du fortsætter, vil alle ændringer, du har foretaget i det indlæg, du er er ved at redigere, blive slettet.",
"confirmations.discard_draft.edit.title": "Kassér ændringer til dit indlæg?",
"confirmations.discard_draft.post.cancel": "Genoptag udkast",
"confirmations.discard_draft.post.message": "Hvis du fortsætter, kasseres det indlæg, du er i gang med at udforme.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Læg op alligevel",
"confirmations.missing_alt_text.title": "Tilføj alt-tekst?",
"confirmations.mute.confirm": "Skjul",
"confirmations.private_quote_notify.cancel": "Tilbage til redigering",
"confirmations.private_quote_notify.confirm": "Offentliggør indlæg",
"confirmations.private_quote_notify.do_not_show_again": "Vis ikke denne besked igen",
"confirmations.private_quote_notify.message": "Den person, du citerer og andre omtalte vil blive underrettet, og vil være i stand til at se dit indlæg, selv om de ikke følger dig.",
"confirmations.private_quote_notify.title": "Del med følgere og omtalte brugere?",
"confirmations.quiet_post_quote_info.dismiss": "Påmind mig ikke igen",
"confirmations.quiet_post_quote_info.got_it": "Forstået",
"confirmations.quiet_post_quote_info.message": "Når du citerer et stille offentligt indlæg, vil dit indlæg blive skjult fra trendtidslinjer.",
@ -267,7 +273,7 @@
"confirmations.withdraw_request.title": "Annullér anmodning om at følge {name}?",
"content_warning.hide": "Skjul indlæg",
"content_warning.show": "Vis alligevel",
"content_warning.show_more": "Vis flere",
"content_warning.show_more": "Vis mere",
"conversation.delete": "Slet samtale",
"conversation.mark_as_read": "Markér som læst",
"conversation.open": "Vis samtale",
@ -281,7 +287,7 @@
"directory.recently_active": "Aktive for nyligt",
"disabled_account_banner.account_settings": "Kontoindstillinger",
"disabled_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret.",
"dismissable_banner.community_timeline": "Disse er de seneste offentlige indlæg fra personer med konti hostet af {domain}.",
"dismissable_banner.community_timeline": "Dette er de seneste offentlige indlæg fra personer med konti hostet af {domain}.",
"dismissable_banner.dismiss": "Afvis",
"dismissable_banner.public_timeline": "Dette er de seneste offentlige indlæg fra personer på fediverset, som folk på {domain} følger.",
"domain_block_modal.block": "Blokér server",
@ -319,7 +325,7 @@
"emoji_button.not_found": "Ingen matchende emojis fundet",
"emoji_button.objects": "Objekter",
"emoji_button.people": "Personer",
"emoji_button.recent": "Oftest brugt",
"emoji_button.recent": "Ofte brugt",
"emoji_button.search": "Søg...",
"emoji_button.search_results": "Søgeresultater",
"emoji_button.symbols": "Symboler",
@ -331,7 +337,7 @@
"empty_column.account_suspended": "Konto suspenderet",
"empty_column.account_timeline": "Ingen indlæg her!",
"empty_column.account_unavailable": "Profil utilgængelig",
"empty_column.blocks": "Ingen brugere blokeret endnu.",
"empty_column.blocks": "Du har ikke blokeret nogle brugere endnu.",
"empty_column.bookmarked_statuses": "Du har ingen bogmærkede indlæg endnu. Når du bogmærker ét, vil det dukke op hér.",
"empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at sætte tingene i gang!",
"empty_column.direct": "Du har ikke nogen private omtaler endnu. Når du sender eller modtager en, vil den blive vist her.",
@ -360,7 +366,7 @@
"explore.trending_links": "Nyheder",
"explore.trending_statuses": "Indlæg",
"explore.trending_tags": "Hashtags",
"featured_carousel.header": "{count, plural, one {Fastgjort indlæg} other {Fastgjorte indlæg}}",
"featured_carousel.header": "{count, plural, one {fastgjort indlæg} other {fastgjorte indlæg}}",
"featured_carousel.next": "Næste",
"featured_carousel.post": "Indlæg",
"featured_carousel.previous": "Foregående",
@ -500,7 +506,7 @@
"keyboard_shortcuts.pinned": "Åbn liste over fastgjorte indlæg",
"keyboard_shortcuts.profile": "Åbn forfatters profil",
"keyboard_shortcuts.quote": "Citér indlæg",
"keyboard_shortcuts.reply": "Besvar indlægget",
"keyboard_shortcuts.reply": "Besvar indlæg",
"keyboard_shortcuts.requests": "Åbn liste over følgeanmodninger",
"keyboard_shortcuts.search": "Fokusér søgebjælke",
"keyboard_shortcuts.spoilers": "Vis/skjul indholdsadvarsel-felt",
@ -574,7 +580,7 @@
"navigation_bar.filters": "Skjulte ord",
"navigation_bar.follow_requests": "Følgeanmodninger",
"navigation_bar.followed_tags": "Hashtags, som følges",
"navigation_bar.follows_and_followers": "Følges og følgere",
"navigation_bar.follows_and_followers": "Følger og følgere",
"navigation_bar.import_export": "Import og eksport",
"navigation_bar.lists": "Lister",
"navigation_bar.live_feed_local": "Live feed (lokalt)",
@ -600,7 +606,7 @@
"notification.admin.report_statuses_other": "{name} anmeldte {target}",
"notification.admin.sign_up": "{name} tilmeldte sig",
"notification.admin.sign_up.name_and_others": "{name} og {count, plural, one {# anden} other {# andre}} tilmeldte sig",
"notification.annual_report.message": "{year} #Wrapstodon venter! Afslør årets højdepunkter og mindeværdige øjeblikke på Mastodon!",
"notification.annual_report.message": "Din {year} #Wrapstodon venter! Afslør årets højdepunkter og mindeværdige øjeblikke på Mastodon!",
"notification.annual_report.view": "Vis #Wrapstodon",
"notification.favourite": "{name} føjede dit indlæg til favoritter",
"notification.favourite.name_and_others_with_link": "{name} og <a>{count, plural, one {# anden} other {# andre}}</a> føjede dit indlæg til favoritter",
@ -668,7 +674,7 @@
"notifications.column_settings.filter_bar.category": "Hurtigfiltreringsbjælke",
"notifications.column_settings.follow": "Nye følgere:",
"notifications.column_settings.follow_request": "Nye følgeanmodninger:",
"notifications.column_settings.group": "Gruppere",
"notifications.column_settings.group": "Gruppér",
"notifications.column_settings.mention": "Omtaler:",
"notifications.column_settings.poll": "Afstemningsresultater:",
"notifications.column_settings.push": "Push-notifikationer",
@ -757,7 +763,8 @@
"privacy_policy.last_updated": "Senest opdateret {date}",
"privacy_policy.title": "Privatlivspolitik",
"quote_error.edit": "Citater kan ikke tilføjes ved redigering af et indlæg.",
"quote_error.poll": "Citering ikke tilladt i afstemninger.",
"quote_error.poll": "Citering er ikke tilladt med afstemninger.",
"quote_error.private_mentions": "Citering er ikke tilladt med direkte omtaler.",
"quote_error.quote": "Kun ét citat ad gangen er tilladt.",
"quote_error.unauthorized": "Du har ikke tilladelse til at citere dette indlæg.",
"quote_error.upload": "Citering ikke tilladt ved medievedhæftninger.",
@ -859,7 +866,7 @@
"search_results.title": "Søg efter \"{q}\"",
"server_banner.about_active_users": "Personer, som brugte denne server de seneste 30 dage (månedlige aktive brugere)",
"server_banner.active_users": "aktive brugere",
"server_banner.administered_by": "Håndteres af:",
"server_banner.administered_by": "Administreret af:",
"server_banner.is_one_of_many": "{domain} er en af de mange uafhængige Mastodon-servere, du kan bruge for at deltage i fediverset.",
"server_banner.server_stats": "Serverstatstik:",
"sign_in_banner.create_account": "Opret konto",
@ -894,7 +901,7 @@
"status.edited": "Senest redigeret {date}",
"status.edited_x_times": "Redigeret {count, plural, one {{count} gang} other {{count} gange}}",
"status.embed": "Hent indlejringskode",
"status.favourite": "Favorit",
"status.favourite": "Favoritmarkér",
"status.favourites": "{count, plural, one {# favorit} other {# favoritter}}",
"status.filter": "Filtrér dette indlæg",
"status.history.created": "{name} oprettet {date}",
@ -911,9 +918,12 @@
"status.pin": "Fastgør til profil",
"status.quote": "Citér",
"status.quote.cancel": "Annullér citat",
"status.quote_error.blocked_account_hint.title": "Dette indlæg er skjult, fordi du har blokeret @{name}.",
"status.quote_error.blocked_domain_hint.title": "Dette indlæg er skjult, fordi du har blokeret @{domain}.",
"status.quote_error.filtered": "Skjult grundet et af filterne",
"status.quote_error.limited_account_hint.action": "Vis alligevel",
"status.quote_error.limited_account_hint.title": "Denne profil er blevet skjult af {domain}-moderatorerne.",
"status.quote_error.muted_account_hint.title": "Dette indlæg er skjult, fordi du har skjult @{name}.",
"status.quote_error.not_available": "Indlæg utilgængeligt",
"status.quote_error.pending_approval": "Afventende indlæg",
"status.quote_error.pending_approval_popout.body": "På Mastodon kan du kontrollere, om nogen kan citere dig. Dette indlæg afventer, mens vi får den oprindelige forfatters godkendelse.",
@ -980,7 +990,7 @@
"units.short.million": "{count} mio.",
"units.short.thousand": "{count} tusind",
"upload_area.title": "Træk og slip for at uploade",
"upload_button.label": "Tilføj billed-, video- eller lydfil(er)",
"upload_button.label": "Tilføj billeder, en video- eller lydfil",
"upload_error.limit": "Grænse for filupload nået.",
"upload_error.poll": "Filupload ikke tilladt for afstemninger.",
"upload_error.quote": "Fil-upload ikke tilladt i citater.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Lydstyrke ned",
"video.volume_up": "Lydstyrke op",
"visibility_modal.button_title": "Indstil synlighed",
"visibility_modal.direct_quote_warning.text": "Hvis du gemmer de aktuelle indstillinger, vil det indlejrede citat blive konverteret til et link.",
"visibility_modal.direct_quote_warning.title": "Citater kan ikke indlejres i private omtaler",
"visibility_modal.header": "Synlighed og interaktion",
"visibility_modal.helper.direct_quoting": "Private omtaler forfattet på Mastodon kan ikke citeres af andre.",
"visibility_modal.helper.privacy_editing": "Synlighed kan ikke ændres, efter at et indlæg er offentliggjort.",

View File

@ -1,13 +1,13 @@
{
"about.blocks": "Moderierte Server",
"about.blocks": "Eingeschränkte Server",
"about.contact": "Kontakt:",
"about.default_locale": "Standard",
"about.disclaimer": "Mastodon ist eine freie, quelloffene Software und eine Marke der Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Grund unbekannt",
"about.domain_blocks.no_reason_available": "Keinen Grund angegeben",
"about.domain_blocks.preamble": "Mastodon erlaubt es dir grundsätzlich, alle Inhalte von allen Nutzer*innen auf allen Servern im Fediverse zu sehen und mit ihnen zu interagieren. Für diesen Server gibt es aber ein paar Ausnahmen.",
"about.domain_blocks.silenced.explanation": "Standardmäßig werden von diesem Server keine Inhalte oder Profile angezeigt. Du kannst die Profile und Inhalte aber dennoch sehen, wenn du explizit nach diesen suchst oder diesen folgst.",
"about.domain_blocks.silenced.title": "Ausgeblendet",
"about.domain_blocks.suspended.explanation": "Es werden keine Daten von diesem Server verarbeitet, gespeichert oder ausgetauscht, sodass eine Interaktion oder Kommunikation mit Nutzer*innen dieses Servers nicht möglich ist.",
"about.domain_blocks.silenced.title": "Stummgeschaltet",
"about.domain_blocks.suspended.explanation": "Es werden keine Daten von diesem Server verarbeitet, gespeichert oder ausgetauscht, sodass eine Interaktion oder Kommunikation mit Profilen dieses Servers nicht möglich ist.",
"about.domain_blocks.suspended.title": "Gesperrt",
"about.language_label": "Sprache",
"about.not_available": "Diese Informationen sind auf diesem Server nicht verfügbar.",
@ -15,21 +15,21 @@
"about.rules": "Serverregeln",
"account.account_note_header": "Persönliche Notiz",
"account.add_or_remove_from_list": "Hinzufügen oder Entfernen von Listen",
"account.badges.bot": "Automatisiert",
"account.badges.bot": "Bot",
"account.badges.group": "Gruppe",
"account.block": "@{name} blockieren",
"account.block_domain": "{domain} sperren",
"account.block_domain": "{domain} blockieren",
"account.block_short": "Blockieren",
"account.blocked": "Blockiert",
"account.blocking": "Blockiert",
"account.cancel_follow_request": "Follower-Anfrage zurückziehen",
"account.cancel_follow_request": "Anfrage zurückziehen",
"account.copy": "Link zum Profil kopieren",
"account.direct": "@{name} privat erwähnen",
"account.disable_notifications": "Höre auf mich zu benachrichtigen wenn @{name} etwas postet",
"account.disable_notifications": "Benachrichtige mich nicht mehr, wenn @{name} etwas veröffentlicht",
"account.domain_blocking": "Domain blockiert",
"account.edit_profile": "Profil bearbeiten",
"account.edit_profile_short": "Bearbeiten",
"account.enable_notifications": "Benachrichtige mich wenn @{name} etwas postet",
"account.enable_notifications": "Benachrichtige mich, wenn @{name} etwas veröffentlicht",
"account.endorse": "Im Profil vorstellen",
"account.familiar_followers_many": "Gefolgt von {name1}, {name2} und {othersCount, plural, one {einem weiteren Profil, das dir bekannt ist} other {# weiteren Profilen, die dir bekannt sind}}",
"account.familiar_followers_one": "Gefolgt von {name1}",
@ -37,11 +37,11 @@
"account.featured": "Vorgestellt",
"account.featured.accounts": "Profile",
"account.featured.hashtags": "Hashtags",
"account.featured_tags.last_status_at": "Letzter Beitrag am {date}",
"account.featured_tags.last_status_at": "Neuester Beitrag vom {date}",
"account.featured_tags.last_status_never": "Keine Beiträge",
"account.follow": "Folgen",
"account.follow_back": "Ebenfalls folgen",
"account.follow_back_short": "Ebenfalls folgen",
"account.follow_back_short": "Zurückfolgen",
"account.follow_request": "Anfrage zum Folgen",
"account.follow_request_cancel": "Anfrage zurückziehen",
"account.follow_request_cancel_short": "Abbrechen",
@ -58,8 +58,8 @@
"account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden",
"account.in_memoriam": "Zum Andenken.",
"account.joined_short": "Mitglied seit",
"account.languages": "Sprache ändern.",
"account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} verifiziert",
"account.languages": "Ausgewählte Sprachen ändern",
"account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt",
"account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.",
"account.media": "Medien",
"account.mention": "@{name} erwähnen",
@ -73,51 +73,51 @@
"account.no_bio": "Keine Beschreibung verfügbar.",
"account.open_original_page": "Ursprüngliche Seite öffnen",
"account.posts": "Beiträge",
"account.posts_with_replies": "Beiträge und Antworten",
"account.remove_from_followers": "{name} als Follower entfernen",
"account.posts_with_replies": "Beiträge & Antworten",
"account.remove_from_followers": "@{name} als Follower entfernen",
"account.report": "@{name} melden",
"account.requested_follow": "{name} möchte dir folgen",
"account.requests_to_follow_you": "Möchte dir folgen",
"account.share": "Profil von @{name} teilen",
"account.show_reblogs": "Geteilte Beiträge von @{name} anzeigen",
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
"account.unblock": "{name} nicht mehr blockieren",
"account.unblock": "Blockierung von {name} aufheben",
"account.unblock_domain": "Blockierung von {domain} aufheben",
"account.unblock_domain_short": "Entsperren",
"account.unblock_domain_short": "Blockierung aufheben",
"account.unblock_short": "Blockierung aufheben",
"account.unendorse": "Im Profil nicht mehr vorstellen",
"account.unfollow": "Entfolgen",
"account.unmute": "Stummschaltung von @{name} aufheben",
"account.unmute_notifications_short": "Stummschaltung der Benachrichtigungen aufheben",
"account.unmute_short": "Stummschaltung aufheben",
"account_note.placeholder": "Klicken, um Notiz hinzuzufügen",
"admin.dashboard.daily_retention": "Verweildauer der Nutzer*innen pro Tag nach der Registrierung",
"admin.dashboard.monthly_retention": "Verweildauer der Nutzer*innen pro Monat nach der Registrierung",
"account_note.placeholder": "Klicken, um private Anmerkung hinzuzufügen",
"admin.dashboard.daily_retention": "Verweildauer der Nutzer*innen pro Tag seit der Registrierung",
"admin.dashboard.monthly_retention": "Verweildauer der Nutzer*innen pro Monat seit der Registrierung",
"admin.dashboard.retention.average": "Durchschnitt",
"admin.dashboard.retention.cohort": "Monat der Registrierung",
"admin.dashboard.retention.cohort_size": "Neue Konten",
"admin.impact_report.instance_accounts": "Profilkonten, die dadurch gelöscht würden",
"admin.impact_report.instance_accounts": "Konten, die dadurch gelöscht würden",
"admin.impact_report.instance_followers": "Follower, die unsere Nutzer*innen verlieren würden",
"admin.impact_report.instance_follows": "Follower, die deren Nutzer*innen verlieren würden",
"admin.impact_report.title": "Zusammenfassung der Auswirkung",
"alert.rate_limited.message": "Bitte versuche es nach {retry_time, time, medium} erneut.",
"alert.rate_limited.message": "Bitte versuche es um {retry_time, time, medium} erneut.",
"alert.rate_limited.title": "Anfragelimit überschritten",
"alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.",
"alert.unexpected.title": "Oha!",
"alert.unexpected.title": "Ups!",
"alt_text_badge.title": "Bildbeschreibung",
"alt_text_modal.add_alt_text": "Bildbeschreibung hinzufügen",
"alt_text_modal.add_text_from_image": "Text aus Bild hinzufügen",
"alt_text_modal.cancel": "Abbrechen",
"alt_text_modal.change_thumbnail": "Vorschaubild ändern",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Beschreibe den Inhalt für Menschen mit Schwerhörigkeit …",
"alt_text_modal.describe_for_people_with_visual_impairments": "Beschreibe den Inhalt für Menschen mit Sehschwäche …",
"alt_text_modal.describe_for_people_with_hearing_impairments": "Beschreibe den Inhalt für Menschen, die taub oder hörbehindert sind …",
"alt_text_modal.describe_for_people_with_visual_impairments": "Beschreibe den Inhalt für Menschen, die blind oder sehbehindert sind …",
"alt_text_modal.done": "Fertig",
"announcement.announcement": "Ankündigung",
"annual_report.summary.archetype.booster": "Trendjäger*in",
"annual_report.summary.archetype.lurker": "Beobachter*in",
"annual_report.summary.archetype.oracle": "Universaltalent",
"annual_report.summary.archetype.pollster": "Meinungsforscher*in",
"annual_report.summary.archetype.replier": "Sozialer Schmetterling",
"annual_report.summary.archetype.replier": "Gesellige*r",
"annual_report.summary.followers.followers": "Follower",
"annual_report.summary.followers.total": "{count} insgesamt",
"annual_report.summary.here_it_is": "Dein Jahresrückblick für {year}:",
@ -142,13 +142,13 @@
"block_modal.they_will_know": "Das Profil wird erkennen können, dass du es blockiert hast.",
"block_modal.title": "Profil blockieren?",
"block_modal.you_wont_see_mentions": "Du wirst keine Beiträge sehen, die dieses Profil erwähnen.",
"boost_modal.combo": "Mit {combo} erscheint dieses Fenster beim nächsten Mal nicht mehr",
"boost_modal.combo": "Mit {combo} erscheint dieses Fenster nicht mehr",
"boost_modal.reblog": "Beitrag teilen?",
"boost_modal.undo_reblog": "Beitrag nicht mehr teilen?",
"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.title": "Oh nein!",
"bundle_column_error.network.body": "Beim Versuch, diese Seite zu laden, ist ein Fehler aufgetreten. Dies könnte auf ein vorübergehendes Problem mit Ihrer Internetverbindung oder diesem Server zurückzuführen sein.",
"bundle_column_error.network.body": "Beim Versuch, diese Seite zu laden, ist ein Fehler aufgetreten. Dies könnte auf ein vorübergehendes Problem mit deiner Internetverbindung oder diesem Server zurückzuführen sein.",
"bundle_column_error.network.title": "Netzwerkfehler",
"bundle_column_error.retry": "Erneut versuchen",
"bundle_column_error.return": "Zurück zur Startseite",
@ -157,10 +157,10 @@
"bundle_modal_error.close": "Schließen",
"bundle_modal_error.message": "Beim Laden des Inhalts ist etwas schiefgelaufen.",
"bundle_modal_error.retry": "Erneut versuchen",
"closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, kannst du ein Konto auf einem anderen Server erstellen und trotzdem mit diesem Server interagieren.",
"closed_registrations_modal.description": "Das Anlegen eines Kontos auf {domain} ist derzeit nicht möglich, aber bedenke, dass du kein extra Konto auf {domain} benötigst, um Mastodon nutzen zu können.",
"closed_registrations_modal.find_another_server": "Einen anderen Server auswählen",
"closed_registrations_modal.preamble": "Mastodon ist dezentralisiert, das heißt, unabhängig davon, wo du dein Konto erstellt hast, kannst du jedem Profil auf diesem Server folgen und mit ihm interagieren. Du kannst sogar deinen eigenen Server hosten!",
"closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, kannst du dich auch woanders im Fediverse registrieren und trotzdem mit diesem Server in Kontakt bleiben.",
"closed_registrations_modal.description": "Das Anlegen eines Kontos auf {domain} ist derzeit nicht möglich, aber bedenke, dass du nicht zwingend auf {domain} ein Konto benötigst, um Mastodon nutzen zu können.",
"closed_registrations_modal.find_another_server": "Anderen Server suchen",
"closed_registrations_modal.preamble": "Mastodon ist dezentralisiert, das heißt, unabhängig davon, wo du dein Konto erstellst, kannst du jedem Profil auf diesem Server folgen und mit ihm interagieren. Du kannst sogar deinen eigenen Mastodon-Server hosten!",
"closed_registrations_modal.title": "Bei Mastodon registrieren",
"column.about": "Über",
"column.blocks": "Blockierte Profile",
@ -168,11 +168,13 @@
"column.community": "Lokale Timeline",
"column.create_list": "Liste erstellen",
"column.direct": "Private Erwähnungen",
"column.directory": "Profile durchsuchen",
"column.directory": "Profile durchstöbern",
"column.domain_blocks": "Blockierte Domains",
"column.edit_list": "Liste bearbeiten",
"column.favourites": "Favoriten",
"column.firehose": "Live-Feeds",
"column.firehose_local": "Live-Feed dieses Servers",
"column.firehose_singular": "Live-Feed",
"column.follow_requests": "Follower-Anfragen",
"column.home": "Startseite",
"column.list_members": "Listenmitglieder verwalten",
@ -191,25 +193,26 @@
"column_search.cancel": "Abbrechen",
"community.column_settings.local_only": "Nur lokal",
"community.column_settings.media_only": "Nur Beiträge mit Medien",
"community.column_settings.remote_only": "Nur andere Mastodon-Server",
"community.column_settings.remote_only": "Nur andere Server im Fediverse",
"compose.error.blank_post": "Beitrag muss einen Inhalt haben.",
"compose.language.change": "Sprache festlegen",
"compose.language.search": "Sprachen suchen …",
"compose.published.body": "Beitrag veröffentlicht.",
"compose.published.open": "Öffnen",
"compose.saved.body": "Beitrag gespeichert.",
"compose_form.direct_message_warning_learn_more": "Mehr erfahren",
"compose_form.encryption_warning": "Beiträge auf Mastodon sind nicht Ende-zu-Ende-verschlüsselt. Teile keine sensiblen Informationen über Mastodon.",
"compose_form.encryption_warning": "Beiträge auf Mastodon sind nicht Ende-zu-Ende-verschlüsselt. Teile keine sensiblen Informationen über Mastodon, auch nicht als „private Erwähnung“.",
"compose_form.hashtag_warning": "Dieser Beitrag wird unter keinem Hashtag sichtbar sein, weil er nicht öffentlich ist. Nur öffentliche Beiträge können nach Hashtags durchsucht werden.",
"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.placeholder": "Was gibts Neues?",
"compose_form.poll.duration": "Umfragedauer",
"compose_form.poll.duration": "Laufzeit",
"compose_form.poll.multiple": "Mehrfachauswahl",
"compose_form.poll.option_placeholder": "{number}. Auswahl",
"compose_form.poll.single": "Einfachauswahl",
"compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben",
"compose_form.poll.switch_to_single": "Nur Einfachauswahl erlauben",
"compose_form.poll.type": "Art",
"compose_form.poll.type": "Typ",
"compose_form.publish": "Veröffentlichen",
"compose_form.reply": "Antworten",
"compose_form.save_changes": "Aktualisieren",
@ -222,7 +225,7 @@
"confirmations.delete.message": "Möchtest du diesen Beitrag wirklich löschen?",
"confirmations.delete.title": "Beitrag löschen?",
"confirmations.delete_list.confirm": "Löschen",
"confirmations.delete_list.message": "Möchtest du diese Liste für immer löschen?",
"confirmations.delete_list.message": "Bist du dir sicher, dass du diese Liste endgültig löschen möchtest?",
"confirmations.delete_list.title": "Liste löschen?",
"confirmations.discard_draft.confirm": "Verwerfen und fortfahren",
"confirmations.discard_draft.edit.cancel": "Bearbeitung fortsetzen",
@ -237,32 +240,37 @@
"confirmations.follow_to_list.message": "Du musst {name} folgen, um das Profil zu einer Liste hinzufügen zu können.",
"confirmations.follow_to_list.title": "Profil folgen?",
"confirmations.logout.confirm": "Abmelden",
"confirmations.logout.message": "Möchtest du dich wirklich abmelden?",
"confirmations.logout.message": "Möchtest du dich wirklich ausloggen?",
"confirmations.logout.title": "Abmelden?",
"confirmations.missing_alt_text.confirm": "Bildbeschreibung hinzufügen",
"confirmations.missing_alt_text.message": "Dein Beitrag enthält Medien ohne Bildbeschreibung. Mit Alt-Texten erreichst du auch Menschen mit einer Sehschwäche.",
"confirmations.missing_alt_text.message": "Dein Beitrag enthält Medien ohne Bildbeschreibung. Mit ALT-Texten erreichst Du auch Menschen, die blind oder sehbehindert sind.",
"confirmations.missing_alt_text.secondary": "Trotzdem veröffentlichen",
"confirmations.missing_alt_text.title": "Bildbeschreibung hinzufügen?",
"confirmations.mute.confirm": "Stummschalten",
"confirmations.quiet_post_quote_info.dismiss": "Nicht mehr anzeigen",
"confirmations.private_quote_notify.cancel": "Zurück zur Bearbeitung",
"confirmations.private_quote_notify.confirm": "Beitrag veröffentlichen",
"confirmations.private_quote_notify.do_not_show_again": "Diesen Hinweis nicht mehr anzeigen",
"confirmations.private_quote_notify.message": "Dein Beitrag wird von dem zitierten sowie den erwähnten Profilen gesehen werden können, auch wenn sie dir nicht folgen.",
"confirmations.private_quote_notify.title": "Mit Followern und erwähnten Profilen teilen?",
"confirmations.quiet_post_quote_info.dismiss": "Nicht erneut erinnern",
"confirmations.quiet_post_quote_info.got_it": "Verstanden",
"confirmations.quiet_post_quote_info.message": "Beim Zitieren eines Beitrags mit der Sichtbarkeit „Öffentlich (still)“ wird dein zitierter Beitrag ebenfalls nicht in den Trends und öffentlichen Timelines angezeigt.",
"confirmations.quiet_post_quote_info.message": "Beim Zitieren eines Beitrags, dessen Sichtbarkeit „Öffentlich (still)“ ist, wird auch dein Beitrag, der das Zitat enthält, aus den Trends und öffentlichen Timelines ausgeblendet.",
"confirmations.quiet_post_quote_info.title": "Zitieren eines Beitrags mit der Sichtbarkeit „Öffentlich (still)“",
"confirmations.redraft.confirm": "Löschen und neu erstellen",
"confirmations.redraft.message": "Möchtest du diesen Beitrag wirklich löschen und neu verfassen? Alle Favoriten sowie die bisher geteilten Beiträge werden verloren gehen und Antworten auf den ursprünglichen Beitrag verlieren den Zusammenhang.",
"confirmations.redraft.title": "Beitrag löschen und neu verfassen?",
"confirmations.redraft.title": "Beitrag löschen & neu verfassen?",
"confirmations.remove_from_followers.confirm": "Follower entfernen",
"confirmations.remove_from_followers.message": "{name} wird dir nicht länger folgen. Bist du dir sicher?",
"confirmations.remove_from_followers.title": "Follower entfernen?",
"confirmations.revoke_quote.confirm": "Beitrag entfernen",
"confirmations.revoke_quote.confirm": "Zitat entfernen",
"confirmations.revoke_quote.message": "Diese Aktion kann nicht rückgängig gemacht werden.",
"confirmations.revoke_quote.title": "Beitrag entfernen?",
"confirmations.unblock.confirm": "Entsperren",
"confirmations.unblock.title": "{name} entsperren?",
"confirmations.revoke_quote.title": "Mein Zitat aus diesem Beitrag entfernen?",
"confirmations.unblock.confirm": "Blockierung aufheben",
"confirmations.unblock.title": "Blockierung von {name} aufheben?",
"confirmations.unfollow.confirm": "Entfolgen",
"confirmations.unfollow.title": "{name} entfolgen?",
"confirmations.withdraw_request.confirm": "Anfrage zurückziehen",
"confirmations.withdraw_request.title": "Anfrage zum Folgen von {name} zurückziehen?",
"confirmations.withdraw_request.title": "Anfrage zum Folgen von {name} widerrufen?",
"content_warning.hide": "Beitrag ausblenden",
"content_warning.show": "Trotzdem anzeigen",
"content_warning.show_more": "Beitrag anzeigen",
@ -274,8 +282,8 @@
"copypaste.copied": "Kopiert",
"copypaste.copy_to_clipboard": "In die Zwischenablage kopieren",
"directory.federated": "Aus bekanntem Fediverse",
"directory.local": "Nur von der Domain {domain}",
"directory.new_arrivals": "Neue Benutzer*innen",
"directory.local": "Nur von dieser Domain {domain}",
"directory.new_arrivals": "Neue Profile",
"directory.recently_active": "Kürzlich aktiv",
"disabled_account_banner.account_settings": "Kontoeinstellungen",
"disabled_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert.",
@ -294,25 +302,25 @@
"domain_pill.activitypub_lets_connect": "Somit kannst du dich nicht nur auf Mastodon mit Leuten verbinden und mit ihnen interagieren, sondern über alle sozialen Apps hinweg.",
"domain_pill.activitypub_like_language": "ActivityPub ist sozusagen die Sprache, die Mastodon mit anderen sozialen Netzwerken spricht.",
"domain_pill.server": "Server",
"domain_pill.their_handle": "Deren Adresse:",
"domain_pill.their_server": "Deren digitale Heimat. Hier „leben“ alle Beiträge von diesem Profil.",
"domain_pill.their_username": "Deren eindeutigen Identität auf dem betreffenden Server. Es ist möglich, Profile mit dem gleichen Profilnamen auf verschiedenen Servern zu finden.",
"domain_pill.their_handle": "Vollständige Adresse:",
"domain_pill.their_server": "Die digitale Heimat, in der sich alle Beiträge dieses Profils befinden.",
"domain_pill.their_username": "Die eindeutige Identifizierung auf einem Server. Es ist möglich, denselben Profilnamen auf verschiedenen Servern im Fediverse zu finden.",
"domain_pill.username": "Profilname",
"domain_pill.whats_in_a_handle": "Woraus besteht eine Adresse?",
"domain_pill.who_they_are": "Adressen teilen mit, wer jemand ist und wo sich jemand aufhält. Daher kannst du mit Leuten im gesamten Social Web interagieren, wenn es eine durch <button>ActivityPub angetriebene Plattform</button> ist.",
"domain_pill.who_they_are": "Adressen teilen mit, wer jemand ist und wo sich jemand im Fediverse aufhält. Daher kannst du mit Leuten im gesamten Social Web interagieren, wenn es eine durch <button>ActivityPub angetriebene Plattform</button> ist.",
"domain_pill.who_you_are": "Deine Adresse teilt mit, wer du bist und wo du dich aufhältst. Daher können andere Leute im gesamten Social Web mit dir interagieren, wenn es eine durch <button>ActivityPub angetriebene Plattform</button> ist.",
"domain_pill.your_handle": "Deine Adresse:",
"domain_pill.your_server": "Deine digitale Heimat. Hier „leben“ alle Beiträge von dir. Falls es dir hier nicht gefällt, kannst du jederzeit den Server wechseln und ebenso deine Follower übertragen.",
"domain_pill.your_username": "Deine eindeutige Identität auf diesem Server. Es ist möglich, Profile mit dem gleichen Profilnamen auf verschiedenen Servern zu finden.",
"dropdown.empty": "Option auswählen",
"embed.instructions": "Du kannst diesen Beitrag auf deiner Website einbetten, indem du den nachfolgenden Code kopierst.",
"embed.instructions": "Du kannst diesen Beitrag außerhalb des Fediverse (z. B. in deine Website) einbetten, indem du diesen Code kopierst und dort einfügst.",
"embed.preview": "Vorschau:",
"emoji_button.activity": "Aktivitäten",
"emoji_button.clear": "Leeren",
"emoji_button.custom": "Spezielle Emojis dieses Servers",
"emoji_button.flags": "Flaggen",
"emoji_button.food": "Essen & Trinken",
"emoji_button.label": "Emoji einfügen",
"emoji_button.label": "Emoji hinzufügen",
"emoji_button.nature": "Natur",
"emoji_button.not_found": "Keine passenden Emojis gefunden",
"emoji_button.objects": "Gegenstände",
@ -326,7 +334,7 @@
"empty_column.account_featured.other": "{acct} hat bisher noch nichts vorgestellt. Wusstest du, dass du deine häufig verwendeten Hashtags und sogar Profile von Freund*innen vorstellen kannst?",
"empty_column.account_featured_other.unknown": "Dieses Profil hat bisher noch nichts vorgestellt.",
"empty_column.account_hides_collections": "Das Konto hat sich dazu entschieden, diese Information nicht zu veröffentlichen",
"empty_column.account_suspended": "Konto gesperrt",
"empty_column.account_suspended": "Konto dauerhaft gesperrt",
"empty_column.account_timeline": "Keine Beiträge vorhanden!",
"empty_column.account_unavailable": "Profil nicht verfügbar",
"empty_column.blocks": "Du hast bisher keine Profile blockiert.",
@ -334,19 +342,19 @@
"empty_column.community": "Die lokale Timeline ist leer. Schreibe einen öffentlichen Beitrag, um den Stein ins Rollen zu bringen!",
"empty_column.direct": "Du hast noch keine privaten Erwähnungen. Sobald du eine sendest oder erhältst, wird sie hier erscheinen.",
"empty_column.disabled_feed": "Diesen Feed haben deine Server-Administrator*innen deaktiviert.",
"empty_column.domain_blocks": "Du hast noch keine Domains blockiert.",
"empty_column.explore_statuses": "Momentan ist nichts im Trend. Schau später wieder vorbei!",
"empty_column.domain_blocks": "Du hast bisher keine Domains blockiert.",
"empty_column.explore_statuses": "Momentan trendet nichts. Schau später wieder vorbei!",
"empty_column.favourited_statuses": "Du hast noch keine Beiträge favorisiert. Sobald du einen favorisierst, wird er hier erscheinen.",
"empty_column.favourites": "Diesen Beitrag hat bisher noch niemand favorisiert. Sobald es jemand tut, wird das Profil hier erscheinen.",
"empty_column.follow_requests": "Es liegen derzeit keine Follower-Anfragen vor. Sobald du eine erhältst, wird sie hier erscheinen.",
"empty_column.followed_tags": "Du folgst noch keinen Hashtags. Wenn du dies tust, werden sie hier erscheinen.",
"empty_column.followed_tags": "Du folgst noch keinen Hashtags. Sobald du Hashtags abonniert hast, werden sie hier angezeigt.",
"empty_column.hashtag": "Unter diesem Hashtag gibt es noch nichts.",
"empty_column.home": "Die Timeline deiner Startseite ist leer! Folge mehr Leuten, um sie zu füllen.",
"empty_column.list": "Diese Liste ist derzeit leer. Wenn Konten auf dieser Liste neue Beiträge veröffentlichen, werden sie hier erscheinen.",
"empty_column.mutes": "Du hast keine Profile stummgeschaltet.",
"empty_column.notification_requests": "Alles klar! Hier gibt es nichts. Wenn Sie neue Mitteilungen erhalten, werden diese entsprechend Ihren Einstellungen hier angezeigt.",
"empty_column.notifications": "Du hast noch keine Benachrichtigungen. Sobald andere Personen mit dir interagieren, wirst du hier darüber informiert.",
"empty_column.public": "Hier ist nichts zu sehen! Schreibe etwas öffentlich oder folge Profilen von anderen Servern, um die Timeline aufzufüllen",
"empty_column.public": "Hier ist nichts zu sehen! Schreibe einen öffentlichen Beitrag oder folge Profilen von anderen Servern im Fediverse, um die Timeline zu füllen",
"error.unexpected_crash.explanation": "Wegen eines Fehlers in unserem Code oder aufgrund einer Browser-Inkompatibilität kann diese Seite nicht korrekt angezeigt werden.",
"error.unexpected_crash.explanation_addons": "Diese Seite konnte nicht korrekt angezeigt werden. Dieser Fehler wird wahrscheinlich durch ein Browser-Add-on oder automatische Übersetzungswerkzeuge verursacht.",
"error.unexpected_crash.next_steps": "Versuche, die Seite neu zu laden. Wenn das nicht helfen sollte, kannst du das Webinterface von Mastodon vermutlich über einen anderen Browser erreichen oder du verwendest eine mobile (native) App.",
@ -354,8 +362,8 @@
"errors.unexpected_crash.copy_stacktrace": "Fehlerdiagnose in die Zwischenablage kopieren",
"errors.unexpected_crash.report_issue": "Fehler melden",
"explore.suggested_follows": "Profile",
"explore.title": "Angesagt",
"explore.trending_links": "Neuigkeiten",
"explore.title": "Im Trend",
"explore.trending_links": "Artikel",
"explore.trending_statuses": "Beiträge",
"explore.trending_tags": "Hashtags",
"featured_carousel.header": "{count, plural, one {Angehefteter Beitrag} other {Angeheftete Beiträge}}",
@ -379,7 +387,7 @@
"filter_modal.select_filter.subtitle": "Einem vorhandenen Filter hinzufügen oder einen neuen erstellen",
"filter_modal.select_filter.title": "Diesen Beitrag filtern",
"filter_modal.title.status": "Beitrag per Filter ausblenden",
"filter_warning.matches_filter": "Ausgeblendet wegen des Filters „<span>{title}</span>“",
"filter_warning.matches_filter": "Ausgeblendet wegen deines Filters „<span>{title}</span>“",
"filtered_notifications_banner.pending_requests": "Von {count, plural, =0 {keinem Profil, das dir möglicherweise bekannt ist} one {einem Profil, das dir möglicherweise bekannt ist} other {# Profilen, die dir möglicherweise bekannt sind}}",
"filtered_notifications_banner.title": "Gefilterte Benachrichtigungen",
"firehose.all": "Alle Server",
@ -400,14 +408,14 @@
"follow_suggestions.personalized_suggestion": "Persönliche Empfehlung",
"follow_suggestions.popular_suggestion": "Beliebte Empfehlung",
"follow_suggestions.popular_suggestion_longer": "Beliebt auf {domain}",
"follow_suggestions.similar_to_recently_followed_longer": "Ähnlich zu Profilen, denen du seit kurzem folgst",
"follow_suggestions.similar_to_recently_followed_longer": "Ähnelt deinen kürzlich gefolgten Profilen",
"follow_suggestions.view_all": "Alle anzeigen",
"follow_suggestions.who_to_follow": "Empfohlene Profile",
"followed_tags": "Gefolgte Hashtags",
"follow_suggestions.who_to_follow": "Wem folgen?",
"followed_tags": "Abonnierte Hashtags",
"footer.about": "Über",
"footer.directory": "Profilverzeichnis",
"footer.get_app": "App herunterladen",
"footer.keyboard_shortcuts": "Tastenkombinationen",
"footer.keyboard_shortcuts": "Tastaturkürzel",
"footer.privacy_policy": "Datenschutzerklärung",
"footer.source_code": "Quellcode anzeigen",
"footer.status": "Status",
@ -430,10 +438,10 @@
"hashtag.counter_by_uses": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}} heute",
"hashtag.feature": "Im Profil vorstellen",
"hashtag.follow": "Hashtag folgen",
"hashtag.follow": "Abonnieren",
"hashtag.mute": "#{hashtag} stummschalten",
"hashtag.unfeature": "Im Profil nicht mehr vorstellen",
"hashtag.unfollow": "Hashtag entfolgen",
"hashtag.unfollow": "Abbestellen",
"hashtags.and_other": "… und {count, plural, one{# weiterer} other {# weitere}}",
"hints.profiles.followers_may_be_missing": "Möglicherweise werden für dieses Profil nicht alle Follower angezeigt.",
"hints.profiles.follows_may_be_missing": "Möglicherweise werden für dieses Profil nicht alle gefolgten Profile angezeigt.",
@ -443,7 +451,7 @@
"hints.profiles.see_more_posts": "Weitere Beiträge auf {domain} ansehen",
"home.column_settings.show_quotes": "Zitierte Beiträge anzeigen",
"home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
"home.column_settings.show_replies": "Antworten anzeigen",
"home.column_settings.show_replies": "Antworten zu Beiträgen anzeigen",
"home.hide_announcements": "Ankündigungen ausblenden",
"home.pending_critical_update.body": "Bitte aktualisiere deinen Mastodon-Server so schnell wie möglich!",
"home.pending_critical_update.link": "Updates ansehen",
@ -461,54 +469,54 @@
"ignore_notifications_modal.not_following_title": "Benachrichtigungen von Profilen ignorieren, denen du nicht folgst?",
"ignore_notifications_modal.private_mentions_title": "Benachrichtigungen von unerwünschten privaten Erwähnungen ignorieren?",
"info_button.label": "Hilfe",
"info_button.what_is_alt_text": "<h1>Was ist Alt-Text?</h1> <p>Alt-Text bietet Bildbeschreibungen für Personen mit einer Sehschwäche, einer schlechten Internetverbindung und für alle, die zusätzlichen Kontext möchten.</p> <p>Du kannst die Zugänglichkeit und die Verständlichkeit für alle verbessern, indem du eine klare, genaue und objektive Bildbeschreibung hinzufügst.</p> <ul> <li>Erfasse wichtige Elemente</li> <li>Fasse Text in Bildern zusammen</li> <li>Verwende einen korrekten Satzbau</li> <li>Vermeide unwichtige Informationen</li> <li>Konzentriere dich bei komplexen Darstellungen (z. B. Diagramme oder Karten) auf Trends und wichtige Erkenntnisse</li> </ul>",
"info_button.what_is_alt_text": "<h1>Was ist Alt-Text?</h1> <p>Der Alt-Text bietet Bildbeschreibungen für blinde und sehbehinderte Menschen, aber auch für alle mit einer schlechten Internetverbindung und wer einen zusätzlichen Kontext möchten.</p> <p>Du kannst die Barrierefreiheit und Verständlichkeit für alle verbessern, indem du eine klare, genaue und objektive Bildbeschreibung erstellst.</p> <ul> <li>Erfasse wichtige Elemente</li> <li>Fasse Texte bildlich zusammen</li> <li>Verwende einen korrekten Satzbau</li> <li>Vermeide unwichtige und überflüssige Informationen</li> <li>Konzentriere dich bei komplexen Darstellungen (z. B. bei Diagrammen oder Karten) auf Veränderungen und Schlüsselwörter</li> </ul>",
"interaction_modal.action": "Melde dich auf deinem Mastodon-Server an, damit du mit dem Beitrag von {name} interagieren kannst.",
"interaction_modal.go": "Los",
"interaction_modal.no_account_yet": "Du hast noch kein Konto?",
"interaction_modal.on_another_server": "Auf einem anderen Server",
"interaction_modal.on_another_server": "Auf anderem Server",
"interaction_modal.on_this_server": "Auf diesem Server",
"interaction_modal.title": "Melde dich an, um fortzufahren",
"interaction_modal.username_prompt": "z. B. {example}",
"interaction_modal.username_prompt": "Z. B. {example}",
"intervals.full.days": "{number, plural, one {# Tag} other {# Tage}}",
"intervals.full.hours": "{number, plural, one {# Stunde} other {# Stunden}}",
"intervals.full.minutes": "{number, plural, one {# Minute} other {# Minuten}}",
"keyboard_shortcuts.back": "Zurücknavigieren",
"keyboard_shortcuts.blocked": "Liste blockierter Profile öffnen",
"keyboard_shortcuts.blocked": "Blockierte Profile öffnen",
"keyboard_shortcuts.boost": "Beitrag teilen",
"keyboard_shortcuts.column": "Auf die aktuelle Spalte fokussieren",
"keyboard_shortcuts.column": "Aktuelle Spalte fokussieren",
"keyboard_shortcuts.compose": "Eingabefeld fokussieren",
"keyboard_shortcuts.description": "Beschreibung",
"keyboard_shortcuts.direct": "Private Erwähnungen öffnen",
"keyboard_shortcuts.down": "Ansicht nach unten bewegen",
"keyboard_shortcuts.down": "Auswahl nach unten bewegen",
"keyboard_shortcuts.enter": "Beitrag öffnen",
"keyboard_shortcuts.favourite": "Beitrag favorisieren",
"keyboard_shortcuts.favourites": "Favoriten öffnen",
"keyboard_shortcuts.federated": "Föderierte Timeline öffnen",
"keyboard_shortcuts.heading": "Tastenkombinationen",
"keyboard_shortcuts.heading": "Tastenkürzel",
"keyboard_shortcuts.home": "Startseite öffnen",
"keyboard_shortcuts.hotkey": "Tastenkürzel",
"keyboard_shortcuts.legend": "Tastenkombinationen anzeigen",
"keyboard_shortcuts.legend": "Tastenkürzel anzeigen (diese Seite)",
"keyboard_shortcuts.load_more": "Schaltfläche „Mehr laden“ fokussieren",
"keyboard_shortcuts.local": "Lokale Timeline öffnen",
"keyboard_shortcuts.mention": "Profil erwähnen",
"keyboard_shortcuts.muted": "Liste stummgeschalteter Profile öffnen",
"keyboard_shortcuts.my_profile": "Eigenes Profil aufrufen",
"keyboard_shortcuts.notifications": "Benachrichtigungen aufrufen",
"keyboard_shortcuts.open_media": "Medieninhalt öffnen",
"keyboard_shortcuts.muted": "Stummgeschaltete Profile öffnen",
"keyboard_shortcuts.my_profile": "Eigenes Profil öffnen",
"keyboard_shortcuts.notifications": "Benachrichtigungen öffnen",
"keyboard_shortcuts.open_media": "Medien öffnen",
"keyboard_shortcuts.pinned": "Liste angehefteter Beiträge öffnen",
"keyboard_shortcuts.profile": "Profil aufrufen",
"keyboard_shortcuts.quote": "Beitrag zitieren",
"keyboard_shortcuts.reply": "Auf Beitrag antworten",
"keyboard_shortcuts.requests": "Liste der Follower-Anfragen aufrufen",
"keyboard_shortcuts.search": "Suchleiste fokussieren",
"keyboard_shortcuts.spoilers": "Feld für Inhaltswarnung anzeigen/ausblenden",
"keyboard_shortcuts.reply": "Beitrag beantworten",
"keyboard_shortcuts.requests": "Follower-Anfragen aufrufen",
"keyboard_shortcuts.search": "Eingabefeld / Suche fokussieren",
"keyboard_shortcuts.spoilers": "Feld für Inhaltswarnung anzeigen / ausblenden",
"keyboard_shortcuts.start": "„Auf gehts!“ öffnen",
"keyboard_shortcuts.toggle_hidden": "Beitragstext hinter der Inhaltswarnung anzeigen/ausblenden",
"keyboard_shortcuts.toggle_sensitivity": "Medien anzeigen/ausblenden",
"keyboard_shortcuts.toggle_hidden": "Beitrag hinter Inhaltswarnung anzeigen / ausblenden",
"keyboard_shortcuts.toggle_sensitivity": "Medien anzeigen / ausblenden",
"keyboard_shortcuts.toot": "Neuen Beitrag erstellen",
"keyboard_shortcuts.translate": "Beitrag übersetzen",
"keyboard_shortcuts.unfocus": "Eingabefeld/Suche nicht mehr fokussieren",
"keyboard_shortcuts.up": "Ansicht nach oben bewegen",
"keyboard_shortcuts.unfocus": "Eingabefeld / Suche nicht mehr fokussieren",
"keyboard_shortcuts.up": "Auswahl nach oben bewegen",
"learn_more_link.got_it": "Verstanden",
"learn_more_link.learn_more": "Mehr erfahren",
"lightbox.close": "Schließen",
@ -531,7 +539,7 @@
"lists.done": "Fertig",
"lists.edit": "Liste bearbeiten",
"lists.exclusive": "Mitglieder auf der Startseite ausblenden",
"lists.exclusive_hint": "Profile, die sich auf dieser Liste befinden, werden nicht auf deiner Startseite angezeigt, damit deren Beiträge nicht doppelt erscheinen.",
"lists.exclusive_hint": "Profile, die sich auf dieser Liste befinden, werden nicht im Feed deiner Startseite angezeigt, damit deren Beiträge nicht doppelt erscheinen.",
"lists.find_users_to_add": "Suche nach Profilen, um sie hinzuzufügen",
"lists.list_members_count": "{count, plural, one {# Mitglied} other {# Mitglieder}}",
"lists.list_name": "Titel der Liste",
@ -540,19 +548,19 @@
"lists.no_members_yet": "Keine Mitglieder vorhanden.",
"lists.no_results_found": "Keine Suchergebnisse.",
"lists.remove_member": "Entfernen",
"lists.replies_policy.followed": "Alle folgenden Profile",
"lists.replies_policy.followed": "alle folgenden Profile",
"lists.replies_policy.list": "Mitglieder der Liste",
"lists.replies_policy.none": "Niemanden",
"lists.replies_policy.none": "niemanden",
"lists.save": "Speichern",
"lists.search": "Suchen",
"lists.show_replies_to": "Antworten von Listenmitgliedern einbeziehen an …",
"load_pending": "{count, plural, one {# neuer Beitrag} other {# neue Beiträge}}",
"loading_indicator.label": "Wird geladen …",
"loading_indicator.label": "Lädt …",
"media_gallery.hide": "Ausblenden",
"moved_to_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert, weil du zu {movedToAccount} umgezogen bist.",
"mute_modal.hide_from_notifications": "Benachrichtigungen ausblenden",
"mute_modal.hide_options": "Einstellungen ausblenden",
"mute_modal.indefinite": "Bis ich die Stummschaltung aufhebe",
"mute_modal.hide_from_notifications": "Auch aus den Benachrichtigungen entfernen",
"mute_modal.hide_options": "Optionen ausblenden",
"mute_modal.indefinite": "Dauerhaft, bis ich die Stummschaltung aufhebe",
"mute_modal.show_options": "Optionen anzeigen",
"mute_modal.they_can_mention_and_follow": "Das Profil wird dich weiterhin erwähnen und dir folgen können, aber du wirst davon nichts sehen.",
"mute_modal.they_wont_know": "Das Profil wird nicht erkennen können, dass du es stummgeschaltet hast.",
@ -562,7 +570,7 @@
"navigation_bar.about": "Über",
"navigation_bar.account_settings": "Passwort und Sicherheit",
"navigation_bar.administration": "Administration",
"navigation_bar.advanced_interface": "Im erweiterten Webinterface öffnen",
"navigation_bar.advanced_interface": "Erweitertes Webinterface öffnen",
"navigation_bar.automated_deletion": "Automatisiertes Löschen",
"navigation_bar.blocks": "Blockierte Profile",
"navigation_bar.bookmarks": "Lesezeichen",
@ -571,24 +579,24 @@
"navigation_bar.favourites": "Favoriten",
"navigation_bar.filters": "Stummgeschaltete Wörter",
"navigation_bar.follow_requests": "Follower-Anfragen",
"navigation_bar.followed_tags": "Gefolgte Hashtags",
"navigation_bar.follows_and_followers": "Follower und Folge ich",
"navigation_bar.import_export": "Importieren und exportieren",
"navigation_bar.followed_tags": "Abonnierte Hashtags",
"navigation_bar.follows_and_followers": "Follower & Folge ich",
"navigation_bar.import_export": "Importieren & exportieren",
"navigation_bar.lists": "Listen",
"navigation_bar.live_feed_local": "Live-Feed (lokal)",
"navigation_bar.live_feed_public": "Live-Feed (öffentlich)",
"navigation_bar.live_feed_local": "Live-Feed (Dieser Server)",
"navigation_bar.live_feed_public": "Live-Feed (Alle Server)",
"navigation_bar.logout": "Abmelden",
"navigation_bar.moderation": "Moderation",
"navigation_bar.more": "Mehr",
"navigation_bar.mutes": "Stummgeschaltete Profile",
"navigation_bar.opened_in_classic_interface": "Beiträge, Konten und andere bestimmte Seiten werden standardmäßig im klassischen Webinterface geöffnet.",
"navigation_bar.preferences": "Einstellungen",
"navigation_bar.privacy_and_reach": "Datenschutz und Reichweite",
"navigation_bar.privacy_and_reach": "Datenschutz & Reichweite",
"navigation_bar.search": "Suche",
"navigation_bar.search_trends": "Suche / Angesagt",
"navigation_panel.collapse_followed_tags": "Menü für gefolgte Hashtags schließen",
"navigation_bar.search_trends": "Suche / Trends",
"navigation_panel.collapse_followed_tags": "Menü für abonnierte Hashtags schließen",
"navigation_panel.collapse_lists": "Listen-Menü schließen",
"navigation_panel.expand_followed_tags": "Menü für gefolgte Hashtags öffnen",
"navigation_panel.expand_followed_tags": "Menü für abonnierte Hashtags öffnen",
"navigation_panel.expand_lists": "Listen-Menü öffnen",
"not_signed_in_indicator.not_signed_in": "Du musst dich anmelden, um auf diesen Inhalt zugreifen zu können.",
"notification.admin.report": "{name} meldete {target}",
@ -619,7 +627,7 @@
"notification.moderation_warning": "Du wurdest von den Moderator*innen verwarnt",
"notification.moderation_warning.action_delete_statuses": "Einige deiner Beiträge sind entfernt worden.",
"notification.moderation_warning.action_disable": "Dein Konto wurde deaktiviert.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Einige deiner Beiträge wurden mit einer Inhaltswarnung versehen.",
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Einige deiner Beiträge haben eine Inhaltswarnung erhalten.",
"notification.moderation_warning.action_none": "Dein Konto ist von den Moderator*innen verwarnt worden.",
"notification.moderation_warning.action_sensitive": "Deine zukünftigen Beiträge werden mit einer Inhaltswarnung versehen.",
"notification.moderation_warning.action_silence": "Dein Konto wurde eingeschränkt.",
@ -634,7 +642,7 @@
"notification.relationships_severance_event.domain_block": "Ein Admin von {from} hat {target} blockiert darunter {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst.",
"notification.relationships_severance_event.learn_more": "Mehr erfahren",
"notification.relationships_severance_event.user_domain_block": "Du hast {target} blockiert {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst, wurden entfernt.",
"notification.status": "{name} postete …",
"notification.status": "{name} veröffentlichte …",
"notification.update": "{name} bearbeitete einen Beitrag",
"notification_requests.accept": "Akzeptieren",
"notification_requests.accept_multiple": "{count, plural, one {# Anfrage akzeptieren …} other {# Anfragen akzeptieren …}}",
@ -670,9 +678,9 @@
"notifications.column_settings.mention": "Erwähnungen:",
"notifications.column_settings.poll": "Umfrageergebnisse:",
"notifications.column_settings.push": "Push-Benachrichtigungen",
"notifications.column_settings.quote": "Zitate:",
"notifications.column_settings.quote": "Zitierte Beiträge:",
"notifications.column_settings.reblog": "Geteilte Beiträge:",
"notifications.column_settings.show": "In dieser Spalte anzeigen",
"notifications.column_settings.show": "Im Feed „Benachrichtigungen“ anzeigen",
"notifications.column_settings.sound": "Ton abspielen",
"notifications.column_settings.status": "Neue Beiträge:",
"notifications.column_settings.unread_notifications.category": "Ungelesene Benachrichtigungen",
@ -681,10 +689,10 @@
"notifications.filter.all": "Alles",
"notifications.filter.boosts": "Geteilte Beiträge",
"notifications.filter.favourites": "Favoriten",
"notifications.filter.follows": "Folgt",
"notifications.filter.follows": "Neue Follower",
"notifications.filter.mentions": "Erwähnungen",
"notifications.filter.polls": "Umfrageergebnisse",
"notifications.filter.statuses": "Neue Beiträge von Personen, denen du folgst",
"notifications.filter.statuses": "Neue Beiträge von abonnierten Profilen",
"notifications.grant_permission": "Berechtigung erteilen.",
"notifications.group": "{count} Benachrichtigungen",
"notifications.mark_as_read": "Alle Benachrichtigungen als gelesen markieren",
@ -694,18 +702,18 @@
"notifications.policy.accept": "Akzeptieren",
"notifications.policy.accept_hint": "In Benachrichtigungen anzeigen",
"notifications.policy.drop": "Ignorieren",
"notifications.policy.drop_hint": "In die Leere senden und nie wieder sehen",
"notifications.policy.drop_hint": "Ins Nirwana befördern und auf Nimmerwiedersehen!",
"notifications.policy.filter": "Filtern",
"notifications.policy.filter_hint": "An gefilterte Benachrichtigungen im Posteingang senden",
"notifications.policy.filter_limited_accounts_hint": "Durch Server-Moderator*innen eingeschränkt",
"notifications.policy.filter_limited_accounts_title": "moderierten Konten",
"notifications.policy.filter_new_accounts.hint": "Innerhalb {days, plural, one {des letzten Tages} other {der letzten # Tagen}} erstellt",
"notifications.policy.filter_new_accounts_title": "neuen Konten",
"notifications.policy.filter_not_followers_hint": "Einschließlich Profilen, die dir seit weniger als {days, plural, one {einem Tag} other {# Tagen}} folgen",
"notifications.policy.filter_hint": "Im separaten Feed „Gefilterte Benachrichtigungen“ anzeigen",
"notifications.policy.filter_limited_accounts_hint": "Durch Server-Moderator*innen eingeschränkte Profile",
"notifications.policy.filter_limited_accounts_title": "eingeschränkten Konten",
"notifications.policy.filter_new_accounts.hint": "Konto {days, plural, one {seit gestern} other {in den vergangenen # Tagen}} registriert",
"notifications.policy.filter_new_accounts_title": "neuen Profilen",
"notifications.policy.filter_not_followers_hint": "Einschließlich Profilen, die mir seit weniger als {days, plural, one {einem Tag} other {# Tagen}} folgen",
"notifications.policy.filter_not_followers_title": "Profilen, die mir nicht folgen",
"notifications.policy.filter_not_following_hint": "Bis du sie manuell genehmigst",
"notifications.policy.filter_not_following_hint": "… bis ich sie manuell genehmige",
"notifications.policy.filter_not_following_title": "Profilen, denen ich nicht folge",
"notifications.policy.filter_private_mentions_hint": "Solange sie keine Antwort auf deine Erwähnung ist oder du dem Profil nicht folgst",
"notifications.policy.filter_private_mentions_hint": "… solange sie keine Antwort auf meine Erwähnungen sind oder ich den Profilen nicht folge",
"notifications.policy.filter_private_mentions_title": "unerwünschten privaten Erwähnungen",
"notifications.policy.title": "Benachrichtigungen verwalten von …",
"notifications_permission_banner.enable": "Aktiviere Desktop-Benachrichtigungen",
@ -740,23 +748,24 @@
"poll_button.add_poll": "Umfrage erstellen",
"poll_button.remove_poll": "Umfrage entfernen",
"privacy.change": "Sichtbarkeit anpassen",
"privacy.direct.long": "Alle in diesem Beitrag erwähnten Profile",
"privacy.direct.long": "Nur in diesem Beitrag erwähnte Profile",
"privacy.direct.short": "Private Erwähnung",
"privacy.private.long": "Nur deine Follower",
"privacy.private.long": "Nur deine eigenen Follower",
"privacy.private.short": "Follower",
"privacy.public.long": "Alle in und außerhalb von Mastodon",
"privacy.public.long": "Alle innerhalb und außerhalb von Mastodon",
"privacy.public.short": "Öffentlich",
"privacy.quote.anyone": "{visibility} alle dürfen zitieren",
"privacy.quote.disabled": "{visibility} niemand darf zitieren",
"privacy.quote.limited": "{visibility} eingeschränktes Zitieren",
"privacy.quote.disabled": "{visibility} Zitieren deaktiviert",
"privacy.quote.limited": "{visibility} nur Follower",
"privacy.unlisted.additional": "Das Verhalten ist wie bei „Öffentlich“, jedoch gibt es einige Einschränkungen. Der Beitrag wird nicht in „Live-Feeds“, „Erkunden“, Hashtags oder über die Mastodon-Suchfunktion auffindbar sein selbst wenn die zugehörige Einstellung aktiviert wurde.",
"privacy.unlisted.long": "Wird nicht in den Suchergebnissen, Trends oder öffentlichen Timelines von Mastodon angezeigt",
"privacy.unlisted.long": "Verborgen vor Suchen, Trends und öffentlichen Timelines",
"privacy.unlisted.short": "Öffentlich (still)",
"privacy_policy.last_updated": "Stand: {date}",
"privacy_policy.title": "Datenschutzerklärung",
"quote_error.edit": "Beim Bearbeiten eines Beitrags können keine Zitate hinzugefügt werden.",
"quote_error.poll": "Zitieren ist bei Umfragen nicht gestattet.",
"quote_error.quote": "Es ist jeweils nur ein Zitat zulässig.",
"quote_error.edit": "Beim Bearbeiten eines vorhandenen Beitrags können keine Zitate hinzugefügt werden.",
"quote_error.poll": "Zitieren ist bei Umfragen nicht erlaubt.",
"quote_error.private_mentions": "Zitieren ist bei privaten Erwähnungen nicht erlaubt.",
"quote_error.quote": "Es darf nur ein Beitrag zitiert werden.",
"quote_error.unauthorized": "Du bist nicht berechtigt, diesen Beitrag zu zitieren.",
"quote_error.upload": "Zitieren ist mit Medien-Anhängen nicht möglich.",
"recommended": "Empfohlen",
@ -766,7 +775,7 @@
"relative_time.days": "{number} T.",
"relative_time.full.days": "vor {number, plural, one {# Tag} other {# Tagen}}",
"relative_time.full.hours": "vor {number, plural, one {# Stunde} other {# Stunden}}",
"relative_time.full.just_now": "gerade eben",
"relative_time.full.just_now": "soeben",
"relative_time.full.minutes": "vor {number, plural, one {# Minute} other {# Minuten}}",
"relative_time.full.seconds": "vor {number, plural, one {1 Sekunde} other {# Sekunden}}",
"relative_time.hours": "{number} Std.",
@ -776,13 +785,13 @@
"relative_time.today": "heute",
"remove_quote_hint.button_label": "Verstanden",
"remove_quote_hint.message": "Klicke dafür im Beitrag auf „{icon} Mehr“.",
"remove_quote_hint.title": "Möchtest du aus dem zitierten Beitrag entfernt werden?",
"remove_quote_hint.title": "Deinen zitierten Beitrag aus diesem Beitrag entfernen?",
"reply_indicator.attachments": "{count, plural, one {# Anhang} other {# Anhänge}}",
"reply_indicator.cancel": "Abbrechen",
"reply_indicator.poll": "Umfrage",
"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.categories.legal": "Rechtlich",
"report.categories.legal": "Rechtliches",
"report.categories.other": "Andere",
"report.categories.spam": "Spam",
"report.categories.violation": "Der Inhalt verletzt eine oder mehrere Serverregeln",
@ -791,9 +800,9 @@
"report.category.title_account": "Profil",
"report.category.title_status": "Beitrag",
"report.close": "Fertig",
"report.comment.title": "Gibt es etwas anderes, was wir wissen sollten?",
"report.forward": "Meldung zusätzlich an {target} weiterleiten",
"report.forward_hint": "Dieses Konto gehört zu einem anderen Server. Soll eine anonymisierte Kopie der Meldung auch dorthin gesendet werden?",
"report.comment.title": "Gibt es noch etwas, das wir wissen sollten?",
"report.forward": "Meldung auch an den externen Server {target} weiterleiten",
"report.forward_hint": "Das gemeldete Konto befindet sich auf einem anderen Server. Soll zusätzlich eine anonymisierte Kopie deiner Meldung an diesen Server geschickt werden?",
"report.mute": "Stummschalten",
"report.mute_explanation": "Du wirst keine Beiträge mehr von diesem Konto sehen. Das stummgeschaltete Konto wird dir weiterhin folgen und deine Beiträge sehen können. Die Person wird nicht mitbekommen, dass du sie stummgeschaltet hast.",
"report.next": "Weiter",
@ -809,9 +818,9 @@
"report.reasons.violation": "Das verstößt gegen Serverregeln",
"report.reasons.violation_description": "Du bist dir sicher, dass eine bestimmte Regel gebrochen wurde",
"report.rules.subtitle": "Wähle alle zutreffenden Inhalte aus",
"report.rules.title": "Welche Regeln werden verletzt?",
"report.rules.title": "Gegen welche Regeln wurde verstoßen?",
"report.statuses.subtitle": "Wähle alle zutreffenden Inhalte aus",
"report.statuses.title": "Gibt es Beiträge, die diese Meldung bekräftigen?",
"report.statuses.title": "Gibt es Beiträge, die diese Meldung stützen?",
"report.submit": "Senden",
"report.target": "{target} melden",
"report.thanks.take_action": "Das sind deine Möglichkeiten zu bestimmen, was du auf Mastodon sehen möchtest:",
@ -828,7 +837,7 @@
"report_notification.categories.spam": "Spam",
"report_notification.categories.spam_sentence": "Spam",
"report_notification.categories.violation": "Regelverstoß",
"report_notification.categories.violation_sentence": "Regelverletzung",
"report_notification.categories.violation_sentence": "Verstoß gegen die Serverregeln",
"report_notification.open": "Meldung öffnen",
"search.clear": "Suchanfrage löschen",
"search.no_recent_searches": "Keine früheren Suchanfragen",
@ -838,7 +847,7 @@
"search.quick_action.go_to_hashtag": "Hashtag {x} aufrufen",
"search.quick_action.open_url": "URL in Mastodon öffnen",
"search.quick_action.status_search": "Beiträge passend zu {x}",
"search.search_or_paste": "Suchen oder URL einfügen",
"search.search_or_paste": "Suche eingeben oder URL einfügen",
"search_popout.full_text_search_disabled_message": "Auf {domain} nicht verfügbar.",
"search_popout.full_text_search_logged_out_message": "Nur verfügbar, wenn angemeldet.",
"search_popout.language_code": "ISO-Sprachcode",
@ -868,13 +877,13 @@
"status.admin_account": "@{name} moderieren",
"status.admin_domain": "{domain} moderieren",
"status.admin_status": "Beitrag moderieren",
"status.all_disabled": "Teilen und Zitieren von Beiträgen ist deaktiviert",
"status.all_disabled": "Teilen und Zitieren sind deaktiviert",
"status.block": "@{name} blockieren",
"status.bookmark": "Lesezeichen setzen",
"status.cancel_reblog_private": "Beitrag nicht mehr teilen",
"status.cannot_quote": "Dir ist es nicht gestattet, diesen Beitrag zu zitieren",
"status.cannot_quote": "Diesen Beitrag darfst du nicht zitieren",
"status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
"status.contains_quote": "Enthält Zitat",
"status.contains_quote": "Enthält zitierten Beitrag",
"status.context.loading": "Weitere Antworten laden",
"status.context.loading_error": "Weitere Antworten konnten nicht geladen werden",
"status.context.loading_success": "Neue Antworten geladen",
@ -890,10 +899,10 @@
"status.direct_indicator": "Private Erwähnung",
"status.edit": "Beitrag bearbeiten",
"status.edited": "Zuletzt am {date} bearbeitet",
"status.edited_x_times": "{count, plural, one {{count}-mal} other {{count}-mal}} bearbeitet",
"status.edited_x_times": "{count, plural, one {{count} ×} other {{count} ×}} bearbeitet",
"status.embed": "Code zum Einbetten",
"status.favourite": "Favorisieren",
"status.favourites": "{count, plural, one {Mal favorisiert} other {Mal favorisiert}}",
"status.favourites": "{count, plural, one {× favorisiert} other {× favorisiert}}",
"status.filter": "Beitrag filtern",
"status.history.created": "{name} erstellte {date}",
"status.history.edited": "{name} bearbeitete {date}",
@ -908,21 +917,24 @@
"status.open": "Beitrag öffnen",
"status.pin": "Im Profil anheften",
"status.quote": "Zitieren",
"status.quote.cancel": "Zitat abbrechen",
"status.quote.cancel": "Zitat entfernen",
"status.quote_error.blocked_account_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du @{name} blockiert hast.",
"status.quote_error.blocked_domain_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du {domain} blockiert hast.",
"status.quote_error.filtered": "Ausgeblendet wegen eines deiner Filter",
"status.quote_error.limited_account_hint.action": "Trotzdem anzeigen",
"status.quote_error.limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen von {domain} ausgeblendet.",
"status.quote_error.muted_account_hint.title": "Dieser Beitrag wurde ausgeblendet, weil du @{name} stummgeschaltet hast.",
"status.quote_error.not_available": "Beitrag nicht verfügbar",
"status.quote_error.pending_approval": "Beitragsveröffentlichung ausstehend",
"status.quote_error.pending_approval_popout.body": "Auf Mastodon kann festgelegt werden, ob man zitiert werden möchte. Wir warten auf die Genehmigung des ursprünglichen Profils. Bis dahin steht deine Beitragsveröffentlichung noch aus.",
"status.quote_error.pending_approval": "Veröffentlichung ausstehend",
"status.quote_error.pending_approval_popout.body": "Auf Mastodon kannst du selbst bestimmen, ob du von anderen zitiert werden darfst oder nicht oder nur nach individueller Genehmigung. Wir warten in diesem Fall noch auf die Genehmigung des ursprünglichen Profils. Bis dahin steht die Veröffentlichung deines Beitrags mit dem zitierten Post noch aus.",
"status.quote_error.revoked": "Beitrag durch Autor*in entfernt",
"status.quote_followers_only": "Nur Follower können diesen Beitrag zitieren",
"status.quote_manual_review": "Zitierte*r überprüft manuell",
"status.quote_noun": "Zitat",
"status.quote_policy_change": "Ändern, wer zitieren darf",
"status.quote_post_author": "Zitierte einen Beitrag von @{name}",
"status.quote_post_author": "Zitierter Beitrag von @{name}",
"status.quote_private": "Private Beiträge können nicht zitiert werden",
"status.quotes": "{count, plural, one {Mal zitiert} other {Mal zitiert}}",
"status.quotes": "{count, plural, one {× zitiert} other {× zitiert}}",
"status.quotes.empty": "Diesen Beitrag hat bisher noch niemand zitiert. Sobald es jemand tut, wird das Profil hier erscheinen.",
"status.quotes.local_other_disclaimer": "Durch Autor*in abgelehnte Zitate werden nicht angezeigt.",
"status.quotes.remote_other_disclaimer": "Nur Zitate von {domain} werden hier garantiert angezeigt. Durch Autor*in abgelehnte Zitate werden nicht angezeigt.",
@ -931,7 +943,7 @@
"status.reblog_or_quote": "Teilen oder zitieren",
"status.reblog_private": "Erneut mit deinen Followern teilen",
"status.reblogged_by": "{name} teilte",
"status.reblogs": "{count, plural, one {Mal geteilt} other {Mal geteilt}}",
"status.reblogs": "{count, plural, one {× geteilt} other {× geteilt}}",
"status.reblogs.empty": "Diesen Beitrag hat bisher noch niemand geteilt. Sobald es jemand tut, wird das Profil hier erscheinen.",
"status.redraft": "Löschen und neu erstellen",
"status.remove_bookmark": "Lesezeichen entfernen",
@ -943,7 +955,7 @@
"status.replyAll": "Allen antworten",
"status.report": "@{name} melden",
"status.request_quote": "Anfrage zum Zitieren",
"status.revoke_quote": "Meinen zitierten Beitrag aus dem Beitrag von @{name} entfernen",
"status.revoke_quote": "Zitat bei @{name} entfernen",
"status.sensitive_warning": "Inhaltswarnung",
"status.share": "Teilen",
"status.show_less_all": "Alles einklappen",
@ -989,7 +1001,7 @@
"upload_form.drag_and_drop.on_drag_start": "Der Medienanhang {item} wurde aufgenommen.",
"upload_form.edit": "Bearbeiten",
"upload_progress.label": "Wird hochgeladen …",
"upload_progress.processing": "Wird verarbeitet…",
"upload_progress.processing": "Wird verarbeitet …",
"username.taken": "Dieser Profilname ist vergeben. Versuche einen anderen",
"video.close": "Video schließen",
"video.download": "Datei herunterladen",
@ -1006,7 +1018,9 @@
"video.volume_down": "Leiser",
"video.volume_up": "Lauter",
"visibility_modal.button_title": "Sichtbarkeit festlegen",
"visibility_modal.header": "Sichtbarkeit und Interaktion",
"visibility_modal.direct_quote_warning.text": "Wenn diese Einstellungen gespeichert werden, wird das eingebettete Zitat in einen Link umgewandelt.",
"visibility_modal.direct_quote_warning.title": "Zitate können in privaten Erwähnungen nicht eingebettet werden",
"visibility_modal.header": "Sichtbarkeit und Zitate",
"visibility_modal.helper.direct_quoting": "Private Erwähnungen, die auf Mastodon verfasst wurden, können nicht von anderen zitiert werden.",
"visibility_modal.helper.privacy_editing": "Die Sichtbarkeit eines bereits veröffentlichten Beitrags kann nachträglich nicht mehr geändert werden.",
"visibility_modal.helper.privacy_private_self_quote": "Beiträge mit privaten Erwähnungen können öffentlich nicht zitiert werden.",
@ -1014,9 +1028,9 @@
"visibility_modal.helper.unlisted_quoting": "Sollten dich andere zitieren, werden ihre zitierten Beiträge ebenfalls nicht in den Trends und öffentlichen Timelines angezeigt.",
"visibility_modal.instructions": "Lege fest, wer mit diesem Beitrag interagieren darf. Du hast auch die Möglichkeit, diese Einstellung auf alle zukünftigen Beiträge anzuwenden. Gehe zu: <link>Einstellungen > Standardeinstellungen für Beiträge</link>",
"visibility_modal.privacy_label": "Sichtbarkeit",
"visibility_modal.quote_followers": "Nur Follower",
"visibility_modal.quote_label": "Wer zitieren darf",
"visibility_modal.quote_nobody": "Nur ich",
"visibility_modal.quote_public": "Alle",
"visibility_modal.quote_followers": "Nur meine Follower dürfen mich zitieren",
"visibility_modal.quote_label": "Wer darf mich zitieren?",
"visibility_modal.quote_nobody": "Niemand darf mich zitieren",
"visibility_modal.quote_public": "Alle dürfen mich zitieren",
"visibility_modal.save": "Speichern"
}

View File

@ -194,6 +194,7 @@
"community.column_settings.local_only": "Τοπικά μόνο",
"community.column_settings.media_only": "Μόνο πολυμέσα",
"community.column_settings.remote_only": "Απομακρυσμένα μόνο",
"compose.error.blank_post": "Η ανάρτηση δεν μπορεί να είναι κενή.",
"compose.language.change": "Αλλαγή γλώσσας",
"compose.language.search": "Αναζήτηση γλωσσών...",
"compose.published.body": "Η ανάρτηση δημοσιεύτηκε.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Δημοσίευση όπως και να ΄χει",
"confirmations.missing_alt_text.title": "Προσθήκη εναλλακτικού κειμένου;",
"confirmations.mute.confirm": "Αποσιώπηση",
"confirmations.private_quote_notify.cancel": "Πίσω στην επεξεργασία",
"confirmations.private_quote_notify.confirm": "Δημοσίευση ανάρτησης",
"confirmations.private_quote_notify.do_not_show_again": "Να μην εμφανιστεί ξανά αυτό το μήνυμα",
"confirmations.private_quote_notify.message": "Το άτομο που παραθέτετε και άλλες επισημάνσεις θα ειδοποιηθούν και θα μπορούν να δουν την ανάρτησή σας, ακόμη και αν δεν σας ακολουθούν.",
"confirmations.private_quote_notify.title": "Κοινοποίηση με τους ακολούθους και τους επισημασμένους χρήστες;",
"confirmations.quiet_post_quote_info.dismiss": "Μη μου το ξαναθυμίσεις",
"confirmations.quiet_post_quote_info.got_it": "Το κατάλαβα",
"confirmations.quiet_post_quote_info.message": "Όταν παραθέτετε μια ήσυχη δημόσια ανάρτηση, η ανάρτηση σας θα είναι κρυμμένη από τις δημοφιλείς ροές.",
@ -723,7 +729,7 @@
"onboarding.profile.display_name": "Εμφανιζόμενο όνομα",
"onboarding.profile.display_name_hint": "Το πλήρες ή το διασκεδαστικό σου όνομα…",
"onboarding.profile.note": "Βιογραφικό",
"onboarding.profile.note_hint": "Μπορείτε να @αναφέρετε άλλα άτομα ή #hashtags…",
"onboarding.profile.note_hint": "Μπορείς να @επισημάνεις άλλα άτομα ή #ετικέτες…",
"onboarding.profile.save_and_continue": "Αποθήκευση και συνέχεια",
"onboarding.profile.title": "Ρύθμιση προφίλ",
"onboarding.profile.upload_avatar": "Μεταφόρτωση εικόνας προφίλ",
@ -758,10 +764,11 @@
"privacy_policy.title": "Πολιτική Απορρήτου",
"quote_error.edit": "Δεν μπορούν να προστεθούν παραθέσεις κατά την επεξεργασία μιας ανάρτησης.",
"quote_error.poll": "Η παράθεση δεν επιτρέπεται με δημοσκοπήσεις.",
"quote_error.private_mentions": "Η παράθεση δεν επιτρέπεται με άμεσες επισημάνσεις.",
"quote_error.quote": "Επιτρέπεται μόνο μία παράθεση τη φορά.",
"quote_error.unauthorized": "Δεν είστε εξουσιοδοτημένοι να παραθέσετε αυτή την ανάρτηση.",
"quote_error.upload": "Η παράθεση δεν επιτρέπεται με συνημμένα πολυμέσων.",
"recommended": "Προτεινόμενα",
"recommended": "Προτείνεται",
"refresh": "Ανανέωση",
"regeneration_indicator.please_stand_by": "Παρακαλούμε περίμενε.",
"regeneration_indicator.preparing_your_home_feed": "Ετοιμάζουμε την αρχική σου ροή…",
@ -911,9 +918,12 @@
"status.pin": "Καρφίτσωσε στο προφίλ",
"status.quote": "Παράθεση",
"status.quote.cancel": "Ακύρωση παράθεσης",
"status.quote_error.blocked_account_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε μπλοκάρει τον/την @{name}.",
"status.quote_error.blocked_domain_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε μπλοκάρει το {domain}.",
"status.quote_error.filtered": "Κρυφό λόγω ενός από τα φίλτρα σου",
"status.quote_error.limited_account_hint.action": "Εμφάνιση ούτως ή άλλως",
"status.quote_error.limited_account_hint.title": "Αυτό το προφίλ έχει αποκρυφτεί από τους διαχειριστές του διακομιστή {domain}.",
"status.quote_error.muted_account_hint.title": "Αυτή η ανάρτηση είναι κρυμμένη επειδή έχετε κάνει σίγαση τον/την @{name}.",
"status.quote_error.not_available": "Ανάρτηση μη διαθέσιμη",
"status.quote_error.pending_approval": "Ανάρτηση σε αναμονή",
"status.quote_error.pending_approval_popout.body": "Στο Mastodon, μπορείς να ελέγξεις αν κάποιος μπορεί να σε παραθέσει. Αυτή η ανάρτηση εκκρεμεί ενώ λαμβάνουμε την έγκριση του αρχικού συντάκτη.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Μείωση έντασης",
"video.volume_up": "Αύξηση έντασης",
"visibility_modal.button_title": "Ορισμός ορατότητας",
"visibility_modal.direct_quote_warning.text": "Εάν αποθηκεύσετε τις τρέχουσες ρυθμίσεις, η ενσωματωμένη παράθεση θα μετατραπεί σε σύνδεσμο.",
"visibility_modal.direct_quote_warning.title": "Οι παραθέσεις δεν μπορούν να ενσωματωθούν σε ιδιωτικές επισημάνσεις",
"visibility_modal.header": "Ορατότητα και αλληλεπίδραση",
"visibility_modal.helper.direct_quoting": "Ιδιωτικές αναφορές που έχουν συνταχθεί στο Mastodon δεν μπορούν να γίνουν παράθεση από άλλους.",
"visibility_modal.helper.privacy_editing": "Η ορατότητα δεν μπορεί να αλλάξει μετά τη δημοσίευση μιας ανάρτησης.",

View File

@ -28,6 +28,7 @@
"account.disable_notifications": "Stop notifying me when @{name} posts",
"account.domain_blocking": "Blocking domain",
"account.edit_profile": "Edit profile",
"account.edit_profile_short": "Edit",
"account.enable_notifications": "Notify me when @{name} posts",
"account.endorse": "Feature on profile",
"account.familiar_followers_many": "Followed by {name1}, {name2}, and {othersCount, plural, one {one other you know} other {# others you know}}",
@ -40,6 +41,11 @@
"account.featured_tags.last_status_never": "No posts",
"account.follow": "Follow",
"account.follow_back": "Follow back",
"account.follow_back_short": "Follow back",
"account.follow_request": "Request to follow",
"account.follow_request_cancel": "Cancel request",
"account.follow_request_cancel_short": "Cancel",
"account.follow_request_short": "Request",
"account.followers": "Followers",
"account.followers.empty": "No one follows this user yet.",
"account.followers_counter": "{count, plural, one {{counter} follower} other {{counter} followers}}",
@ -167,6 +173,8 @@
"column.edit_list": "Edit list",
"column.favourites": "Favourites",
"column.firehose": "Live feeds",
"column.firehose_local": "Live feed for this server",
"column.firehose_singular": "Live feed",
"column.follow_requests": "Follow requests",
"column.home": "Home",
"column.list_members": "Manage list members",
@ -186,6 +194,7 @@
"community.column_settings.local_only": "Local only",
"community.column_settings.media_only": "Media Only",
"community.column_settings.remote_only": "Remote only",
"compose.error.blank_post": "Post can't be blank.",
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose.published.body": "Post published.",
@ -238,13 +247,30 @@
"confirmations.missing_alt_text.secondary": "Post anyway",
"confirmations.missing_alt_text.title": "Add alt text?",
"confirmations.mute.confirm": "Mute",
"confirmations.private_quote_notify.cancel": "Back to editing",
"confirmations.private_quote_notify.confirm": "Publish post",
"confirmations.private_quote_notify.do_not_show_again": "Don't show me this message again",
"confirmations.private_quote_notify.message": "The person you are quoting and other mentions will be notified and will be able to view your post, even if they're not following you.",
"confirmations.private_quote_notify.title": "Share with followers and mentioned users?",
"confirmations.quiet_post_quote_info.dismiss": "Don't remind me again",
"confirmations.quiet_post_quote_info.got_it": "Got it",
"confirmations.quiet_post_quote_info.message": "When quoting a quiet public post, your post will be hidden from trending timelines.",
"confirmations.quiet_post_quote_info.title": "Quoting quiet public posts",
"confirmations.redraft.confirm": "Delete & redraft",
"confirmations.redraft.message": "Are you sure you want to delete this post and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
"confirmations.redraft.title": "Delete & redraft post?",
"confirmations.remove_from_followers.confirm": "Remove follower",
"confirmations.remove_from_followers.message": "{name} will stop following you. Are you sure you want to proceed?",
"confirmations.remove_from_followers.title": "Remove follower?",
"confirmations.revoke_quote.confirm": "Remove post",
"confirmations.revoke_quote.message": "This action cannot be undone.",
"confirmations.revoke_quote.title": "Remove post?",
"confirmations.unblock.confirm": "Unblock",
"confirmations.unblock.title": "Unblock {name}?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.title": "Unfollow {name}?",
"confirmations.withdraw_request.confirm": "Withdraw request",
"confirmations.withdraw_request.title": "Withdraw request to follow {name}?",
"content_warning.hide": "Hide post",
"content_warning.show": "Show anyway",
"content_warning.show_more": "Show more",
@ -286,6 +312,7 @@
"domain_pill.your_handle": "Your handle:",
"domain_pill.your_server": "Your digital home, where all of your posts live. Dont like this one? Transfer servers at any time and bring your followers, too.",
"domain_pill.your_username": "Your unique identifier on this server. Its possible to find users with the same username on different servers.",
"dropdown.empty": "Select an option",
"embed.instructions": "Embed this post on your website by copying the code below.",
"embed.preview": "Here is what it will look like:",
"emoji_button.activity": "Activity",
@ -314,6 +341,7 @@
"empty_column.bookmarked_statuses": "You don't have any bookmarked posts yet. When you bookmark one, it will show up here.",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.direct": "You don't have any private mentions yet. When you send or receive one, it will show up here.",
"empty_column.disabled_feed": "This feed has been disabled by your server administrators.",
"empty_column.domain_blocks": "There are no blocked domains yet.",
"empty_column.explore_statuses": "Nothing is trending right now. Check back later!",
"empty_column.favourited_statuses": "You don't have any favourite posts yet. When you favourite one, it will show up here.",
@ -442,10 +470,12 @@
"ignore_notifications_modal.private_mentions_title": "Ignore notifications from unsolicited Private Mentions?",
"info_button.label": "Help",
"info_button.what_is_alt_text": "<h1>What is alt text?</h1> <p>Alt text provides image descriptions for people with vision impairments, low-bandwidth connections, or those seeking extra context.</p> <p>You can improve accessibility and understanding for everyone by writing clear, concise, and objective alt text.</p> <ul> <li>Capture important elements</li> <li>Summarise text in images</li> <li>Use regular sentence structure</li> <li>Avoid redundant information</li> <li>Focus on trends and key findings in complex visuals (like diagrams or maps)</li> </ul>",
"interaction_modal.action": "To interact with {name}'s post, you need to sign into your account on whatever Mastodon server you use.",
"interaction_modal.go": "Go",
"interaction_modal.no_account_yet": "Don't have an account yet?",
"interaction_modal.on_another_server": "On a different server",
"interaction_modal.on_this_server": "On this server",
"interaction_modal.title": "Sign in to continue",
"interaction_modal.username_prompt": "E.g. {example}",
"intervals.full.days": "{number, plural, one {# day} other {# days}}",
"intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
@ -466,6 +496,7 @@
"keyboard_shortcuts.home": "Open home timeline",
"keyboard_shortcuts.hotkey": "Hotkey",
"keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.load_more": "Focus \"Load more\" button",
"keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author",
"keyboard_shortcuts.muted": "to open muted users list",
@ -474,6 +505,7 @@
"keyboard_shortcuts.open_media": "to open media",
"keyboard_shortcuts.pinned": "to open pinned posts list",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.quote": "Quote post",
"keyboard_shortcuts.reply": "to reply",
"keyboard_shortcuts.requests": "to open follow requests list",
"keyboard_shortcuts.search": "to focus search",
@ -485,6 +517,8 @@
"keyboard_shortcuts.translate": "to translate a post",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "Move up in the list",
"learn_more_link.got_it": "Got it",
"learn_more_link.learn_more": "Learn more",
"lightbox.close": "Close",
"lightbox.next": "Next",
"lightbox.previous": "Previous",
@ -585,6 +619,7 @@
"notification.label.mention": "Mention",
"notification.label.private_mention": "Private mention",
"notification.label.private_reply": "Private reply",
"notification.label.quote": "{name} quoted your post",
"notification.label.reply": "Reply",
"notification.mention": "Mention",
"notification.mentioned_you": "{name} mentioned you",
@ -599,6 +634,7 @@
"notification.moderation_warning.action_suspend": "Your account has been suspended.",
"notification.own_poll": "Your poll has ended",
"notification.poll": "A poll you voted in has ended",
"notification.quoted_update": "{name} edited a post you have quoted",
"notification.reblog": "{name} boosted your post",
"notification.reblog.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> boosted your post",
"notification.relationships_severance_event": "Lost connections with {name}",
@ -642,6 +678,7 @@
"notifications.column_settings.mention": "Mentions:",
"notifications.column_settings.poll": "Poll results:",
"notifications.column_settings.push": "Push notifications",
"notifications.column_settings.quote": "Quotes:",
"notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column",
"notifications.column_settings.sound": "Play sound",
@ -717,10 +754,20 @@
"privacy.private.short": "Followers",
"privacy.public.long": "Anyone on and off Mastodon",
"privacy.public.short": "Public",
"privacy.quote.anyone": "{visibility}, anyone can quote",
"privacy.quote.disabled": "{visibility}, quotes disabled",
"privacy.quote.limited": "{visibility}, quotes limited",
"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.long": "Hidden from Mastodon search results, trending, and public timelines",
"privacy.unlisted.short": "Quiet public",
"privacy_policy.last_updated": "Last updated {date}",
"privacy_policy.title": "Privacy Policy",
"quote_error.edit": "Quotes cannot be added when editing a post.",
"quote_error.poll": "Quoting is not allowed with polls.",
"quote_error.private_mentions": "Quoting is not allowed with direct mentions.",
"quote_error.quote": "Only one quote at a time is allowed.",
"quote_error.unauthorized": "You are not authorised to quote this post.",
"quote_error.upload": "Quoting is not allowed with media attachments.",
"recommended": "Recommended",
"refresh": "Refresh",
"regeneration_indicator.please_stand_by": "Please stand by.",
@ -736,6 +783,9 @@
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"relative_time.today": "today",
"remove_quote_hint.button_label": "Got it",
"remove_quote_hint.message": "You can do so from the {icon} options menu.",
"remove_quote_hint.title": "Want to remove your quoted post?",
"reply_indicator.attachments": "{count, plural, one {# attachment} other {# attachments}}",
"reply_indicator.cancel": "Cancel",
"reply_indicator.poll": "Poll",
@ -827,13 +877,23 @@
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_domain": "Open moderation interface for {domain}",
"status.admin_status": "Open this post in the moderation interface",
"status.all_disabled": "Boosts and quotes are disabled",
"status.block": "Block @{name}",
"status.bookmark": "Bookmark",
"status.cancel_reblog_private": "Unboost",
"status.cannot_quote": "You are not allowed to quote this post",
"status.cannot_reblog": "This post cannot be boosted",
"status.contains_quote": "Contains quote",
"status.context.loading": "Loading more replies",
"status.context.loading_error": "Couldn't load new replies",
"status.context.loading_success": "New replies loaded",
"status.context.more_replies_found": "More replies found",
"status.context.retry": "Retry",
"status.context.show": "Show",
"status.continued_thread": "Continued thread",
"status.copy": "Copy link to status",
"status.delete": "Delete",
"status.delete.success": "Post deleted",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Privately mention @{name}",
"status.direct_indicator": "Private mention",
@ -856,20 +916,46 @@
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this post",
"status.pin": "Pin on profile",
"status.quote": "Quote",
"status.quote.cancel": "Cancel quote",
"status.quote_error.blocked_account_hint.title": "This post is hidden because you've blocked @{name}.",
"status.quote_error.blocked_domain_hint.title": "This post is hidden because you've blocked {domain}.",
"status.quote_error.filtered": "Hidden due to one of your filters",
"status.quote_error.limited_account_hint.action": "Show anyway",
"status.quote_error.limited_account_hint.title": "This account has been hidden by the moderators of {domain}.",
"status.quote_error.muted_account_hint.title": "This post is hidden because you've muted @{name}.",
"status.quote_error.not_available": "Post unavailable",
"status.quote_error.pending_approval": "Post pending",
"status.quote_error.pending_approval_popout.body": "On Mastodon, you can control whether someone can quote you. This post is pending while we're getting the original author's approval.",
"status.quote_error.revoked": "Post removed by author",
"status.quote_followers_only": "Only followers can quote this post",
"status.quote_manual_review": "Author will manually review",
"status.quote_noun": "Quote",
"status.quote_policy_change": "Change who can quote",
"status.quote_post_author": "Quoted a post by @{name}",
"status.quote_private": "Private posts cannot be quoted",
"status.quotes": "{count, plural, one {quote} other {quotes}}",
"status.quotes.empty": "No one has quoted this post yet. When someone does, it will show up here.",
"status.quotes.local_other_disclaimer": "Quotes rejected by the author will not be shown.",
"status.quotes.remote_other_disclaimer": "Only quotes from {domain} are guaranteed to be shown here. Quotes rejected by the author will not be shown.",
"status.read_more": "Read more",
"status.reblog": "Boost",
"status.reblog_or_quote": "Boost or quote",
"status.reblog_private": "Share again with your followers",
"status.reblogged_by": "{name} boosted",
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
"status.reblogs.empty": "No one has boosted this post yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.remove_bookmark": "Remove bookmark",
"status.remove_favourite": "Remove from favourites",
"status.remove_quote": "Remove",
"status.replied_in_thread": "Replied in thread",
"status.replied_to": "Replied to {name}",
"status.reply": "Reply",
"status.replyAll": "Reply to thread",
"status.report": "Report @{name}",
"status.request_quote": "Request to quote",
"status.revoke_quote": "Remove my post from @{name}s post",
"status.sensitive_warning": "Sensitive content",
"status.share": "Share",
"status.show_less_all": "Show less for all",
@ -907,6 +993,7 @@
"upload_button.label": "Add images, a video or an audio file",
"upload_error.limit": "File upload limit exceeded.",
"upload_error.poll": "File upload not allowed with polls.",
"upload_error.quote": "File upload not allowed with quotes.",
"upload_form.drag_and_drop.instructions": "To pick up a media attachment, press space or enter. While dragging, use the arrow keys to move the media attachment in any given direction. Press space or enter again to drop the media attachment in its new position, or press escape to cancel.",
"upload_form.drag_and_drop.on_drag_cancel": "Dragging was cancelled. Media attachment {item} was dropped.",
"upload_form.drag_and_drop.on_drag_end": "Media attachment {item} was dropped.",
@ -929,5 +1016,21 @@
"video.skip_forward": "Skip forward",
"video.unmute": "Unmute",
"video.volume_down": "Volume down",
"video.volume_up": "Volume up"
"video.volume_up": "Volume up",
"visibility_modal.button_title": "Set visibility",
"visibility_modal.direct_quote_warning.text": "If you save the current settings, the embedded quote will be converted to a link.",
"visibility_modal.direct_quote_warning.title": "Quotes can't be embedded in private mentions",
"visibility_modal.header": "Visibility and interaction",
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
"visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.",
"visibility_modal.helper.privacy_private_self_quote": "Self-quotes of private posts cannot be made public.",
"visibility_modal.helper.private_quoting": "Follower-only posts authored on Mastodon can't be quoted by others.",
"visibility_modal.helper.unlisted_quoting": "When people quote you, their post will also be hidden from trending timelines.",
"visibility_modal.instructions": "Control who can interact with this post. You can also apply settings to all future posts by navigating to <link>Preferences > Posting defaults</link>.",
"visibility_modal.privacy_label": "Visibility",
"visibility_modal.quote_followers": "Followers only",
"visibility_modal.quote_label": "Who can quote",
"visibility_modal.quote_nobody": "Just me",
"visibility_modal.quote_public": "Anyone",
"visibility_modal.save": "Save"
}

View File

@ -194,6 +194,7 @@
"community.column_settings.local_only": "Local only",
"community.column_settings.media_only": "Media Only",
"community.column_settings.remote_only": "Remote only",
"compose.error.blank_post": "Post can't be blank.",
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose.published.body": "Post published.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Post anyway",
"confirmations.missing_alt_text.title": "Add alt text?",
"confirmations.mute.confirm": "Mute",
"confirmations.private_quote_notify.cancel": "Back to editing",
"confirmations.private_quote_notify.confirm": "Publish post",
"confirmations.private_quote_notify.do_not_show_again": "Don't show me this message again",
"confirmations.private_quote_notify.message": "The person you are quoting and other mentions will be notified and will be able to view your post, even if they're not following you.",
"confirmations.private_quote_notify.title": "Share with followers and mentioned users?",
"confirmations.quiet_post_quote_info.dismiss": "Don't remind me again",
"confirmations.quiet_post_quote_info.got_it": "Got it",
"confirmations.quiet_post_quote_info.message": "When quoting a quiet public post, your post will be hidden from trending timelines.",
@ -758,6 +764,7 @@
"privacy_policy.title": "Privacy Policy",
"quote_error.edit": "Quotes cannot be added when editing a post.",
"quote_error.poll": "Quoting is not allowed with polls.",
"quote_error.private_mentions": "Quoting is not allowed with direct mentions.",
"quote_error.quote": "Only one quote at a time is allowed.",
"quote_error.unauthorized": "You are not authorized to quote this post.",
"quote_error.upload": "Quoting is not allowed with media attachments.",
@ -1011,6 +1018,8 @@
"video.volume_down": "Volume down",
"video.volume_up": "Volume up",
"visibility_modal.button_title": "Set visibility",
"visibility_modal.direct_quote_warning.text": "If you save the current settings, the embedded quote will be converted to a link.",
"visibility_modal.direct_quote_warning.title": "Quotes can't be embedded in private mentions",
"visibility_modal.header": "Visibility and interaction",
"visibility_modal.helper.direct_quoting": "Private mentions authored on Mastodon can't be quoted by others.",
"visibility_modal.helper.privacy_editing": "Visibility can't be changed after a post is published.",

View File

@ -39,6 +39,7 @@
"account.featured_tags.last_status_never": "Neniu afiŝo",
"account.follow": "Sekvi",
"account.follow_back": "Sekvu reen",
"account.follow_back_short": "Sekvu reen",
"account.followers": "Sekvantoj",
"account.followers.empty": "Ankoraŭ neniu sekvas ĉi tiun uzanton.",
"account.followers_counter": "{count, plural, one{{counter} sekvanto} other {{counter} sekvantoj}}",

View File

@ -194,6 +194,7 @@
"community.column_settings.local_only": "Sólo local",
"community.column_settings.media_only": "Sólo medios",
"community.column_settings.remote_only": "Sólo remoto",
"compose.error.blank_post": "El mensaje no puede estar en blanco.",
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas…",
"compose.published.body": "Mensaje publicado.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Enviar de todos modos",
"confirmations.missing_alt_text.title": "¿Agregar texto alternativo?",
"confirmations.mute.confirm": "Silenciar",
"confirmations.private_quote_notify.cancel": "Volver a editar",
"confirmations.private_quote_notify.confirm": "Enviar mensaje",
"confirmations.private_quote_notify.do_not_show_again": "No mostrarme este mensaje de nuevo",
"confirmations.private_quote_notify.message": "La cuenta a la que estás citando y otras menciones serán notificadas y podrán ver tu mensaje, incluso si no te están siguiendo.",
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
"confirmations.quiet_post_quote_info.dismiss": "No recordar de nuevo",
"confirmations.quiet_post_quote_info.got_it": "Entendido",
"confirmations.quiet_post_quote_info.message": "Al citar un mensaje público pero silencioso, tu mensaje se ocultará de las líneas temporales de tendencias.",
@ -735,10 +741,10 @@
"poll.refresh": "Refrescar",
"poll.reveal": "Ver resultados",
"poll.total_people": "{count, plural, one {# persona} other {# personas}}",
"poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
"poll.total_votes": "{count, plural, one {voto} other {votos}}",
"poll.vote": "Votar",
"poll.voted": "Votaste esta opción",
"poll.votes": "{votes, plural, one {# voto} other {# votos}}",
"poll.votes": "{votes, plural, one {voto} other {votos}}",
"poll_button.add_poll": "Agregar encuesta",
"poll_button.remove_poll": "Quitar encuesta",
"privacy.change": "Configurar privacidad del mensaje",
@ -753,11 +759,12 @@
"privacy.quote.limited": "{visibility}, citas limitadas",
"privacy.unlisted.additional": "Esto se comporta exactamente igual que con la configuración de privacidad de mensaje «Público», excepto que el mensaje no aparecerá en las líneas temporales en vivo, ni en las etiquetas, ni en la línea temporal «Explorá», ni en la búsqueda de Mastodon; incluso si optaste por hacer tu cuenta visible.",
"privacy.unlisted.long": "Oculto de los resultados de búsqueda, tendencias y líneas temporales públicas de Mastodon",
"privacy.unlisted.short": "Público silencioso",
"privacy.unlisted.short": "Público pero silencioso",
"privacy_policy.last_updated": "Última actualización: {date}",
"privacy_policy.title": "Política de privacidad",
"quote_error.edit": "Las citas no se pueden agregar al editar un mensaje.",
"quote_error.poll": "No se permite citar encuestas.",
"quote_error.private_mentions": "No se permite citar con menciones directas.",
"quote_error.quote": "Solo se permite una cita a la vez.",
"quote_error.unauthorized": "No tenés autorización para citar este mensaje.",
"quote_error.upload": "No se permite citar con archivos multimedia.",
@ -911,9 +918,12 @@
"status.pin": "Fijar en el perfil",
"status.quote": "Citar",
"status.quote.cancel": "Cancelar cita",
"status.quote_error.blocked_account_hint.title": "Este mensaje está oculto porque bloqueaste a @{name}.",
"status.quote_error.blocked_domain_hint.title": "Este mensaje está oculto porque bloqueaste {domain}.",
"status.quote_error.filtered": "Oculto debido a uno de tus filtros",
"status.quote_error.limited_account_hint.action": "Mostrar de todos modos",
"status.quote_error.limited_account_hint.title": "Esta cuenta fue ocultada por los moderadores de {domain}.",
"status.quote_error.muted_account_hint.title": "Este mensaje está oculto porque silenciaste a @{name}.",
"status.quote_error.not_available": "Mensaje no disponible",
"status.quote_error.pending_approval": "Mensaje pendiente",
"status.quote_error.pending_approval_popout.body": "En Mastodon, podés controlar si alguien te puede citar. Este mensaje está pendiente hasta obtener la aprobación del autor original.",
@ -924,7 +934,7 @@
"status.quote_policy_change": "Cambiá quién puede citar",
"status.quote_post_author": "Se citó un mensaje de @{name}",
"status.quote_private": "No se pueden citar los mensajes privados",
"status.quotes": "{count, plural, one {# voto} other {# votos}}",
"status.quotes": "{count, plural, one {voto} other {votos}}",
"status.quotes.empty": "Todavía nadie citó este mensaje. Cuando alguien lo haga, se mostrará acá.",
"status.quotes.local_other_disclaimer": "Las citas rechazadas por el autor no serán mostradas.",
"status.quotes.remote_other_disclaimer": "Solo las citas de {domain} están garantizadas de ser mostradas acá. Las citas rechazadas por el autor no serán mostradas.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Bajar volumen",
"video.volume_up": "Subir volumen",
"visibility_modal.button_title": "Establecer visibilidad",
"visibility_modal.direct_quote_warning.text": "Si guardás la configuración actual, la cita insertada se convertirá en un enlace.",
"visibility_modal.direct_quote_warning.title": "Las citas no pueden ser insertadas en menciones privadas",
"visibility_modal.header": "Visibilidad e interacción",
"visibility_modal.helper.direct_quoting": "Las menciones privadas redactadas en Mastodon no pueden ser citadas por otras cuentas.",
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya enviado un mensaje.",
@ -1016,7 +1028,7 @@
"visibility_modal.helper.unlisted_quoting": "Cuando otras cuentas te citen, sus publicaciones también se ocultarán de las líneas temporales de tendencias.",
"visibility_modal.instructions": "Controlá quién puede interactuar con este mensaje. También podés aplicar los ajustes para todos los mensajes futuros accediendo a <link>«Configuración» > «Configuración predeterminada de mensajes»</link>.",
"visibility_modal.privacy_label": "Visibilidad",
"visibility_modal.quote_followers": "Solo para seguidores",
"visibility_modal.quote_followers": "Solo seguidores",
"visibility_modal.quote_label": "Quién puede citar",
"visibility_modal.quote_nobody": "Solo yo",
"visibility_modal.quote_public": "Cualquier cuenta",

View File

@ -42,7 +42,7 @@
"account.follow": "Seguir",
"account.follow_back": "Seguir también",
"account.follow_back_short": "Seguir también",
"account.follow_request": "Solicitud de seguimiento",
"account.follow_request": "Solicitar seguimiento",
"account.follow_request_cancel": "Cancelar solicitud",
"account.follow_request_cancel_short": "Cancelar",
"account.follow_request_short": "Solicitar",
@ -172,9 +172,9 @@
"column.domain_blocks": "Dominios ocultados",
"column.edit_list": "Editar lista",
"column.favourites": "Favoritos",
"column.firehose": "Cronologías",
"column.firehose_local": "Cronología para este servidor",
"column.firehose_singular": "Cronología",
"column.firehose": "Feeds en vivo",
"column.firehose_local": "Feed en vivo para este servidor",
"column.firehose_singular": "Feed en vivo",
"column.follow_requests": "Solicitudes de seguimiento",
"column.home": "Inicio",
"column.list_members": "Administrar miembros de la lista",
@ -194,6 +194,7 @@
"community.column_settings.local_only": "Solo local",
"community.column_settings.media_only": "Solo media",
"community.column_settings.remote_only": "Solo remoto",
"compose.error.blank_post": "La publicación no puede estar vacía.",
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas...",
"compose.published.body": "Publicado.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Publicar de todas maneras",
"confirmations.missing_alt_text.title": "¿Añadir texto alternativo?",
"confirmations.mute.confirm": "Silenciar",
"confirmations.private_quote_notify.cancel": "Seguir editando",
"confirmations.private_quote_notify.confirm": "Publicar",
"confirmations.private_quote_notify.do_not_show_again": "No mostrar este mensaje de nuevo",
"confirmations.private_quote_notify.message": "Tu publicación será notificada y podrá ser vista por la persona a la que mencionas y otras menciones, aún si no te siguen.",
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
"confirmations.quiet_post_quote_info.dismiss": "No me lo recuerdes otra vez",
"confirmations.quiet_post_quote_info.got_it": "Entendido",
"confirmations.quiet_post_quote_info.message": "Al citar una publicación pública discreta, tu publicación se ocultará de las cronologías de tendencias.",
@ -263,8 +269,8 @@
"confirmations.unblock.title": "¿Desbloquear a {name}?",
"confirmations.unfollow.confirm": "Dejar de seguir",
"confirmations.unfollow.title": "¿Dejar de seguir a {name}?",
"confirmations.withdraw_request.confirm": "Retirar solicitud",
"confirmations.withdraw_request.title": "¿Retirar solicitud de seguimiento a {name}?",
"confirmations.withdraw_request.confirm": "Cancelar solicitud",
"confirmations.withdraw_request.title": "¿Cancelar solicitud para seguir a {name}?",
"content_warning.hide": "Ocultar publicación",
"content_warning.show": "Mostrar de todos modos",
"content_warning.show_more": "Mostrar más",
@ -335,7 +341,7 @@
"empty_column.bookmarked_statuses": "Aún no tienes ninguna publicación guardada como marcador. Cuando guardes una, se mostrará aquí.",
"empty_column.community": "La cronología local está vacía. ¡Escribe algo públicamente para ponerla en marcha!",
"empty_column.direct": "Aún no tienes menciones privadas. Cuando envíes o recibas una, aparecerán aquí.",
"empty_column.disabled_feed": "Esta cronología ha sido desactivada por los administradores del servidor.",
"empty_column.disabled_feed": "Este feed fue desactivado por los administradores de tu servidor.",
"empty_column.domain_blocks": "Todavía no hay dominios ocultos.",
"empty_column.explore_statuses": "Nada es tendencia en este momento. ¡Revisa más tarde!",
"empty_column.favourited_statuses": "Todavía no tienes publicaciones favoritas. Cuando le des favorito a una publicación se mostrarán acá.",
@ -756,8 +762,9 @@
"privacy.unlisted.short": "Pública, pero discreta",
"privacy_policy.last_updated": "Actualizado por última vez {date}",
"privacy_policy.title": "Política de Privacidad",
"quote_error.edit": "No se pueden añadir citas cuando se edita una publicación.",
"quote_error.edit": "No se pueden añadir citas mientras un post está siendo editado.",
"quote_error.poll": "No se permite citar encuestas.",
"quote_error.private_mentions": "Citar no está disponible sin menciones directas.",
"quote_error.quote": "Solo se permite una cita a la vez.",
"quote_error.unauthorized": "No estás autorizado a citar esta publicación.",
"quote_error.upload": "No se permite citar con archivos multimedia.",
@ -797,7 +804,7 @@
"report.forward": "Reenviar a {target}",
"report.forward_hint": "Esta cuenta es de otro servidor. ¿Enviar una copia anonimizada del informe allí también?",
"report.mute": "Silenciar",
"report.mute_explanation": "No veras sus publiaciones. Todavía pueden seguirte y ver tus publicaciones y no sabrán que están silenciados.",
"report.mute_explanation": "No verás sus publicaciones. Todavía pueden seguirte y ver tus publicaciones y no sabrán que están silenciados.",
"report.next": "Siguiente",
"report.placeholder": "Comentarios adicionales",
"report.reasons.dislike": "No me gusta",
@ -879,7 +886,7 @@
"status.contains_quote": "Contiene cita",
"status.context.loading": "Cargando más respuestas",
"status.context.loading_error": "No se pudieron cargar nuevas respuestas",
"status.context.loading_success": "Cargadas nuevas respuestas",
"status.context.loading_success": "Nuevas respuestas cargadas",
"status.context.more_replies_found": "Se han encontrado más respuestas",
"status.context.retry": "Reintentar",
"status.context.show": "Mostrar",
@ -911,9 +918,12 @@
"status.pin": "Fijar",
"status.quote": "Citar",
"status.quote.cancel": "Cancelar cita",
"status.quote_error.blocked_account_hint.title": "Esta publicación se ocultó porque bloqueaste a @{name}.",
"status.quote_error.blocked_domain_hint.title": "Este post está oculto porque bloqueaste {domain}.",
"status.quote_error.filtered": "Oculto debido a uno de tus filtros",
"status.quote_error.limited_account_hint.action": "Mostrar de todas formas",
"status.quote_error.limited_account_hint.title": "Esta cuenta ha sido ocultada por los moderadores de {domain}.",
"status.quote_error.muted_account_hint.title": "Esta publicación está oculta porque silenciaste a @{name}.",
"status.quote_error.not_available": "Publicación no disponible",
"status.quote_error.pending_approval": "Publicación pendiente",
"status.quote_error.pending_approval_popout.body": "En Mastodon, puedes controlar si alguien puede citarte. Esta publicación está pendiente mientras obtenemos la aprobación del autor original.",
@ -926,8 +936,8 @@
"status.quote_private": "Las publicaciones privadas no pueden citarse",
"status.quotes": "{count, plural,one {cita} other {citas}}",
"status.quotes.empty": "Nadie ha citado esta publicación todavía. Cuando alguien lo haga, aparecerá aquí.",
"status.quotes.local_other_disclaimer": "Las citas rechazadas por el autor no se mostrarán.",
"status.quotes.remote_other_disclaimer": "Solo se garantiza que se muestren las citas de {domain}. Las citas rechazadas por el autor no se mostrarán.",
"status.quotes.local_other_disclaimer": "Las citas rechazadas pro el autor no serán mostradas.",
"status.quotes.remote_other_disclaimer": "Solo las citas hechas por {domain} están garantizadas a ser vistas aquí. Las citas rechazadas por el autor no serán mostradas.",
"status.read_more": "Leer más",
"status.reblog": "Impulsar",
"status.reblog_or_quote": "Impulsar o citar",
@ -1008,6 +1018,8 @@
"video.volume_down": "Bajar el volumen",
"video.volume_up": "Subir el volumen",
"visibility_modal.button_title": "Establece la visibilidad",
"visibility_modal.direct_quote_warning.text": "Si guardas la siguiente configuración, se mostrará un enlace en vez de la cita incrustada.",
"visibility_modal.direct_quote_warning.title": "No se pueden incrustar citas en menciones privadas",
"visibility_modal.header": "Visibilidad e interacción",
"visibility_modal.helper.direct_quoting": "Las menciones privadas creadas en Mastodon no pueden ser citadas por otros.",
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya hecho una publicación.",

View File

@ -194,6 +194,7 @@
"community.column_settings.local_only": "Solo local",
"community.column_settings.media_only": "Solo multimedia",
"community.column_settings.remote_only": "Solo remoto",
"compose.error.blank_post": "El mensaje no puede estar en blanco.",
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas...",
"compose.published.body": "Publicado.",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Publicar de todos modos",
"confirmations.missing_alt_text.title": "¿Deseas añadir texto alternativo?",
"confirmations.mute.confirm": "Silenciar",
"confirmations.private_quote_notify.cancel": "Volver a la edición",
"confirmations.private_quote_notify.confirm": "Publicar",
"confirmations.private_quote_notify.do_not_show_again": "No mostrar este mensaje de nuevo",
"confirmations.private_quote_notify.message": "La persona a la que estás citando y otras mencionadas serán notificadas y podrán ver tu publicación, incluso si no te siguen.",
"confirmations.private_quote_notify.title": "¿Compartir con seguidores y usuarios mencionados?",
"confirmations.quiet_post_quote_info.dismiss": "No me lo vuelvas a recordar",
"confirmations.quiet_post_quote_info.got_it": "Entendido",
"confirmations.quiet_post_quote_info.message": "Cuando cites una publicación pública silenciosa, tu publicación se ocultará de las cronologías de tendencias.",
@ -758,6 +764,7 @@
"privacy_policy.title": "Política de Privacidad",
"quote_error.edit": "No se pueden añadir citas cuando se edita una publicación.",
"quote_error.poll": "No es posible citar encuestas.",
"quote_error.private_mentions": "No se permite citar con menciones privadas.",
"quote_error.quote": "Solo se permite una cita a la vez.",
"quote_error.unauthorized": "No tienes permiso para citar esta publicación.",
"quote_error.upload": "No se permite citar con archivos multimedia.",
@ -911,9 +918,12 @@
"status.pin": "Fijar",
"status.quote": "Citar",
"status.quote.cancel": "Cancelar cita",
"status.quote_error.blocked_account_hint.title": "Esta publicación está oculta porque has bloqueado a @{name}.",
"status.quote_error.blocked_domain_hint.title": "Esta publicación está oculta porque has bloqueado @{domain}.",
"status.quote_error.filtered": "Oculto debido a uno de tus filtros",
"status.quote_error.limited_account_hint.action": "Mostrar de todos modos",
"status.quote_error.limited_account_hint.title": "Esta cuenta ha sido ocultada por los moderadores de {domain}.",
"status.quote_error.muted_account_hint.title": "Esta publicación está oculta porque has silenciado a @{name}.",
"status.quote_error.not_available": "Publicación no disponible",
"status.quote_error.pending_approval": "Publicación pendiente",
"status.quote_error.pending_approval_popout.body": "En Mastodon, puedes controlar si alguien puede citarte. Esta publicación está pendiente mientras obtenemos la aprobación del autor original.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Bajar volumen",
"video.volume_up": "Subir volumen",
"visibility_modal.button_title": "Configura la visibilidad",
"visibility_modal.direct_quote_warning.text": "Si guardas la configuración actual, la cita incrustada se convertirá en un enlace.",
"visibility_modal.direct_quote_warning.title": "No se pueden incluir citas en menciones privadas",
"visibility_modal.header": "Visibilidad e interacciones",
"visibility_modal.helper.direct_quoting": "Las menciones privadas publicadas en Mastodon no pueden ser citadas por otros usuarios.",
"visibility_modal.helper.privacy_editing": "La visibilidad no se puede cambiar después de que se haya hecho una publicación.",

View File

@ -3,7 +3,7 @@
"about.contact": "Kontakt:",
"about.default_locale": "Vaikimisi",
"about.disclaimer": "Mastodon on tasuta ja vaba tarkvara ning Mastodon gGmbH kaubamärk.",
"about.domain_blocks.no_reason_available": "Põhjus teadmata",
"about.domain_blocks.no_reason_available": "Põhjus on teadmata",
"about.domain_blocks.preamble": "Mastodon lubab tavaliselt vaadata sisu ning suhelda kasutajatega ükskõik millisest teisest fediversumi serverist. Need on erandid, mis on paika pandud sellel kindlal serveril.",
"about.domain_blocks.silenced.explanation": "Sa ei näe üldiselt profiile ja sisu sellelt serverilt, kui sa just tahtlikult seda ei otsi või jälgimise moel nõusolekut ei anna.",
"about.domain_blocks.silenced.title": "Piiratud",
@ -36,7 +36,7 @@
"account.familiar_followers_two": "Jälgijateks {name1} ja {name2}",
"account.featured": "Esiletõstetud",
"account.featured.accounts": "Profiilid",
"account.featured.hashtags": "Sildid",
"account.featured.hashtags": "Teemaviited",
"account.featured_tags.last_status_at": "Viimane postitus {date}",
"account.featured_tags.last_status_never": "Postitusi pole",
"account.follow": "Jälgi",
@ -64,10 +64,10 @@
"account.media": "Meedia",
"account.mention": "Maini @{name}",
"account.moved_to": "{name} on teada andnud, et ta uus konto on nüüd:",
"account.mute": "Vaigista @{name}",
"account.mute_notifications_short": "Vaigista teavitused",
"account.mute_short": "Vaigista",
"account.muted": "Vaigistatud",
"account.mute": "Summuta @{name}",
"account.mute_notifications_short": "Summuta teavitused",
"account.mute_short": "Summuta",
"account.muted": "Summutatud",
"account.muting": "Summutatud konto",
"account.mutual": "Te jälgite teineteist",
"account.no_bio": "Kirjeldust pole lisatud.",
@ -87,9 +87,9 @@
"account.unblock_short": "Eemalda blokeering",
"account.unendorse": "Ära kuva profiilil",
"account.unfollow": "Jälgid",
"account.unmute": "Ära vaigista @{name}",
"account.unmute_notifications_short": "Tühista teadete vaigistamine",
"account.unmute_short": "Lõpeta vaigistamine",
"account.unmute": "Lõpeta {name} kasutaja summutamine",
"account.unmute_notifications_short": "Lõpeta teavituste summutamine",
"account.unmute_short": "Lõpeta summutamine",
"account_note.placeholder": "Klõpsa märke lisamiseks",
"admin.dashboard.daily_retention": "Kasutajate päevane allesjäämine peale registreerumist",
"admin.dashboard.monthly_retention": "Kasutajate kuine allesjäämine peale registreerumist",
@ -126,8 +126,8 @@
"annual_report.summary.highlighted_post.by_replies": "kõige vastatum postitus",
"annual_report.summary.highlighted_post.possessive": "omanik {name}",
"annual_report.summary.most_used_app.most_used_app": "enim kasutatud äpp",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "enim kasutatud silt",
"annual_report.summary.most_used_hashtag.none": "Pole",
"annual_report.summary.most_used_hashtag.most_used_hashtag": "enim kasutatud teemaviide",
"annual_report.summary.most_used_hashtag.none": "Puudub",
"annual_report.summary.new_posts.new_posts": "uus postitus",
"annual_report.summary.percentile.text": "<topLabel>See paneb su top</topLabel><percentage></percentage><bottomLabel> {domain} kasutajate hulka.</bottomLabel>",
"annual_report.summary.percentile.we_wont_tell_bernie": "Vägev.",
@ -173,11 +173,13 @@
"column.edit_list": "Muuda loendit",
"column.favourites": "Lemmikud",
"column.firehose": "Postitused reaalajas",
"column.firehose_local": "Selle serveri sisuvoog reaalajas",
"column.firehose_singular": "Postitused reaalajas",
"column.follow_requests": "Jälgimistaotlused",
"column.home": "Kodu",
"column.list_members": "Halda loendi liikmeid",
"column.lists": "Loetelud",
"column.mutes": "Vaigistatud kasutajad",
"column.mutes": "Summutatud kasutajad",
"column.notifications": "Teated",
"column.pins": "Kinnitatud postitused",
"column.public": "Föderatiivne ajajoon",
@ -192,6 +194,7 @@
"community.column_settings.local_only": "Ainult kohalik",
"community.column_settings.media_only": "Ainult meedia",
"community.column_settings.remote_only": "Ainult kaug",
"compose.error.blank_post": "Postitus ei saa jääda tühjaks.",
"compose.language.change": "Muuda keelt",
"compose.language.search": "Otsi keeli...",
"compose.published.body": "Postitus tehtud.",
@ -199,7 +202,7 @@
"compose.saved.body": "Postitus salvestatud.",
"compose_form.direct_message_warning_learn_more": "Vaata lisa",
"compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krüpteeritud. Ära jaga mingeid delikaatseid andmeid Mastodoni kaudu.",
"compose_form.hashtag_warning": "See postitus ei ilmu ühegi märksõna all, kuna pole avalik. Vaid avalikud postitused on märksõnade kaudu leitavad.",
"compose_form.hashtag_warning": "See postitus ei ilmu ühegi teemaviite all, kuna pole avalik. Vaid avalikud postitused on teemaviidete kaudu leitavad.",
"compose_form.lock_disclaimer": "Su konto ei ole {locked}. Igaüks saab sind jälgida, et näha su ainult-jälgijatele postitusi.",
"compose_form.lock_disclaimer.lock": "lukus",
"compose_form.placeholder": "Millest mõtled?",
@ -243,7 +246,12 @@
"confirmations.missing_alt_text.message": "Sinu postituses on ilma alt-tekstita meediat. Kirjelduse lisamine aitab su sisu muuta ligipääsetavaks rohkematele inimestele.",
"confirmations.missing_alt_text.secondary": "Postita siiski",
"confirmations.missing_alt_text.title": "Lisada alt-tekst?",
"confirmations.mute.confirm": "Vaigista",
"confirmations.mute.confirm": "Summuta",
"confirmations.private_quote_notify.cancel": "Tagasi muutmise juurde",
"confirmations.private_quote_notify.confirm": "Avalda postitus",
"confirmations.private_quote_notify.do_not_show_again": "Ära kuva enam seda sõnumit uuesti",
"confirmations.private_quote_notify.message": "Nii see, keda sa tsiteerid, kui need, keda mainid, saavad asjakohase teavituse ja võivad vaadata sinu postitust ka siis, kui nad pole sinu jälgijad.",
"confirmations.private_quote_notify.title": "Kas jagad jälgijate ja mainitud kasutajatega?",
"confirmations.quiet_post_quote_info.dismiss": "Ära tuleta enam meelde",
"confirmations.quiet_post_quote_info.got_it": "Sain aru",
"confirmations.quiet_post_quote_info.message": "Vaikse, aga avaliku postituse tsiteerimisel sinu postitus on peidetud populaarsust koguvatel ajajoontel.",
@ -287,7 +295,7 @@
"domain_block_modal.they_can_interact_with_old_posts": "Inimesed sellest serverist saavad suhestuda sinu vanade postitustega.",
"domain_block_modal.they_cant_follow": "Sellest serverist ei saa keegi sind jälgida.",
"domain_block_modal.they_wont_know": "Nad ei tea, et nad on blokeeritud.",
"domain_block_modal.title": "Blokeerida domeen?",
"domain_block_modal.title": "Kas blokeerid domeeni?",
"domain_block_modal.you_will_lose_num_followers": "Sult kaob {followersCount, plural, one {{followersCountDisplay} jälgija} other {{followersCountDisplay} jälgijat}} ja {followingCount, plural, one {{followingCountDisplay} inimene} other {{followingCountDisplay} inimest}}, keda sa ise jälgid.",
"domain_block_modal.you_will_lose_relationships": "Sa kaotad kõik oma jälgijad ja inimesed, kes sind jälgivad sellest serverist.",
"domain_block_modal.you_wont_see_posts": "Sa ei näe selle serveri kasutajate postitusi ega teavitusi.",
@ -322,8 +330,8 @@
"emoji_button.search_results": "Otsitulemused",
"emoji_button.symbols": "Sümbolid",
"emoji_button.travel": "Reisimine & kohad",
"empty_column.account_featured.me": "Sa pole veel midagi esile tõstnud. Kas sa teadsid, et oma profiilis saad esile tõsta enamkasutatavaid silte või või sõbra kasutajakontot?",
"empty_column.account_featured.other": "{acct} pole veel midagi esile tõstnud. Kas sa teadsid, et oma profiilis saad esile tõsta enamkasutatavaid silte või või sõbra kasutajakontot?",
"empty_column.account_featured.me": "Sa pole veel midagi esile tõstnud. Kas sa teadsid, et oma profiilis saad esile tõsta enamkasutatavaid teemaviiteid või sõbra kasutajakontot?",
"empty_column.account_featured.other": "{acct} pole veel midagi esile tõstnud. Kas sa teadsid, et oma profiilis saad esile tõsta enamkasutatavaid teemaviiteid või sõbra kasutajakontot?",
"empty_column.account_featured_other.unknown": "See kasutajakonto pole veel midagi esile tõstnud.",
"empty_column.account_hides_collections": "See kasutaja otsustas mitte teha seda infot saadavaks",
"empty_column.account_suspended": "Konto kustutatud",
@ -339,11 +347,11 @@
"empty_column.favourited_statuses": "Pole veel lemmikpostitusi. Kui märgid mõne, näed neid siin.",
"empty_column.favourites": "Keegi pole veel seda postitust lemmikuks märkinud. Kui keegi seda teeb, siis on ta nähtav siin.",
"empty_column.follow_requests": "Pole hetkel ühtegi jälgimistaotlust. Kui saad mõne, näed neid siin.",
"empty_column.followed_tags": "Sa ei jälgi veel ühtegi märksõna. Kui jälgid, ilmuvad need siia.",
"empty_column.hashtag": "Selle sildi all ei ole ühtegi postitust.",
"empty_column.followed_tags": "Sa ei jälgi veel ühtegi teemaviidet. Kui jälgid, ilmuvad need siia.",
"empty_column.hashtag": "Selle teemaviite all ei ole ühtegi postitust.",
"empty_column.home": "Su koduajajoon on tühi. Jälgi rohkemaid inimesi, et seda täita {suggestions}",
"empty_column.list": "Siin loetelus pole veel midagi. Kui loetelu liikmed teevad uusi postitusi, näed neid siin.",
"empty_column.mutes": "Sa pole veel ühtegi kasutajat vaigistanud.",
"empty_column.mutes": "Sa pole veel ühtegi kasutajat summutanud.",
"empty_column.notification_requests": "Kõik tühi! Siin pole mitte midagi. Kui saad uusi teavitusi, ilmuvad need siin vastavalt sinu seadistustele.",
"empty_column.notifications": "Ei ole veel teateid. Kui keegi suhtleb sinuga, näed seda siin.",
"empty_column.public": "Siin pole midagi! Kirjuta midagi avalikku või jälgi ise kasutajaid täitmaks seda ruumi",
@ -357,7 +365,7 @@
"explore.title": "Populaarsust koguv",
"explore.trending_links": "Uudised",
"explore.trending_statuses": "Postitused",
"explore.trending_tags": "Sildid",
"explore.trending_tags": "Teemaviited",
"featured_carousel.header": "{count, plural, one {Esiletõstetud postitus} other {Esiletõstetud postitust}}",
"featured_carousel.next": "Järgmine",
"featured_carousel.post": "Postita",
@ -403,7 +411,7 @@
"follow_suggestions.similar_to_recently_followed_longer": "Sarnane profiilile, mida hiljuti jälgima hakkasid",
"follow_suggestions.view_all": "Vaata kõiki",
"follow_suggestions.who_to_follow": "Keda jälgida",
"followed_tags": "Jälgitavad märksõnad",
"followed_tags": "Jälgitavad teemaviited",
"footer.about": "Teave",
"footer.directory": "Profiilikataloog",
"footer.get_app": "Laadi rakendus",
@ -415,23 +423,23 @@
"generic.saved": "Salvestatud",
"getting_started.heading": "Alustamine",
"hashtag.admin_moderation": "Ava modereerimisliides #{name} jaoks",
"hashtag.browse": "Sirvi #{hashtag} sildiga postitusi",
"hashtag.browse_from_account": "Sirvi @{name} kasutaja #{hashtag} sildiga postitusi",
"hashtag.browse": "Sirvi #{hashtag} teemaviitega postitusi",
"hashtag.browse_from_account": "Sirvi @{name} kasutaja #{hashtag} teemaviitega postitusi",
"hashtag.column_header.tag_mode.all": "ja {additional}",
"hashtag.column_header.tag_mode.any": "või {additional}",
"hashtag.column_header.tag_mode.none": "ilma {additional}",
"hashtag.column_header.tag_mode.any": "või teemaviide {additional}",
"hashtag.column_header.tag_mode.none": "ilma teemaviiteta {additional}",
"hashtag.column_settings.select.no_options_message": "Soovitusi ei leitud",
"hashtag.column_settings.select.placeholder": "Sisesta sildid…",
"hashtag.column_settings.tag_mode.all": "Kõik need",
"hashtag.column_settings.tag_mode.any": "Mõni neist",
"hashtag.column_settings.tag_mode.none": "Mitte ükski neist",
"hashtag.column_settings.tag_toggle": "Kaasa lisamärked selle tulba jaoks",
"hashtag.column_settings.tag_toggle": "Kaasa lisasildid selle veeru jaoks",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} osalejaga} other {{counter} osalejaga}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} postitusega} other {{counter} postitusega}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postitust} other {{counter} postitust}} täna",
"hashtag.feature": "Tõsta profiilis esile",
"hashtag.follow": "Jälgi silti",
"hashtag.mute": "Vaigista @#{hashtag}",
"hashtag.mute": "Summuta teemaviide @#{hashtag}",
"hashtag.unfeature": "Ära tõsta profiilis esile",
"hashtag.unfollow": "Lõpeta sildi jälgimine",
"hashtags.and_other": "…ja {count, plural, one {}other {# veel}}",
@ -491,7 +499,7 @@
"keyboard_shortcuts.load_more": "Fookus „Laadi veel“ nupule",
"keyboard_shortcuts.local": "Ava kohalik ajajoon",
"keyboard_shortcuts.mention": "Maini autorit",
"keyboard_shortcuts.muted": "Ava vaigistatud kasutajate loetelu",
"keyboard_shortcuts.muted": "Ava summutatud kasutajate loetelu",
"keyboard_shortcuts.my_profile": "Ava oma profiil",
"keyboard_shortcuts.notifications": "Ava teadete veerg",
"keyboard_shortcuts.open_media": "Ava meedia",
@ -552,11 +560,11 @@
"moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.",
"mute_modal.hide_from_notifications": "Peida teavituste hulgast",
"mute_modal.hide_options": "Peida valikud",
"mute_modal.indefinite": "Kuni eemaldan neilt vaigistuse",
"mute_modal.indefinite": "Kuni eemaldan neilt summutamise",
"mute_modal.show_options": "Kuva valikud",
"mute_modal.they_can_mention_and_follow": "Ta saab sind mainida ja sind jälgida, kuid sa ei näe teda.",
"mute_modal.they_wont_know": "Ta ei tea, et ta on vaigistatud.",
"mute_modal.title": "Vaigistada kasutaja?",
"mute_modal.they_wont_know": "Ta ei tea, et ta on summutatud.",
"mute_modal.title": "Kas summutad kasutaja?",
"mute_modal.you_wont_see_mentions": "Sa ei näe postitusi, mis teda mainivad.",
"mute_modal.you_wont_see_posts": "Ta näeb jätkuvalt sinu postitusi, kuid sa ei näe tema omi.",
"navigation_bar.about": "Teave",
@ -569,9 +577,9 @@
"navigation_bar.direct": "Privaatsed mainimised",
"navigation_bar.domain_blocks": "Peidetud domeenid",
"navigation_bar.favourites": "Lemmikud",
"navigation_bar.filters": "Vaigistatud sõnad",
"navigation_bar.filters": "Summutatud sõnad",
"navigation_bar.follow_requests": "Jälgimistaotlused",
"navigation_bar.followed_tags": "Jälgitavad märksõnad",
"navigation_bar.followed_tags": "Jälgitavad teemaviited",
"navigation_bar.follows_and_followers": "Jälgitavad ja jälgijad",
"navigation_bar.import_export": "Import ja eksport",
"navigation_bar.lists": "Loetelud",
@ -580,7 +588,7 @@
"navigation_bar.logout": "Logi välja",
"navigation_bar.moderation": "Modereerimine",
"navigation_bar.more": "Lisavalikud",
"navigation_bar.mutes": "Vaigistatud kasutajad",
"navigation_bar.mutes": "Summutatud kasutajad",
"navigation_bar.opened_in_classic_interface": "Postitused, kontod ja teised spetsiaalsed lehed avatakse vaikimisi klassikalises veebiliideses.",
"navigation_bar.preferences": "Eelistused",
"navigation_bar.privacy_and_reach": "Privaatsus ja ulatus",
@ -721,7 +729,7 @@
"onboarding.profile.display_name": "Näidatav nimi",
"onboarding.profile.display_name_hint": "Su täisnimi või naljanimi…",
"onboarding.profile.note": "Elulugu",
"onboarding.profile.note_hint": "Saad @mainida teisi kasutajaid või #sildistada…",
"onboarding.profile.note_hint": "Saad @mainida teisi kasutajaid või lisada #teemaviidet…",
"onboarding.profile.save_and_continue": "Salvesta ja jätka",
"onboarding.profile.title": "Profiili seadistamine",
"onboarding.profile.upload_avatar": "Laadi üles profiilipilt",
@ -749,13 +757,14 @@
"privacy.quote.anyone": "{visibility}, kõik võivad tsiteerida",
"privacy.quote.disabled": "{visibility}, tsiteerimine pole lubatud",
"privacy.quote.limited": "{visibility}, tsiteerimine on piiratud",
"privacy.unlisted.additional": "See on olemuselt küll avalik, aga postitus ei ilmu voogudes ega märksõnades, lehitsedes ega Mastodoni otsingus, isegi kui konto on seadistustes avalik.",
"privacy.unlisted.additional": "See on olemuselt küll avalik, aga postitus ei ilmu voogudes ega teemaviidetes, lehitsedes ega Mastodoni otsingus, isegi kui konto on seadistustes avalik.",
"privacy.unlisted.long": "Peidetud Mastodoni otsingutulemustest, pupulaarsust koguva sisu voost ja avalikult ajajoonelt",
"privacy.unlisted.short": "Vaikselt avalik",
"privacy_policy.last_updated": "Viimati uuendatud {date}",
"privacy_policy.title": "Isikuandmete kaitse",
"quote_error.edit": "Postituse muutmisel ei saa tsitaati lisada.",
"quote_error.poll": "Tsiteerimine pole küsitlustes lubatud.",
"quote_error.private_mentions": "Tsiteerimine pole otsemainimiste puhul lubatud.",
"quote_error.quote": "Korraga on lubatud vaid üks tsitaat.",
"quote_error.unauthorized": "Sul pole õigust seda postitust tsiteerida.",
"quote_error.upload": "Tsiteerimine pole manuste puhul lubatud.",
@ -794,8 +803,8 @@
"report.comment.title": "Kas arvad, et on veel midagi, mida me peaks teadma?",
"report.forward": "Edasta ka {target} domeeni",
"report.forward_hint": "See kasutaja on teisest serverist. Kas saadan anonümiseeritud koopia sellest teatest sinna ka?",
"report.mute": "Vaigista",
"report.mute_explanation": "Sa ei näe tema postitusi. Ta võib ikka sind jälgida ja su postitusi näha. Ta ei saa teada, et ta on vaigistatud.",
"report.mute": "Summuta",
"report.mute_explanation": "Sa ei näe tema postitusi. Ta võib ikka sind jälgida ja su postitusi näha. Ta ei saa teada, et ta on summutatud.",
"report.next": "Järgmine",
"report.placeholder": "Lisaks kommentaarid",
"report.reasons.dislike": "Mulle ei meeldi see",
@ -835,7 +844,7 @@
"search.placeholder": "Otsi",
"search.quick_action.account_search": "Sobivaid profiile {x}",
"search.quick_action.go_to_account": "Mine profiili {x}",
"search.quick_action.go_to_hashtag": "Ava silt {x}",
"search.quick_action.go_to_hashtag": "Ava teemaviide {x}",
"search.quick_action.open_url": "Ava URL Mastodonis",
"search.quick_action.status_search": "Sobivad postitused {x}",
"search.search_or_paste": "Otsi või kleebi URL",
@ -851,7 +860,7 @@
"search_results.all": "Kõik",
"search_results.hashtags": "Sildid",
"search_results.no_results": "Tulemusi pole.",
"search_results.no_search_yet": "Proovi otsida postitusi, profiile või silte.",
"search_results.no_search_yet": "Proovi otsida postitusi, profiile või teemaviiteid.",
"search_results.see_all": "Vaata kõiki",
"search_results.statuses": "Postitused",
"search_results.title": "Otsi märksõna: {q}",
@ -903,15 +912,18 @@
"status.media_hidden": "Meedia peidetud",
"status.mention": "Maini @{name}'i",
"status.more": "Veel",
"status.mute": "Vaigista @{name}",
"status.mute_conversation": "Vaigista vestlus",
"status.mute": "Summuta @{name}",
"status.mute_conversation": "Summuta vestlus",
"status.open": "Laienda postitus",
"status.pin": "Kinnita profiilile",
"status.quote": "Tsiteeri",
"status.quote.cancel": "Katkesta tsiteerimine",
"status.quote_error.blocked_account_hint.title": "Kuna sa oled blokeerinud kasutaja @{name}, siis see postitus on peidetud.",
"status.quote_error.blocked_domain_hint.title": "Kuna sa oled blokeerinud domeeni @{domain}, siis see postitus on peidetud.",
"status.quote_error.filtered": "Peidetud mõne kasutatud filtri tõttu",
"status.quote_error.limited_account_hint.action": "Näita ikkagi",
"status.quote_error.limited_account_hint.title": "See profiil on peidetud {domain} serveri moderaatorite poolt.",
"status.quote_error.muted_account_hint.title": "Kuna sa oled summutanud kasutaja @{name}, siis see postitus on peidetud.",
"status.quote_error.not_available": "Postitus pole saadaval",
"status.quote_error.pending_approval": "Postitus on ootel",
"status.quote_error.pending_approval_popout.body": "Mastodonis saad sa kontrollida seda, kes võib sind tsiteerida. See postitus on seni ootel, kuni pole algse autori kinnitust tsiteerimisele.",
@ -953,7 +965,7 @@
"status.translate": "Tõlgi",
"status.translated_from_with": "Tõlgitud {lang} keelest kasutades teenust {provider}",
"status.uncached_media_warning": "Eelvaade pole saadaval",
"status.unmute_conversation": "Ära vaigista vestlust",
"status.unmute_conversation": "Lõpeta vestluse summutamine",
"status.unpin": "Eemalda profiilile kinnitus",
"subscribed_languages.lead": "Pärast muudatust näed koduvaates ja loetelude ajajoontel postitusi valitud keeltes. Ära vali midagi, kui tahad näha postitusi kõikides keeltes.",
"subscribed_languages.save": "Salvesta muudatused",
@ -997,15 +1009,17 @@
"video.expand": "Suurenda video",
"video.fullscreen": "Täisekraan",
"video.hide": "Peida video",
"video.mute": "Vaigista",
"video.mute": "Summuta",
"video.pause": "Paus",
"video.play": "Mängi",
"video.skip_backward": "Keri tagasi",
"video.skip_forward": "Keri edasi",
"video.unmute": "Lõpeta vaigistamine",
"video.unmute": "Lõpeta summutamine",
"video.volume_down": "Heli vaiksemaks",
"video.volume_up": "Heli valjemaks",
"visibility_modal.button_title": "Muuda nähtavust",
"visibility_modal.direct_quote_warning.text": "Kui sa need seadistused salvestad, siis lõimitud tsitaat muutub lingiks.",
"visibility_modal.direct_quote_warning.title": "Tsitaate ei saa privaatse mainimise puhul lõimida",
"visibility_modal.header": "Nähtavus ja kasutus",
"visibility_modal.helper.direct_quoting": "Ainult mainituile mõeldud Mastodoni postitusi ei saa teiste poolt tsiteerida.",
"visibility_modal.helper.privacy_editing": "Nähtavust ei saa peale postituse avaldamist muuta.",

View File

@ -28,6 +28,7 @@
"account.disable_notifications": "Utzi jakinarazteari @{name} erabiltzaileak argitaratzean",
"account.domain_blocking": "Eragotzitako domeinua",
"account.edit_profile": "Editatu profila",
"account.edit_profile_short": "Editatu",
"account.enable_notifications": "Jakinarazi @{name} erabiltzaileak argitaratzean",
"account.endorse": "Nabarmendu profilean",
"account.familiar_followers_many": "Jarraitzaileak: {name1}, {name2} eta beste {othersCount, plural, one {ezagun bat} other {# ezagun}}",
@ -40,6 +41,11 @@
"account.featured_tags.last_status_never": "Bidalketarik ez",
"account.follow": "Jarraitu",
"account.follow_back": "Jarraitu bueltan",
"account.follow_back_short": "Jarraitu bueltan",
"account.follow_request": "Eskatu jarraitzeko",
"account.follow_request_cancel": "Ezeztatu eskaera",
"account.follow_request_cancel_short": "Ezeztatu",
"account.follow_request_short": "Eskaera",
"account.followers": "Jarraitzaileak",
"account.followers.empty": "Ez du inork erabiltzaile hau jarraitzen oraindik.",
"account.followers_counter": "{count, plural, one {{counter} jarraitzaile} other {{counter} jarraitzaile}}",
@ -107,6 +113,11 @@
"alt_text_modal.describe_for_people_with_visual_impairments": "Deskribatu hau ikusmen arazoak dituzten pertsonentzat…",
"alt_text_modal.done": "Egina",
"announcement.announcement": "Iragarpena",
"annual_report.summary.archetype.booster": "Sustatzailea",
"annual_report.summary.archetype.lurker": "Begiluzea",
"annual_report.summary.archetype.oracle": "Orakulua",
"annual_report.summary.archetype.pollster": "Bozketazalea",
"annual_report.summary.archetype.replier": "Tolosa",
"annual_report.summary.followers.followers": "jarraitzaileak",
"annual_report.summary.followers.total": "{count} guztira",
"annual_report.summary.here_it_is": "Hona hemen zure {year}. urtearen bilduma:",
@ -162,6 +173,8 @@
"column.edit_list": "Editatu zerrenda",
"column.favourites": "Gogokoak",
"column.firehose": "Zuzeneko jarioak",
"column.firehose_local": "Zerbitzari honen zuzeneko jarioa",
"column.firehose_singular": "Zuzeneko jarioa",
"column.follow_requests": "Jarraitzeko eskaerak",
"column.home": "Hasiera",
"column.list_members": "Kudeatu zerrrendako partaideak",
@ -181,6 +194,7 @@
"community.column_settings.local_only": "Lokala soilik",
"community.column_settings.media_only": "Edukiak soilik",
"community.column_settings.remote_only": "Urrunekoa soilik",
"compose.error.blank_post": "Bidalketa ezin da hutsik egon.",
"compose.language.change": "Aldatu hizkuntza",
"compose.language.search": "Bilatu hizkuntzak...",
"compose.published.body": "Argitalpena argitaratuta.",
@ -233,13 +247,30 @@
"confirmations.missing_alt_text.secondary": "Bidali edonola ere",
"confirmations.missing_alt_text.title": "Testu alternatiboa gehitu?",
"confirmations.mute.confirm": "Mututu",
"confirmations.private_quote_notify.cancel": "Ediziora bueltatu",
"confirmations.private_quote_notify.confirm": "Argitaratu bidalketa",
"confirmations.private_quote_notify.do_not_show_again": "Ez erakutsi mezu hau berriro",
"confirmations.private_quote_notify.message": "Aipatzen ari zaren pertsonak eta aipatutako besteek jakinarazpena jasoko dute eta zure sarrera ikusi ahalko dute, zure jarraitzaileak ez badira ere.",
"confirmations.private_quote_notify.title": "Partekatu jarraitzaileekin eta aipatutako erabiltzaileekin?",
"confirmations.quiet_post_quote_info.dismiss": "Ez gogorarazi berriro",
"confirmations.quiet_post_quote_info.got_it": "Ulertuta",
"confirmations.quiet_post_quote_info.message": "Deiadar urriko bidalketa bat aipatzen duzunean, zure bidalketa joeretatik ezkutatuko da.",
"confirmations.quiet_post_quote_info.title": "Deiadar urriko bidalketaren aipua",
"confirmations.redraft.confirm": "Ezabatu eta berridatzi",
"confirmations.redraft.message": "Ziur argitalpen hau ezabatu eta zirriborroa berriro egitea nahi duzula? Gogokoak eta bultzadak galduko dira, eta jatorrizko argitalpenaren erantzunak zurtz geratuko dira.",
"confirmations.redraft.title": "Ezabatu eta berridatzi bidalketa?",
"confirmations.remove_from_followers.confirm": "Jarraitzailea Kendu",
"confirmations.remove_from_followers.message": "{name}-k zu jarraitzeari utziko dio. Seguru zaude jarraitu nahi duzula?",
"confirmations.remove_from_followers.title": "Jarraitzailea kendu nahi duzu?",
"confirmations.revoke_quote.confirm": "Ezabatu bidalketa",
"confirmations.revoke_quote.message": "Ekintza hau ezin da desegin.",
"confirmations.revoke_quote.title": "Ezabatu bidalketa?",
"confirmations.unblock.confirm": "Desblokeatu",
"confirmations.unblock.title": "Desblokeatu {name}?",
"confirmations.unfollow.confirm": "Utzi jarraitzeari",
"confirmations.unfollow.title": "{name} jarraitzeari utzi?",
"confirmations.withdraw_request.confirm": "Baztertu eskaera",
"confirmations.withdraw_request.title": "Baztertu {name} jarraitzeko eskaera?",
"content_warning.hide": "Tuta ezkutatu",
"content_warning.show": "Erakutsi hala ere",
"content_warning.show_more": "Erakutsi gehiago",
@ -265,6 +296,7 @@
"domain_block_modal.they_cant_follow": "Zerbitzari honetako inork ezin zaitu jarraitu.",
"domain_block_modal.they_wont_know": "Ez dute jakingo blokeatuak izan direnik.",
"domain_block_modal.title": "Domeinua blokeatu nahi duzu?",
"domain_block_modal.you_will_lose_num_followers": "{followersCount, plural, one {Jarraitzaile {followersCountDisplay}} other {{followersCountDisplay} jarraitzaile}} eta {followingCount, plural, one {jarraitzen duzun pertsona {followingCountDisplay}} other {jarraitzen dituzun beste {followingCountDisplay} pertsona}} galduko dituzu.",
"domain_block_modal.you_will_lose_relationships": "Instantzia honetatik jarraitzen dituzun jarraitzaile eta pertsona guztiak galduko dituzu.",
"domain_block_modal.you_wont_see_posts": "Ez dituzu zerbitzari honetako erabiltzaileen argitalpenik edota jakinarazpenik ikusiko.",
"domain_pill.activitypub_lets_connect": "Mastodon-en ez ezik, beste sare sozialen aplikazioetako jendearekin konektatzea eta harremanetan jartzea uzten dizu.",
@ -280,6 +312,7 @@
"domain_pill.your_handle": "Zure helbidea:",
"domain_pill.your_server": "Zure etxe digitala, non zure bidalketak dauden. Ez al zaizu gustatzen? Transferitu zerbitzariak edonoiz eta ekarri zure jarraitzaileak ere.",
"domain_pill.your_username": "Zerbitzarian duzun identifikatzaile bakarra. Baliteke erabiltzaile-izen bera duten erabiltzaileak zerbitzari desberdinetan aurkitzea.",
"dropdown.empty": "Aukeratu bat",
"embed.instructions": "Txertatu bidalketa hau zure webgunean beheko kodea kopiatuz.",
"embed.preview": "Hau da izango duen itxura:",
"emoji_button.activity": "Jarduera",
@ -308,6 +341,7 @@
"empty_column.bookmarked_statuses": "Oraindik ez dituzu bidalketa laster-markatutarik. Bat laster-markatzerakoan, hemen agertuko da.",
"empty_column.community": "Denbora-lerro lokala hutsik dago. Idatzi zerbait publikoki pilota biraka jartzeko!",
"empty_column.direct": "Ez duzu aipamen pribaturik oraindik. Baten bat bidali edo jasotzen duzunean, hemen agertuko da.",
"empty_column.disabled_feed": "Zure zerbitzariko administratzaileek jario hau desgaitu dute.",
"empty_column.domain_blocks": "Ez dago ezkutatutako domeinurik oraindik.",
"empty_column.explore_statuses": "Ez dago joerarik une honetan. Begiratu beranduago!",
"empty_column.favourited_statuses": "Ez duzu gogokorik oraindik. Gogoko bat duzunean, hemen agertuko da.",
@ -332,6 +366,7 @@
"explore.trending_links": "Berriak",
"explore.trending_statuses": "Tutak",
"explore.trending_tags": "Traolak",
"featured_carousel.header": "{count, plural, one {Finkatutako sarrera} other {Finkatutako sarrerak}}",
"featured_carousel.next": "Hurrengoa",
"featured_carousel.post": "Argitaratu",
"featured_carousel.previous": "Aurrekoa",
@ -435,10 +470,12 @@
"ignore_notifications_modal.private_mentions_title": "Eskatu gabeko aipamen pribatuen jakinarazpenei ez ikusiarena egin?",
"info_button.label": "Laguntza",
"info_button.what_is_alt_text": "<h1>Zer da Alt testua?</h1><p>Alt testuak irudiak deskribatzeko aukera ematen du, ikusmen-urritasunak, banda-zabalera txikiko konexioak edo testuinguru gehigarria nahi duten pertsonentzat.</p><p>Alt testu argi, zehatz eta objektiboen bidez, guztion irisgarritasuna eta ulermena hobetu ditzakezu.</p><ul><li>Hartu elementu garrantzitsuenak</li><li>Laburbildu irudietako testua</li><li>Erabili esaldien egitura erregularra</li><li>Baztertu informazio erredundantea.</li><li>Enfokatu joeretan eta funtsezko elementuetan irudi konplexuetan (diagrametan edo mapetan, adibidez)</li></ul>",
"interaction_modal.action": "{name} erabiltzailearen sarrerarekin interaktuatzeko, saioa hasi behar duzu erabiltzen duzun Mastodon zerbitzarian.",
"interaction_modal.go": "Joan",
"interaction_modal.no_account_yet": "Ez al duzu konturik oraindik?",
"interaction_modal.on_another_server": "Beste zerbitzari batean",
"interaction_modal.on_this_server": "Zerbitzari honetan",
"interaction_modal.title": "Hasi saioa jarraitzeko",
"interaction_modal.username_prompt": "Adib. {example}",
"intervals.full.days": "{number, plural, one {egun #} other {# egun}}",
"intervals.full.hours": "{number, plural, one {ordu #} other {# ordu}}",
@ -459,6 +496,7 @@
"keyboard_shortcuts.home": "hasierako denbora-lerroa irekitzeko",
"keyboard_shortcuts.hotkey": "Laster-tekla",
"keyboard_shortcuts.legend": "legenda hau bistaratzea",
"keyboard_shortcuts.load_more": "Fokuratu \"Kargatu gehiago\" botoia",
"keyboard_shortcuts.local": "denbora-lerro lokala irekitzeko",
"keyboard_shortcuts.mention": "egilea aipatzea",
"keyboard_shortcuts.muted": "mutututako erabiltzaileen zerrenda irekitzeko",
@ -467,6 +505,7 @@
"keyboard_shortcuts.open_media": "Ireki edukia",
"keyboard_shortcuts.pinned": "Ireki finkatutako bidalketen zerrenda",
"keyboard_shortcuts.profile": "egilearen profila irekitzeko",
"keyboard_shortcuts.quote": "Aipatu sarrera",
"keyboard_shortcuts.reply": "Erantzun bidalketari",
"keyboard_shortcuts.requests": "Jarraitzeko eskaeren zerrenda irekia",
"keyboard_shortcuts.search": "bilaketan fokua jartzea",
@ -478,6 +517,8 @@
"keyboard_shortcuts.translate": "bidalketa itzultzeko",
"keyboard_shortcuts.unfocus": "testua konposatzeko area / bilaketatik fokua kentzea",
"keyboard_shortcuts.up": "zerrendan gora mugitzea",
"learn_more_link.got_it": "Ulertuta",
"learn_more_link.learn_more": "Ikasi gehiago",
"lightbox.close": "Itxi",
"lightbox.next": "Hurrengoa",
"lightbox.previous": "Aurrekoa",
@ -500,6 +541,7 @@
"lists.exclusive": "Ezkutatu kideak Hasieran",
"lists.exclusive_hint": "Norbait zerrenda honetan badago, ezkutatu zure Hasierako jariotik mezuak bi aldiz ez ikusteko.",
"lists.find_users_to_add": "Bilatu erabiltzaileak gehitzeko",
"lists.list_members_count": "{count, plural, one {kide #} other {# kide}}",
"lists.list_name": "Zerrenda izena",
"lists.new_list_name": "Zerrenda izen berria",
"lists.no_lists_yet": "Ez duzu zerrendarik oraindik.",
@ -511,6 +553,7 @@
"lists.replies_policy.none": "Bat ere ez",
"lists.save": "Gorde",
"lists.search": "Bilatu",
"lists.show_replies_to": "Erakutsi zerrendako kideen erantzunak hauei:",
"load_pending": "{count, plural, one {elementu berri #} other {# elementu berri}}",
"loading_indicator.label": "Kargatzen…",
"media_gallery.hide": "Ezkutatu",
@ -551,6 +594,10 @@
"navigation_bar.privacy_and_reach": "Pribatutasuna eta irismena",
"navigation_bar.search": "Bilatu",
"navigation_bar.search_trends": "Bilatu / Joera",
"navigation_panel.collapse_followed_tags": "Itxi jarraitzen dituzun traolen menua",
"navigation_panel.collapse_lists": "Itxi zerrenden menua",
"navigation_panel.expand_followed_tags": "Zabaldu jarraitzen dituzun traolen menua",
"navigation_panel.expand_lists": "Zabaldu zerrenden menua",
"not_signed_in_indicator.not_signed_in": "Baliabide honetara sarbidea izateko saioa hasi behar duzu.",
"notification.admin.report": "{name} erabiltzaileak {target} salatu du",
"notification.admin.report_account": "{name}-(e)k {target}-ren {count, plural, one {bidalketa bat} other {# bidalketa}} salatu zituen {category} delakoagatik",
@ -559,15 +606,20 @@
"notification.admin.report_statuses_other": "{name} erabiltzaileak {target} salatu du",
"notification.admin.sign_up": "{name} erabiltzailea erregistratu da",
"notification.admin.sign_up.name_and_others": "{name} eta {count, plural, one {erabiltzaile # gehiago} other {# erabiltzaile gehiago}} erregistratu dira",
"notification.annual_report.message": "Zain duzu {year}(e)ko #Wrapstodon! Ikusi urteko zure unerik gogoangarrienak Mastodonen!",
"notification.annual_report.view": "Ikusi #Wrapstodon",
"notification.favourite": "{name}(e)k zure bidalketa gogoko du",
"notification.favourite.name_and_others_with_link": "{name} eta <a>{count, plural, one {erabiltzaile # gehiagok} other {# erabiltzaile gehiagok}}</a> zure bidalketa gogoko dute",
"notification.favourite_pm": "{name}-ek zure aipamen pribatua gogokoetan jarri du",
"notification.favourite_pm.name_and_others_with_link": "{name} erabiltzaileak eta beste <a>{count, plural, one {#ek} other {#(e)k}}</a> gogoko dute zure aipu pribatua",
"notification.follow": "{name}(e)k jarraitzen dizu",
"notification.follow.name_and_others": "{name} erabiltzaileak eta <a>{count, plural, one {# gehiagok} other {# gehiagok}}</a> jarraitu dizute",
"notification.follow_request": "{name}(e)k zu jarraitzeko eskaera egin du",
"notification.follow_request.name_and_others": "{name} eta {count, plural, one {erabiltzaile # gehiagok} other {# erabiltzaile gehiagok}} zu jarraitzeko eskaera egin dute",
"notification.label.mention": "Aipamena",
"notification.label.private_mention": "Aipamen pribatua",
"notification.label.private_reply": "Erantzun pribatua",
"notification.label.quote": "{name} erabiltzaileak zure bidalketa aipatu du",
"notification.label.reply": "Erantzuna",
"notification.mention": "Aipamena",
"notification.mentioned_you": "{name}(e)k aipatu zaitu",
@ -582,18 +634,23 @@
"notification.moderation_warning.action_suspend": "Kontua itxi da.",
"notification.own_poll": "Zure inkesta amaitu da",
"notification.poll": "Zuk erantzun duzun inkesta bat bukatu da",
"notification.quoted_update": "{name} erabiltzaileak aipatu duzun post bat editatu du",
"notification.reblog": "{name}(e)k bultzada eman dio zure bidalketari",
"notification.reblog.name_and_others_with_link": "{name} eta <a>{count, plural, one {erabiltzaile # gehiagok} other {# erabiltzaile gehiagok}}</a> bultzada eman diote zure bidalketari",
"notification.relationships_severance_event": "{name} erabiltzailearekin galdutako konexioak",
"notification.relationships_severance_event.account_suspension": "{from} zerbitzariko administratzaile batek {target} bertan behera utzi du, hau da, ezin izango dituzu jaso hango eguneratzerik edo hangoekin elkarreragin.",
"notification.relationships_severance_event.domain_block": "{from} zerbitzariko administratzaile batek {target} blokeatu du, tartean zure {followersCount} jarraitzaile eta jarraitzen duzun {followingCount, plural, one {kontu #} other {# kontu}}.",
"notification.relationships_severance_event.learn_more": "Informazio gehiago",
"notification.relationships_severance_event.user_domain_block": "{target} blokeatu duzu, tartean zure {followersCount} jarraitzaile eta jarraitzen duzun {followingCount, plural, one {kontu #} other {# kontu}}.",
"notification.status": "{name} erabiltzaileak bidalketa egin berri du",
"notification.update": "{name} erabiltzaileak bidalketa bat editatu du",
"notification_requests.accept": "Onartu",
"notification_requests.accept_multiple": "{count, plural, one {Onartu eskaera…} other {Onartu # eskaerak…}}",
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Onartu eskaera} other {Onartu eskaerak}}",
"notification_requests.confirm_accept_multiple.message": "{count, plural, one {Jakinarazpen eskaera bat} other {# jakinarazpen eskaera}} onartzekotan zaude. Jarraitu nahi duzu?",
"notification_requests.confirm_accept_multiple.title": "Onartu jakinarazpen-eskaerak?",
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Baztertu eskaera} other {Baztertu eskaerak}}",
"notification_requests.confirm_dismiss_multiple.message": "{count, plural, one {Jakinarazpen eskaera bat} other {# jakinarazpen eskaera}} baztertzekotan zaude. Gerora ezingo {count, plural, one {duzu} other {dituzu}} berriz erraz atzitu. Jarraitu nahi duzu?",
"notification_requests.confirm_dismiss_multiple.title": "Baztertu jakinarazpen-eskaerak?",
"notification_requests.dismiss": "Baztertu",
"notification_requests.dismiss_multiple": "{count, plural, one {Baztertu eskaera…} other {Baztertu # eskaerak…}}",
@ -621,6 +678,7 @@
"notifications.column_settings.mention": "Aipamenak:",
"notifications.column_settings.poll": "Inkestaren emaitzak:",
"notifications.column_settings.push": "Push jakinarazpenak",
"notifications.column_settings.quote": "Aipuak:",
"notifications.column_settings.reblog": "Bultzadak:",
"notifications.column_settings.show": "Erakutsi zutabean",
"notifications.column_settings.sound": "Jo soinua",
@ -691,14 +749,25 @@
"poll_button.remove_poll": "Kendu inkesta",
"privacy.change": "Aldatu bidalketaren pribatutasuna",
"privacy.direct.long": "Argitalpen honetan aipatutako denak",
"privacy.direct.short": "Aipu pribatua",
"privacy.private.long": "Soilik jarraitzaileak",
"privacy.private.short": "Jarraitzaileak",
"privacy.public.long": "Mastodonen dagoen edo ez dagoen edonor",
"privacy.public.short": "Publikoa",
"privacy.quote.anyone": "{visibility}, edonork aipa dezake",
"privacy.quote.disabled": "{visibility}, aipuak desgaituta",
"privacy.quote.limited": "{visibility}, aipuak mugatuta",
"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.long": "Ezkutatuta Mastodon bilaketen emaitzetatik, joeretatik, eta denbora-lerro publikoetatik",
"privacy.unlisted.short": "Deiadar urrikoa",
"privacy_policy.last_updated": "Azkenengo eguneraketa {date}",
"privacy_policy.title": "Pribatutasun politika",
"quote_error.edit": "Aipuak ezin dira gehitu bidalketa bat editatzean.",
"quote_error.poll": "Inkestak ezin dira aipatu.",
"quote_error.private_mentions": "Aipuak ez dira onartzen aipamen pribatuetan.",
"quote_error.quote": "Bidalketa bakoitzeko aipu bakarra onartzen da.",
"quote_error.unauthorized": "Ez duzu baimenik bidalketa hau aipatzeko.",
"quote_error.upload": "Aipuak ez dira onartzen multimedia eranskinekin.",
"recommended": "Gomendatua",
"refresh": "Berritu",
"regeneration_indicator.please_stand_by": "Itxaron, mesedez.",
@ -714,6 +783,9 @@
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"relative_time.today": "gaur",
"remove_quote_hint.button_label": "Ulertuta",
"remove_quote_hint.message": "{icon} aukeren menutik egin dezakezu.",
"remove_quote_hint.title": "Aipatu dizuten bidalketa kendu nahi duzu?",
"reply_indicator.attachments": "{count, plural, one {# eranskin} other {# eranskin}}",
"reply_indicator.cancel": "Utzi",
"reply_indicator.poll": "Inkesta",
@ -788,8 +860,10 @@
"search_results.all": "Guztiak",
"search_results.hashtags": "Traolak",
"search_results.no_results": "Emaitzarik ez.",
"search_results.no_search_yet": "Saiatu bilatzen bidalketak, profilak edo traolak.",
"search_results.see_all": "Ikusi guztiak",
"search_results.statuses": "Bidalketak",
"search_results.title": "Bilatu \"{q}\"",
"server_banner.about_active_users": "Azken 30 egunetan zerbitzari hau erabili duen jendea (hilabeteko erabiltzaile aktiboak)",
"server_banner.active_users": "erabiltzaile aktibo",
"server_banner.administered_by": "Administratzailea(k):",
@ -803,13 +877,23 @@
"status.admin_account": "Ireki @{name} erabiltzailearen moderazio interfazea",
"status.admin_domain": "{domain}-(r)en moderazio-interfazea ireki",
"status.admin_status": "Ireki bidalketa hau moderazio interfazean",
"status.all_disabled": "Bultzadak eta aipuak desgaituta daude",
"status.block": "Blokeatu @{name}",
"status.bookmark": "Laster-marka",
"status.cancel_reblog_private": "Kendu bultzada",
"status.cannot_quote": "Ez duzu bidalketa hau aipatzeko baimenik",
"status.cannot_reblog": "Bidalketa honi ezin zaio bultzada eman",
"status.contains_quote": "Aipua darama",
"status.context.loading": "Erantzun gehiago kargatzen",
"status.context.loading_error": "Ezin erantzun berririk kargatu",
"status.context.loading_success": "Erantzun berriak kargatuta",
"status.context.more_replies_found": "Erantzun gehiago aurkitu dira",
"status.context.retry": "Saiatu berriz",
"status.context.show": "Erakutsi",
"status.continued_thread": "Harian jarraitu zuen",
"status.copy": "Kopiatu bidalketaren esteka",
"status.delete": "Ezabatu",
"status.delete.success": "Bidalketa ezabatuta",
"status.detailed_status": "Elkarrizketaren ikuspegi xehetsua",
"status.direct": "Aipatu pribatuki @{name}",
"status.direct_indicator": "Aipamen pribatua",
@ -832,18 +916,46 @@
"status.mute_conversation": "Mututu elkarrizketa",
"status.open": "Hedatu bidalketa hau",
"status.pin": "Finkatu profilean",
"status.quote": "Aipua",
"status.quote.cancel": "Utzi aipua",
"status.quote_error.blocked_account_hint.title": "Bidalketa hau ezkutatuta dago @{name} blokeatu duzulako.",
"status.quote_error.blocked_domain_hint.title": "Bidalketa hau ezkutatuta dago {domain} blokeatu duzulako.",
"status.quote_error.filtered": "Ezkutatuta zure iragazki baten ondorioz",
"status.quote_error.limited_account_hint.action": "Erakutsi hala ere",
"status.quote_error.limited_account_hint.title": "{domain} zerbitzariaren moderatzaileek kontu hau ezkutatu dute.",
"status.quote_error.muted_account_hint.title": "Bidalketa hau ezkutatuta dago @{name} mututu duzulako.",
"status.quote_error.not_available": "Bidalketa ez dago eskuragarri",
"status.quote_error.pending_approval": "Bidalketa zain dago",
"status.quote_error.pending_approval_popout.body": "Mastodonen, norbaitek aipa zaitzakeen kontrola dezakezu. Bidalketa hau argitaratzeke dago jatorrizko egilearen oniritzia jaso bitartean.",
"status.quote_error.revoked": "Egileak bidalketa kendu du",
"status.quote_followers_only": "Bidalketa hau jarraitzaileek soilik aipatu dezakete",
"status.quote_manual_review": "Egileak eskuz berrikusiko du",
"status.quote_noun": "Aipua",
"status.quote_policy_change": "Aldatu nork aipa zaitzakeen",
"status.quote_post_author": "@{name} erabiltzailearen bidalketaren aipua",
"status.quote_private": "Bidalketa pribatuak ezin dira aipatu",
"status.quotes": "{count, plural, one {aipu} other {aipu}}",
"status.quotes.empty": "Momentuz inork ez du bidalketa hau aipatu. Norbaitek eginez gero, hemen agertuko da.",
"status.quotes.local_other_disclaimer": "Egileak errefusatutako aipuak ez dira erakutsiko.",
"status.quotes.remote_other_disclaimer": "{domain} zerbitzariko aipuak baino ez daude bermatuta hemen. Egileak errefusatutako aipuak ez dira erakutsiko.",
"status.read_more": "Irakurri gehiago",
"status.reblog": "Bultzada",
"status.reblog_or_quote": "Bultzatu edo aipatu",
"status.reblog_private": "Partekatu berriz zure jarraitzaileekin",
"status.reblogged_by": "{name}(r)en bultzada",
"status.reblogs": "{count, plural, one {bultzada} other {bultzada}}",
"status.reblogs.empty": "Inork ez dio bultzada eman bidalketa honi oraindik. Inork egiten badu, hemen agertuko da.",
"status.redraft": "Ezabatu eta berridatzi",
"status.remove_bookmark": "Kendu laster-marka",
"status.remove_favourite": "Kendu gogokoetatik",
"status.remove_quote": "Kendu",
"status.replied_in_thread": "Harian erantzun zuen",
"status.replied_to": "{name} erabiltzaileari erantzuna",
"status.reply": "Erantzun",
"status.replyAll": "Erantzun harian",
"status.report": "Salatu @{name}",
"status.request_quote": "Eskatu aipatzeko",
"status.revoke_quote": "Ezabatu nire bidalketa @{name}-(r)en bidalketatik",
"status.sensitive_warning": "Kontuz: Eduki hunkigarria",
"status.share": "Partekatu",
"status.show_less_all": "Erakutsi denetarik gutxiago",
@ -863,7 +975,9 @@
"tabs_bar.notifications": "Jakinarazpenak",
"tabs_bar.publish": "Bidalketa berria",
"tabs_bar.search": "Bilatu",
"terms_of_service.effective_as_of": "Indarrean {date}tik aurrera",
"terms_of_service.title": "Zerbitzuaren baldintzak",
"terms_of_service.upcoming_changes_on": "{date} datarako datozen aldaketak",
"time_remaining.days": "{number, plural, one {egun #} other {# egun}} amaitzeko",
"time_remaining.hours": "{number, plural, one {ordu #} other {# ordu}} amaitzeko",
"time_remaining.minutes": "{number, plural, one {minutu #} other {# minutu}} amaitzeko",
@ -879,6 +993,12 @@
"upload_button.label": "Gehitu multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_error.limit": "Fitxategi igoera muga gaindituta.",
"upload_error.poll": "Ez da inkestetan fitxategiak igotzea onartzen.",
"upload_error.quote": "Artxiboak igotzea ez da onartzen aipuekin.",
"upload_form.drag_and_drop.instructions": "Multimedia eranskin bat aukeratzeko, sakatu espazioa edo enter. Arrastatu bitartean, erabili gezi-teklak multimedia eranskina edozein norabidetan mugitzeko. Sakatu berriz espazioa edon enter multimedia eranskina bere kokapen berrian jartzeko, edo sakatu ESC uzteko.",
"upload_form.drag_and_drop.on_drag_cancel": "Arrastatzea bertan behera utzi da. {item} multimedia eranskina ez da mugitu.",
"upload_form.drag_and_drop.on_drag_end": "{item} multimedia eranskina ez da mugitu.",
"upload_form.drag_and_drop.on_drag_over": "{item} multimedia eranskina mugitu da.",
"upload_form.drag_and_drop.on_drag_start": "{item} multimedia eranskina hautatu da.",
"upload_form.edit": "Editatu",
"upload_progress.label": "Igotzen...",
"upload_progress.processing": "Prozesatzen…",
@ -889,10 +1009,28 @@
"video.expand": "Hedatu bideoa",
"video.fullscreen": "Pantaila osoa",
"video.hide": "Ezkutatu bideoa",
"video.mute": "Mututu",
"video.pause": "Pausatu",
"video.play": "Jo",
"video.skip_backward": "Saltatu atzerantz",
"video.skip_forward": "Jauzi aurrerantz",
"video.unmute": "Soinua ezarri",
"video.volume_down": "Bolumena jaitsi",
"video.volume_up": "Bolumena Igo"
"video.volume_up": "Bolumena Igo",
"visibility_modal.button_title": "Ezarri ikusgarritasuna",
"visibility_modal.direct_quote_warning.text": "Uneko ezarpenak gordez gero, txertatutako aipua lotura bilakatuko da.",
"visibility_modal.direct_quote_warning.title": "Aipuak ezin dira sartu aipamen prbatuetan",
"visibility_modal.header": "Ikusgarritasuna eta elkarreraginak",
"visibility_modal.helper.direct_quoting": "Mastodonen argitaratutako aipamen pribatuak ezin dituzte beste erabiltzaileek aipatu.",
"visibility_modal.helper.privacy_editing": "Ikusgarritasuna ezin da aldatu bidalketa argitaratu ondoren.",
"visibility_modal.helper.privacy_private_self_quote": "Bidalketa pribatuen auto-aipuak ezin dira publiko egin.",
"visibility_modal.helper.private_quoting": "Jarraitzaileentzat soilik sortutako bidalketak Mastodonen ezin dituzte beste batzuek aipatu.",
"visibility_modal.helper.unlisted_quoting": "Jendeak aipatzen zaituenean, bere bidalketa ere joeren denbora-lerro publikoetatik ezkutatuko da.",
"visibility_modal.instructions": "Kontrolatu nork izan dezakeen elkarreragina bidalketa honekin. Ezarpenak etorkizuneko bidalketa guztiei ere aplika diezazkiekezu <link>Hobespenak > Bidalketarako lehentsitakoak</link> atalera joanda.",
"visibility_modal.privacy_label": "Ikusgarritasuna",
"visibility_modal.quote_followers": "Jarraitzaileentzat soilik",
"visibility_modal.quote_label": "Nork aipa dezake",
"visibility_modal.quote_nobody": "Nik bakarrik",
"visibility_modal.quote_public": "Edonork",
"visibility_modal.save": "Gorde"
}

View File

@ -1,10 +1,10 @@
{
"about.blocks": "کارسازهای نظارت شده",
"about.blocks": "کارسازهای نظارت شده",
"about.contact": "تماس:",
"about.default_locale": "پیش‌فرض",
"about.default_locale": "پیش‌گزیده",
"about.disclaimer": "ماستودون نرم‌افزار آزاد و نشان تجاری یک شرکت غیر انتفاعی با مسئولیت محدود آلمانی است.",
"about.domain_blocks.no_reason_available": "دلیلی موجود نیست",
"about.domain_blocks.preamble": "ماستودون عموماً می‌گذارد محتوا را از از هر کارساز دیگری در دنیای شبکه‌های اجتماعی غیرمتمرکز دیده و با آنان برهم‌کنش داشته باشید. این‌ها استثناهایی هستند که روی این کارساز خاص وضع شده‌اند.",
"about.domain_blocks.preamble": "ماستودون عموماً می‌گذارد محتوا را از هر کارساز دیگری در دنیای شبکه‌های اجتماعی غیرمتمرکز دیده و با آنان برهم‌کنش داشته باشید. این‌ها استثناهایی هستند که روی این کارساز خاص وضع شده‌اند.",
"about.domain_blocks.silenced.explanation": "عموماً نمایه‌ها و محتوا از این کارساز را نمی‌بینید، مگر این که به طور خاص دنبالشان گشته یا با پی گیری، داوطلب دیدنشان شوید.",
"about.domain_blocks.silenced.title": "محدود",
"about.domain_blocks.suspended.explanation": "هیچ داده‌ای از این کارساز پردازش، ذخیره یا مبادله نخواهد شد، که هرگونه برهم‌کنش یا ارتباط با کاربران این کارساز را غیرممکن خواهد کرد.",
@ -28,18 +28,24 @@
"account.disable_notifications": "آگاه کردن من هنگام فرسته‌های @{name} را متوقّف کن",
"account.domain_blocking": "دامنهٔ مسدود کرده",
"account.edit_profile": "ویرایش نمایه",
"account.edit_profile_short": "ویرایش",
"account.enable_notifications": "هنگام فرسته‌های @{name} مرا آگاه کن",
"account.endorse": "معرّفی در نمایه",
"account.familiar_followers_many": "پی‌گرفته از سوی {name1}، {name2} و {othersCount, plural,one {یکی دیگر از پی‌گرفته‌هایتان} other {# نفر دیگر از پی‌گرفته‌هایتان}}",
"account.familiar_followers_one": "پی‌گرفته از سوی {name1}",
"account.familiar_followers_two": "پی‌گرفته از سوی {name1} و {name2}",
"account.featured": " پیشنهادی",
"account.featured": "پیشنهادی",
"account.featured.accounts": "نمایه‌ها",
"account.featured.hashtags": "برچسب‌ها",
"account.featured_tags.last_status_at": "آخرین فرسته در {date}",
"account.featured_tags.last_status_never": "بدون فرسته",
"account.follow": "پی‌گرفتن",
"account.follow_back": "پی‌گیری متقابل",
"account.follow_back_short": "پی‌گیری متقابل",
"account.follow_request": "درخواست پی‌گیری",
"account.follow_request_cancel": "لغو درخواست",
"account.follow_request_cancel_short": "لغو",
"account.follow_request_short": "درخواست",
"account.followers": "پی‌گیرندگان",
"account.followers.empty": "هنوز کسی پی‌گیر این کاربر نیست.",
"account.followers_counter": "{count, plural, one {{counter} پی‌گیرنده} other {{counter} پی‌گیرنده}}",
@ -111,7 +117,7 @@
"annual_report.summary.archetype.lurker": "کم‌پیدا",
"annual_report.summary.archetype.oracle": "غیب‌گو",
"annual_report.summary.archetype.pollster": "نظرسنج",
"annual_report.summary.archetype.replier": "پاسخگو",
"annual_report.summary.archetype.replier": "پاسخگو",
"annual_report.summary.followers.followers": "دنبال کننده",
"annual_report.summary.followers.total": "در مجموع {count}",
"annual_report.summary.here_it_is": "بازبینی {year} تان:",
@ -167,6 +173,8 @@
"column.edit_list": "ویرایش سیاهه",
"column.favourites": "برگزیده‌ها",
"column.firehose": "خوراک‌های زنده",
"column.firehose_local": "خوراک زندهٔ این کارساز",
"column.firehose_singular": "خوراک زنده",
"column.follow_requests": "درخواست‌های پی‌گیری",
"column.home": "خانه",
"column.list_members": "مدیریت اعضای سیاهه",
@ -186,6 +194,7 @@
"community.column_settings.local_only": "فقط محلی",
"community.column_settings.media_only": "فقط رسانه",
"community.column_settings.remote_only": "تنها دوردست",
"compose.error.blank_post": "فرسته نمی‌تواند خالی باشد.",
"compose.language.change": "تغییر زبان",
"compose.language.search": "جست‌وجوی زبان‌ها...",
"compose.published.body": "فرسته منتشر شد.",
@ -238,6 +247,15 @@
"confirmations.missing_alt_text.secondary": "به هر حال پست کن",
"confirmations.missing_alt_text.title": "متن جایگزین اضافه شود؟",
"confirmations.mute.confirm": "خموش",
"confirmations.private_quote_notify.cancel": "بازگشت به ویرایش کردن",
"confirmations.private_quote_notify.confirm": "انتشار فرسته",
"confirmations.private_quote_notify.do_not_show_again": "دیگر این پیام نشان داده نشود",
"confirmations.private_quote_notify.message": "فردی که نقلش می‌کنید و کسانی که اشاره شده‌اند آگاه خواهند شد و می‌توانند فرسته‌تان را ببینند؛ حتا اگر پیتان نگیرند.",
"confirmations.private_quote_notify.title": "هم‌رسانی با پی‌گیرندگان و کاربران اشاره شده؟",
"confirmations.quiet_post_quote_info.dismiss": "دیگر یادآوری نشود",
"confirmations.quiet_post_quote_info.got_it": "گرفتم",
"confirmations.quiet_post_quote_info.message": "هنگام نقل کردن فرستهٔ عمومی ساکت، فرسته‌تان از خط‌های زمانی داغ پنهان خواهد بود.",
"confirmations.quiet_post_quote_info.title": "نقل کردن فرسته‌های عمومی ساکت",
"confirmations.redraft.confirm": "حذف و بازنویسی",
"confirmations.redraft.message": "مطمئنید که می‌خواهید این فرسته را حذف کنید و از نو بنویسید؟ با این کار تقویت‌ها و پسندهایش از دست رفته و پاسخ‌ها به آن بی‌مرجع می‌شود.",
"confirmations.redraft.title": "حذف و پیش‌نویسی دوبارهٔ فرسته؟",
@ -247,7 +265,12 @@
"confirmations.revoke_quote.confirm": "حذف فرسته",
"confirmations.revoke_quote.message": "این اقدام قابل بازگشت نیست.",
"confirmations.revoke_quote.title": "آیا فرسته را حذف کنم؟",
"confirmations.unblock.confirm": "رفع انسداد",
"confirmations.unblock.title": "رفع انسداد {name}؟",
"confirmations.unfollow.confirm": "پی‌نگرفتن",
"confirmations.unfollow.title": "ناپی‌گیری {name}؟",
"confirmations.withdraw_request.confirm": "انصراف از درخواست",
"confirmations.withdraw_request.title": "انصراف از درخواست پی‌گیری {name}؟",
"content_warning.hide": "نهفتن فرسته",
"content_warning.show": "در هر صورت نشان داده شود",
"content_warning.show_more": "نمایش بیش‌تر",
@ -318,6 +341,7 @@
"empty_column.bookmarked_statuses": "هنوز هیچ فرستهٔ نشانه‌گذاری شده‌ای ندارید. هنگامی که فرسته‌ای را نشانه‌گذاری کنید، این‌جا نشان داده خواهد شد.",
"empty_column.community": "خط زمانی محلی خالیست. چیزی نوشته تا چرخش بچرخد!",
"empty_column.direct": "هنوز هیچ اشاره خصوصی‌ای ندارید. هنگامی که چنین پیامی بگیرید یا بفرستید این‌جا نشان داده خواهد شد.",
"empty_column.disabled_feed": "این خوراک به دست مدیران کارسازتان از کار انداخته شده.",
"empty_column.domain_blocks": "هنوز هیچ دامنه‌ای مسدود نشده است.",
"empty_column.explore_statuses": "الآن چیزی پرطرفدار نیست. بعداً دوباره بررسی کنید!",
"empty_column.favourited_statuses": "شما هنوز هیچ فرسته‌ای را نپسندیده‌اید. هنگامی که فرسته‌ای را بپسندید، این‌جا نشان داده خواهد شد.",
@ -446,10 +470,12 @@
"ignore_notifications_modal.private_mentions_title": "چشم‌پوشی از نام‌بری‌های خصوصی ناخواسته؟",
"info_button.label": "راهنما",
"info_button.what_is_alt_text": "<h1>متن جایگزین چیست؟</h1> <p>متن جایگزین توضیحات تصویری را برای افراد دارای اختلالات بینایی، اتصالات با پهنای باند کم یا کسانی که به دنبال زمینه اضافی هستند ارائه می دهد.</p> <p>با نوشتن متن جایگزین واضح، مختصر و عینی می توانید دسترسی و درک را برای همه بهبود بخشید.</p> <ul> <li>عناصر مهم را ضبط کنید</li> <li>متن را در تصاویر خلاصه کنید</li> <li>از ساختار جمله منظم استفاده کنید</li> <li>از اطلاعات اضافی خودداری کنید</li> <li>روی روندها و یافته های کلیدی در تصاویر پیچیده (مانند نمودارها یا نقشه ها) تمرکز کنید.</li> </ul>",
"interaction_modal.action": "برای تعامل با فرستهٔ {name} باید به حسابتان روی هر کارساز ماستودونی که استفاده می‌کنید وارد شوید.",
"interaction_modal.go": "برو",
"interaction_modal.no_account_yet": "هنوز حساب کاربری ندارید؟",
"interaction_modal.on_another_server": "روی کارسازی دیگر",
"interaction_modal.on_this_server": "روی این کارساز",
"interaction_modal.title": "ورود برای ادامه",
"interaction_modal.username_prompt": "به عنوان مثال {example}",
"intervals.full.days": "{number, plural, one {# روز} other {# روز}}",
"intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}",
@ -470,6 +496,7 @@
"keyboard_shortcuts.home": "گشودن خط زمانی خانگی",
"keyboard_shortcuts.hotkey": "میان‌بر",
"keyboard_shortcuts.legend": "نمایش این نشانه",
"keyboard_shortcuts.load_more": "تمرکز روی دکمهٔ «بار کردن بیش‌تر»",
"keyboard_shortcuts.local": "گشودن خط زمانی محلی",
"keyboard_shortcuts.mention": "اشاره به نویسنده",
"keyboard_shortcuts.muted": "گشودن فهرست کاربران خموش",
@ -478,6 +505,7 @@
"keyboard_shortcuts.open_media": "گشودن رسانه",
"keyboard_shortcuts.pinned": "گشودن سیاههٔ فرسته‌های سنجاق شده",
"keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده",
"keyboard_shortcuts.quote": "نقل فرسته",
"keyboard_shortcuts.reply": "پاسخ به فرسته",
"keyboard_shortcuts.requests": "گشودن سیاههٔ درخواست‌های پی‌گیری",
"keyboard_shortcuts.search": "تمرکز روی نوار جست‌وجو",
@ -527,7 +555,7 @@
"lists.search": "جست‌وجو",
"lists.show_replies_to": "شامل پاسخ از اعضای لیست به",
"load_pending": "{count, plural, one {# مورد جدید} other {# مورد جدید}}",
"loading_indicator.label": "در حال بارگذاری…",
"loading_indicator.label": "بار کردن…",
"media_gallery.hide": "نهفتن",
"moved_to_account_banner.text": "حسابتان {disabledAccount} اکنون از کار افتاده؛ چرا که به {movedToAccount} منتقل شدید.",
"mute_modal.hide_from_notifications": "نهفتن از آگاهی‌ها",
@ -578,12 +606,12 @@
"notification.admin.report_statuses_other": "{name}، {target} را گزارش داد",
"notification.admin.sign_up": "{name} ثبت نام کرد",
"notification.admin.sign_up.name_and_others": "{name} و {count, plural, one {# نفر دیگر} other {# نفر دیگر}} ثبت‌نام کردند",
"notification.annual_report.message": "آمار #Wrapstodon {year} تان منتظر است! لحظه‌های به یاد ماندنی و نقاط پررنگ سال را روی ماستودون رونمایی کنید!",
"notification.annual_report.view": "دیدن #Wrapstodon",
"notification.annual_report.message": "#خلاصهاستودون {year} منتظرتان است! رونمایی از لحظه‌های به یاد ماندنی و نقاط پررنگ سال روی ماستودون!",
"notification.annual_report.view": "دیدن #خلاصهاستودون",
"notification.favourite": "{name} فرسته‌تان را برگزید",
"notification.favourite.name_and_others_with_link": "{name} و <a>{count, plural, one {# نفر دیگر} other {# نفر دیگر}}</a> فرسته‌تان را برگزیدند",
"notification.favourite_pm": "{name} ذکر خصوصی شما را مورد علاقه قرار داد",
"notification.favourite_pm.name_and_others_with_link": "{name} و <a>{count, plural, one {دیگری} other {دیگران}}</a> ذکر خصوصی شما را مورد علاقه قرار دادند",
"notification.favourite_pm": "{name} اشارهٔ خصوصیتان را برگزید",
"notification.favourite_pm.name_and_others_with_link": "{name} و <a>{count, plural, one {# نفر دیگر} other {# نفر دیگر}}</a> اشارهٔ خصوصیتان را برگزیدند",
"notification.follow": "{name} پی‌گیرتان شد",
"notification.follow.name_and_others": "{name} و <a>{count, plural, other {#}} نفر دیگر</a> پیتان گرفتند",
"notification.follow_request": "{name} درخواست پی‌گیریتان را داد",
@ -606,6 +634,7 @@
"notification.moderation_warning.action_suspend": "حسابتان معلّق شده.",
"notification.own_poll": "نظرسنجیتان پایان یافت",
"notification.poll": "نظرسنجی‌ای که در آن رأی دادید به پایان رسید",
"notification.quoted_update": "{name} فرسته‌ای که نقل کردید را ویراست",
"notification.reblog": "{name} فرسته‌تان را تقویت کرد",
"notification.reblog.name_and_others_with_link": "{name} و <a>{count, plural, one {# نفر دیگر} other {# نفر دیگر}}</a> فرسته‌تان را تقویت کردند",
"notification.relationships_severance_event": "قطع ارتباط با {name}",
@ -618,10 +647,10 @@
"notification_requests.accept": "پذیرش",
"notification_requests.accept_multiple": "{count, plural, one {پذیرش درخواست…} other {پذیرش درخواست‌ها…}}",
"notification_requests.confirm_accept_multiple.button": "پذیرش {count, plural,one {درخواست} other {درخواست‌ها}}",
"notification_requests.confirm_accept_multiple.message": ر حال پذیرش {count, plural,one {یک}other {#}} درخواست آگاهی هستید. مطمئنید که می‌خواهید ادامه دهید؟",
"notification_requests.confirm_accept_multiple.message": ارید {count, plural,one {یک}other {#}} درخواست آگاهی را می‌پذیرید. مطمئنید که می‌خواهید ادامه دهید؟",
"notification_requests.confirm_accept_multiple.title": "پذیرش درخواست‌های آگاهی؟",
"notification_requests.confirm_dismiss_multiple.button": "رد {count, plural,one {درخواست} other {درخواست‌ها}}",
"notification_requests.confirm_dismiss_multiple.message": "شما در شرف رد کردن {count, plural, one {یک درخواست آگاهی} other {درخواست آگاهی}} هستید. دیگر نمی توانید به راحتی به {count, plural, one {آن} other {آن‌ها}} دسترسی پیدا کنید. آیا مطمئن هستید که می خواهید ادامه دهید؟",
"notification_requests.confirm_dismiss_multiple.message": "دارید {count, plural, one {یک درخواست آگاهی} other {# درخواست آگاهی}} را رد می‌کنید که دیگر نمی توانید به راحتی به {count, plural, one {آن} other {آن‌ها}} دسترسی پیدا کنید. مطمئنید که می‌خواهید ادامه دهید؟",
"notification_requests.confirm_dismiss_multiple.title": "رد کردن درخواست‌های آگاهی؟",
"notification_requests.dismiss": "دورانداختن",
"notification_requests.dismiss_multiple": "{count, plural, one {دورانداختن درخواست…} other {دورانداختن درخواست‌ها…}}",
@ -720,19 +749,29 @@
"poll_button.remove_poll": "برداشتن نظرسنجی",
"privacy.change": "تغییر محرمانگی فرسته",
"privacy.direct.long": "هرکسی که در فرسته نام برده شده",
"privacy.direct.short": "ذکر خصوصی",
"privacy.direct.short": "اشارهٔ خصوصی",
"privacy.private.long": "تنها پی‌گیرندگانتان",
"privacy.private.short": "پی‌گیرندگان",
"privacy.public.long": "هرکسی در و بیرون از ماستودون",
"privacy.public.short": "عمومی",
"privacy.quote.anyone": "{visibility}، هرکسی می‌تواند نقل کند",
"privacy.quote.disabled": "{visibility}، نقل‌ها از کار افتاده",
"privacy.quote.limited": "{visibility}، نقل‌ها محدود شده",
"privacy.unlisted.additional": "درست مثل عمومی رفتار می‌کند؛ جز این که فرسته در برچسب‌ها یا خوراک‌های زنده، کشف یا جست‌وجوی ماستودون ظاهر نخواهد شد. حتا اگر کلیّت نمایه‌تان اجازه داده باشد.",
"privacy.unlisted.long": "نهفته از نتیجه‌های جست‌وجوی ماستودون و خط‌های زمانی داغ و عمومی",
"privacy.unlisted.short": "عمومی ساکت",
"privacy_policy.last_updated": "آخرین به‌روز رسانی در {date}",
"privacy_policy.title": "سیاست محرمانگی",
"quote_error.edit": "هنگام ویراستن فرسته نمی‌توان نقلی افزود.",
"quote_error.poll": "نقل نظرسنجی‌ها مجاز نیست.",
"quote_error.private_mentions": "نقل اشاره‌های مستقیم مجاز نیست.",
"quote_error.quote": "در هر زمان تنها یک نقل مجاز است.",
"quote_error.unauthorized": "مجاز به نقل این فرسته نیستید.",
"quote_error.upload": "نقل پیوست‌های رسانه‌ای مجاز نیست.",
"recommended": "پیشنهادشده",
"refresh": "نوسازی",
"regeneration_indicator.please_stand_by": "لطفا منتظر باشید.",
"regeneration_indicator.preparing_your_home_feed": "در حال آماده کردن خوراک خانگی شما…",
"regeneration_indicator.preparing_your_home_feed": "آماده کردن خوراک خانگیتان…",
"relative_time.days": "{number} روز",
"relative_time.full.days": "{number, plural, one {# روز} other {# روز}} پیش",
"relative_time.full.hours": "{number, plural, one {# ساعت} other {# ساعت}} پیش",
@ -744,6 +783,9 @@
"relative_time.minutes": "{number} دقیقه",
"relative_time.seconds": "{number} ثانیه",
"relative_time.today": "امروز",
"remove_quote_hint.button_label": "گرفتم",
"remove_quote_hint.message": "می‌توانید این کار را از {icon} فهرست گزینه‌ها انجام دهید.",
"remove_quote_hint.title": "می‌خواهید فرستهٔ نقل شده‌تان را بردارید؟",
"reply_indicator.attachments": "{count, plural, one {# پیوست} other {# پیوست}}",
"reply_indicator.cancel": "لغو",
"reply_indicator.poll": "نظرسنجی",
@ -780,9 +822,9 @@
"report.statuses.subtitle": "همهٔ موارد انجام شده را برگزینید",
"report.statuses.title": "آیا فرسته‌ای وجود دارد که از این گزارش پشتیبانی کند؟",
"report.submit": "فرستادن",
"report.target": "در حال گزارش {target}",
"report.target": "گزارش کردن {target}",
"report.thanks.take_action": "در اینجا گزینه‌هایی برای کنترل آنچه در ماستودون میبینید، وجود دارد:",
"report.thanks.take_action_actionable": "در حالی که ما این مورد را بررسی می‌کنیم، می‌توانید علیه @{name} اقدام کنید:",
"report.thanks.take_action_actionable": "تا بررسیش می‌کنیم می‌توانید علیه @{name} اقدام کنید:",
"report.thanks.title": "نمی‌خواهید این را ببینید؟",
"report.thanks.title_actionable": "ممنون بابت گزارش، ما آن را بررسی خواهیم کرد.",
"report.unfollow": "پی‌نگرفتن @{name}",
@ -835,13 +877,23 @@
"status.admin_account": "گشودن واسط مدیریت برای @{name}",
"status.admin_domain": "گشودن واسط مدیریت برای {domain}",
"status.admin_status": "گشودن این فرسته در واسط مدیریت",
"status.all_disabled": "تقویت‌ها و نقل‌ها از کار افتاده‌اند",
"status.block": "انسداد @{name}",
"status.bookmark": "نشانک",
"status.cancel_reblog_private": "ناتقویت",
"status.cannot_quote": "مجاز به نقل این فرسته نیستید",
"status.cannot_reblog": "این فرسته قابل تقویت نیست",
"status.contains_quote": "دارای نقل",
"status.context.loading": "بار کردن پاسخ‌های بیش‌تر",
"status.context.loading_error": "نتوانست پاسخ‌های بیش‌تری بار کند",
"status.context.loading_success": "پاسخ‌های جدید بار شدند",
"status.context.more_replies_found": "پاسخ‌های بیش‌تری پیدا شد",
"status.context.retry": "تلاش دوباره",
"status.context.show": "نمایش",
"status.continued_thread": "رشتهٔ دنباله دار",
"status.copy": "رونوشت از پیوند فرسته",
"status.delete": "حذف",
"status.delete.success": "فرسته حذف شد",
"status.detailed_status": "نمایش کامل گفتگو",
"status.direct": "اشارهٔ خصوصی به @{name}",
"status.direct_indicator": "اشارهٔ خصوصی",
@ -866,24 +918,43 @@
"status.pin": "سنجاق به نمایه",
"status.quote": "نقل‌قول",
"status.quote.cancel": "لغو نقل",
"status.quote_error.blocked_account_hint.title": "این فرسته نهفته است چرا که @{name} را مسدود کرده‌اید.",
"status.quote_error.blocked_domain_hint.title": "این فرسته نهفته است چرا که {domain} را مسدود کرده‌اید.",
"status.quote_error.filtered": "نهفته بنا بر یکی از پالایه‌هایتان",
"status.quote_error.limited_account_hint.action": "نمایش به هر روی",
"status.quote_error.limited_account_hint.title": "این حساب به دست ناظم‌های {domain} پنهان شده.",
"status.quote_error.muted_account_hint.title": "این فرسته نهفته است چرا که @{name} را خموش کرده‌اید.",
"status.quote_error.not_available": "فرسته در دسترس نیست",
"status.quote_error.pending_approval": "فرسته منتظر",
"status.quote_error.pending_approval_popout.body": "روی ماستودون می‌توان افراد مجاز به نقل را واپایید. این فرسته تا زمان گرفتن تأییده از نگارندهٔ اصلی معلّق است.",
"status.quote_error.revoked": "فرسته به دست نگارنده برداشته شد",
"status.quote_followers_only": "تنها پی‌گیران می‌توانند این فرسته را نقل کنند",
"status.quote_manual_review": "نگارنده به صورت دستی بررسی خواهد کرد",
"status.quote_noun": "نقل",
"status.quote_policy_change": "تغییر کسانی که می‌توانند نقل کنند",
"status.quote_post_author": "فرسته‌ای از @{name} نقل شد",
"status.quote_private": "فرسته‌های خصوصی نمی‌توانند نقل شوند",
"status.quotes": "{count, plural, one {نقل} other {نقل}}",
"status.quotes.empty": "هنوز کسی این فرسته را نقل نکرده. وقتی کسی چنین کند این‌جا نشان داده خواهد شد.",
"status.quotes.local_other_disclaimer": "نقل‌هایی که به دست نگارنده رد شده باشند نشان داده نخواهند شد.",
"status.quotes.remote_other_disclaimer": "تنها نقل‌ها از {domain} تضمین نمایش در این‌جا را دارند. نقل‌های رد شده به دست نگاره نشان داده نخواهند شد.",
"status.read_more": "بیشتر بخوانید",
"status.reblog": "تقویت",
"status.reblog_or_quote": "نقل یا تقویت",
"status.reblog_private": "هم‌رسانی دوباره با پی‌گیرانتان",
"status.reblogged_by": "{name} تقویت کرد",
"status.reblogs": "{count, plural, one {تقویت} other {تقویت}}",
"status.reblogs.empty": "هنوز هیچ کسی این فرسته را تقویت نکرده است. وقتی کسی چنین کاری کند، این‌جا نمایش داده خواهد شد.",
"status.redraft": "حذف و بازنویسی",
"status.remove_bookmark": "برداشتن نشانک",
"status.remove_favourite": "حذف از موارد دلخواه",
"status.remove_quote": "برداشتن",
"status.replied_in_thread": "در رشته پاسخ داده",
"status.replied_to": "به {name} پاسخ داد",
"status.reply": "پاسخ",
"status.replyAll": "پاسخ به رشته",
"status.report": "گزارش @{name}",
"status.request_quote": "درخواست نقل",
"status.revoke_quote": "حذف فرسته‌ام از فرسته @{name}",
"status.sensitive_warning": "محتوای حساس",
"status.share": "هم‌رسانی",
@ -922,14 +993,15 @@
"upload_button.label": "افزودن تصاویر، ویدیو یا یک پروندهٔ صوتی",
"upload_error.limit": "از حد مجاز بارگذاری پرونده فراتر رفتید.",
"upload_error.poll": "بارگذاری پرونده در نظرسنجی‌ها مجاز نیست.",
"upload_error.quote": "بارگذاری پرونده در نقل‌ها محاز نیست.",
"upload_form.drag_and_drop.instructions": "برای دریافت پیوست رسانه، space را فشار دهید یا وارد کنید. در حین کشیدن، از کلیدهای جهت دار برای حرکت دادن پیوست رسانه در هر جهت معین استفاده کنید. برای رها کردن ضمیمه رسانه در موقعیت جدید خود، مجدداً space یا enter را فشار دهید، یا برای لغو، escape را فشار دهید.",
"upload_form.drag_and_drop.on_drag_cancel": "کشیدن لغو شد. پیوست رسانه {item} حذف شد.",
"upload_form.drag_and_drop.on_drag_end": "پیوست رسانه {item} حذف شد.",
"upload_form.drag_and_drop.on_drag_over": "پیوست رسانه {item} منتقل شد.",
"upload_form.drag_and_drop.on_drag_start": "پیوست رسانه {item} برداشته شد.",
"upload_form.edit": "ویرایش",
"upload_progress.label": "در حال بارگذاری...",
"upload_progress.processing": "در حال پردازش…",
"upload_progress.label": "بار گذاشتن...",
"upload_progress.processing": "پردازش کردن…",
"username.taken": "این نام کاربری گرفته شده. نام دیگری امتحان کنید",
"video.close": "بستن ویدیو",
"video.download": "بارگیری پرونده",
@ -946,9 +1018,19 @@
"video.volume_down": "کاهش حجم صدا",
"video.volume_up": "افزایش حجم صدا",
"visibility_modal.button_title": "تنظیم نمایانی",
"visibility_modal.direct_quote_warning.text": "اگر تنظبمات کنونی را ذخیره کنید نقل تعبیه شده تبدیل به پیوند خواهد شد.",
"visibility_modal.direct_quote_warning.title": "نقل‌ها نمی‌توانند در اشاره‌های خصوصی تعبیه شوند",
"visibility_modal.header": "نمایانی و برهم‌کنش",
"visibility_modal.helper.direct_quoting": "اشاره‌های خصوصی روی ماستودون نیم‌توانند به دست دیگران نقل شوند.",
"visibility_modal.helper.privacy_editing": "پس از انتشار فرسته نمی‌توان نمایانی را تغییر داد.",
"visibility_modal.helper.privacy_private_self_quote": "خودنقلی فرسته‌های خصوصی نمی‌تواند عمومی شود.",
"visibility_modal.helper.private_quoting": "فرسته‌ّای فقط پی‌گیران روی ماستودون نمی‌توانند به دست دیگران نقل شوند.",
"visibility_modal.helper.unlisted_quoting": "هنگامی که افراد نقلتان می‌کنند فرسته‌شان هم از خط‌زمانی‌های داغ پنهان خواهد بود.",
"visibility_modal.instructions": "واپایش کسانی که می‌توانند با این فرسته تعامل داشته باشند. می‌تواند با رفتن به <link>ترجیحات > پیش‌گزیده‌ها فرستادن</link> تنظیمات را به همهٔ فرسته‌های آینده نیز اعمال کنید.",
"visibility_modal.privacy_label": "نمایانی",
"visibility_modal.quote_followers": "فقط پی‌گیرندگان",
"visibility_modal.quote_label": "چه‌کسی می‌تواند نقل کند",
"visibility_modal.quote_nobody": "فقط من",
"visibility_modal.quote_public": "هرکسی",
"visibility_modal.save": "ذخیره"
}

View File

@ -3,7 +3,7 @@
"about.contact": "Yhteydenotto:",
"about.default_locale": "Oletus",
"about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.",
"about.domain_blocks.no_reason_available": "Syytä ei ole ilmoitettu",
"about.domain_blocks.no_reason_available": "Syy ei ole tiedossa",
"about.domain_blocks.preamble": "Mastodonin avulla voi yleensä tarkastella minkä tahansa fediversumiin kuuluvan palvelimen sisältöä ja olla yhteyksissä eri palvelinten käyttäjien kanssa. Nämä poikkeukset koskevat yksin tätä palvelinta.",
"about.domain_blocks.silenced.explanation": "Et yleensä näe tämän palvelimen profiileja ja sisältöä, jollet erityisesti etsi juuri sitä tai liity siihen seuraamalla.",
"about.domain_blocks.silenced.title": "Rajoitettu",
@ -80,7 +80,7 @@
"account.requests_to_follow_you": "Pyynnöt seurata sinua",
"account.share": "Jaa käyttäjän @{name} profiili",
"account.show_reblogs": "Näytä käyttäjän @{name} tehostukset",
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"account.unblock": "Kumoa käyttäjän @{name} esto",
"account.unblock_domain": "Kumoa verkkotunnuksen {domain} esto",
"account.unblock_domain_short": "Kumoa esto",
@ -100,7 +100,7 @@
"admin.impact_report.instance_followers": "Seuraajat, jotka käyttäjämme menettäisivät",
"admin.impact_report.instance_follows": "Seuraajat, jotka heidän käyttäjänsä menettäisivät",
"admin.impact_report.title": "Vaikutusten yhteenveto",
"alert.rate_limited.message": "Yritä uudelleen {retry_time, time, medium} jälkeen.",
"alert.rate_limited.message": "Yritä uudelleen kello {retry_time, time, medium} jälkeen.",
"alert.rate_limited.title": "Pyyntömäärää rajoitettu",
"alert.unexpected.message": "Tapahtui odottamaton virhe.",
"alert.unexpected.title": "Hups!",
@ -194,12 +194,13 @@
"community.column_settings.local_only": "Vain paikalliset",
"community.column_settings.media_only": "Vain media",
"community.column_settings.remote_only": "Vain etätilit",
"compose.error.blank_post": "Julkaisu ei voi olla tyhjä.",
"compose.language.change": "Vaihda kieli",
"compose.language.search": "Hae kieliä…",
"compose.published.body": "Julkaisu lähetetty.",
"compose.published.open": "Avaa",
"compose.saved.body": "Julkaisu tallennettu.",
"compose_form.direct_message_warning_learn_more": "Lisätietoja",
"compose_form.direct_message_warning_learn_more": "Lue lisää",
"compose_form.encryption_warning": "Mastodonin julkaisut eivät ole päästä päähän salattuja. Älä jaa arkaluonteisia tietoja Mastodonissa.",
"compose_form.hashtag_warning": "Tätä julkaisua ei voi liittää aihetunnisteisiin, koska se ei ole julkinen. Vain näkyvyydeltään julkisiksi määritettyjä julkaisuja voidaan hakea aihetunnisteiden avulla.",
"compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.",
@ -230,7 +231,7 @@
"confirmations.discard_draft.edit.cancel": "Palaa muokkaamaan",
"confirmations.discard_draft.edit.message": "Jatkaminen tuhoaa kaikki muutokset, joita olet tehnyt julkaisuun, jota olet parhaillaan muokkaamassa.",
"confirmations.discard_draft.edit.title": "Hylätäänkö luonnosjulkaisusi muutokset?",
"confirmations.discard_draft.post.cancel": "Palaa lunnokseen",
"confirmations.discard_draft.post.cancel": "Palaa luonnokseen",
"confirmations.discard_draft.post.message": "Jatkaminen tuhoaa julkaisun, jota olet parhaillaan laatimassa.",
"confirmations.discard_draft.post.title": "Hylätäänkö luonnosjulkaisusi?",
"confirmations.discard_edit_media.confirm": "Hylkää",
@ -246,6 +247,11 @@
"confirmations.missing_alt_text.secondary": "Julkaise silti",
"confirmations.missing_alt_text.title": "Lisätäänkö vaihtoehtoinen teksti?",
"confirmations.mute.confirm": "Mykistä",
"confirmations.private_quote_notify.cancel": "Takaisin muokkaukseen",
"confirmations.private_quote_notify.confirm": "Julkaise",
"confirmations.private_quote_notify.do_not_show_again": "Älä näytä tätä viestiä uudelleen",
"confirmations.private_quote_notify.message": "Lainaamasi käyttäjä ja muut mainitut saavat ilmoituksen ja voivat tarkastella julkaisuasi, vaikka he eivät seuraisi sinua.",
"confirmations.private_quote_notify.title": "Jaetaanko seuraajien ja mainittujen käyttäjien kanssa?",
"confirmations.quiet_post_quote_info.dismiss": "Älä muistuta minua uudelleen",
"confirmations.quiet_post_quote_info.got_it": "Selvä",
"confirmations.quiet_post_quote_info.message": "Kun lainaat vaivihkaa julkisia julkaisuja, oma julkaisusi piilotetaan suosittujen julkaisujen aikajanoilta.",
@ -290,7 +296,7 @@
"domain_block_modal.they_cant_follow": "Kukaan tältä palvelimelta ei voi seurata sinua.",
"domain_block_modal.they_wont_know": "Hän ei saa tietää tulleensa estetyksi.",
"domain_block_modal.title": "Estetäänkö verkkotunnus?",
"domain_block_modal.you_will_lose_num_followers": "Menetät {followersCount, plural, one {{followersCountDisplay} seuraajasi} other {{followersCountDisplay} seuraajaasi}} ja {followingCount, plural, one {{followingCountDisplay} seurattavasi} other {{followingCountDisplay} seurattavaasi}}.",
"domain_block_modal.you_will_lose_num_followers": "Menetät {followersCount, plural, one {{followersCountDisplay}:n seuraajasi} other {{followersCountDisplay} seuraajaasi}} ja {followingCount, plural, one {{followingCountDisplay}:n seurattavasi} other {{followingCountDisplay} seurattavaasi}}.",
"domain_block_modal.you_will_lose_relationships": "Menetät kaikki tämän palvelimen seuraajasi ja seurattavasi.",
"domain_block_modal.you_wont_see_posts": "Et enää näe julkaisuja etkä ilmoituksia tämän palvelimen käyttäjiltä.",
"domain_pill.activitypub_lets_connect": "Sen avulla voit muodostaa yhteyden ja olla vuorovaikutuksessa ihmisten kanssa, ei vain Mastodonissa vaan myös muissa sosiaalisissa sovelluksissa.",
@ -330,7 +336,7 @@
"empty_column.account_hides_collections": "Käyttäjä on päättänyt pitää nämä tiedot yksityisinä",
"empty_column.account_suspended": "Tili jäädytetty",
"empty_column.account_timeline": "Ei julkaisuja täällä!",
"empty_column.account_unavailable": "Profiilia ei ole saatavilla",
"empty_column.account_unavailable": "Profiili ei saatavilla",
"empty_column.blocks": "Et ole vielä estänyt käyttäjiä.",
"empty_column.bookmarked_statuses": "Et ole vielä lisännyt julkaisuja kirjanmerkkeihisi. Kun lisäät yhden, se näkyy tässä.",
"empty_column.community": "Paikallinen aikajana on tyhjä. Kirjoita jotain julkista, niin homma lähtee käyntiin!",
@ -351,7 +357,7 @@
"empty_column.public": "Täällä ei ole mitään! Kirjoita jotain julkisesti tai seuraa muiden palvelinten käyttäjiä, niin saat sisältöä",
"error.unexpected_crash.explanation": "Sivua ei voida näyttää oikein ohjelmointivirheen tai selaimen yhteensopivuusvajeen vuoksi.",
"error.unexpected_crash.explanation_addons": "Sivua ei voitu näyttää oikein. Tämä virhe johtuu todennäköisesti selaimen lisäosasta tai automaattisista käännöstyökaluista.",
"error.unexpected_crash.next_steps": "Kokeile päivittää sivu. Jos se ei auta, voi Mastodonin käyttö ehkä onnistua eri selaimella tai natiivisovelluksella.",
"error.unexpected_crash.next_steps": "Kokeile päivittää sivu. Jos se ei auta, Mastodonin käyttö voi ehkä onnistua eri selaimella tai natiivisovelluksella.",
"error.unexpected_crash.next_steps_addons": "Yritä poistaa ne käytöstä, ja virkistä sitten sivunlataus. Mikäli ongelma jatkuu, voit mahdollisesti käyttää Mastodonia eri selaimella tai natiivilla sovelluksella.",
"errors.unexpected_crash.copy_stacktrace": "Kopioi pinon jäljitys leikepöydälle",
"errors.unexpected_crash.report_issue": "Ilmoita ongelmasta",
@ -428,15 +434,15 @@
"hashtag.column_settings.tag_mode.any": "Mikä tahansa näistä",
"hashtag.column_settings.tag_mode.none": "Ei mitään näistä",
"hashtag.column_settings.tag_toggle": "Sisällytä lisätunnisteet tähän sarakkeeseen",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} osallistuja} other {{counter} osallistujaa}}",
"hashtag.counter_by_uses": "{count, plural, one{{counter} julkaisu} other {{counter} julkaisua}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}} tänään",
"hashtag.counter_by_accounts": "{count, plural, one {{counter} osallistuja} other {{counter} osallistujaa}}",
"hashtag.counter_by_uses": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}} tänään",
"hashtag.feature": "Suosittele profiilissa",
"hashtag.follow": "Seuraa aihetunnistetta",
"hashtag.mute": "Mykistä #{hashtag}",
"hashtag.unfeature": "Kumoa suosittelu profiilissa",
"hashtag.unfollow": "Lopeta aihetunnisteen seuraaminen",
"hashtags.and_other": "…ja {count, plural, other {# lisää}}",
"hashtags.and_other": "…ja {count, plural, other {# lisää}}",
"hints.profiles.followers_may_be_missing": "Tämän profiilin seuraajia saattaa puuttua.",
"hints.profiles.follows_may_be_missing": "Tämän profiilin seurattavia saattaa puuttua.",
"hints.profiles.posts_may_be_missing": "Tämän profiilin julkaisuja saattaa puuttua.",
@ -471,9 +477,9 @@
"interaction_modal.on_this_server": "Tällä palvelimella",
"interaction_modal.title": "Jatka kirjautumalla sisään",
"interaction_modal.username_prompt": "Esim. {example}",
"intervals.full.days": "{number, plural, one {# päivä} other {# päivää}}",
"intervals.full.hours": "{number, plural, one {# tunti} other {# tuntia}}",
"intervals.full.minutes": "{number, plural, one {# minuutti} other {# minuuttia}}",
"intervals.full.days": "{number, plural, one {# päivä} other {# päivää}}",
"intervals.full.hours": "{number, plural, one {# tunti} other {# tuntia}}",
"intervals.full.minutes": "{number, plural, one {# minuutti} other {# minuuttia}}",
"keyboard_shortcuts.back": "Siirry takaisin",
"keyboard_shortcuts.blocked": "Avaa estettyjen käyttäjien luettelo",
"keyboard_shortcuts.boost": "Tehosta julkaisua",
@ -490,7 +496,7 @@
"keyboard_shortcuts.home": "Avaa kotiaikajana",
"keyboard_shortcuts.hotkey": "Pikanäppäin",
"keyboard_shortcuts.legend": "Näytä tämä ohje",
"keyboard_shortcuts.load_more": "Kohdista ”Lataa lisää” -painikkeeseen",
"keyboard_shortcuts.load_more": "Kohdista ”Lataa lisää” -painikkeeseen",
"keyboard_shortcuts.local": "Avaa paikallinen aikajana",
"keyboard_shortcuts.mention": "Mainitse tekijä",
"keyboard_shortcuts.muted": "Avaa mykistettyjen käyttäjien luettelo",
@ -504,7 +510,7 @@
"keyboard_shortcuts.requests": "Avaa seurantapyyntöjen luettelo",
"keyboard_shortcuts.search": "Kohdista hakukenttään",
"keyboard_shortcuts.spoilers": "Näytä tai piilota sisältövaroituskenttä",
"keyboard_shortcuts.start": "Avaa Näin pääset alkuun -sarake",
"keyboard_shortcuts.start": "Avaa Näin pääset alkuun -sarake",
"keyboard_shortcuts.toggle_hidden": "Näytä tai piilota sisältövaroituksella merkitty teksti",
"keyboard_shortcuts.toggle_sensitivity": "Näytä tai piilota media",
"keyboard_shortcuts.toot": "Luo uusi julkaisu",
@ -522,7 +528,7 @@
"limited_account_hint.title": "Palvelimen {domain} moderaattorit ovat piilottaneet tämän profiilin.",
"link_preview.author": "Tehnyt {name}",
"link_preview.more_from_author": "Lisää tekijältä {name}",
"link_preview.shares": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"link_preview.shares": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"lists.add_member": "Lisää",
"lists.add_to_list": "Lisää listaan",
"lists.add_to_lists": "Lisää {name} listaan",
@ -535,7 +541,7 @@
"lists.exclusive": "Piilota jäsenet kotisyötteestä",
"lists.exclusive_hint": "Jos joku on tässä listassa, piilota hänet kotisyötteestäsi, jotta et näe hänen julkaisujaan kahteen kertaan.",
"lists.find_users_to_add": "Etsi lisättäviä käyttäjiä",
"lists.list_members_count": "{count, plural, one {# jäsen} other {# jäsentä}}",
"lists.list_members_count": "{count, plural, one {# jäsen} other {# jäsentä}}",
"lists.list_name": "Listan nimi",
"lists.new_list_name": "Uuden listan nimi",
"lists.no_lists_yet": "Ei vielä listoja.",
@ -548,7 +554,7 @@
"lists.save": "Tallenna",
"lists.search": "Haku",
"lists.show_replies_to": "Sisällytä listan jäsenten vastaukset kohteeseen",
"load_pending": "{count, plural, one {# uusi kohde} other {# uutta kohdetta}}",
"load_pending": "{count, plural, one {# uusi kohde} other {# uutta kohdetta}}",
"loading_indicator.label": "Ladataan…",
"media_gallery.hide": "Piilota",
"moved_to_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä, koska teit siirron tiliin {movedToAccount}.",
@ -607,7 +613,7 @@
"notification.favourite_pm": "{name} lisäsi yksityismainintasi suosikkeihinsa",
"notification.favourite_pm.name_and_others_with_link": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> lisäsivät yksityismainintasi suosikkeihinsa",
"notification.follow": "{name} seurasi sinua",
"notification.follow.name_and_others": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> seurasivat sinua",
"notification.follow.name_and_others": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> seurasivat sinua",
"notification.follow_request": "{name} on pyytänyt lupaa seurata sinua",
"notification.follow_request.name_and_others": "{name} ja {count, plural, one {# muu} other {# muuta}} pyysivät saada seurata sinua",
"notification.label.mention": "Maininta",
@ -630,7 +636,7 @@
"notification.poll": "Äänestys, johon osallistuit, on päättynyt",
"notification.quoted_update": "{name} muokkasi lainaamaasi julkaisua",
"notification.reblog": "{name} tehosti julkaisuasi",
"notification.reblog.name_and_others_with_link": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> tehostivat julkaisuasi",
"notification.reblog.name_and_others_with_link": "{name} ja <a>{count, plural, one {# muu} other {# muuta}}</a> tehostivat julkaisuasi",
"notification.relationships_severance_event": "Menetettiin yhteydet palvelimeen {name}",
"notification.relationships_severance_event.account_suspension": "Palvelimen {from} ylläpitäjä on jäädyttänyt palvelimen {target} vuorovaikutuksen. Enää et voi siis vastaanottaa päivityksiä heiltä tai olla yhteyksissä heidän kanssaan.",
"notification.relationships_severance_event.domain_block": "Palvelimen {from} ylläpitäjä on estänyt palvelimen {target} vuorovaikutuksen mukaan lukien {followersCount} seuraajistasi ja {followingCount, plural, one {# seurattavistasi} other {# seurattavistasi}}.",
@ -639,7 +645,7 @@
"notification.status": "{name} julkaisi juuri",
"notification.update": "{name} muokkasi julkaisua",
"notification_requests.accept": "Hyväksy",
"notification_requests.accept_multiple": "{count, plural, one {Hyväksy # pyyntö…} other {Hyväksy # pyyntöä…}}",
"notification_requests.accept_multiple": "{count, plural, one {Hyväksy # pyyntö…} other {Hyväksy # pyyntöä…}}",
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Hyväksy pyyntö} other {Hyväksy pyynnöt}}",
"notification_requests.confirm_accept_multiple.message": "Olet aikeissa hyväksyä {count, plural, one {ilmoituspyynnön} other {# ilmoituspyyntöä}}. Haluatko varmasti jatkaa?",
"notification_requests.confirm_accept_multiple.title": "Hyväksytäänkö ilmoituspyynnöt?",
@ -703,7 +709,7 @@
"notifications.policy.filter_limited_accounts_title": "Moderoidut tilit",
"notifications.policy.filter_new_accounts.hint": "Luotu {days, plural, one {viime päivän} other {viimeisen # päivän}} aikana",
"notifications.policy.filter_new_accounts_title": "Uudet tilit",
"notifications.policy.filter_not_followers_hint": "Mukaan lukien alle {days, plural, one {päivän} other {# päivää}} sinua seuranneet",
"notifications.policy.filter_not_followers_hint": "Mukaan lukien alle {days, plural, one {päivän} other {# päivää}} sinua seuranneet",
"notifications.policy.filter_not_followers_title": "Käyttäjät, jotka eivät seuraa sinua",
"notifications.policy.filter_not_following_hint": "Kunnes hyväksyt heidät manuaalisesti",
"notifications.policy.filter_not_following_title": "Käyttäjät, joita et seuraa",
@ -734,11 +740,11 @@
"poll.closed": "Päättynyt",
"poll.refresh": "Päivitä",
"poll.reveal": "Näytä tulokset",
"poll.total_people": "{count, plural, one {# käyttäjä} other {# käyttäjää}}",
"poll.total_votes": "{count, plural, one {# ääni} other {# ääntä}}",
"poll.total_people": "{count, plural, one {# käyttäjä} other {# käyttäjää}}",
"poll.total_votes": "{count, plural, one {# ääni} other {# ääntä}}",
"poll.vote": "Äänestä",
"poll.voted": "Äänestit tätä vastausta",
"poll.votes": "{votes, plural, one {# ääni} other {# ääntä}}",
"poll.votes": "{votes, plural, one {# ääni} other {# ääntä}}",
"poll_button.add_poll": "Lisää äänestys",
"poll_button.remove_poll": "Poista äänestys",
"privacy.change": "Muuta julkaisun näkyvyyttä",
@ -748,7 +754,7 @@
"privacy.private.short": "Seuraajat",
"privacy.public.long": "Kuka tahansa Mastodonissa ja sen ulkopuolella",
"privacy.public.short": "Julkinen",
"privacy.quote.anyone": "{visibility}, kuka vain voi lainata",
"privacy.quote.anyone": "{visibility}, kuka tahansa voi lainata",
"privacy.quote.disabled": "{visibility}, lainaukset poissa käytöstä",
"privacy.quote.limited": "{visibility}, lainauksia rajoitettu",
"privacy.unlisted.additional": "Tämä toimii muuten kuin julkinen, mutta julkaisut eivät näy livesyöte-, aihetunniste- tai selausnäkymissä eivätkä Mastodonin hakutuloksissa, vaikka ne olisivat käyttäjätililläsi yleisesti sallittuina.",
@ -757,7 +763,8 @@
"privacy_policy.last_updated": "Päivitetty viimeksi {date}",
"privacy_policy.title": "Tietosuojakäytäntö",
"quote_error.edit": "Lainauksia ei voi lisätä julkaisua muokattaessa.",
"quote_error.poll": "Äänestysten lainaaminen ei ole sallittua.",
"quote_error.poll": "Lainaaminen äänestyksen ohessa ei ole sallittua.",
"quote_error.private_mentions": "Lainaaminen ei ole sallittua yksityismaininnoissa.",
"quote_error.quote": "Vain yksi lainaus kerrallaan on sallittu.",
"quote_error.unauthorized": "Sinulla ei ole valtuuksia lainata tätä julkaisua.",
"quote_error.upload": "Medialiitteiden lainaaminen ei ole sallittua.",
@ -765,21 +772,21 @@
"refresh": "Päivitä",
"regeneration_indicator.please_stand_by": "Ole valmiina.",
"regeneration_indicator.preparing_your_home_feed": "Kotisyötettäsi valmistellaan…",
"relative_time.days": "{number} pv",
"relative_time.full.days": "{number, plural, one {# päivä} other {# päivää}} sitten",
"relative_time.full.hours": "{number, plural, one {# tunti} other {# tuntia}} sitten",
"relative_time.days": "{number} pv",
"relative_time.full.days": "{number, plural, one {# päivä} other {# päivää}} sitten",
"relative_time.full.hours": "{number, plural, one {# tunti} other {# tuntia}} sitten",
"relative_time.full.just_now": "juuri nyt",
"relative_time.full.minutes": "{number, plural, one {# minuutti} other {# minuuttia}} sitten",
"relative_time.full.seconds": "{number, plural, one {# sekunti} other {# sekuntia}} sitten",
"relative_time.hours": "{number} t",
"relative_time.full.minutes": "{number, plural, one {# minuutti} other {# minuuttia}} sitten",
"relative_time.full.seconds": "{number, plural, one {# sekunti} other {# sekuntia}} sitten",
"relative_time.hours": "{number} t",
"relative_time.just_now": "nyt",
"relative_time.minutes": "{number} min",
"relative_time.seconds": "{number} s",
"relative_time.minutes": "{number} min",
"relative_time.seconds": "{number} s",
"relative_time.today": "tänään",
"remove_quote_hint.button_label": "Selvä",
"remove_quote_hint.message": "Voit tehdä sen {icon}-valikosta.",
"remove_quote_hint.title": "Haluatko poistaa lainatun julkaisusi?",
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
"reply_indicator.attachments": "{count, plural, one {# liite} other {# liitettä}}",
"reply_indicator.cancel": "Peruuta",
"reply_indicator.poll": "Äänestys",
"report.block": "Estä",
@ -822,7 +829,7 @@
"report.thanks.title_actionable": "Kiitos raportista tutkimme asiaa.",
"report.unfollow": "Lopeta käyttäjän @{name} seuraaminen",
"report.unfollow_explanation": "Seuraat tätä tiliä. Jotta et enää näkisi sen julkaisuja kotisyötteessäsi, lopeta tilin seuraaminen.",
"report_notification.attached_statuses": "{count, plural, one {{count} julkaisu} other {{count} julkaisua}} liitteenä",
"report_notification.attached_statuses": "{count, plural, one {{count} julkaisu} other {{count} julkaisua}} liitteenä",
"report_notification.categories.legal": "Lakiseikat",
"report_notification.categories.legal_sentence": "laiton sisältö",
"report_notification.categories.other": "Muu",
@ -838,11 +845,11 @@
"search.quick_action.account_search": "Profiilit haulla {x}",
"search.quick_action.go_to_account": "Siirry profiiliin {x}",
"search.quick_action.go_to_hashtag": "Siirry aihetunnisteeseen {x}",
"search.quick_action.open_url": "Avaa URL-osoite Mastodonissa",
"search.quick_action.open_url": "Avaa URL-osoite Mastodonissa",
"search.quick_action.status_search": "Julkaisut haulla {x}",
"search.search_or_paste": "Hae tai liitä URL-osoite",
"search.search_or_paste": "Hae tai liitä URL-osoite",
"search_popout.full_text_search_disabled_message": "Ei saatavilla palvelimella {domain}.",
"search_popout.full_text_search_logged_out_message": "Käytettävissä vain sisäänkirjautuneena.",
"search_popout.full_text_search_logged_out_message": "Saatavilla vain sisäänkirjautuneena.",
"search_popout.language_code": "ISO-kielikoodi",
"search_popout.options": "Hakuvalinnat",
"search_popout.quick_actions": "Pikatoiminnot",
@ -892,7 +899,7 @@
"status.direct_indicator": "Yksityismaininta",
"status.edit": "Muokkaa",
"status.edited": "Viimeksi muokattu {date}",
"status.edited_x_times": "Muokattu {count, plural, one {{count} kerran} other {{count} kertaa}}",
"status.edited_x_times": "Muokattu {count, plural, one {{count} kerran} other {{count} kertaa}}",
"status.embed": "Hanki upotuskoodi",
"status.favourite": "Suosikki",
"status.favourites": "{count, plural, one {suosikki} other {suosikkia}}",
@ -911,9 +918,12 @@
"status.pin": "Kiinnitä profiiliin",
"status.quote": "Lainaa",
"status.quote.cancel": "Peruuta lainaus",
"status.quote_error.blocked_account_hint.title": "Tämä julkaisu on piilotettu, koska olet estänyt käyttäjän @{name}.",
"status.quote_error.blocked_domain_hint.title": "Tämä julkaisu on piilotettu, koska olet estänyt verkkotunnuksen {domain}.",
"status.quote_error.filtered": "Piilotettu jonkin asettamasi suodattimen takia",
"status.quote_error.limited_account_hint.action": "Näytä kuitenkin",
"status.quote_error.limited_account_hint.title": "Palvelimen {domain} moderaattorit ovat piilottaneet tämän profiilin.",
"status.quote_error.muted_account_hint.title": "Tämä julkaisu on piilotettu, koska olet mykistänyt käyttäjän @{name}.",
"status.quote_error.not_available": "Julkaisu ei saatavilla",
"status.quote_error.pending_approval": "Julkaisu odottaa",
"status.quote_error.pending_approval_popout.body": "Mastodonissa voit hallita, voiko joku lainata sinua. Tämä julkaisu on vireillä siihen asti, että saamme alkuperäisen tekijän hyväksynnän.",
@ -951,10 +961,10 @@
"status.show_less_all": "Näytä kaikista vähemmän",
"status.show_more_all": "Näytä kaikista enemmän",
"status.show_original": "Näytä alkuperäinen",
"status.title.with_attachments": "{user} liitti {attachmentCount, plural, one {{attachmentCount} tiedoston} other {{attachmentCount} tiedostoa}}",
"status.title.with_attachments": "{user} julkaisi {attachmentCount, plural, one {liitteen} other {{attachmentCount} liitettä}}",
"status.translate": "Käännä",
"status.translated_from_with": "Käännetty kielestä {lang} käyttäen palvelua {provider}",
"status.uncached_media_warning": "Esikatselu ei ole käytettävissä",
"status.translated_from_with": "Käännetty kielestä {lang} palvelulla {provider}",
"status.uncached_media_warning": "Esikatselu ei saatavilla",
"status.unmute_conversation": "Kumoa keskustelun mykistys",
"status.unpin": "Irrota profiilista",
"subscribed_languages.lead": "Vain valituilla kielillä kirjoitetut julkaisut näkyvät koti- ja lista-aikajanoillasi muutoksen jälkeen. Älä valitse mitään, jos haluat nähdä julkaisuja kaikilla kielillä.",
@ -968,17 +978,17 @@
"terms_of_service.effective_as_of": "Tulee voimaan {date}",
"terms_of_service.title": "Käyttöehdot",
"terms_of_service.upcoming_changes_on": "Tulevia muutoksia {date}",
"time_remaining.days": "{number, plural, one {# päivä} other {# päivää}} jäljellä",
"time_remaining.hours": "{number, plural, one {# tunti} other {# tuntia}} jäljellä",
"time_remaining.minutes": "{number, plural, one {# minuutti} other {# minuuttia}} jäljellä",
"time_remaining.days": "{number, plural, one {# päivä} other {# päivää}} jäljellä",
"time_remaining.hours": "{number, plural, one {# tunti} other {# tuntia}} jäljellä",
"time_remaining.minutes": "{number, plural, one {# minuutti} other {# minuuttia}} jäljellä",
"time_remaining.moments": "Hetkiä jäljellä",
"time_remaining.seconds": "{number, plural, one {# sekunti} other {# sekuntia}} jäljellä",
"time_remaining.seconds": "{number, plural, one {# sekunti} other {# sekuntia}} jäljellä",
"trends.counter_by_accounts": "{count, plural, one {{counter} käyttäjä} other {{counter} käyttäjää}} {days, plural, one {viime päivänä} other {viimeisenä {days} päivänä}}",
"trends.trending_now": "Suosittua nyt",
"ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.",
"units.short.billion": "{count} mrd.",
"units.short.million": "{count} milj.",
"units.short.thousand": "{count} t.",
"units.short.billion": "{count} mrd.",
"units.short.million": "{count} milj.",
"units.short.thousand": "{count} t.",
"upload_area.title": "Lähetä raahaamalla ja pudottamalla tähän",
"upload_button.label": "Lisää kuvia, video tai äänitiedosto",
"upload_error.limit": "Tiedostolähetysten rajoitus ylitetty.",
@ -1008,6 +1018,8 @@
"video.volume_down": "Vähennä äänenvoimakkuutta",
"video.volume_up": "Lisää äänenvoimakkuutta",
"visibility_modal.button_title": "Aseta näkyvyys",
"visibility_modal.direct_quote_warning.text": "Jos tallennat nykyiset asetukset, upotettu lainaus muunnetaan linkiksi.",
"visibility_modal.direct_quote_warning.title": "Lainauksia ei voi upottaa yksityismainintoihin",
"visibility_modal.header": "Näkyvyys ja vuorovaikutus",
"visibility_modal.helper.direct_quoting": "Muut eivät voi lainata Mastodonissa kirjoitettuja yksityismainintoja.",
"visibility_modal.helper.privacy_editing": "Näkyvyyttä ei voi muuttaa julkaisun jälkeen.",

View File

@ -1,6 +1,7 @@
{
"about.blocks": "Mga pinatimping server",
"about.contact": "Kontak:",
"about.default_locale": "Default",
"about.disclaimer": "Ang Mastodon ay software na malaya at bukas-na-pinagmulan, at isang tatak-pangkalakal ng Mastodon gGmbH.",
"about.domain_blocks.no_reason_available": "Hindi makuha ang dahilan",
"about.domain_blocks.preamble": "Sa kadalasan, hinahayaan ka ng Mastodon na makita ang mga content sa, at makipag-interact sa users ng, ibang servers sa fediverse. Narito ang exceptions na ginawa sa partikular na server na ito.",
@ -8,6 +9,7 @@
"about.domain_blocks.silenced.title": "Limitado",
"about.domain_blocks.suspended.explanation": "Walang data mula sa server na ito ang mapoproseso, maiimbak o maipagpapaplitan. Sa gayon. imposibleng magawa ang interaksiyon o komunikasyon sa ibang users sa server na ito.",
"about.domain_blocks.suspended.title": "Suspendido",
"about.language_label": "Wika",
"about.not_available": "Hindi available ang impormasyong ito.",
"about.powered_by": "Decentralisadong social media na pinapagana ng {mastodon}",
"about.rules": "Mga alituntunin ng server",
@ -19,21 +21,31 @@
"account.block_domain": "Hadlangan ang domain na {domain}",
"account.block_short": "Hadlangan",
"account.blocked": "Hinadlangan",
"account.blocking": "Pagharang",
"account.cancel_follow_request": "I-kansela ang pagsunod",
"account.copy": "I-sipi ang kawing sa profile",
"account.direct": "Palihim banggitin si @{name}",
"account.disable_notifications": "I-tigil ang pagpapaalam sa akin tuwing nagpopost si @{name}",
"account.domain_blocking": "Pag-block ng domain",
"account.edit_profile": "Baguhin ang profile",
"account.edit_profile_short": "I-edit",
"account.enable_notifications": "Ipaalam sa akin kapag nag-post si @{name}",
"account.endorse": "I-tampok sa profile",
"account.familiar_followers_many": "Sinusundan nina {name1}, {name2}, at {othersCount, plural, one {# iba pa na kilala mo} other {# na iba pa na kilala mo}}",
"account.familiar_followers_one": "Sinusindan ni/ng {name1}",
"account.familiar_followers_two": "Sinusindan nina {name1} at {name2}",
"account.featured": "Itinatampok",
"account.featured.accounts": "Mga Profile",
"account.featured.hashtags": "Mga Hashtag",
"account.featured_tags.last_status_at": "Huling post noong {date}",
"account.featured_tags.last_status_never": "Walang mga post",
"account.follow": "Sundan",
"account.follow_back": "Sundan pabalik",
"account.follow_back_short": "I-follow back",
"account.follow_request": "Humiling na mag-follow",
"account.follow_request_cancel": "I-cancel ang request",
"account.follow_request_cancel_short": "Cancel",
"account.follow_request_short": "Request",
"account.followers": "Mga tagasunod",
"account.followers.empty": "Wala pang sumusunod sa tagagamit na ito.",
"account.followers_counter": "{count, plural, one {{counter} tagasunod} other {{counter} tagasunod}}",
@ -56,15 +68,29 @@
"account.mute_notifications_short": "I-mute ang mga abiso",
"account.mute_short": "I-mute",
"account.muted": "Naka-mute",
"account.muting": "Pag-mute",
"account.mutual": "Pina-follow nyo ang isa't-isa",
"account.no_bio": "Walang nakalaan na paglalarawan.",
"account.open_original_page": "Buksan ang pinagmulang pahina",
"account.posts": "Mga post",
"account.posts_with_replies": "Mga Post at Reply",
"account.remove_from_followers": "Alisin si {name} sa mga follower",
"account.report": "I-ulat si/ang @{name}",
"account.requested_follow": "Hinihiling ni {name} na sundan ka",
"account.requests_to_follow_you": "Mga Request para i-fillow ka",
"account.share": "Ibahagi ang profile ni @{name}",
"account.show_reblogs": "Ipakita ang mga pagpapalakas mula sa/kay {name}",
"account.statuses_counter": "{count,plural,one {{counter} i-post} other {{counter} mga post}}",
"account.unblock": "I-unblock si @{name}",
"account.unblock_domain": "I-unblock ang domain {domain}",
"account.unblock_domain_short": "I-unblock",
"account.unblock_short": "I-unblock",
"account.unendorse": "Huwag itampok sa profile",
"account.unfollow": "Huwag nang sundan",
"account.unmute": "I-unmute si @{name}",
"account.unmute_notifications_short": "I-unmute ang mga notification",
"account.unmute_short": "I-unmute",
"account_note.placeholder": "I-click para magdagdag ng note",
"admin.dashboard.retention.cohort_size": "Mga bagong tagagamit",
"alert.rate_limited.message": "Mangyaring subukan muli pagkatapos ng {retry_time, time, medium}.",
"audio.hide": "Itago ang tunog",

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