mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 07:49:29 +00:00
Compare commits
206 Commits
77a316e475
...
v4.3.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2d65f7142 | ||
|
|
13ab4b54e2 | ||
|
|
df0b641914 | ||
|
|
624b942c2e | ||
|
|
cfa2e0503a | ||
|
|
de945eef63 | ||
|
|
9a7030fb69 | ||
|
|
221da1ba04 | ||
|
|
ff85540904 | ||
|
|
c2862049a2 | ||
|
|
0d69cc068c | ||
|
|
26f25ef4ba | ||
|
|
3b4070cfcc | ||
|
|
eb997c9f0e | ||
|
|
4239baa1f4 | ||
|
|
5532d1c2cb | ||
|
|
3f0d90f019 | ||
|
|
15e1a63e4a | ||
|
|
6b8ff1cf6e | ||
|
|
6cbd217055 | ||
|
|
90c7c1bf7d | ||
|
|
e06448e652 | ||
|
|
3752db3c9a | ||
|
|
cc5c125cc7 | ||
|
|
f65523c5b6 | ||
|
|
5b6b23eeef | ||
|
|
0cbf03efa7 | ||
|
|
90f2c7a1e9 | ||
|
|
f0d734cc6e | ||
|
|
0720ef5f62 | ||
|
|
dc9a106d4c | ||
|
|
c634da32cf | ||
|
|
2d8ce9e19a | ||
|
|
1ddf1aedf1 | ||
|
|
931870ca34 | ||
|
|
7f9b0f36ba | ||
|
|
dd0992b25d | ||
|
|
9b677f099e | ||
|
|
c13b8026f0 | ||
|
|
bf1375ae37 | ||
|
|
b06161dba3 | ||
|
|
a089109b77 | ||
|
|
74f9f7c600 | ||
|
|
ea1b598246 | ||
|
|
dbedd021f5 | ||
|
|
5d79af928c | ||
|
|
a62be22cb1 | ||
|
|
96ffbc05c0 | ||
|
|
39fb314421 | ||
|
|
90f6984ff1 | ||
|
|
9adb96f3a1 | ||
|
|
d5a3478864 | ||
|
|
9877a053f6 | ||
|
|
605ed50603 | ||
|
|
e1609c6813 | ||
|
|
de5d6e98ae | ||
|
|
2b0410f903 | ||
|
|
f7aab0cc2f | ||
|
|
de5f522cc0 | ||
|
|
d728fa9991 | ||
|
|
044dd3f788 | ||
|
|
afc440435c | ||
|
|
d0fb7939bb | ||
|
|
7388a6ce9a | ||
|
|
cd2a3bac79 | ||
|
|
f0e011fbc9 | ||
|
|
acbc273d6e | ||
|
|
1f0c84749d | ||
|
|
e507b4f884 | ||
|
|
93348136a5 | ||
|
|
3a5e83b91a | ||
|
|
8d37565c19 | ||
|
|
177e8fe972 | ||
|
|
198283a188 | ||
|
|
36452845d7 | ||
|
|
5c4bcd2f08 | ||
|
|
a20f38c930 | ||
|
|
b01bd74698 | ||
|
|
41e342a88f | ||
|
|
9258ee8847 | ||
|
|
6d72c13a4d | ||
|
|
ad4be12473 | ||
|
|
527d1253bf | ||
|
|
ae676edc2b | ||
|
|
63df649fe5 | ||
|
|
0ff427fab3 | ||
|
|
dc2f9eef77 | ||
|
|
ff1247ad16 | ||
|
|
fbe55a4545 | ||
|
|
a72819660a | ||
|
|
c292ed07fe | ||
|
|
2d008108a4 | ||
|
|
0c59ef44b1 | ||
|
|
12297faa1d | ||
|
|
9b6f92e47f | ||
|
|
8b6247ca44 | ||
|
|
836cbca469 | ||
|
|
b091e531a5 | ||
|
|
49b3d5692e | ||
|
|
70472de726 | ||
|
|
304e440f88 | ||
|
|
ca68a3cacb | ||
|
|
066efc2d3f | ||
|
|
a2e24ee2de | ||
|
|
ee61f7772a | ||
|
|
5ee72f0e2d | ||
|
|
192e9d16eb | ||
|
|
a3f40309fb | ||
|
|
782a785893 | ||
|
|
9f165436d2 | ||
|
|
592945e498 | ||
|
|
bfb610922d | ||
|
|
480dcecc11 | ||
|
|
2647606a15 | ||
|
|
b40adb4a89 | ||
|
|
f99da81ef8 | ||
|
|
799f507dce | ||
|
|
81472396bc | ||
|
|
a295832960 | ||
|
|
e018e6321f | ||
|
|
f75eb1a8b0 | ||
|
|
de4f7859b4 | ||
|
|
e5e0144957 | ||
|
|
45a520603b | ||
|
|
6ac78ead52 | ||
|
|
c0d3b3de10 | ||
|
|
9e04e46521 | ||
|
|
fa4a82326d | ||
|
|
93fa102f9a | ||
|
|
9ee86a738e | ||
|
|
e272cf5983 | ||
|
|
4382de310c | ||
|
|
94c69bba25 | ||
|
|
ab36c152f9 | ||
|
|
fc5b558b32 | ||
|
|
77ff94d3d2 | ||
|
|
959841ae95 | ||
|
|
f669493d96 | ||
|
|
83b3c50778 | ||
|
|
dc7a42551f | ||
|
|
4a859140ec | ||
|
|
edcf3d9234 | ||
|
|
cae93e79a4 | ||
|
|
83a98cb81a | ||
|
|
889edc560a | ||
|
|
2e0d918d7d | ||
|
|
3b4312476f | ||
|
|
4fba4f8c82 | ||
|
|
25de2f57ee | ||
|
|
026643ab24 | ||
|
|
61e3e81e28 | ||
|
|
354f54907d | ||
|
|
4d611e94ee | ||
|
|
a09a26da49 | ||
|
|
59a8066045 | ||
|
|
3cad5095c9 | ||
|
|
e58d99a771 | ||
|
|
69c76fd94a | ||
|
|
1b6bd585ab | ||
|
|
dfe851b476 | ||
|
|
6d5aa58f88 | ||
|
|
81cd489208 | ||
|
|
55b5364534 | ||
|
|
2e8b752c55 | ||
|
|
d82ffdccbb | ||
|
|
5c72b46a4e | ||
|
|
aa46348c03 | ||
|
|
404f467fcf | ||
|
|
4a2d3929c5 | ||
|
|
ceba0f082e | ||
|
|
7de8d5ffca | ||
|
|
74291dfb77 | ||
|
|
f07707a9bb | ||
|
|
931553844d | ||
|
|
243a85ec8d | ||
|
|
cbf1349370 | ||
|
|
b8fdffe824 | ||
|
|
c91e06bcad | ||
|
|
b2ce9bb4c7 | ||
|
|
19d1392b33 | ||
|
|
09cf617d7f | ||
|
|
784d1bfb29 | ||
|
|
754b03d8cb | ||
|
|
f397550311 | ||
|
|
97db4bd4dd | ||
|
|
1e19242134 | ||
|
|
4e6f13a0fb | ||
|
|
f517f0dbef | ||
|
|
53624b1b54 | ||
|
|
a473988969 | ||
|
|
4ad1e955eb | ||
|
|
66ef4b9984 | ||
|
|
ce2481a81b | ||
|
|
efa74a6c44 | ||
|
|
bdceb1dacf | ||
|
|
e13453aec4 | ||
|
|
25e8a6eaeb | ||
|
|
c828e7731c | ||
|
|
6734b6550f | ||
|
|
6398d7b784 | ||
|
|
1283c3544c | ||
|
|
8ac00533ff | ||
|
|
1b3472bec8 | ||
|
|
c8df7f4995 | ||
|
|
94743fea2c | ||
|
|
deee164acf |
@@ -73,6 +73,16 @@ DB_PORT=5432
|
||||
SECRET_KEY_BASE=
|
||||
OTP_SECRET=
|
||||
|
||||
# Encryption secrets
|
||||
# ------------------
|
||||
# Must be available (and set to same values) for all server processes
|
||||
# These are private/secret values, do not share outside hosting environment
|
||||
# Use `bin/rails db:encryption:init` to generate fresh secrets
|
||||
# Do not change these secrets once in use, as this would cause data loss and other issues
|
||||
# ------------------
|
||||
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
|
||||
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
|
||||
# ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY=
|
||||
|
||||
# Web Push
|
||||
# --------
|
||||
|
||||
6
.github/workflows/build-push-pr.yml
vendored
6
.github/workflows/build-push-pr.yml
vendored
@@ -21,9 +21,11 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
- id: version_vars
|
||||
run: |
|
||||
echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
|
||||
echo mastodon_version_metadata=pr-${{ github.event.pull_request.number }}-$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT
|
||||
echo mastodon_short_sha=$(git rev-parse --short ${{github.event.pull_request.head.sha}}) >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
metadata: ${{ steps.version_vars.outputs.mastodon_version_metadata }}
|
||||
short_sha: ${{ steps.version_vars.outputs.mastodon_short_sha }}
|
||||
|
||||
build-image:
|
||||
needs: compute-suffix
|
||||
@@ -39,6 +41,7 @@ jobs:
|
||||
latest=auto
|
||||
tags: |
|
||||
type=ref,event=pr
|
||||
type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }}
|
||||
secrets: inherit
|
||||
|
||||
build-image-streaming:
|
||||
@@ -55,4 +58,5 @@ jobs:
|
||||
latest=auto
|
||||
tags: |
|
||||
type=ref,event=pr
|
||||
type=ref,event=pr,suffix=-${{ needs.compute-suffix.outputs.short_sha }}
|
||||
secrets: inherit
|
||||
|
||||
2
.github/workflows/build-releases.yml
vendored
2
.github/workflows/build-releases.yml
vendored
@@ -22,7 +22,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.2.') }}
|
||||
latest=${{ startsWith(github.ref, 'refs/tags/v4.3.') }}
|
||||
tags: |
|
||||
type=pep440,pattern={{raw}}
|
||||
type=pep440,pattern=v{{major}}.{{minor}}
|
||||
|
||||
70
.github/workflows/crowdin-download-stable.yml
vendored
Normal file
70
.github/workflows/crowdin-download-stable.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
name: Crowdin / Download translations (stable branches)
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
download-translations-stable:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'glitch-soc/mastodon'
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Increase Git http.postBuffer
|
||||
# This is needed due to a bug in Ubuntu's cURL version?
|
||||
# See https://github.com/orgs/community/discussions/55820
|
||||
run: |
|
||||
git config --global http.version HTTP/1.1
|
||||
git config --global http.postBuffer 157286400
|
||||
|
||||
# Download the translation files from Crowdin
|
||||
- name: crowdin action
|
||||
uses: crowdin/github-action@v2
|
||||
with:
|
||||
config: crowdin-glitch.yml
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
download_translations: true
|
||||
crowdin_branch_name: ${{ github.base_ref || github.ref_name }}
|
||||
push_translations: false
|
||||
create_pull_request: false
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
|
||||
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||
|
||||
# As the files are extracted from a Docker container, they belong to root:root
|
||||
# We need to fix this before the next steps
|
||||
- name: Fix file permissions
|
||||
run: sudo chown -R runner:docker .
|
||||
|
||||
# This is needed to run the normalize step
|
||||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
|
||||
- name: Run i18n normalize task
|
||||
run: bundle exec i18n-tasks normalize
|
||||
|
||||
# Create or update the pull request
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v7.0.5
|
||||
with:
|
||||
commit-message: 'New Crowdin translations'
|
||||
title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)'
|
||||
author: 'GitHub Actions <noreply@github.com>'
|
||||
body: |
|
||||
New Crowdin translations, automated with GitHub Actions
|
||||
|
||||
See `.github/workflows/crowdin-download.yml`
|
||||
|
||||
This PR will be updated every day with new translations.
|
||||
|
||||
Due to a limitation in GitHub Actions, checks are not running on this PR without manual action.
|
||||
If you want to run the checks, then close and re-open it.
|
||||
branch: i18n/crowdin/translations-${{ github.base_ref || github.ref_name }}
|
||||
base: ${{ github.base_ref || github.ref_name }}
|
||||
labels: i18n
|
||||
2
.github/workflows/crowdin-download.yml
vendored
2
.github/workflows/crowdin-download.yml
vendored
@@ -53,7 +53,7 @@ jobs:
|
||||
|
||||
# Create or update the pull request
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v7.0.1
|
||||
uses: peter-evans/create-pull-request@v7.0.5
|
||||
with:
|
||||
commit-message: 'New Crowdin translations'
|
||||
title: 'New Crowdin Translations (automated)'
|
||||
|
||||
3
.github/workflows/crowdin-upload.yml
vendored
3
.github/workflows/crowdin-upload.yml
vendored
@@ -1,7 +1,6 @@
|
||||
name: Crowdin / Upload translations
|
||||
|
||||
on:
|
||||
merge_group:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
@@ -32,7 +31,7 @@ jobs:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
download_translations: false
|
||||
crowdin_branch_name: main
|
||||
crowdin_branch_name: ${{ github.base_ref || github.ref_name }}
|
||||
|
||||
env:
|
||||
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }}
|
||||
|
||||
2
.github/workflows/test-migrations.yml
vendored
2
.github/workflows/test-migrations.yml
vendored
@@ -32,6 +32,8 @@ jobs:
|
||||
postgres:
|
||||
- 14-alpine
|
||||
- 15-alpine
|
||||
- 16-alpine
|
||||
- 17-alpine
|
||||
|
||||
services:
|
||||
postgres:
|
||||
|
||||
8
.github/workflows/test-ruby.yml
vendored
8
.github/workflows/test-ruby.yml
vendored
@@ -143,7 +143,7 @@ jobs:
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg libpam-dev
|
||||
additional-system-dependencies: ffmpeg imagemagick libpam-dev
|
||||
|
||||
- name: Load database schema
|
||||
run: |
|
||||
@@ -245,7 +245,7 @@ jobs:
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg libpam-dev libyaml-dev
|
||||
additional-system-dependencies: ffmpeg libpam-dev
|
||||
|
||||
- name: Load database schema
|
||||
run: './bin/rails db:create db:schema:load db:seed'
|
||||
@@ -325,7 +325,7 @@ jobs:
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg
|
||||
additional-system-dependencies: ffmpeg imagemagick
|
||||
|
||||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
@@ -445,7 +445,7 @@ jobs:
|
||||
uses: ./.github/actions/setup-ruby
|
||||
with:
|
||||
ruby-version: ${{ matrix.ruby-version}}
|
||||
additional-system-dependencies: ffmpeg
|
||||
additional-system-dependencies: ffmpeg imagemagick
|
||||
|
||||
- name: Set up Javascript environment
|
||||
uses: ./.github/actions/setup-javascript
|
||||
|
||||
112
CHANGELOG.md
112
CHANGELOG.md
@@ -2,7 +2,91 @@
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.3.0] - UNRELEASED
|
||||
## [4.3.2] - 2024-12-03
|
||||
|
||||
### Added
|
||||
|
||||
- Add `tootctl feeds vacuum` (#33065 by @ClearlyClaire)
|
||||
- Add error message when user tries to follow their own account (#31910 by @lenikadali)
|
||||
- Add client_secret_expires_at to OAuth Applications (#30317 by @ThisIsMissEm)
|
||||
|
||||
### Changed
|
||||
|
||||
- Change design of Content Warnings and filters (#32543 by @ClearlyClaire)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix processing incoming post edits with mentions to unresolvable accounts (#33129 by @ClearlyClaire)
|
||||
- Fix error when including multiple instances of `embed.js` (#33107 by @YKWeyer)
|
||||
- Fix inactive users' timelines being backfilled on follow and unsuspend (#33094 by @ClearlyClaire)
|
||||
- Fix direct inbox delivery pushing posts into inactive followers' timelines (#33067 by @ClearlyClaire)
|
||||
- Fix `TagFollow` records not being correctly handled in account operations (#33063 by @ClearlyClaire)
|
||||
- Fix pushing hashtag-followed posts to feeds of inactive users (#33018 by @Gargron)
|
||||
- Fix duplicate notifications in notification groups when using slow mode (#33014 by @ClearlyClaire)
|
||||
- Fix posts made in the future being allowed to trend (#32996 by @ClearlyClaire)
|
||||
- Fix uploading higher-than-wide GIF profile picture with libvips enabled (#32911 by @ClearlyClaire)
|
||||
- Fix domain attribution field having autocorrect and autocapitalize enabled (#32903 by @ClearlyClaire)
|
||||
- Fix titles being escaped twice (#32889 by @ClearlyClaire)
|
||||
- Fix list creation limit check (#32869 by @ClearlyClaire)
|
||||
- Fix error in `tootctl email_domain_blocks` when supplying `--with-dns-records` (#32863 by @mjankowski)
|
||||
- Fix `min_id` and `max_id` causing error in search API (#32857 by @Gargron)
|
||||
- Fix inefficiencies when processing removal of posts that use featured tags (#32787 by @ClearlyClaire)
|
||||
- Fix alt-text pop-in not using the translated description (#32766 by @ClearlyClaire)
|
||||
- Fix preview cards with long titles erroneously causing layout changes (#32678 by @ClearlyClaire)
|
||||
- Fix embed modal layout on mobile (#32641 by @DismalShadowX)
|
||||
- Fix and improve batch attachment deletion handling when using OpenStack Swift (#32637 by @hugogameiro)
|
||||
- Fix blocks not being applied on link timeline (#32625 by @tribela)
|
||||
- Fix follow counters being incorrectly changed (#32622 by @oneiros)
|
||||
- Fix 'unknown' media attachment type rendering (#32613 and #32713 by @ThisIsMissEm and @renatolond)
|
||||
- Fix tl language native name (#32606 by @seav)
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependencies
|
||||
|
||||
## [4.3.1] - 2024-10-21
|
||||
|
||||
### Added
|
||||
|
||||
- Add more explicit explanations about author attribution and `fediverse:creator` (#32383 by @ClearlyClaire)
|
||||
- Add ability to group follow notifications in WebUI, can be disabled in the column settings (#32520 by @renchap)
|
||||
- Add back a 6 hours mute duration option (#32522 by @renchap)
|
||||
- Add note about not changing ActiveRecord encryption secrets once they are set (#32413, #32476, #32512, and #32537 by @ClearlyClaire and @mjankowski)
|
||||
|
||||
### Changed
|
||||
|
||||
- Change translation feature to translate to selected regional variant (e.g. pt-BR) if available (#32428 by @c960657)
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove ability to get embed code for remote posts (#32578 by @ClearlyClaire)\
|
||||
Getting the embed code is only reliable for local posts.\
|
||||
It never worked for non-Mastodon servers, and stopped working correctly with the changes made in 4.3.0.\
|
||||
We have therefore decided to remove the menu entry while we investigate solutions.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix follow recommendation moderation page default language when using regional variant (#32580 by @ClearlyClaire)
|
||||
- Fix column-settings spacing in local timeline in advanced view (#32567 by @lindwurm)
|
||||
- Fix broken i18n in text welcome mailer tags area (#32571 by @mjankowski)
|
||||
- Fix missing or incorrect cache-control headers for Streaming server (#32551 by @ThisIsMissEm)
|
||||
- Fix only the first paragraph being displayed in some notifications (#32348 by @ClearlyClaire)
|
||||
- Fix reblog icons on account media view (#32506 by @tribela)
|
||||
- Fix Content-Security-Policy not allowing OpenStack SWIFT object storage URI (#32439 by @kenkiku1021)
|
||||
- Fix back arrow pointing to the incorrect direction in RTL languages (#32485 by @renchap)
|
||||
- Fix streaming server using `REDIS_USERNAME` instead of `REDIS_USER` (#32493 by @ThisIsMissEm)
|
||||
- Fix follow recommendation carrousel scrolling on RTL layouts (#32462 and #32505 by @ClearlyClaire)
|
||||
- Fix follow recommendation suppressions not applying immediately (#32392 by @ClearlyClaire)
|
||||
- Fix language of push notifications (#32415 by @ClearlyClaire)
|
||||
- Fix mute duration not being shown in list of muted accounts in web UI (#32388 by @ClearlyClaire)
|
||||
- Fix “Mark every notification as read” not updating the read marker if scrolled down (#32385 by @ClearlyClaire)
|
||||
- Fix “Mention” appearing for otherwise filtered posts (#32356 by @ClearlyClaire)
|
||||
- Fix notification requests from suspended accounts still being listed (#32354 by @ClearlyClaire)
|
||||
- Fix list edition modal styling (#32358 and #32367 by @ClearlyClaire and @vmstan)
|
||||
- Fix 4 columns barely not fitting on 1920px screen (#32361 by @ClearlyClaire)
|
||||
- Fix icon alignment in applications list (#32293 by @mjankowski)
|
||||
|
||||
## [4.3.0] - 2024-10-08
|
||||
|
||||
The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by @mjankowski.
|
||||
|
||||
@@ -11,12 +95,12 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- **Add confirmation interstitial instead of silently redirecting logged-out visitors to remote resources** (#27792, #28902, and #30651 by @ClearlyClaire and @Gargron)\
|
||||
This fixes a longstanding open redirect in Mastodon, at the cost of added friction when local links to remote resources are shared.
|
||||
- Fix ReDoS vulnerability on some Ruby versions ([GHSA-jpxp-r43f-rhvx](https://github.com/mastodon/mastodon/security/advisories/GHSA-jpxp-r43f-rhvx))
|
||||
- Change `form-action` Content-Security-Policy directive to be more restrictive (#26897 by @ClearlyClaire)
|
||||
- Change `form-action` Content-Security-Policy directive to be more restrictive (#26897 and #32241 by @ClearlyClaire)
|
||||
- Update dependencies
|
||||
|
||||
### Added
|
||||
|
||||
- **Add server-side notification grouping** (#29889, #30576, #30685, #30688, #30707, #30776, #30779, #30781, #30440, #31062, #31098, #31076, #31111, #31123, #31223, #31214, #31224, #31299, #31325, #31347, #31304, #31326, #31384, #31403, #31433, #31509, #31486, #31513, #31592, #31594, #31638, #31746, #31652, #31709, #31725, #31745, #31613, #31657, #31840, #31610, #31929, #32089 and #32085 by @ClearlyClaire, @Gargron, @mgmn, and @renchap)\
|
||||
- **Add server-side notification grouping** (#29889, #30576, #30685, #30688, #30707, #30776, #30779, #30781, #30440, #31062, #31098, #31076, #31111, #31123, #31223, #31214, #31224, #31299, #31325, #31347, #31304, #31326, #31384, #31403, #31433, #31509, #31486, #31513, #31592, #31594, #31638, #31746, #31652, #31709, #31725, #31745, #31613, #31657, #31840, #31610, #31929, #32089, #32085, #32243, #32179 and #32254 by @ClearlyClaire, @Gargron, @mgmn, and @renchap)\
|
||||
Group notifications of the same type for the same target, so that your notifications no longer get cluttered by boost and favorite notifications as soon as a couple of your posts get traction.\
|
||||
This is done server-side so that clients can efficiently get relevant groups without having to go through numerous pages of individual notifications.\
|
||||
As part of this, the visual design of the entire notifications feature has been revamped.\
|
||||
@@ -28,7 +112,7 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- `GET /api/v2/notifications/:group_key/accounts`: https://docs.joinmastodon.org/methods/grouped_notifications/#get-group-accounts
|
||||
- `POST /api/v2/notifications/:group_key/dimsiss`: https://docs.joinmastodon.org/methods/grouped_notifications/#dismiss-group
|
||||
- `GET /api/v2/notifications/:unread_count`: https://docs.joinmastodon.org/methods/grouped_notifications/#unread-group-count
|
||||
- **Add notification policies, filtered notifications and notification requests** (#29366, #29529, #29433, #29565, #29567, #29572, #29575, #29588, #29646, #29652, #29658, #29666, #29693, #29699, #29737, #29706, #29570, #29752, #29810, #29826, #30114, #30251, #30559, #29868, #31008, #31011, #30996, #31149, #31220, #31222, #31225, #31242, #31262, #31250, #31273, #31310, #31316, #31322, #31329, #31324, #31331, #31343, #31342, #31309, #31358, #31378, #31406, #31256, #31456, #31419, #31457, #31508, #31540, #31541, #31723 and #32062 by @ClearlyClaire, @Gargron, @TheEssem, @mgmn, @oneiros, and @renchap)\
|
||||
- **Add notification policies, filtered notifications and notification requests** (#29366, #29529, #29433, #29565, #29567, #29572, #29575, #29588, #29646, #29652, #29658, #29666, #29693, #29699, #29737, #29706, #29570, #29752, #29810, #29826, #30114, #30251, #30559, #29868, #31008, #31011, #30996, #31149, #31220, #31222, #31225, #31242, #31262, #31250, #31273, #31310, #31316, #31322, #31329, #31324, #31331, #31343, #31342, #31309, #31358, #31378, #31406, #31256, #31456, #31419, #31457, #31508, #31540, #31541, #31723, #32062 and #32281 by @ClearlyClaire, @Gargron, @TheEssem, @mgmn, @oneiros, and @renchap)\
|
||||
The old “Block notifications from non-followers”, “Block notifications from people you don't follow” and “Block direct messages from people you don't follow” notification settings have been replaced by a new set of settings found directly in the notification column.\
|
||||
You can now separately filter or drop notifications from people you don't follow, people who don't follow you, accounts created within the past 30 days, as well as unsolicited private mentions, and accounts limited by the moderation.\
|
||||
Instead of being outright dropped, notifications that you chose to filter are put in a separate “Filtered notifications” box that you can review separately without it clogging your main notifications.\
|
||||
@@ -61,13 +145,13 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- **Add timeline of public posts about a trending link** (#30381 and #30840 by @Gargron)\
|
||||
You can now see public posts mentioning currently-trending articles from people who have opted into discovery features.\
|
||||
This adds a new REST API endpoint: https://docs.joinmastodon.org/methods/timelines/#link
|
||||
- **Add author highlight for news articles whose authors are on the fediverse** (#30398, #30670, #30521, #30846, #31819, and #31900 by @Gargron and @oneiros)\
|
||||
- **Add author highlight for news articles whose authors are on the fediverse** (#30398, #30670, #30521, #30846, #31819, #31900 and #32188 by @Gargron, @mjankowski and @oneiros)\
|
||||
This adds a mechanism to [highlight the author of news articles](https://blog.joinmastodon.org/2024/07/highlighting-journalism-on-mastodon/) shared on Mastodon.\
|
||||
Articles hosted outside the fediverse can indicate a fediverse author with a meta tag:
|
||||
```html
|
||||
<meta name="fediverse:creator" content="username@domain" />
|
||||
```
|
||||
On the API side, this is represented by a new `authors` attribute to the `PreviewCard` entity: https://docs.joinmastodon.org/entities/PreviewCard/#authors\
|
||||
On the API side, this is represented by a new `authors` attribute to the `PreviewCard` entity: https://docs.joinmastodon.org/entities/PreviewCard/#authors \
|
||||
Users can allow arbitrary domains to use `fediverse:creator` to credit them by visiting `/settings/verification`.\
|
||||
This is federated as a new `attributionDomains` property in the `http://joinmastodon.org/ns` namespace, containing an array of domain names: https://docs.joinmastodon.org/spec/activitypub/#properties-used-1
|
||||
- **Add in-app notifications for moderation actions and warnings** (#30065, #30082, and #30081 by @ClearlyClaire)\
|
||||
@@ -150,10 +234,12 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- Add groundwork for annual reports for accounts (#28693 by @Gargron)\
|
||||
This lays the groundwork for a “year-in-review”/“wrapped” style report for local users, but is currently not in use.
|
||||
- Add notification email on invalid second authenticator (#28822 by @ClearlyClaire)
|
||||
- Add date of account deletion in list of accounts in the admin interface (#25640 by @tribela)
|
||||
- Add new emojis from `jdecked/twemoji` 15.0 (#28404 by @TheEssem)
|
||||
- Add configurable error handling in attachment batch deletion (#28184 by @vmstan)\
|
||||
This makes the S3 batch size configurable through the `S3_BATCH_DELETE_LIMIT` environment variable (defaults to 1000), and adds some retry logic, configurable through the `S3_BATCH_DELETE_RETRY` environment variable (defaults to 3).
|
||||
- Add VAPID public key to instance serializer (#28006 by @ThisIsMissEm)
|
||||
- Add support for serving JRD `/.well-known/host-meta.json` in addition to XRD host-meta (#32206 by @c960657)
|
||||
- Add `nodeName` and `nodeDescription` to nodeinfo `metadata` (#28079 by @6543)
|
||||
- Add Thai diacritics and tone marks in `HASHTAG_INVALID_CHARS_RE` (#26576 by @ppnplus)
|
||||
- Add variable delay before link verification of remote account links (#27774 by @ClearlyClaire)
|
||||
@@ -168,7 +254,7 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
|
||||
### Changed
|
||||
|
||||
- **Change icons throughout the web interface** (#27385, #27539, #27555, #27579, #27700, #27817, #28519, #28709, #28064, #28775, #28780, #27924, #29294, #29395, #29537, #29569, #29610, #29612, #29649, #29844, #27780, #30974, #30963, #30962, #30961, #31362, #31363, #31359, #31371, #31360, #31512, #31511, and #31525 by @ClearlyClaire, @Gargron, @arbolitoloco1, @mjankowski, @nclm, @renchap, @ronilaukkarinen, and @zunda)\
|
||||
- **Change icons throughout the web interface** (#27385, #27539, #27555, #27579, #27700, #27817, #28519, #28709, #28064, #28775, #28780, #27924, #29294, #29395, #29537, #29569, #29610, #29612, #29649, #29844, #27780, #30974, #30963, #30962, #30961, #31362, #31363, #31359, #31371, #31360, #31512, #31511, #31525, #32153, and #32201 by @ClearlyClaire, @Gargron, @arbolitoloco1, @mjankowski, @nclm, @renchap, @ronilaukkarinen, and @zunda)\
|
||||
This changes all the interface icons from FontAwesome to Material Symbols for a more modern look, consistent with the official Mastodon Android app.\
|
||||
In addition, better care is given to pixel alignment, and icon variants are used to better highlight active/inactive state.
|
||||
- **Change design of compose form in web UI** (#28119, #29059, #29248, #29372, #29384, #29417, #29456, #29406, #29651, #29659, #31889 and #32033 by @ClearlyClaire, @Gargron, @eai04191, @hinaloe, and @ronilaukkarinen)\
|
||||
@@ -192,9 +278,9 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
Administrators may need to update their setup accordingly.
|
||||
- Change how content warnings and filters are displayed in web UI (#31365, and #31761 by @Gargron)
|
||||
- Change preview card processing to ignore `undefined` as canonical url (#31882 by @oneiros)
|
||||
- Change embedded posts to use web UI (#31766 and #32135 by @Gargron)
|
||||
- Change embedded posts to use web UI (#31766, #32135 and #32271 by @Gargron)
|
||||
- Change inner borders in media galleries in web UI (#31852 by @Gargron)
|
||||
- Change design of media attachments and profile media tab in web UI (#31807, #32048, and #31967 by @Gargron)
|
||||
- Change design of media attachments and profile media tab in web UI (#31807, #32048, #31967, #32217, #32224 and #32257 by @ClearlyClaire and @Gargron)
|
||||
- Change labels on thread indicators in web UI (#31806 by @Gargron)
|
||||
- Change label of "Data export" menu item in settings interface (#32099 by @c960657)
|
||||
- Change responsive break points on navigation panel in web UI (#32034 by @Gargron)
|
||||
@@ -284,9 +370,10 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- Fix error when accepting an appeal for sensitive posts deleted in the meantime (#32037 by @ClearlyClaire)
|
||||
- Fix error when encountering reblog of deleted post in feed rebuild (#32001 by @ClearlyClaire)
|
||||
- Fix Safari browser glitch related to horizontal scrolling (#31960 by @Gargron)
|
||||
- Fix unresolvable mentions sometimes preventing processing incoming posts (#29215 by @tribela and @ClearlyClaire)
|
||||
- Fix too many requests caused by relationship look-ups in web UI (#32042 by @Gargron)
|
||||
- Fix links for reblogs in moderation interface (#31979 by @ClearlyClaire)
|
||||
- Fix the appearance of avatars when they do not load (#31966 by @renchap)
|
||||
- Fix the appearance of avatars when they do not load (#31966 and #32270 by @Gargron and @renchap)
|
||||
- Fix spurious error notifications for aborted requests in web UI (#31952 by @c960657)
|
||||
- Fix HTTP 500 error in `/api/v1/polls/:id/votes` when required `choices` parameter is missing (#25598 by @danielmbrasil)
|
||||
- Fix security context sometimes not being added in LD-Signed activities (#31871 by @ClearlyClaire)
|
||||
@@ -309,10 +396,12 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- Fix “Redirect URI” field not being marked as required in “New application” form (#30311 by @ThisIsMissEm)
|
||||
- Fix right-to-left text in preview cards (#30930 by @ClearlyClaire)
|
||||
- Fix rack attack `match_type` value typo in logging config (#30514 by @mjankowski)
|
||||
- Fix various cases of duplicate, missing, or inconsistent borders or scrollbar styles (#31068, #31286, #31268, #31275, #31284, #31305, #31346, #31372, #31373, #31389, #31432, #31391, #31445 and #32091 by @ClearlyClaire, @valtlai and @vmstan)
|
||||
- Fix various cases of duplicate, missing, or inconsistent borders or scrollbar styles (#31068, #31286, #31268, #31275, #31284, #31305, #31346, #31372, #31373, #31389, #31432, #31391, #31445, #32091, #32147 and #32137 by @ClearlyClaire, @mjankowski, @valtlai and @vmstan)
|
||||
- Fix editing description of media uploads with custom thumbnails (#32221 by @ClearlyClaire)
|
||||
- Fix race condition in `POST /api/v1/push/subscription` (#30166 by @ClearlyClaire)
|
||||
- Fix post deletion not being delayed when those are part of an account warning (#30163 by @ClearlyClaire)
|
||||
- Fix rendering error on `/start` when not logged in (#30023 by @timothyjrogers)
|
||||
- Fix unneeded requests to blocked domains when receiving relayed signed activities from them (#31161 by @ClearlyClaire)
|
||||
- Fix logo pushing header buttons out of view on certain conditions in mobile layout (#29787 by @ClearlyClaire)
|
||||
- Fix notification-related records not being reattributed when merging accounts (#29694 by @ClearlyClaire)
|
||||
- Fix results/query in `api/v1/featured_tags/suggestions` (#29597 by @mjankowski)
|
||||
@@ -322,6 +411,7 @@ The following changelog entries focus on changes visible to users, administrator
|
||||
- Fix full date display not respecting the locale 12/24h format (#29448 by @renchap)
|
||||
- Fix filters title and keywords overflow (#29396 by @GeopJr)
|
||||
- Fix incorrect date format in “Follows and followers” (#29390 by @JasonPunyon)
|
||||
- Fix navigation item active highlight for some paths (#32159 by @mjankowski)
|
||||
- Fix “Edit media” modal sizing and layout when space-constrained (#27095 by @ronilaukkarinen)
|
||||
- Fix modal container bounds (#29185 by @nico3333fr)
|
||||
- Fix inefficient HTTP signature parsing using regexps and `StringScanner` (#29133 by @ClearlyClaire)
|
||||
|
||||
120
Gemfile.lock
120
Gemfile.lock
@@ -10,35 +10,35 @@ GIT
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actioncable (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
zeitwerk (~> 2.6)
|
||||
actionmailbox (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
activejob (= 7.1.4)
|
||||
activerecord (= 7.1.4)
|
||||
activestorage (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actionmailbox (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
activejob (= 7.1.4.1)
|
||||
activerecord (= 7.1.4.1)
|
||||
activestorage (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
actionview (= 7.1.4)
|
||||
activejob (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actionmailer (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
actionview (= 7.1.4.1)
|
||||
activejob (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.2)
|
||||
actionpack (7.1.4)
|
||||
actionview (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actionpack (7.1.4.1)
|
||||
actionview (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
nokogiri (>= 1.8.5)
|
||||
racc
|
||||
rack (>= 2.2.4)
|
||||
@@ -46,15 +46,15 @@ GEM
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.2)
|
||||
rails-html-sanitizer (~> 1.6)
|
||||
actiontext (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
activerecord (= 7.1.4)
|
||||
activestorage (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actiontext (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
activerecord (= 7.1.4.1)
|
||||
activestorage (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
actionview (7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.11)
|
||||
rails-dom-testing (~> 2.2)
|
||||
@@ -64,22 +64,22 @@ GEM
|
||||
activemodel (>= 4.1)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||
activejob (7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
activejob (7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
activerecord (7.1.4)
|
||||
activemodel (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
activemodel (7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
activerecord (7.1.4.1)
|
||||
activemodel (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
timeout (>= 0.4.0)
|
||||
activestorage (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
activejob (= 7.1.4)
|
||||
activerecord (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
activestorage (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
activejob (= 7.1.4.1)
|
||||
activerecord (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
marcel (~> 1.0)
|
||||
activesupport (7.1.4)
|
||||
activesupport (7.1.4.1)
|
||||
base64
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
@@ -601,7 +601,7 @@ GEM
|
||||
actionmailer (>= 3)
|
||||
net-smtp
|
||||
premailer (~> 1.7, >= 1.7.9)
|
||||
propshaft (1.0.1)
|
||||
propshaft (1.1.0)
|
||||
actionpack (>= 7.0.0)
|
||||
activesupport (>= 7.0.0)
|
||||
rack
|
||||
@@ -638,20 +638,20 @@ GEM
|
||||
rackup (1.0.0)
|
||||
rack (< 3)
|
||||
webrick
|
||||
rails (7.1.4)
|
||||
actioncable (= 7.1.4)
|
||||
actionmailbox (= 7.1.4)
|
||||
actionmailer (= 7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
actiontext (= 7.1.4)
|
||||
actionview (= 7.1.4)
|
||||
activejob (= 7.1.4)
|
||||
activemodel (= 7.1.4)
|
||||
activerecord (= 7.1.4)
|
||||
activestorage (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
rails (7.1.4.1)
|
||||
actioncable (= 7.1.4.1)
|
||||
actionmailbox (= 7.1.4.1)
|
||||
actionmailer (= 7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
actiontext (= 7.1.4.1)
|
||||
actionview (= 7.1.4.1)
|
||||
activejob (= 7.1.4.1)
|
||||
activemodel (= 7.1.4.1)
|
||||
activerecord (= 7.1.4.1)
|
||||
activestorage (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.1.4)
|
||||
railties (= 7.1.4.1)
|
||||
rails-controller-testing (1.0.5)
|
||||
actionpack (>= 5.0.1.rc1)
|
||||
actionview (>= 5.0.1.rc1)
|
||||
@@ -666,9 +666,9 @@ GEM
|
||||
rails-i18n (7.0.9)
|
||||
i18n (>= 0.7, < 2)
|
||||
railties (>= 6.0.0, < 8)
|
||||
railties (7.1.4)
|
||||
actionpack (= 7.1.4)
|
||||
activesupport (= 7.1.4)
|
||||
railties (7.1.4.1)
|
||||
actionpack (= 7.1.4.1)
|
||||
activesupport (= 7.1.4.1)
|
||||
irb
|
||||
rackup (>= 1.0.0)
|
||||
rake (>= 12.2)
|
||||
@@ -698,7 +698,7 @@ GEM
|
||||
responders (3.1.1)
|
||||
actionpack (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rexml (3.3.7)
|
||||
rexml (3.3.9)
|
||||
rotp (6.3.0)
|
||||
rouge (4.3.0)
|
||||
rpam2 (4.0.2)
|
||||
@@ -748,15 +748,15 @@ GEM
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-capybara (2.21.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-performance (1.21.1)
|
||||
rubocop-performance (1.22.1)
|
||||
rubocop (>= 1.48.1, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rails (2.25.1)
|
||||
rubocop-rails (2.26.2)
|
||||
activesupport (>= 4.2.0)
|
||||
rack (>= 1.1)
|
||||
rubocop (>= 1.33.0, < 2.0)
|
||||
rubocop (>= 1.52.0, < 2.0)
|
||||
rubocop-ast (>= 1.31.1, < 2.0)
|
||||
rubocop-rspec (3.0.4)
|
||||
rubocop-rspec (3.0.5)
|
||||
rubocop (~> 1.61)
|
||||
rubocop-rspec_rails (2.30.0)
|
||||
rubocop (~> 1.61)
|
||||
@@ -884,7 +884,7 @@ GEM
|
||||
webfinger (1.2.0)
|
||||
activesupport
|
||||
httpclient (>= 2.4)
|
||||
webmock (3.23.1)
|
||||
webmock (3.24.0)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
hashdiff (>= 0.4.0, < 2.0.0)
|
||||
|
||||
11
SECURITY.md
11
SECURITY.md
@@ -13,8 +13,9 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | --------- |
|
||||
| 4.2.x | Yes |
|
||||
| 4.1.x | Yes |
|
||||
| < 4.1 | No |
|
||||
| Version | Supported |
|
||||
| ------- | ---------------- |
|
||||
| 4.3.x | Yes |
|
||||
| 4.2.x | Yes |
|
||||
| 4.1.x | Until 2025-04-08 |
|
||||
| < 4.1 | No |
|
||||
|
||||
@@ -6,6 +6,7 @@ class Admin::AnnouncementsController < Admin::BaseController
|
||||
|
||||
def index
|
||||
authorize :announcement, :index?
|
||||
@published_announcements_count = Announcement.published.async_count
|
||||
end
|
||||
|
||||
def new
|
||||
|
||||
@@ -6,6 +6,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController
|
||||
def index
|
||||
authorize :appeal, :index?
|
||||
|
||||
@pending_appeals_count = Appeal.pending.async_count
|
||||
@appeals = filtered_appeals.page(params[:page])
|
||||
end
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ class Admin::Trends::Links::PreviewCardProvidersController < Admin::BaseControll
|
||||
def index
|
||||
authorize :preview_card_provider, :review?
|
||||
|
||||
@pending_preview_card_providers_count = PreviewCardProvider.unreviewed.async_count
|
||||
@preview_card_providers = filtered_preview_card_providers.page(params[:page])
|
||||
@form = Trends::PreviewCardProviderBatch.new
|
||||
end
|
||||
|
||||
@@ -4,6 +4,7 @@ class Admin::Trends::TagsController < Admin::BaseController
|
||||
def index
|
||||
authorize :tag, :review?
|
||||
|
||||
@pending_tags_count = Tag.pending_review.async_count
|
||||
@tags = filtered_tags.page(params[:page])
|
||||
@form = Trends::TagBatch.new
|
||||
end
|
||||
|
||||
@@ -16,6 +16,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
before_action :check_account_confirmation, except: [:index, :create]
|
||||
before_action :check_enabled_registrations, only: [:create]
|
||||
before_action :check_accounts_limit, only: [:index]
|
||||
before_action :check_following_self, only: [:follow]
|
||||
|
||||
skip_before_action :require_authenticated_user!, only: :create
|
||||
|
||||
@@ -101,6 +102,10 @@ class Api::V1::AccountsController < Api::BaseController
|
||||
raise(Mastodon::ValidationError) if account_ids.size > DEFAULT_ACCOUNTS_LIMIT
|
||||
end
|
||||
|
||||
def check_following_self
|
||||
render json: { error: I18n.t('accounts.self_follow_error') }, status: 403 if current_user.account.id == @account.id
|
||||
end
|
||||
|
||||
def relationships(**options)
|
||||
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
|
||||
end
|
||||
|
||||
@@ -52,7 +52,7 @@ class Api::V1::Notifications::RequestsController < Api::BaseController
|
||||
private
|
||||
|
||||
def load_requests
|
||||
requests = NotificationRequest.where(account: current_account).includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
|
||||
requests = NotificationRequest.where(account: current_account).without_suspended.includes(:last_status, from_account: [:account_stat, :user]).to_a_paginated_by_id(
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
params_slice(:max_id, :since_id, :min_id)
|
||||
)
|
||||
|
||||
@@ -23,6 +23,6 @@ class Api::V1::Statuses::TranslationsController < Api::V1::Statuses::BaseControl
|
||||
private
|
||||
|
||||
def set_translation
|
||||
@translation = TranslateStatusService.new.call(@status, content_locale)
|
||||
@translation = TranslateStatusService.new.call(@status, I18n.locale.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ module WebAppControllerConcern
|
||||
policy = ContentSecurityPolicy.new
|
||||
|
||||
if policy.sso_host.present?
|
||||
p.form_action policy.sso_host
|
||||
p.form_action policy.sso_host, -> { "https://#{request.host}/auth/auth/" }
|
||||
else
|
||||
p.form_action :none
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ module Settings
|
||||
end
|
||||
|
||||
def create
|
||||
session[:new_otp_secret] = User.generate_otp_secret(32)
|
||||
session[:new_otp_secret] = User.generate_otp_secret
|
||||
|
||||
redirect_to new_settings_two_factor_authentication_confirmation_path
|
||||
end
|
||||
|
||||
@@ -7,7 +7,23 @@ module WellKnown
|
||||
def show
|
||||
@webfinger_template = "#{webfinger_url}?resource={uri}"
|
||||
expires_in 3.days, public: true
|
||||
render content_type: 'application/xrd+xml', formats: [:xml]
|
||||
|
||||
respond_to do |format|
|
||||
format.any do
|
||||
render content_type: 'application/xrd+xml', formats: [:xml]
|
||||
end
|
||||
|
||||
format.json do
|
||||
render json: {
|
||||
links: [
|
||||
{
|
||||
rel: 'lrdd',
|
||||
template: @webfinger_template,
|
||||
},
|
||||
],
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,4 +35,11 @@ module Admin::ActionLogsHelper
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def sorted_action_log_types
|
||||
Admin::ActionLogFilter::ACTION_TYPE_MAP
|
||||
.keys
|
||||
.map { |key| [I18n.t("admin.action_logs.action_types.#{key}"), key] }
|
||||
.sort_by(&:first)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -18,6 +18,11 @@ module Admin::DashboardHelper
|
||||
end
|
||||
end
|
||||
|
||||
def date_range(range)
|
||||
[l(range.first), l(range.last)]
|
||||
.join(' - ')
|
||||
end
|
||||
|
||||
def relevant_account_timestamp(account)
|
||||
timestamp, exact = if account.user_current_sign_in_at && account.user_current_sign_in_at < 24.hours.ago
|
||||
[account.user_current_sign_in_at, true]
|
||||
@@ -25,6 +30,8 @@ module Admin::DashboardHelper
|
||||
[account.user_current_sign_in_at, false]
|
||||
elsif account.user_pending?
|
||||
[account.user_created_at, true]
|
||||
elsif account.suspended_at.present? && account.local? && account.user.nil?
|
||||
[account.suspended_at, true]
|
||||
elsif account.last_status_at.present?
|
||||
[account.last_status_at, true]
|
||||
else
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationHelper
|
||||
DANGEROUS_SCOPES = %w(
|
||||
read
|
||||
write
|
||||
follow
|
||||
).freeze
|
||||
|
||||
RTL_LOCALES = %i(
|
||||
ar
|
||||
ckb
|
||||
@@ -85,7 +79,7 @@ module ApplicationHelper
|
||||
|
||||
def html_title
|
||||
safe_join(
|
||||
[content_for(:page_title).to_s.chomp, title]
|
||||
[content_for(:page_title), title]
|
||||
.compact_blank,
|
||||
' - '
|
||||
)
|
||||
@@ -95,8 +89,11 @@ module ApplicationHelper
|
||||
Rails.env.production? ? site_title : "#{site_title} (Dev)"
|
||||
end
|
||||
|
||||
def class_for_scope(scope)
|
||||
'scope-danger' if DANGEROUS_SCOPES.include?(scope.to_s)
|
||||
def label_for_scope(scope)
|
||||
safe_join [
|
||||
tag.samp(scope, class: { 'scope-danger' => SessionActivation::DEFAULT_SCOPES.include?(scope.to_s) }),
|
||||
tag.span(t("doorkeeper.scopes.#{scope}"), class: :hint),
|
||||
]
|
||||
end
|
||||
|
||||
def can?(action, record)
|
||||
@@ -244,6 +241,15 @@ module ApplicationHelper
|
||||
full_asset_url(instance_presenter.mascot&.file&.url || frontend_asset_path('images/elephant_ui_plane.svg'))
|
||||
end
|
||||
|
||||
def copyable_input(options = {})
|
||||
tag.input(type: :text, maxlength: 999, spellcheck: false, readonly: true, **options)
|
||||
end
|
||||
|
||||
def recent_tag_usage(tag)
|
||||
people = tag.history.aggregate(2.days.ago.to_date..Time.zone.today).accounts
|
||||
I18n.t 'user_mailer.welcome.hashtags_recent_count', people: number_with_delimiter(people), count: people
|
||||
end
|
||||
|
||||
# glitch-soc addition to handle the multiple flavors
|
||||
def preload_locale_pack
|
||||
supported_locales = Themes.instance.flavour(current_flavour)['locales']
|
||||
|
||||
@@ -162,7 +162,7 @@ module LanguagesHelper
|
||||
th: ['Thai', 'ไทย'].freeze,
|
||||
ti: ['Tigrinya', 'ትግርኛ'].freeze,
|
||||
tk: ['Turkmen', 'Türkmen'].freeze,
|
||||
tl: ['Tagalog', 'Wikang Tagalog'].freeze,
|
||||
tl: ['Tagalog', 'Tagalog'].freeze,
|
||||
tn: ['Tswana', 'Setswana'].freeze,
|
||||
to: ['Tonga', 'faka Tonga'].freeze,
|
||||
tr: ['Turkish', 'Türkçe'].freeze,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WebfingerHelper
|
||||
def webfinger!(uri)
|
||||
Webfinger.new(uri).perform
|
||||
end
|
||||
end
|
||||
@@ -37,8 +37,7 @@ export const synchronouslySubmitMarkers = createAppAsyncThunk(
|
||||
});
|
||||
|
||||
return;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} else if ('navigator' && 'sendBeacon' in navigator) {
|
||||
} else if ('sendBeacon' in navigator) {
|
||||
// Failing that, we can use sendBeacon, but we have to encode the data as
|
||||
// FormData for DoorKeeper to recognize the token.
|
||||
const formData = new FormData();
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { ApiAccountJSON } from 'flavours/glitch/api_types/accounts';
|
||||
import type {
|
||||
ApiNotificationGroupJSON,
|
||||
ApiNotificationJSON,
|
||||
NotificationType,
|
||||
} from 'flavours/glitch/api_types/notifications';
|
||||
import { allNotificationTypes } from 'flavours/glitch/api_types/notifications';
|
||||
import type { ApiStatusJSON } from 'flavours/glitch/api_types/statuses';
|
||||
@@ -15,6 +16,7 @@ import { usePendingItems } from 'flavours/glitch/initial_state';
|
||||
import type { NotificationGap } from 'flavours/glitch/reducers/notification_groups';
|
||||
import {
|
||||
selectSettingsNotificationsExcludedTypes,
|
||||
selectSettingsNotificationsGroupFollows,
|
||||
selectSettingsNotificationsQuickFilterActive,
|
||||
selectSettingsNotificationsShows,
|
||||
} from 'flavours/glitch/selectors/settings';
|
||||
@@ -68,13 +70,19 @@ function dispatchAssociatedRecords(
|
||||
dispatch(importFetchedStatuses(fetchedStatuses));
|
||||
}
|
||||
|
||||
const supportedGroupedNotificationTypes = ['favourite', 'reblog'];
|
||||
function selectNotificationGroupedTypes(state: RootState) {
|
||||
const types: NotificationType[] = ['favourite', 'reblog'];
|
||||
|
||||
if (selectSettingsNotificationsGroupFollows(state)) types.push('follow');
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
export const fetchNotifications = createDataLoadingThunk(
|
||||
'notificationGroups/fetch',
|
||||
async (_params, { getState }) =>
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
({ notifications, accounts, statuses }, { dispatch }) => {
|
||||
@@ -98,7 +106,7 @@ export const fetchNotificationsGap = createDataLoadingThunk(
|
||||
'notificationGroups/fetchGap',
|
||||
async (params: { gap: NotificationGap }, { getState }) =>
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
max_id: params.gap.maxId,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
@@ -115,7 +123,7 @@ export const pollRecentNotifications = createDataLoadingThunk(
|
||||
'notificationGroups/pollRecentNotifications',
|
||||
async (_params, { getState }) => {
|
||||
return apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
max_id: undefined,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
// In slow mode, we don't want to include notifications that duplicate the already-displayed ones
|
||||
@@ -164,7 +172,10 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
|
||||
|
||||
dispatchAssociatedRecords(dispatch, [notification]);
|
||||
|
||||
return notification;
|
||||
return {
|
||||
notification,
|
||||
groupedTypes: selectNotificationGroupedTypes(state),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface ApiAccountRoleJSON {
|
||||
}
|
||||
|
||||
// See app/serializers/rest/account_serializer.rb
|
||||
export interface ApiAccountJSON {
|
||||
export interface BaseApiAccountJSON {
|
||||
acct: string;
|
||||
avatar: string;
|
||||
avatar_static: string;
|
||||
@@ -45,3 +45,12 @@ export interface ApiAccountJSON {
|
||||
memorial?: boolean;
|
||||
hide_collections: boolean;
|
||||
}
|
||||
|
||||
// See app/serializers/rest/muted_account_serializer.rb
|
||||
export interface ApiMutedAccountJSON extends BaseApiAccountJSON {
|
||||
mute_expires_at?: string | null;
|
||||
}
|
||||
|
||||
// For now, we have the same type representing both `Account` and `MutedAccount`
|
||||
// objects, but we should refactor this in the future.
|
||||
export type ApiAccountJSON = ApiMutedAccountJSON;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { useHovering } from 'flavours/glitch/hooks/useHovering';
|
||||
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
||||
import type { Account } from 'flavours/glitch/models/account';
|
||||
|
||||
import { useHovering } from '../hooks/useHovering';
|
||||
import { autoPlayGif } from '../initial_state';
|
||||
|
||||
interface Props {
|
||||
account: Account | undefined; // FIXME: remove `undefined` once we know for sure its always there
|
||||
size: number;
|
||||
@@ -25,6 +26,8 @@ export const Avatar: React.FC<Props> = ({
|
||||
counterBorderColor,
|
||||
}) => {
|
||||
const { hovering, handleMouseEnter, handleMouseLeave } = useHovering(animate);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const style = {
|
||||
...styleFromParent,
|
||||
@@ -37,17 +40,29 @@ export const Avatar: React.FC<Props> = ({
|
||||
? account?.get('avatar')
|
||||
: account?.get('avatar_static');
|
||||
|
||||
const handleLoad = useCallback(() => {
|
||||
setLoading(false);
|
||||
}, [setLoading]);
|
||||
|
||||
const handleError = useCallback(() => {
|
||||
setError(true);
|
||||
}, [setError]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('account__avatar', {
|
||||
'account__avatar-inline': inline,
|
||||
'account__avatar--inline': inline,
|
||||
'account__avatar--loading': loading,
|
||||
})}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
style={style}
|
||||
data-avatar-of={account && `@${account.get('acct')}`}
|
||||
>
|
||||
{src && <img src={src} alt='' />}
|
||||
{src && !error && (
|
||||
<img src={src} alt='' onLoad={handleLoad} onError={handleError} />
|
||||
)}
|
||||
|
||||
{counter && (
|
||||
<div
|
||||
className='account__avatar__counter'
|
||||
|
||||
@@ -19,6 +19,7 @@ export const CollapseButton = ({ collapsed, setCollapsed }) => {
|
||||
if (e.button === 0) {
|
||||
setCollapsed(!collapsed);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, [collapsed, setCollapsed]);
|
||||
|
||||
|
||||
@@ -17,9 +17,15 @@ export const ContentWarning: React.FC<{
|
||||
aria-expanded={expanded}
|
||||
>
|
||||
{expanded ? (
|
||||
<FormattedMessage id='status.show_less' defaultMessage='Show less' />
|
||||
<FormattedMessage
|
||||
id='content_warning.hide'
|
||||
defaultMessage='Hide post'
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage id='status.show_more' defaultMessage='Show more' />
|
||||
<FormattedMessage
|
||||
id='content_warning.show_more'
|
||||
defaultMessage='Show more'
|
||||
/>
|
||||
)}
|
||||
{icons}
|
||||
</button>
|
||||
|
||||
@@ -10,13 +10,16 @@ export const FilterWarning: React.FC<{
|
||||
<StatusBanner
|
||||
expanded={expanded}
|
||||
onClick={onClick}
|
||||
variant={BannerVariant.Blue}
|
||||
variant={BannerVariant.Filter}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='filter_warning.matches_filter'
|
||||
defaultMessage='Matches filter “{title}”'
|
||||
values={{ title }}
|
||||
defaultMessage='Matches filter “<span>{title}</span>”'
|
||||
values={{
|
||||
title,
|
||||
span: (chunks) => <span className='filter-name'>{chunks}</span>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</StatusBanner>
|
||||
|
||||
@@ -98,12 +98,12 @@ class Item extends PureComponent {
|
||||
height = 50;
|
||||
}
|
||||
|
||||
if (attachment.get('description')?.length > 0) {
|
||||
badges.push(<AltTextBadge key='alt' description={attachment.get('description')} />);
|
||||
}
|
||||
|
||||
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
|
||||
|
||||
if (description?.length > 0) {
|
||||
badges.push(<AltTextBadge key='alt' description={description} />);
|
||||
}
|
||||
|
||||
if (attachment.get('type') === 'unknown') {
|
||||
return (
|
||||
<div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
|
||||
@@ -198,7 +198,7 @@ class Item extends PureComponent {
|
||||
|
||||
{visible && thumbnail}
|
||||
|
||||
{badges && (
|
||||
{visible && badges && (
|
||||
<div className='media-gallery__item__badges'>
|
||||
{badges}
|
||||
</div>
|
||||
@@ -356,14 +356,14 @@ class MediaGallery extends PureComponent {
|
||||
|
||||
return (
|
||||
<div className={computedClass} style={style} ref={this.handleRef}>
|
||||
{children}
|
||||
|
||||
{(!visible || uncached) && (
|
||||
<div className={classNames('spoiler-button', { 'spoiler-button--click-thru': uncached })}>
|
||||
{spoilerButton}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{children}
|
||||
|
||||
{(visible && !uncached) && (
|
||||
<div className='media-gallery__actions'>
|
||||
<button className='media-gallery__actions__pill' onClick={this.handleOpen}><FormattedMessage id='media_gallery.hide' defaultMessage='Hide' /></button>
|
||||
|
||||
@@ -372,26 +372,29 @@ class Status extends ImmutablePureComponent {
|
||||
const { isCollapsed } = this.state;
|
||||
if (!history) return;
|
||||
|
||||
if (e.button === 0 && !(e.ctrlKey || e.altKey || e.metaKey)) {
|
||||
if (isCollapsed) this.setCollapsed(false);
|
||||
else if (e.shiftKey) {
|
||||
this.setCollapsed(true);
|
||||
document.getSelection().removeAllRanges();
|
||||
} else if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
return;
|
||||
} else {
|
||||
if (destination === undefined) {
|
||||
destination = `/@${
|
||||
status.getIn(['reblog', 'account', 'acct'], status.getIn(['account', 'acct']))
|
||||
}/${
|
||||
status.getIn(['reblog', 'id'], status.get('id'))
|
||||
}`;
|
||||
}
|
||||
history.push(destination);
|
||||
}
|
||||
e.preventDefault();
|
||||
if (e.button !== 0 || e.ctrlKey || e.altKey || e.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isCollapsed) this.setCollapsed(false);
|
||||
else if (e.shiftKey) {
|
||||
this.setCollapsed(true);
|
||||
document.getSelection().removeAllRanges();
|
||||
} else if (this.props.onClick) {
|
||||
this.props.onClick();
|
||||
return;
|
||||
} else {
|
||||
if (destination === undefined) {
|
||||
destination = `/@${
|
||||
status.getIn(['reblog', 'account', 'acct'], status.getIn(['account', 'acct']))
|
||||
}/${
|
||||
status.getIn(['reblog', 'id'], status.get('id'))
|
||||
}`;
|
||||
}
|
||||
history.push(destination);
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
handleToggleMediaVisibility = () => {
|
||||
@@ -648,7 +651,7 @@ class Status extends ImmutablePureComponent {
|
||||
media={status.get('media_attachments')}
|
||||
/>,
|
||||
);
|
||||
} else if (['image', 'gifv'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
|
||||
} else if (['image', 'gifv', 'unknown'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
|
||||
media.push(
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
|
||||
{Component => (
|
||||
@@ -806,7 +809,8 @@ class Status extends ImmutablePureComponent {
|
||||
{(connectReply || connectUp || connectToRoot) && <div className={classNames('status__line', { 'status__line--full': connectReply, 'status__line--first': !status.get('in_reply_to_id') && !connectToRoot })} />}
|
||||
|
||||
{(!muted || !isCollapsed) && (
|
||||
<header className='status__info'>
|
||||
/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */
|
||||
<header onClick={this.parseClick} className='status__info'>
|
||||
<StatusHeader
|
||||
status={status}
|
||||
friend={account}
|
||||
|
||||
@@ -233,7 +233,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
menu.push({ text: intl.formatMessage(messages.share), action: this.handleShareClick });
|
||||
}
|
||||
|
||||
if (publicStatus && (signedIn || !isRemote)) {
|
||||
if (publicStatus && !isRemote) {
|
||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
export enum BannerVariant {
|
||||
Yellow = 'yellow',
|
||||
Blue = 'blue',
|
||||
Warning = 'warning',
|
||||
Filter = 'filter',
|
||||
}
|
||||
|
||||
export const StatusBanner: React.FC<{
|
||||
@@ -11,9 +11,9 @@ export const StatusBanner: React.FC<{
|
||||
expanded?: boolean;
|
||||
onClick?: () => void;
|
||||
}> = ({ children, variant, expanded, onClick }) => (
|
||||
<div
|
||||
<label
|
||||
className={
|
||||
variant === BannerVariant.Yellow
|
||||
variant === BannerVariant.Warning
|
||||
? 'content-warning'
|
||||
: 'content-warning content-warning--filter'
|
||||
}
|
||||
@@ -26,6 +26,11 @@ export const StatusBanner: React.FC<{
|
||||
id='content_warning.hide'
|
||||
defaultMessage='Hide post'
|
||||
/>
|
||||
) : variant === BannerVariant.Warning ? (
|
||||
<FormattedMessage
|
||||
id='content_warning.show_more'
|
||||
defaultMessage='Show more'
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id='content_warning.show'
|
||||
@@ -33,5 +38,5 @@ export const StatusBanner: React.FC<{
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
|
||||
@@ -18,15 +18,10 @@ export default class StatusHeader extends PureComponent {
|
||||
parseClick: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
// Handles clicks on account name/image
|
||||
handleClick = (acct, e) => {
|
||||
const { parseClick } = this.props;
|
||||
parseClick(e, `/@${acct}`);
|
||||
};
|
||||
|
||||
handleAccountClick = (e) => {
|
||||
const { status } = this.props;
|
||||
this.handleClick(status.getIn(['account', 'acct']), e);
|
||||
const { status, parseClick } = this.props;
|
||||
parseClick(e, `/@${status.getIn(['account', 'acct'])}`);
|
||||
e.stopPropagation();
|
||||
};
|
||||
|
||||
// Rendering.
|
||||
|
||||
@@ -27,15 +27,19 @@ class ColumnSettings extends PureComponent {
|
||||
|
||||
return (
|
||||
<div className='column-settings'>
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
|
||||
</div>
|
||||
<section>
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||
<section>
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingText settings={settings} settingPath={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
||||
</div>
|
||||
<div className='column-settings__row'>
|
||||
<SettingText settings={settings} settingPath={['regex', 'body']} onChange={onChange} label={intl.formatMessage(messages.filter_regex)} />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -129,8 +129,13 @@ export const InlineFollowSuggestions = ({ hidden }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
if (getComputedStyle(bodyRef.current).direction === 'rtl') {
|
||||
setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth);
|
||||
setCanScrollRight(bodyRef.current.scrollLeft < 0);
|
||||
} else {
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
}
|
||||
}, [setCanScrollRight, setCanScrollLeft, bodyRef, suggestions]);
|
||||
|
||||
const handleLeftNav = useCallback(() => {
|
||||
@@ -146,8 +151,13 @@ export const InlineFollowSuggestions = ({ hidden }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
if (getComputedStyle(bodyRef.current).direction === 'rtl') {
|
||||
setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth);
|
||||
setCanScrollRight(bodyRef.current.scrollLeft < 0);
|
||||
} else {
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
}
|
||||
}, [setCanScrollRight, setCanScrollLeft, bodyRef]);
|
||||
|
||||
const handleDismiss = useCallback(() => {
|
||||
|
||||
@@ -40,6 +40,7 @@ class ColumnSettings extends PureComponent {
|
||||
const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
|
||||
const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
|
||||
const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
|
||||
const groupStr = <FormattedMessage id='notifications.column_settings.group' defaultMessage='Group' />;
|
||||
|
||||
const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed');
|
||||
const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
|
||||
@@ -96,6 +97,10 @@ class ColumnSettings extends PureComponent {
|
||||
<PillBarButton prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} />
|
||||
<PillBarButton prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['group', 'follow']} onChange={onChange} label={groupStr} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section role='group' aria-labelledby='notifications-follow-request'>
|
||||
|
||||
@@ -56,11 +56,12 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
} else {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
}
|
||||
} else if(path[0] === 'groupingBeta') {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
dispatch(initializeNotifications());
|
||||
} else {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
|
||||
if(path[0] === 'group' && path[1] === 'follow') {
|
||||
dispatch(initializeNotifications());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react';
|
||||
import { FollowersCounter } from 'flavours/glitch/components/counters';
|
||||
import { FollowButton } from 'flavours/glitch/components/follow_button';
|
||||
import { ShortNumber } from 'flavours/glitch/components/short_number';
|
||||
import { me } from 'flavours/glitch/initial_state';
|
||||
import type { NotificationGroupFollow } from 'flavours/glitch/models/notification_group';
|
||||
import { useAppSelector } from 'flavours/glitch/store';
|
||||
|
||||
import type { LabelRenderer } from './notification_group_with_status';
|
||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||
|
||||
const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||
const labelRenderer: LabelRenderer = (displayedName, total, seeMoreHref) => {
|
||||
if (total === 1)
|
||||
return (
|
||||
<FormattedMessage
|
||||
@@ -23,10 +26,12 @@ const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='notification.follow.name_and_others'
|
||||
defaultMessage='{name} and {count, plural, one {# other} other {# others}} followed you'
|
||||
defaultMessage='{name} and <a>{count, plural, one {# other} other {# others}}</a> followed you'
|
||||
values={{
|
||||
name: displayedName,
|
||||
count: total - 1,
|
||||
a: (chunks) =>
|
||||
seeMoreHref ? <Link to={seeMoreHref}>{chunks}</Link> : chunks,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -46,6 +51,10 @@ export const NotificationFollow: React.FC<{
|
||||
notification: NotificationGroupFollow;
|
||||
unread: boolean;
|
||||
}> = ({ notification, unread }) => {
|
||||
const username = useAppSelector(
|
||||
(state) => state.accounts.getIn([me, 'username']) as string,
|
||||
);
|
||||
|
||||
let actions: JSX.Element | undefined;
|
||||
let additionalContent: JSX.Element | undefined;
|
||||
|
||||
@@ -68,6 +77,7 @@ export const NotificationFollow: React.FC<{
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
count={notification.notifications_count}
|
||||
labelRenderer={labelRenderer}
|
||||
labelSeeMoreHref={`/@${username}/followers`}
|
||||
unread={unread}
|
||||
actions={actions}
|
||||
additionalContent={additionalContent}
|
||||
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import type { IconProp } from 'flavours/glitch/components/icon';
|
||||
import { Icon } from 'flavours/glitch/components/icon';
|
||||
import Status from 'flavours/glitch/containers/status_container';
|
||||
import { getStatusHidden } from 'flavours/glitch/selectors/filters';
|
||||
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
|
||||
|
||||
import { DisplayedName } from './displayed_name';
|
||||
@@ -51,6 +52,12 @@ export const NotificationWithStatus: React.FC<{
|
||||
(state) => state.statuses.getIn([statusId, 'visibility']) === 'direct',
|
||||
);
|
||||
|
||||
const isFiltered = useAppSelector(
|
||||
(state) =>
|
||||
statusId &&
|
||||
getStatusHidden(state, { id: statusId, contextType: 'notifications' }),
|
||||
);
|
||||
|
||||
const handlers = useMemo(
|
||||
() => ({
|
||||
open: () => {
|
||||
@@ -77,7 +84,7 @@ export const NotificationWithStatus: React.FC<{
|
||||
[dispatch, statusId],
|
||||
);
|
||||
|
||||
if (!statusId) return null;
|
||||
if (!statusId || isFiltered) return null;
|
||||
|
||||
return (
|
||||
<HotKeys handlers={handlers}>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Icon } from 'flavours/glitch/components/icon';
|
||||
import {
|
||||
selectSettingsNotificationsQuickFilterActive,
|
||||
selectSettingsNotificationsQuickFilterAdvanced,
|
||||
selectSettingsNotificationsQuickFilterShow,
|
||||
} from 'flavours/glitch/selectors/settings';
|
||||
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||
|
||||
@@ -65,6 +66,11 @@ export const FilterBar: React.FC = () => {
|
||||
const advancedMode = useAppSelector(
|
||||
selectSettingsNotificationsQuickFilterAdvanced,
|
||||
);
|
||||
const useFilterBar = useAppSelector(
|
||||
selectSettingsNotificationsQuickFilterShow,
|
||||
);
|
||||
|
||||
if (!useFilterBar) return null;
|
||||
|
||||
if (advancedMode)
|
||||
return (
|
||||
|
||||
@@ -14,6 +14,8 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react';
|
||||
import StarIcon from '@/material-icons/400-24px/star.svg?react';
|
||||
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
|
||||
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
|
||||
import { replyCompose } from 'flavours/glitch/actions/compose';
|
||||
import { toggleReblog, toggleFavourite } from 'flavours/glitch/actions/interactions';
|
||||
import { openModal } from 'flavours/glitch/actions/modal';
|
||||
@@ -161,16 +163,20 @@ class Footer extends ImmutablePureComponent {
|
||||
replyTitle = intl.formatMessage(messages.replyAll);
|
||||
}
|
||||
|
||||
let reblogTitle = '';
|
||||
let reblogTitle, reblogIconComponent;
|
||||
|
||||
if (status.get('reblogged')) {
|
||||
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
||||
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon;
|
||||
} else if (publicStatus) {
|
||||
reblogTitle = intl.formatMessage(messages.reblog);
|
||||
reblogIconComponent = RepeatIcon;
|
||||
} else if (reblogPrivate) {
|
||||
reblogTitle = intl.formatMessage(messages.reblog_private);
|
||||
reblogIconComponent = RepeatPrivateIcon;
|
||||
} else {
|
||||
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
||||
reblogIconComponent = RepeatDisabledIcon;
|
||||
}
|
||||
|
||||
let replyButton = null;
|
||||
@@ -201,7 +207,7 @@ class Footer extends ImmutablePureComponent {
|
||||
return (
|
||||
<div className='picture-in-picture__footer'>
|
||||
{replyButton}
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={reblogIconComponent} onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={StarIcon} onClick={this.handleFavouriteClick} counter={status.get('favourites_count')} />
|
||||
{withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' iconComponent={OpenInNewIcon} onClick={this.handleOpenClick} href={status.get('url')} />}
|
||||
</div>
|
||||
|
||||
@@ -196,7 +196,7 @@ export const DetailedStatus: React.FC<{
|
||||
) {
|
||||
media.push(<AttachmentList media={status.get('media_attachments')} />);
|
||||
} else if (
|
||||
['image', 'gifv'].includes(
|
||||
['image', 'gifv', 'unknown'].includes(
|
||||
status.getIn(['media_attachments', 0, 'type']) as string,
|
||||
) ||
|
||||
status.get('media_attachments').size > 1
|
||||
@@ -259,6 +259,7 @@ export const DetailedStatus: React.FC<{
|
||||
src={attachment.get('url')}
|
||||
alt={description}
|
||||
lang={language}
|
||||
inline
|
||||
width={300}
|
||||
height={150}
|
||||
onOpenVideo={handleOpenVideo}
|
||||
|
||||
@@ -116,6 +116,7 @@ export const MuteModal = ({ accountId, acct }) => {
|
||||
<div className='safety-action-modal__bottom__collapsible'>
|
||||
<div className='safety-action-modal__field-group'>
|
||||
<RadioButtonLabel name='duration' value='0' label={intl.formatMessage(messages.indefinite)} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='21600' label={intl.formatMessage(messages.hours, { number: 6 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='86400' label={intl.formatMessage(messages.hours, { number: 24 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='604800' label={intl.formatMessage(messages.days, { number: 7 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='2592000' label={intl.formatMessage(messages.days, { number: 30 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Permalink } from 'flavours/glitch/components/permalink';
|
||||
import { PictureInPicture } from 'flavours/glitch/features/picture_in_picture';
|
||||
import { identityContextPropShape, withIdentity } from 'flavours/glitch/identity_context';
|
||||
import { layoutFromWindow } from 'flavours/glitch/is_mobile';
|
||||
import { selectUnreadNotificationGroupsCount } from 'flavours/glitch/selectors/notifications';
|
||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||
|
||||
import { uploadCompose, resetCompose, changeComposeSpoilerness } from '../../actions/compose';
|
||||
@@ -90,7 +91,7 @@ const mapStateToProps = state => ({
|
||||
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4,
|
||||
isWide: state.getIn(['local_settings', 'stretch']),
|
||||
unreadNotifications: state.getIn(['notifications', 'unread']),
|
||||
unreadNotifications: selectUnreadNotificationGroupsCount(state),
|
||||
showFaviconBadge: state.getIn(['local_settings', 'notifications', 'favicon_badge']),
|
||||
hicolorPrivacyIcons: state.getIn(['local_settings', 'hicolor_privacy_icons']),
|
||||
moved: state.getIn(['accounts', me, 'moved']) && state.getIn(['accounts', state.getIn(['accounts', me, 'moved'])]),
|
||||
|
||||
@@ -154,7 +154,5 @@
|
||||
"status.is_poll": "This toot is a poll",
|
||||
"status.local_only": "Only visible from your instance",
|
||||
"status.show_filter_reason": "Show anyway",
|
||||
"status.show_less": "Show less",
|
||||
"status.show_more": "Show more",
|
||||
"status.uncollapse": "Uncollapse"
|
||||
}
|
||||
|
||||
@@ -95,6 +95,9 @@ export const accountDefaultValues: AccountShape = {
|
||||
limited: false,
|
||||
moved: null,
|
||||
hide_collections: false,
|
||||
// This comes from `ApiMutedAccountJSON`, but we should eventually
|
||||
// store that in a different object.
|
||||
mute_expires_at: null,
|
||||
};
|
||||
|
||||
const AccountFactory = ImmutableRecord<AccountShape>(accountDefaultValues);
|
||||
|
||||
@@ -16,6 +16,7 @@ export const NOTIFICATIONS_GROUP_MAX_AVATARS = 8;
|
||||
interface BaseNotificationGroup
|
||||
extends Omit<BaseNotificationGroupJSON, 'sample_account_ids'> {
|
||||
sampleAccountIds: string[];
|
||||
partial: boolean;
|
||||
}
|
||||
|
||||
interface BaseNotificationWithStatus<Type extends NotificationWithStatusType>
|
||||
@@ -128,6 +129,7 @@ export function createNotificationGroupFromJSON(
|
||||
return {
|
||||
statusId: statusId ?? undefined,
|
||||
sampleAccountIds,
|
||||
partial: false,
|
||||
...groupWithoutStatus,
|
||||
};
|
||||
}
|
||||
@@ -136,12 +138,14 @@ export function createNotificationGroupFromJSON(
|
||||
return {
|
||||
report: createReportFromJSON(report),
|
||||
sampleAccountIds,
|
||||
partial: false,
|
||||
...groupWithoutTargetAccount,
|
||||
};
|
||||
}
|
||||
case 'severed_relationships':
|
||||
return {
|
||||
...group,
|
||||
partial: false,
|
||||
event: createAccountRelationshipSeveranceEventFromJSON(group.event),
|
||||
sampleAccountIds,
|
||||
};
|
||||
@@ -150,13 +154,16 @@ export function createNotificationGroupFromJSON(
|
||||
const { moderation_warning, ...groupWithoutModerationWarning } = group;
|
||||
return {
|
||||
...groupWithoutModerationWarning,
|
||||
partial: false,
|
||||
moderationWarning: createAccountWarningFromJSON(moderation_warning),
|
||||
sampleAccountIds,
|
||||
};
|
||||
}
|
||||
|
||||
default:
|
||||
return {
|
||||
sampleAccountIds,
|
||||
partial: false,
|
||||
...group,
|
||||
};
|
||||
}
|
||||
@@ -164,17 +171,17 @@ export function createNotificationGroupFromJSON(
|
||||
|
||||
export function createNotificationGroupFromNotificationJSON(
|
||||
notification: ApiNotificationJSON,
|
||||
) {
|
||||
): NotificationGroup {
|
||||
const group = {
|
||||
sampleAccountIds: [notification.account.id],
|
||||
group_key: notification.group_key,
|
||||
notifications_count: 1,
|
||||
type: notification.type,
|
||||
most_recent_notification_id: notification.id,
|
||||
page_min_id: notification.id,
|
||||
page_max_id: notification.id,
|
||||
latest_page_notification_at: notification.created_at,
|
||||
} as NotificationGroup;
|
||||
partial: true,
|
||||
};
|
||||
|
||||
switch (notification.type) {
|
||||
case 'favourite':
|
||||
@@ -183,12 +190,21 @@ export function createNotificationGroupFromNotificationJSON(
|
||||
case 'mention':
|
||||
case 'poll':
|
||||
case 'update':
|
||||
return { ...group, statusId: notification.status?.id };
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
statusId: notification.status?.id,
|
||||
};
|
||||
case 'admin.report':
|
||||
return { ...group, report: createReportFromJSON(notification.report) };
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
report: createReportFromJSON(notification.report),
|
||||
};
|
||||
case 'severed_relationships':
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
event: createAccountRelationshipSeveranceEventFromJSON(
|
||||
notification.event,
|
||||
),
|
||||
@@ -196,11 +212,15 @@ export function createNotificationGroupFromNotificationJSON(
|
||||
case 'moderation_warning':
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
moderationWarning: createAccountWarningFromJSON(
|
||||
notification.moderation_warning,
|
||||
),
|
||||
};
|
||||
default:
|
||||
return group;
|
||||
return {
|
||||
...group,
|
||||
type: notification.type,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,10 @@ export const accountsReducer: Reducer<typeof initialState> = (
|
||||
return state.setIn([action.payload.id, 'hidden'], false);
|
||||
else if (importAccounts.match(action))
|
||||
return normalizeAccounts(state, action.payload.accounts);
|
||||
else if (followAccountSuccess.match(action)) {
|
||||
else if (
|
||||
followAccountSuccess.match(action) &&
|
||||
!action.payload.alreadyFollowing
|
||||
) {
|
||||
return state
|
||||
.update(action.payload.relationship.id, (account) =>
|
||||
account?.update('followers_count', (n) => n + 1),
|
||||
|
||||
@@ -507,7 +507,7 @@ export default function compose(state = initialState, action) {
|
||||
.set('isUploadingThumbnail', false)
|
||||
.update('media_attachments', list => list.map(item => {
|
||||
if (item.get('id') === action.media.id) {
|
||||
return fromJS(action.media);
|
||||
return fromJS(action.media).set('unattached', item.get('unattached'));
|
||||
}
|
||||
|
||||
return item;
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
import type {
|
||||
ApiNotificationJSON,
|
||||
ApiNotificationGroupJSON,
|
||||
NotificationType,
|
||||
} from 'flavours/glitch/api_types/notifications';
|
||||
import { compareId } from 'flavours/glitch/compare_id';
|
||||
import { usePendingItems } from 'flavours/glitch/initial_state';
|
||||
@@ -204,7 +205,15 @@ function mergeGapsAround(
|
||||
function processNewNotification(
|
||||
groups: NotificationGroupsState['groups'],
|
||||
notification: ApiNotificationJSON,
|
||||
groupedTypes: NotificationType[],
|
||||
) {
|
||||
if (!groupedTypes.includes(notification.type)) {
|
||||
notification = {
|
||||
...notification,
|
||||
group_key: `ungrouped-${notification.id}`,
|
||||
};
|
||||
}
|
||||
|
||||
const existingGroupIndex = groups.findIndex(
|
||||
(group) =>
|
||||
group.type !== 'gap' && group.group_key === notification.group_key,
|
||||
@@ -242,7 +251,7 @@ function processNewNotification(
|
||||
groups.unshift(existingGroup);
|
||||
}
|
||||
} else {
|
||||
// Create a new group
|
||||
// We have not found an existing group, create a new one
|
||||
groups.unshift(createNotificationGroupFromNotificationJSON(notification));
|
||||
}
|
||||
}
|
||||
@@ -468,11 +477,13 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
||||
trimNotifications(state);
|
||||
})
|
||||
.addCase(processNewNotificationForGroups.fulfilled, (state, action) => {
|
||||
const notification = action.payload;
|
||||
if (notification) {
|
||||
if (action.payload) {
|
||||
const { notification, groupedTypes } = action.payload;
|
||||
|
||||
processNewNotification(
|
||||
usePendingItems ? state.pendingGroups : state.groups,
|
||||
notification,
|
||||
groupedTypes,
|
||||
);
|
||||
updateLastReadId(state);
|
||||
trimNotifications(state);
|
||||
@@ -523,10 +534,13 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
||||
if (existingGroupIndex > -1) {
|
||||
const existingGroup = state.groups[existingGroupIndex];
|
||||
if (existingGroup && existingGroup.type !== 'gap') {
|
||||
group.notifications_count += existingGroup.notifications_count;
|
||||
group.sampleAccountIds = group.sampleAccountIds
|
||||
.concat(existingGroup.sampleAccountIds)
|
||||
.slice(0, NOTIFICATIONS_GROUP_MAX_AVATARS);
|
||||
if (group.partial) {
|
||||
group.notifications_count +=
|
||||
existingGroup.notifications_count;
|
||||
group.sampleAccountIds = group.sampleAccountIds
|
||||
.concat(existingGroup.sampleAccountIds)
|
||||
.slice(0, NOTIFICATIONS_GROUP_MAX_AVATARS);
|
||||
}
|
||||
state.groups.splice(existingGroupIndex, 1);
|
||||
}
|
||||
}
|
||||
@@ -551,7 +565,10 @@ export const notificationGroupsReducer = createReducer<NotificationGroupsState>(
|
||||
compareId(state.lastReadId, mostRecentGroup.page_max_id) < 0
|
||||
)
|
||||
state.lastReadId = mostRecentGroup.page_max_id;
|
||||
commitLastReadId(state);
|
||||
|
||||
// We don't call `commitLastReadId`, because that is conditional
|
||||
// and we want to unconditionally update the state instead.
|
||||
state.readMarkerId = state.lastReadId;
|
||||
})
|
||||
.addCase(fetchMarkers.fulfilled, (state, action) => {
|
||||
if (
|
||||
|
||||
@@ -79,6 +79,10 @@ const initialState = ImmutableMap({
|
||||
'admin.sign_up': true,
|
||||
'admin.report': true,
|
||||
}),
|
||||
|
||||
group: ImmutableMap({
|
||||
follow: true
|
||||
}),
|
||||
}),
|
||||
|
||||
firehose: ImmutableMap({
|
||||
|
||||
50
app/javascript/flavours/glitch/selectors/filters.ts
Normal file
50
app/javascript/flavours/glitch/selectors/filters.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
|
||||
import type { RootState } from 'flavours/glitch/store';
|
||||
import { toServerSideType } from 'flavours/glitch/utils/filters';
|
||||
|
||||
// TODO: move to `app/javascript/flavours/glitch/models` and use more globally
|
||||
type Filter = Immutable.Map<string, unknown>;
|
||||
|
||||
// TODO: move to `app/javascript/flavours/glitch/models` and use more globally
|
||||
type FilterResult = Immutable.Map<string, unknown>;
|
||||
|
||||
export const getFilters = createSelector(
|
||||
[
|
||||
(state: RootState) => state.filters as Immutable.Map<string, Filter>,
|
||||
(_, { contextType }: { contextType: string }) => contextType,
|
||||
],
|
||||
(filters, contextType) => {
|
||||
if (!contextType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const serverSideType = toServerSideType(contextType);
|
||||
|
||||
return filters.filter((filter) => {
|
||||
const context = filter.get('context') as Immutable.List<string>;
|
||||
const expiration = filter.get('expires_at') as Date | null;
|
||||
return (
|
||||
context.includes(serverSideType) &&
|
||||
(expiration === null || expiration > now)
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
export const getStatusHidden = (
|
||||
state: RootState,
|
||||
{ id, contextType }: { id: string; contextType: string },
|
||||
) => {
|
||||
const filters = getFilters(state, { contextType });
|
||||
if (filters === null) return false;
|
||||
|
||||
const filtered = state.statuses.getIn([id, 'filtered']) as
|
||||
| Immutable.List<FilterResult>
|
||||
| undefined;
|
||||
return filtered?.some(
|
||||
(result) =>
|
||||
filters.getIn([result.get('filter'), 'filter_action']) === 'hide',
|
||||
);
|
||||
};
|
||||
@@ -1,23 +1,12 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import { toServerSideType } from 'flavours/glitch/utils/filters';
|
||||
|
||||
import { me } from '../initial_state';
|
||||
|
||||
import { getFilters } from './filters';
|
||||
|
||||
export { makeGetAccount } from "./accounts";
|
||||
|
||||
const getFilters = createSelector([state => state.get('filters'), (_, { contextType }) => contextType], (filters, contextType) => {
|
||||
if (!contextType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const serverSideType = toServerSideType(contextType);
|
||||
|
||||
return filters.filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || filter.get('expires_at') > now));
|
||||
});
|
||||
|
||||
export const makeGetStatus = () => {
|
||||
return createSelector(
|
||||
[
|
||||
|
||||
@@ -52,4 +52,7 @@ export const selectSettingsNotificationsMinimizeFilteredBanner = (
|
||||
) =>
|
||||
state.settings.getIn(['notifications', 'minimizeFilteredBanner']) as boolean;
|
||||
|
||||
export const selectSettingsNotificationsGroupFollows = (state: RootState) =>
|
||||
state.settings.getIn(['notifications', 'group', 'follow']) as boolean;
|
||||
|
||||
/* eslint-enable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
||||
|
||||
@@ -226,6 +226,10 @@ $content-width: 840px;
|
||||
gap: 5px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media screen and (max-width: $mobile-breakpoint) {
|
||||
flex: 1 0 50%;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active {
|
||||
@@ -1046,6 +1050,12 @@ a.name-tag,
|
||||
color: var(--user-role-accent);
|
||||
}
|
||||
|
||||
.applications-list {
|
||||
.icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.announcements-list,
|
||||
.filters-list {
|
||||
border: 1px solid var(--background-border-color);
|
||||
@@ -1075,6 +1085,10 @@ a.name-tag,
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
a.announcements-list__item__title {
|
||||
&:hover,
|
||||
&:focus,
|
||||
|
||||
@@ -2259,7 +2259,6 @@ body > [data-popper-placement] {
|
||||
display: block;
|
||||
position: relative;
|
||||
border-radius: var(--avatar-border-radius);
|
||||
background-color: var(--surface-background-color);
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
@@ -2269,7 +2268,11 @@ body > [data-popper-placement] {
|
||||
display: inline-block; // to not show broken images
|
||||
}
|
||||
|
||||
&-inline {
|
||||
&--loading {
|
||||
background-color: var(--surface-background-color);
|
||||
}
|
||||
|
||||
&--inline {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin-inline-end: 5px;
|
||||
@@ -2938,6 +2941,7 @@ a.account__display-name {
|
||||
flex: 0 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
contain: inline-size layout paint style;
|
||||
|
||||
@media screen and (min-width: $no-gap-breakpoint) {
|
||||
max-width: 600px;
|
||||
@@ -3793,6 +3797,7 @@ $ui-header-logo-wordmark-width: 99px;
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.drawer__inner__mastodon {
|
||||
@@ -4233,6 +4238,7 @@ input.glitch-setting-text {
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--background-border-color);
|
||||
border-radius: 8px;
|
||||
contain: inline-size layout paint style;
|
||||
|
||||
&.bottomless {
|
||||
border-radius: 8px 8px 0 0;
|
||||
@@ -6271,6 +6277,7 @@ a.status-card {
|
||||
pointer-events: auto;
|
||||
user-select: text;
|
||||
display: flex;
|
||||
max-width: 100vw;
|
||||
|
||||
@media screen and (width <= $mobile-breakpoint) {
|
||||
margin-top: auto;
|
||||
@@ -8521,79 +8528,23 @@ noscript {
|
||||
background: rgba($base-overlay-background, 0.5);
|
||||
}
|
||||
|
||||
.list-adder,
|
||||
.list-editor {
|
||||
background: $ui-base-color;
|
||||
backdrop-filter: var(--background-filter);
|
||||
background: var(--modal-background-color);
|
||||
border: 1px solid var(--modal-border-color);
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
|
||||
width: 380px;
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (width <= 420px) {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding: 15px 0;
|
||||
background: lighten($ui-base-color, 13%);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.drawer__pager {
|
||||
height: 50vh;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.drawer__inner {
|
||||
border-radius: 0 0 8px 8px;
|
||||
|
||||
&.backdrop {
|
||||
width: calc(100% - 60px);
|
||||
box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
|
||||
border-radius: 0 0 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&__accounts {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.account__display-name {
|
||||
&:hover strong {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.account__avatar {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.list-adder {
|
||||
background: $ui-base-color;
|
||||
flex-direction: column;
|
||||
border-radius: 8px;
|
||||
box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
|
||||
width: 380px;
|
||||
overflow: hidden;
|
||||
|
||||
@media screen and (width <= 420px) {
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
&__account {
|
||||
background: lighten($ui-base-color, 13%);
|
||||
}
|
||||
|
||||
&__lists {
|
||||
background: lighten($ui-base-color, 13%);
|
||||
height: 50vh;
|
||||
border-radius: 0 0 8px 8px;
|
||||
overflow-y: auto;
|
||||
@@ -8614,6 +8565,52 @@ noscript {
|
||||
text-decoration: none;
|
||||
font-size: 16px;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-editor {
|
||||
h4 {
|
||||
padding: 15px 0;
|
||||
background: lighten($ui-base-color, 13%);
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
border-radius: 8px 8px 0 0;
|
||||
}
|
||||
|
||||
.drawer__pager {
|
||||
height: 50vh;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.drawer__inner {
|
||||
&.backdrop {
|
||||
width: calc(100% - 60px);
|
||||
box-shadow: 2px 4px 15px rgba($base-shadow-color, 0.4);
|
||||
border-radius: 0 0 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&__accounts {
|
||||
background: unset;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.account__display-name {
|
||||
&:hover strong {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
.account__avatar {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11171,6 +11168,7 @@ noscript {
|
||||
gap: 8px;
|
||||
|
||||
.logo {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: $darker-text-color;
|
||||
}
|
||||
@@ -11359,21 +11357,17 @@ noscript {
|
||||
color: $darker-text-color;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-box-orient: vertical;
|
||||
max-height: 4 * 22px;
|
||||
max-height: none;
|
||||
overflow: hidden;
|
||||
|
||||
p {
|
||||
display: none;
|
||||
|
||||
&:first-child {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
|
||||
p,
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.reply-indicator__attachments {
|
||||
@@ -11657,19 +11651,21 @@ noscript {
|
||||
}
|
||||
|
||||
.content-warning {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
background: rgba($ui-highlight-color, 0.05);
|
||||
color: $secondary-text-color;
|
||||
border-top: 1px solid;
|
||||
border-bottom: 1px solid;
|
||||
border-color: rgba($ui-highlight-color, 0.15);
|
||||
border: 1px solid rgba($ui-highlight-color, 0.15);
|
||||
border-radius: 8px;
|
||||
padding: 8px (5px + 8px);
|
||||
position: relative;
|
||||
font-size: 15px;
|
||||
line-height: 22px;
|
||||
cursor: pointer;
|
||||
|
||||
p {
|
||||
margin-bottom: 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.link-button {
|
||||
@@ -11678,31 +11674,16 @@ noscript {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
background: url('~images/warning-stripes.svg') repeat-y;
|
||||
width: 5px;
|
||||
top: 0;
|
||||
}
|
||||
&--filter {
|
||||
color: $darker-text-color;
|
||||
|
||||
&::before {
|
||||
border-start-start-radius: 4px;
|
||||
border-end-start-radius: 4px;
|
||||
inset-inline-start: 0;
|
||||
}
|
||||
p {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&::after {
|
||||
border-start-end-radius: 4px;
|
||||
border-end-end-radius: 4px;
|
||||
inset-inline-end: 0;
|
||||
}
|
||||
|
||||
&--filter::before,
|
||||
&--filter::after {
|
||||
background-image: url('~images/filter-stripes.svg');
|
||||
.filter-name {
|
||||
font-weight: 500;
|
||||
color: $secondary-text-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ code {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 160px;
|
||||
max-width: 566px;
|
||||
margin-inline: auto;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
|
||||
@@ -90,6 +90,10 @@ body.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
.column-back-button__icon {
|
||||
transform: scale(-1, 1);
|
||||
}
|
||||
|
||||
.simple_form select {
|
||||
background: $ui-base-color
|
||||
url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(lighten($ui-base-color, 12%))}'/></svg>")
|
||||
|
||||
@@ -137,6 +137,7 @@ a.table-action-link {
|
||||
padding: 0 10px;
|
||||
color: $darker-text-color;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
color: $highlight-text-color;
|
||||
|
||||
@@ -37,8 +37,7 @@ export const synchronouslySubmitMarkers = createAppAsyncThunk(
|
||||
});
|
||||
|
||||
return;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
} else if ('navigator' && 'sendBeacon' in navigator) {
|
||||
} else if ('sendBeacon' in navigator) {
|
||||
// Failing that, we can use sendBeacon, but we have to encode the data as
|
||||
// FormData for DoorKeeper to recognize the token.
|
||||
const formData = new FormData();
|
||||
|
||||
@@ -8,6 +8,7 @@ import type { ApiAccountJSON } from 'mastodon/api_types/accounts';
|
||||
import type {
|
||||
ApiNotificationGroupJSON,
|
||||
ApiNotificationJSON,
|
||||
NotificationType,
|
||||
} from 'mastodon/api_types/notifications';
|
||||
import { allNotificationTypes } from 'mastodon/api_types/notifications';
|
||||
import type { ApiStatusJSON } from 'mastodon/api_types/statuses';
|
||||
@@ -15,6 +16,7 @@ import { usePendingItems } from 'mastodon/initial_state';
|
||||
import type { NotificationGap } from 'mastodon/reducers/notification_groups';
|
||||
import {
|
||||
selectSettingsNotificationsExcludedTypes,
|
||||
selectSettingsNotificationsGroupFollows,
|
||||
selectSettingsNotificationsQuickFilterActive,
|
||||
selectSettingsNotificationsShows,
|
||||
} from 'mastodon/selectors/settings';
|
||||
@@ -68,13 +70,19 @@ function dispatchAssociatedRecords(
|
||||
dispatch(importFetchedStatuses(fetchedStatuses));
|
||||
}
|
||||
|
||||
const supportedGroupedNotificationTypes = ['favourite', 'reblog'];
|
||||
function selectNotificationGroupedTypes(state: RootState) {
|
||||
const types: NotificationType[] = ['favourite', 'reblog'];
|
||||
|
||||
if (selectSettingsNotificationsGroupFollows(state)) types.push('follow');
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
export const fetchNotifications = createDataLoadingThunk(
|
||||
'notificationGroups/fetch',
|
||||
async (_params, { getState }) =>
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
({ notifications, accounts, statuses }, { dispatch }) => {
|
||||
@@ -98,7 +106,7 @@ export const fetchNotificationsGap = createDataLoadingThunk(
|
||||
'notificationGroups/fetchGap',
|
||||
async (params: { gap: NotificationGap }, { getState }) =>
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
max_id: params.gap.maxId,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
@@ -115,7 +123,7 @@ export const pollRecentNotifications = createDataLoadingThunk(
|
||||
'notificationGroups/pollRecentNotifications',
|
||||
async (_params, { getState }) => {
|
||||
return apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
grouped_types: selectNotificationGroupedTypes(getState()),
|
||||
max_id: undefined,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
// In slow mode, we don't want to include notifications that duplicate the already-displayed ones
|
||||
@@ -164,7 +172,10 @@ export const processNewNotificationForGroups = createAppAsyncThunk(
|
||||
|
||||
dispatchAssociatedRecords(dispatch, [notification]);
|
||||
|
||||
return notification;
|
||||
return {
|
||||
notification,
|
||||
groupedTypes: selectNotificationGroupedTypes(state),
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ export interface ApiAccountRoleJSON {
|
||||
}
|
||||
|
||||
// See app/serializers/rest/account_serializer.rb
|
||||
export interface ApiAccountJSON {
|
||||
export interface BaseApiAccountJSON {
|
||||
acct: string;
|
||||
avatar: string;
|
||||
avatar_static: string;
|
||||
@@ -45,3 +45,12 @@ export interface ApiAccountJSON {
|
||||
memorial?: boolean;
|
||||
hide_collections: boolean;
|
||||
}
|
||||
|
||||
// See app/serializers/rest/muted_account_serializer.rb
|
||||
export interface ApiMutedAccountJSON extends BaseApiAccountJSON {
|
||||
mute_expires_at?: string | null;
|
||||
}
|
||||
|
||||
// For now, we have the same type representing both `Account` and `MutedAccount`
|
||||
// objects, but we should refactor this in the future.
|
||||
export type ApiAccountJSON = ApiMutedAccountJSON;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
|
||||
<div
|
||||
className="account__avatar"
|
||||
className="account__avatar account__avatar--loading"
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
style={
|
||||
@@ -14,6 +14,8 @@ exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
onError={[Function]}
|
||||
onLoad={[Function]}
|
||||
src="/animated/alice.gif"
|
||||
/>
|
||||
</div>
|
||||
@@ -21,7 +23,7 @@ exports[`<Avatar /> Autoplay renders a animated avatar 1`] = `
|
||||
|
||||
exports[`<Avatar /> Still renders a still avatar 1`] = `
|
||||
<div
|
||||
className="account__avatar"
|
||||
className="account__avatar account__avatar--loading"
|
||||
onMouseEnter={[Function]}
|
||||
onMouseLeave={[Function]}
|
||||
style={
|
||||
@@ -33,6 +35,8 @@ exports[`<Avatar /> Still renders a still avatar 1`] = `
|
||||
>
|
||||
<img
|
||||
alt=""
|
||||
onError={[Function]}
|
||||
onLoad={[Function]}
|
||||
src="/static/alice.jpg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useState, useCallback } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { useHovering } from 'mastodon/../hooks/useHovering';
|
||||
import { autoPlayGif } from 'mastodon/initial_state';
|
||||
import type { Account } from 'mastodon/models/account';
|
||||
|
||||
import { useHovering } from '../../hooks/useHovering';
|
||||
import { autoPlayGif } from '../initial_state';
|
||||
|
||||
interface Props {
|
||||
account: Account | undefined; // FIXME: remove `undefined` once we know for sure its always there
|
||||
size: number;
|
||||
@@ -25,6 +26,8 @@ export const Avatar: React.FC<Props> = ({
|
||||
counterBorderColor,
|
||||
}) => {
|
||||
const { hovering, handleMouseEnter, handleMouseLeave } = useHovering(animate);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(false);
|
||||
|
||||
const style = {
|
||||
...styleFromParent,
|
||||
@@ -37,16 +40,28 @@ export const Avatar: React.FC<Props> = ({
|
||||
? account?.get('avatar')
|
||||
: account?.get('avatar_static');
|
||||
|
||||
const handleLoad = useCallback(() => {
|
||||
setLoading(false);
|
||||
}, [setLoading]);
|
||||
|
||||
const handleError = useCallback(() => {
|
||||
setError(true);
|
||||
}, [setError]);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames('account__avatar', {
|
||||
'account__avatar-inline': inline,
|
||||
'account__avatar--inline': inline,
|
||||
'account__avatar--loading': loading,
|
||||
})}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
style={style}
|
||||
>
|
||||
{src && <img src={src} alt='' />}
|
||||
{src && !error && (
|
||||
<img src={src} alt='' onLoad={handleLoad} onError={handleError} />
|
||||
)}
|
||||
|
||||
{counter && (
|
||||
<div
|
||||
className='account__avatar__counter'
|
||||
|
||||
@@ -8,7 +8,7 @@ export const ContentWarning: React.FC<{
|
||||
<StatusBanner
|
||||
expanded={expanded}
|
||||
onClick={onClick}
|
||||
variant={BannerVariant.Yellow}
|
||||
variant={BannerVariant.Warning}
|
||||
>
|
||||
<p dangerouslySetInnerHTML={{ __html: text }} />
|
||||
</StatusBanner>
|
||||
|
||||
@@ -10,13 +10,16 @@ export const FilterWarning: React.FC<{
|
||||
<StatusBanner
|
||||
expanded={expanded}
|
||||
onClick={onClick}
|
||||
variant={BannerVariant.Blue}
|
||||
variant={BannerVariant.Filter}
|
||||
>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='filter_warning.matches_filter'
|
||||
defaultMessage='Matches filter “{title}”'
|
||||
values={{ title }}
|
||||
defaultMessage='Matches filter “<span>{title}</span>”'
|
||||
values={{
|
||||
title,
|
||||
span: (chunks) => <span className='filter-name'>{chunks}</span>,
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</StatusBanner>
|
||||
|
||||
@@ -97,12 +97,12 @@ class Item extends PureComponent {
|
||||
height = 50;
|
||||
}
|
||||
|
||||
if (attachment.get('description')?.length > 0) {
|
||||
badges.push(<AltTextBadge key='alt' description={attachment.get('description')} />);
|
||||
}
|
||||
|
||||
const description = attachment.getIn(['translation', 'description']) || attachment.get('description');
|
||||
|
||||
if (description?.length > 0) {
|
||||
badges.push(<AltTextBadge key='alt' description={description} />);
|
||||
}
|
||||
|
||||
if (attachment.get('type') === 'unknown') {
|
||||
return (
|
||||
<div className={classNames('media-gallery__item', { standalone, 'media-gallery__item--tall': height === 100, 'media-gallery__item--wide': width === 100 })} key={attachment.get('id')}>
|
||||
@@ -196,7 +196,7 @@ class Item extends PureComponent {
|
||||
|
||||
{visible && thumbnail}
|
||||
|
||||
{badges && (
|
||||
{visible && badges && (
|
||||
<div className='media-gallery__item__badges'>
|
||||
{badges}
|
||||
</div>
|
||||
@@ -336,14 +336,14 @@ class MediaGallery extends PureComponent {
|
||||
|
||||
return (
|
||||
<div className={`media-gallery media-gallery--layout-${size}`} style={style} ref={this.handleRef}>
|
||||
{children}
|
||||
|
||||
{(!visible || uncached) && (
|
||||
<div className={classNames('spoiler-button', { 'spoiler-button--click-thru': uncached })}>
|
||||
{spoilerButton}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{children}
|
||||
|
||||
{(visible && !uncached) && (
|
||||
<div className='media-gallery__actions'>
|
||||
<button className='media-gallery__actions__pill' onClick={this.handleOpen}><FormattedMessage id='media_gallery.hide' defaultMessage='Hide' /></button>
|
||||
|
||||
@@ -449,7 +449,7 @@ class Status extends ImmutablePureComponent {
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
const language = status.getIn(['translation', 'language']) || status.get('language');
|
||||
|
||||
if (['image', 'gifv'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
|
||||
if (['image', 'gifv', 'unknown'].includes(status.getIn(['media_attachments', 0, 'type'])) || status.get('media_attachments').size > 1) {
|
||||
media = (
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery}>
|
||||
{Component => (
|
||||
|
||||
@@ -264,7 +264,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
menu.push({ text: intl.formatMessage(messages.share), action: this.handleShareClick });
|
||||
}
|
||||
|
||||
if (publicStatus && (signedIn || !isRemote)) {
|
||||
if (publicStatus && !isRemote) {
|
||||
menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
export enum BannerVariant {
|
||||
Yellow = 'yellow',
|
||||
Blue = 'blue',
|
||||
Warning = 'warning',
|
||||
Filter = 'filter',
|
||||
}
|
||||
|
||||
export const StatusBanner: React.FC<{
|
||||
@@ -11,9 +11,9 @@ export const StatusBanner: React.FC<{
|
||||
expanded?: boolean;
|
||||
onClick?: () => void;
|
||||
}> = ({ children, variant, expanded, onClick }) => (
|
||||
<div
|
||||
<label
|
||||
className={
|
||||
variant === BannerVariant.Yellow
|
||||
variant === BannerVariant.Warning
|
||||
? 'content-warning'
|
||||
: 'content-warning content-warning--filter'
|
||||
}
|
||||
@@ -26,6 +26,11 @@ export const StatusBanner: React.FC<{
|
||||
id='content_warning.hide'
|
||||
defaultMessage='Hide post'
|
||||
/>
|
||||
) : variant === BannerVariant.Warning ? (
|
||||
<FormattedMessage
|
||||
id='content_warning.show_more'
|
||||
defaultMessage='Show more'
|
||||
/>
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id='content_warning.show'
|
||||
@@ -33,5 +38,5 @@ export const StatusBanner: React.FC<{
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</label>
|
||||
);
|
||||
|
||||
@@ -21,9 +21,11 @@ class ColumnSettings extends PureComponent {
|
||||
|
||||
return (
|
||||
<div className='column-settings'>
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
|
||||
</div>
|
||||
<section>
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle settings={settings} settingPath={['other', 'onlyMedia']} onChange={onChange} label={<FormattedMessage id='community.column_settings.media_only' defaultMessage='Media only' />} />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -129,8 +129,13 @@ export const InlineFollowSuggestions = ({ hidden }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
if (getComputedStyle(bodyRef.current).direction === 'rtl') {
|
||||
setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth);
|
||||
setCanScrollRight(bodyRef.current.scrollLeft < 0);
|
||||
} else {
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
}
|
||||
}, [setCanScrollRight, setCanScrollLeft, bodyRef, suggestions]);
|
||||
|
||||
const handleLeftNav = useCallback(() => {
|
||||
@@ -146,8 +151,13 @@ export const InlineFollowSuggestions = ({ hidden }) => {
|
||||
return;
|
||||
}
|
||||
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
if (getComputedStyle(bodyRef.current).direction === 'rtl') {
|
||||
setCanScrollLeft((bodyRef.current.clientWidth - bodyRef.current.scrollLeft) < bodyRef.current.scrollWidth);
|
||||
setCanScrollRight(bodyRef.current.scrollLeft < 0);
|
||||
} else {
|
||||
setCanScrollLeft(bodyRef.current.scrollLeft > 0);
|
||||
setCanScrollRight((bodyRef.current.scrollLeft + bodyRef.current.clientWidth) < bodyRef.current.scrollWidth);
|
||||
}
|
||||
}, [setCanScrollRight, setCanScrollLeft, bodyRef]);
|
||||
|
||||
const handleDismiss = useCallback(() => {
|
||||
|
||||
@@ -38,6 +38,7 @@ class ColumnSettings extends PureComponent {
|
||||
const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
|
||||
const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
|
||||
const soundStr = <FormattedMessage id='notifications.column_settings.sound' defaultMessage='Play sound' />;
|
||||
const groupStr = <FormattedMessage id='notifications.column_settings.group' defaultMessage='Group' />;
|
||||
|
||||
const showPushSettings = pushSettings.get('browserSupport') && pushSettings.get('isSubscribed');
|
||||
const pushStr = showPushSettings && <FormattedMessage id='notifications.column_settings.push' defaultMessage='Push notifications' />;
|
||||
@@ -94,6 +95,7 @@ class ColumnSettings extends PureComponent {
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow']} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['group', 'follow']} onChange={onChange} label={groupStr} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -56,11 +56,12 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
} else {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
}
|
||||
} else if(path[0] === 'groupingBeta') {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
dispatch(initializeNotifications());
|
||||
} else {
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
|
||||
if(path[0] === 'group' && path[1] === 'follow') {
|
||||
dispatch(initializeNotifications());
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import PersonAddIcon from '@/material-icons/400-24px/person_add-fill.svg?react';
|
||||
import { FollowersCounter } from 'mastodon/components/counters';
|
||||
import { FollowButton } from 'mastodon/components/follow_button';
|
||||
import { ShortNumber } from 'mastodon/components/short_number';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import type { NotificationGroupFollow } from 'mastodon/models/notification_group';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import type { LabelRenderer } from './notification_group_with_status';
|
||||
import { NotificationGroupWithStatus } from './notification_group_with_status';
|
||||
|
||||
const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||
const labelRenderer: LabelRenderer = (displayedName, total, seeMoreHref) => {
|
||||
if (total === 1)
|
||||
return (
|
||||
<FormattedMessage
|
||||
@@ -23,10 +26,12 @@ const labelRenderer: LabelRenderer = (displayedName, total) => {
|
||||
return (
|
||||
<FormattedMessage
|
||||
id='notification.follow.name_and_others'
|
||||
defaultMessage='{name} and {count, plural, one {# other} other {# others}} followed you'
|
||||
defaultMessage='{name} and <a>{count, plural, one {# other} other {# others}}</a> followed you'
|
||||
values={{
|
||||
name: displayedName,
|
||||
count: total - 1,
|
||||
a: (chunks) =>
|
||||
seeMoreHref ? <Link to={seeMoreHref}>{chunks}</Link> : chunks,
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -46,6 +51,10 @@ export const NotificationFollow: React.FC<{
|
||||
notification: NotificationGroupFollow;
|
||||
unread: boolean;
|
||||
}> = ({ notification, unread }) => {
|
||||
const username = useAppSelector(
|
||||
(state) => state.accounts.getIn([me, 'username']) as string,
|
||||
);
|
||||
|
||||
let actions: JSX.Element | undefined;
|
||||
let additionalContent: JSX.Element | undefined;
|
||||
|
||||
@@ -68,6 +77,7 @@ export const NotificationFollow: React.FC<{
|
||||
timestamp={notification.latest_page_notification_at}
|
||||
count={notification.notifications_count}
|
||||
labelRenderer={labelRenderer}
|
||||
labelSeeMoreHref={`/@${username}/followers`}
|
||||
unread={unread}
|
||||
actions={actions}
|
||||
additionalContent={additionalContent}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import type { IconProp } from 'mastodon/components/icon';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import Status from 'mastodon/containers/status_container';
|
||||
import { getStatusHidden } from 'mastodon/selectors/filters';
|
||||
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||
|
||||
import { DisplayedName } from './displayed_name';
|
||||
@@ -48,6 +49,12 @@ export const NotificationWithStatus: React.FC<{
|
||||
(state) => state.statuses.getIn([statusId, 'visibility']) === 'direct',
|
||||
);
|
||||
|
||||
const isFiltered = useAppSelector(
|
||||
(state) =>
|
||||
statusId &&
|
||||
getStatusHidden(state, { id: statusId, contextType: 'notifications' }),
|
||||
);
|
||||
|
||||
const handlers = useMemo(
|
||||
() => ({
|
||||
open: () => {
|
||||
@@ -73,7 +80,7 @@ export const NotificationWithStatus: React.FC<{
|
||||
[dispatch, statusId],
|
||||
);
|
||||
|
||||
if (!statusId) return null;
|
||||
if (!statusId || isFiltered) return null;
|
||||
|
||||
return (
|
||||
<HotKeys handlers={handlers}>
|
||||
|
||||
@@ -14,6 +14,8 @@ import RepeatIcon from '@/material-icons/400-24px/repeat.svg?react';
|
||||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import ReplyAllIcon from '@/material-icons/400-24px/reply_all.svg?react';
|
||||
import StarIcon from '@/material-icons/400-24px/star.svg?react';
|
||||
import RepeatDisabledIcon from '@/svg-icons/repeat_disabled.svg?react';
|
||||
import RepeatPrivateIcon from '@/svg-icons/repeat_private.svg?react';
|
||||
import { replyCompose } from 'mastodon/actions/compose';
|
||||
import { toggleReblog, toggleFavourite } from 'mastodon/actions/interactions';
|
||||
import { openModal } from 'mastodon/actions/modal';
|
||||
@@ -159,22 +161,26 @@ class Footer extends ImmutablePureComponent {
|
||||
replyTitle = intl.formatMessage(messages.replyAll);
|
||||
}
|
||||
|
||||
let reblogTitle = '';
|
||||
let reblogTitle, reblogIconComponent;
|
||||
|
||||
if (status.get('reblogged')) {
|
||||
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
||||
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon;
|
||||
} else if (publicStatus) {
|
||||
reblogTitle = intl.formatMessage(messages.reblog);
|
||||
reblogIconComponent = RepeatIcon;
|
||||
} else if (reblogPrivate) {
|
||||
reblogTitle = intl.formatMessage(messages.reblog_private);
|
||||
reblogIconComponent = RepeatPrivateIcon;
|
||||
} else {
|
||||
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
||||
reblogIconComponent = RepeatDisabledIcon;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='picture-in-picture__footer'>
|
||||
<IconButton className='status__action-bar-button' title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} iconComponent={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
||||
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={reblogIconComponent} onClick={this.handleReblogClick} counter={status.get('reblogs_count')} />
|
||||
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={StarIcon} onClick={this.handleFavouriteClick} counter={status.get('favourites_count')} />
|
||||
{withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' iconComponent={OpenInNewIcon} onClick={this.handleOpenClick} href={`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`} />}
|
||||
</div>
|
||||
|
||||
@@ -152,7 +152,7 @@ export const DetailedStatus: React.FC<{
|
||||
media = <PictureInPicturePlaceholder aspectRatio={attachmentAspectRatio} />;
|
||||
} else if (status.get('media_attachments').size > 0) {
|
||||
if (
|
||||
['image', 'gifv'].includes(
|
||||
['image', 'gifv', 'unknown'].includes(
|
||||
status.getIn(['media_attachments', 0, 'type']) as string,
|
||||
) ||
|
||||
status.get('media_attachments').size > 1
|
||||
|
||||
@@ -116,6 +116,7 @@ export const MuteModal = ({ accountId, acct }) => {
|
||||
<div className='safety-action-modal__bottom__collapsible'>
|
||||
<div className='safety-action-modal__field-group'>
|
||||
<RadioButtonLabel name='duration' value='0' label={intl.formatMessage(messages.indefinite)} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='21600' label={intl.formatMessage(messages.hours, { number: 6 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='86400' label={intl.formatMessage(messages.hours, { number: 24 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='604800' label={intl.formatMessage(messages.days, { number: 7 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
<RadioButtonLabel name='duration' value='2592000' label={intl.formatMessage(messages.days, { number: 30 })} currentValue={muteDuration} onChange={handleChangeMuteDuration} />
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
"alert.rate_limited.title": "معدل الطلبات محدود",
|
||||
"alert.unexpected.message": "لقد طرأ خطأ غير متوقّع.",
|
||||
"alert.unexpected.title": "المعذرة!",
|
||||
"alt_text_badge.title": "نص بديل",
|
||||
"announcement.announcement": "إعلان",
|
||||
"attachments_list.unprocessed": "(غير معالَج)",
|
||||
"audio.hide": "إخفاء المقطع الصوتي",
|
||||
@@ -301,7 +302,6 @@
|
||||
"filter_modal.select_filter.subtitle": "استخدم فئة موجودة أو قم بإنشاء فئة جديدة",
|
||||
"filter_modal.select_filter.title": "تصفية هذا المنشور",
|
||||
"filter_modal.title.status": "تصفية منشور",
|
||||
"filter_warning.matches_filter": "يطابق عامل التصفية \"{title}\"",
|
||||
"filtered_notifications_banner.title": "الإشعارات المصفاة",
|
||||
"firehose.all": "الكل",
|
||||
"firehose.local": "هذا الخادم",
|
||||
@@ -490,6 +490,7 @@
|
||||
"notification.label.private_reply": "رد خاص",
|
||||
"notification.label.reply": "ردّ",
|
||||
"notification.mention": "إشارة",
|
||||
"notification.mentioned_you": "{name} mentioned you",
|
||||
"notification.moderation-warning.learn_more": "اعرف المزيد",
|
||||
"notification.moderation_warning": "لقد تلقيت تحذيرًا بالإشراف",
|
||||
"notification.moderation_warning.action_delete_statuses": "تم حذف بعض من منشوراتك.",
|
||||
@@ -758,7 +759,7 @@
|
||||
"status.history.edited": "عدله {name} {date}",
|
||||
"status.load_more": "حمّل المزيد",
|
||||
"status.media.open": "اضغط للفتح",
|
||||
"status.media.show": "اضغط لإظهاره",
|
||||
"status.media.show": "اضغط لإظهارها",
|
||||
"status.media_hidden": "وسائط مخفية",
|
||||
"status.mention": "أذكُر @{name}",
|
||||
"status.more": "المزيد",
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"account.followers": "Siguidores",
|
||||
"account.followers.empty": "Naide sigue a esti perfil.",
|
||||
"account.follows.empty": "Esti perfil nun sigue a naide.",
|
||||
"account.hide_reblogs": "Anubrir los artículos compartíos de @{name}",
|
||||
"account.hide_reblogs": "Esconder los artículos compartíos de @{name}",
|
||||
"account.in_memoriam": "N'alcordanza.",
|
||||
"account.joined_short": "Data de xunión",
|
||||
"account.link_verified_on": "La propiedá d'esti enllaz comprobóse'l {date}",
|
||||
@@ -122,6 +122,7 @@
|
||||
"conversation.open": "Ver la conversación",
|
||||
"conversation.with": "Con {names}",
|
||||
"copypaste.copied": "Copióse",
|
||||
"copypaste.copy_to_clipboard": "Copiar nel cartafueyu",
|
||||
"directory.federated": "Del fediversu conocíu",
|
||||
"directory.local": "De «{domain}» namás",
|
||||
"directory.new_arrivals": "Cuentes nueves",
|
||||
@@ -130,7 +131,7 @@
|
||||
"dismissable_banner.dismiss": "Escartar",
|
||||
"dismissable_banner.explore_tags": "Esta seición contién les etiquetes del fediversu que tán ganando popularidá güei. Les etiquetes más usaes polos perfiles apaecen no cimero.",
|
||||
"dismissable_banner.public_timeline": "Esta seición contién los artículos más nuevos de les persones na web social que les persones de {domain} siguen.",
|
||||
"embed.instructions": "Empotra esti artículu nel to sitiu web pente la copia del códigu d'abaxo.",
|
||||
"embed.instructions": "Empotra esti artículu nel to sitiu web copiando'l códigu d'abaxo.",
|
||||
"embed.preview": "Va apaecer asina:",
|
||||
"emoji_button.activity": "Actividá",
|
||||
"emoji_button.flags": "Banderes",
|
||||
@@ -213,6 +214,7 @@
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.follow": "Siguir a la etiqueta",
|
||||
"hashtag.unfollow": "Dexar de siguir a la etiqueta",
|
||||
"hints.threads.replies_may_be_missing": "Ye posible que falten les rempuestes d'otros sirvidores.",
|
||||
"home.column_settings.show_reblogs": "Amosar los artículos compartíos",
|
||||
"home.column_settings.show_replies": "Amosar les rempuestes",
|
||||
"home.pending_critical_update.body": "¡Anueva'l sirvidor de Mastodon namás que puedas!",
|
||||
@@ -251,7 +253,7 @@
|
||||
"keyboard_shortcuts.requests": "Abrir la llista de solicitúes de siguimientu",
|
||||
"keyboard_shortcuts.search": "Enfocar la barra de busca",
|
||||
"keyboard_shortcuts.start": "Abrir la columna «Entamar»",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Amosar/anubrir el conteníu multimedia",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Amosar/esconder el conteníu multimedia",
|
||||
"keyboard_shortcuts.toot": "Comenzar un artículu nuevu",
|
||||
"keyboard_shortcuts.unfocus": "Desenfocar l'área de composición/busca",
|
||||
"keyboard_shortcuts.up": "Xubir na llista",
|
||||
@@ -299,6 +301,7 @@
|
||||
"notifications.column_settings.admin.sign_up": "Rexistros nuevos:",
|
||||
"notifications.column_settings.follow": "Siguidores nuevos:",
|
||||
"notifications.column_settings.follow_request": "Solicitúes de siguimientu nueves:",
|
||||
"notifications.column_settings.group": "Agrupar",
|
||||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.poll": "Resultaos de les encuestes:",
|
||||
"notifications.column_settings.reblog": "Artículos compartíos:",
|
||||
@@ -418,11 +421,12 @@
|
||||
"status.direct": "Mentar a @{name} per privao",
|
||||
"status.direct_indicator": "Mención privada",
|
||||
"status.edited_x_times": "Editóse {count, plural, one {{count} vegada} other {{count} vegaes}}",
|
||||
"status.embed": "Consiguir el códigu pa empotrar",
|
||||
"status.filter": "Peñerar esti artículu",
|
||||
"status.history.created": "{name} creó {date}",
|
||||
"status.history.edited": "{name} editó {date}",
|
||||
"status.load_more": "Cargar más",
|
||||
"status.media_hidden": "Conteníu multimedia anubríu",
|
||||
"status.media_hidden": "Conteníu multimedia escondíu",
|
||||
"status.mention": "Mentar a @{name}",
|
||||
"status.more": "Más",
|
||||
"status.mute": "Desactivar los avisos de @{name}",
|
||||
@@ -468,14 +472,14 @@
|
||||
"upload_modal.applying": "Aplicando…",
|
||||
"upload_modal.detect_text": "Detectar el testu de la semeya",
|
||||
"upload_modal.edit_media": "Edición",
|
||||
"upload_modal.hint": "Calca o arrastra'l círculu de la previsualización pa escoyer el puntu d'enfoque que siempres va tar a la vista en toles miniatures.",
|
||||
"upload_modal.hint": "Calca o arrastra'l círculu de la previsualización pa escoyer el puntu d'enfoque que siempre va tar a la vista en toles miniatures.",
|
||||
"upload_progress.label": "Xubiendo…",
|
||||
"upload_progress.processing": "Procesando…",
|
||||
"video.close": "Zarrar el videu",
|
||||
"video.download": "Baxar el ficheru",
|
||||
"video.expand": "Espander el videu",
|
||||
"video.fullscreen": "Pantalla completa",
|
||||
"video.hide": "Anubrir el videu",
|
||||
"video.hide": "Esconder el videu",
|
||||
"video.mute": "Desactivar el soníu",
|
||||
"video.pause": "Posar",
|
||||
"video.play": "Reproducir",
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"alert.rate_limited.title": "Ліміт перавышаны",
|
||||
"alert.unexpected.message": "Узнікла нечаканая памылка.",
|
||||
"alert.unexpected.title": "Вой!",
|
||||
"alt_text_badge.title": "Альтернативный текст",
|
||||
"announcement.announcement": "Аб'ява",
|
||||
"attachments_list.unprocessed": "(неапрацаваны)",
|
||||
"audio.hide": "Схаваць аўдыя",
|
||||
@@ -97,6 +98,8 @@
|
||||
"block_modal.title": "Заблакіраваць карыстальніка?",
|
||||
"block_modal.you_wont_see_mentions": "Вы не ўбачыце паведамленняў са згадваннем карыстальніка.",
|
||||
"boost_modal.combo": "Націсніце {combo}, каб прапусціць наступным разам",
|
||||
"boost_modal.reblog": "Пашырыць допіс?",
|
||||
"boost_modal.undo_reblog": "Прыбраць допіс?",
|
||||
"bundle_column_error.copy_stacktrace": "Скапіраваць справаздачу пра памылку",
|
||||
"bundle_column_error.error.body": "Запытаная старонка не можа быць адлюстраваная. Гэта магло стацца праз хібу ў нашым кодзе, або праз памылку сумяшчальнасці з браўзерам.",
|
||||
"bundle_column_error.error.title": "Халера!",
|
||||
@@ -151,7 +154,7 @@
|
||||
"compose_form.hashtag_warning": "Гэты допіс не будзе паказаны пад аніякім хэштэгам, бо ён не публічны. Толькі публічныя допісы можна знайсці па хэштэгу.",
|
||||
"compose_form.lock_disclaimer": "Ваш уліковы запіс не {locked}. Усе могуць падпісацца на вас, каб бачыць допісы толькі для падпісчыкаў.",
|
||||
"compose_form.lock_disclaimer.lock": "закрыты",
|
||||
"compose_form.placeholder": "Што здарылася?",
|
||||
"compose_form.placeholder": "Што ў вас новага?",
|
||||
"compose_form.poll.duration": "Працягласць апытання",
|
||||
"compose_form.poll.multiple": "Множны выбар",
|
||||
"compose_form.poll.option_placeholder": "Варыянт {number}",
|
||||
@@ -194,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Адпісацца ад карыстальніка?",
|
||||
"content_warning.hide": "Схаваць допіс",
|
||||
"content_warning.show": "Усё адно паказаць",
|
||||
"content_warning.show_more": "Паказаць усё роўна",
|
||||
"conversation.delete": "Выдаліць размову",
|
||||
"conversation.mark_as_read": "Адзначыць прачытаным",
|
||||
"conversation.open": "Прагледзець размову",
|
||||
@@ -219,6 +223,8 @@
|
||||
"domain_block_modal.they_cant_follow": "Ніхто з гэтага сервера не зможа падпісацца на вас.",
|
||||
"domain_block_modal.they_wont_know": "Карыстальнік не будзе ведаць пра блакіроўку.",
|
||||
"domain_block_modal.title": "Заблакіраваць дамен?",
|
||||
"domain_block_modal.you_will_lose_num_followers": "Вы страціце {followersCount, plural, one {{followersCountDisplay} падпісчыка} other {{followersCountDisplay} падпісчыкаў}} і {followingCount, plural, one {{followingCountDisplay} чалавека, на якога падпісаны} other {{followingCountDisplay} людзей, на якіх падпісаны}}.",
|
||||
"domain_block_modal.you_will_lose_relationships": "Вы страціце ўсех падпісчыкаў і людзей на якіх падпісаны на гэтым.",
|
||||
"domain_block_modal.you_wont_see_posts": "Вы не ўбачыце допісаў і апавяшчэнняў ад карыстальнікаў з гэтага сервера.",
|
||||
"domain_pill.activitypub_lets_connect": "Ён дазваляе вам узаемадзейнічаць не толькі з карыстальнікамі Mastodon, але і розных іншых сацыяльных платформ.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub — гэта мова, на якой Mastodon размаўляе з іншымі сацыяльнымі сеткамі.",
|
||||
@@ -300,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Скарыстайцеся існуючай катэгорыяй або стварыце новую",
|
||||
"filter_modal.select_filter.title": "Фільтраваць гэты допіс",
|
||||
"filter_modal.title.status": "Фільтраваць допіс",
|
||||
"filter_warning.matches_filter": "Адпавядае фільтру \"{title}\"",
|
||||
"filter_warning.matches_filter": "Адпавядае фільтру \"<span>{title}</span>\"",
|
||||
"filtered_notifications_banner.pending_requests": "Ад {count, plural, =0 {# людзей якіх} one {# чалавека якіх} few {# чалавек якіх} many {# людзей якіх} other {# чалавека якіх}} вы магчыма ведаеце",
|
||||
"filtered_notifications_banner.title": "Адфільтраваныя апавяшчэнні",
|
||||
"firehose.all": "Усе",
|
||||
@@ -350,6 +356,9 @@
|
||||
"hashtag.follow": "Падпісацца на хэштэг",
|
||||
"hashtag.unfollow": "Адпісацца ад хэштэга",
|
||||
"hashtags.and_other": "…і яшчэ {count, plural, other {#}}",
|
||||
"hints.profiles.followers_may_be_missing": "Падпісчыкі гэтага профілю могуць адсутнічаць.",
|
||||
"hints.profiles.follows_may_be_missing": "Падпіскі гэтага профілю могуць адсутнічаць.",
|
||||
"hints.profiles.posts_may_be_missing": "Некаторыя допісы гэтага профілю могуць адсутнічаць.",
|
||||
"home.column_settings.show_reblogs": "Паказваць пашырэнні",
|
||||
"home.column_settings.show_replies": "Паказваць адказы",
|
||||
"home.hide_announcements": "Схаваць аб'явы",
|
||||
@@ -434,6 +443,7 @@
|
||||
"lists.subheading": "Вашыя спісы",
|
||||
"load_pending": "{count, plural, one {# новы элемент} few {# новыя элементы} many {# новых элементаў} other {# новых элементаў}}",
|
||||
"loading_indicator.label": "Загрузка…",
|
||||
"media_gallery.hide": "Схаваць",
|
||||
"moved_to_account_banner.text": "Ваш уліковы запіс {disabledAccount} зараз адключаны таму што вы перанесены на {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Схаваць з апавяшчэнняў",
|
||||
"mute_modal.hide_options": "Схаваць опцыі",
|
||||
@@ -479,11 +489,13 @@
|
||||
"notification.favourite": "Ваш допіс упадабаны {name}",
|
||||
"notification.follow": "{name} падпісаўся на вас",
|
||||
"notification.follow_request": "{name} адправіў запыт на падпіску",
|
||||
"notification.follow_request.name_and_others": "{name} і {count, plural, one {# іншы} many {# іншых} other {# іншых}} запыталіся падпісацца на вас",
|
||||
"notification.label.mention": "Згадванне",
|
||||
"notification.label.private_mention": "Асабістае згадванне",
|
||||
"notification.label.private_reply": "Асабісты адказ",
|
||||
"notification.label.reply": "Адказ",
|
||||
"notification.mention": "Згадванне",
|
||||
"notification.mentioned_you": "{name} згадаў вас",
|
||||
"notification.moderation-warning.learn_more": "Даведацца больш",
|
||||
"notification.moderation_warning": "Вы атрымалі папярэджанне аб мадэрацыі",
|
||||
"notification.moderation_warning.action_delete_statuses": "Некаторыя вашыя допісы былі выдаленыя.",
|
||||
@@ -496,6 +508,7 @@
|
||||
"notification.own_poll": "Ваша апытанне скончылася",
|
||||
"notification.poll": "Апытанне, дзе вы прынялі ўдзел, скончылася",
|
||||
"notification.reblog": "{name} пашырыў ваш допіс",
|
||||
"notification.reblog.name_and_others_with_link": "{name} і <a>{count, plural, one {# іншы} many {# іншых} other {# іншых}}</a> абагулілі ваш допіс",
|
||||
"notification.relationships_severance_event": "Страціў сувязь з {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Адміністратар з {from} прыпыніў працу {target}, што азначае, што вы больш не можаце атрымліваць ад іх абнаўлення ці ўзаемадзейнічаць з імі.",
|
||||
"notification.relationships_severance_event.domain_block": "Адміністратар з {from} заблакіраваў {target}, у тым ліку {followersCount} вашых падпісчыка(-аў) і {followingCount, plural, one {# уліковы запіс} few {# уліковыя запісы} many {# уліковых запісаў} other {# уліковых запісаў}}.",
|
||||
@@ -525,6 +538,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Панэль хуткай фільтрацыі",
|
||||
"notifications.column_settings.follow": "Новыя падпісчыкі:",
|
||||
"notifications.column_settings.follow_request": "Новыя запыты на падпіску:",
|
||||
"notifications.column_settings.group": "Аб'яднаць апавяшчэнні ад падпісчыкаў",
|
||||
"notifications.column_settings.mention": "Згадванні:",
|
||||
"notifications.column_settings.poll": "Вынікі апытання:",
|
||||
"notifications.column_settings.push": "Push-апавяшчэнні",
|
||||
@@ -743,6 +757,7 @@
|
||||
"status.edit": "Рэдагаваць",
|
||||
"status.edited": "Апошняе рэдагаванне {date}",
|
||||
"status.edited_x_times": "Рэдагавана {count, plural, one {{count} раз} few {{count} разы} many {{count} разоў} other {{count} разу}}",
|
||||
"status.embed": "Атрымаць убудаваны код",
|
||||
"status.favourite": "Упадабанае",
|
||||
"status.favourites": "{count, plural, one {# упадабанае} few {# упадабаныя} many {# упадабаных} other {# упадабанага}}",
|
||||
"status.filter": "Фільтраваць гэты допіс",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"account.cancel_follow_request": "Оттегляне на заявката за последване",
|
||||
"account.copy": "Копиране на връзка към профила",
|
||||
"account.direct": "Частно споменаване на @{name}",
|
||||
"account.disable_notifications": "Сприране на известия при публикуване от @{name}",
|
||||
"account.disable_notifications": "Спиране на известяване при публикуване от @{name}",
|
||||
"account.domain_blocked": "Блокиран домейн",
|
||||
"account.edit_profile": "Редактиране на профила",
|
||||
"account.enable_notifications": "Известяване при публикуване от @{name}",
|
||||
@@ -120,7 +120,7 @@
|
||||
"column.about": "Относно",
|
||||
"column.blocks": "Блокирани потребители",
|
||||
"column.bookmarks": "Отметки",
|
||||
"column.community": "Локален инфопоток",
|
||||
"column.community": "Локална хронология",
|
||||
"column.direct": "Частни споменавания",
|
||||
"column.directory": "Разглеждане на профили",
|
||||
"column.domain_blocks": "Блокирани домейни",
|
||||
@@ -132,7 +132,7 @@
|
||||
"column.mutes": "Заглушени потребители",
|
||||
"column.notifications": "Известия",
|
||||
"column.pins": "Закачени публикации",
|
||||
"column.public": "Федериран инфопоток",
|
||||
"column.public": "Федеративна хронология",
|
||||
"column_back_button.label": "Назад",
|
||||
"column_header.hide_settings": "Скриване на настройките",
|
||||
"column_header.moveLeft_settings": "Преместване на колона вляво",
|
||||
@@ -193,9 +193,11 @@
|
||||
"confirmations.reply.message": "Отговарянето сега ще замени съобщението, което в момента съставяте. Сигурни ли сте, че искате да продължите?",
|
||||
"confirmations.reply.title": "Презаписвате ли публикацията?",
|
||||
"confirmations.unfollow.confirm": "Без следване",
|
||||
"confirmations.unfollow.message": "Наистина ли искате да не следвате {name}?",
|
||||
"confirmations.unfollow.message": "Наистина ли искате вече да не следвате {name}?",
|
||||
"confirmations.unfollow.title": "Спирате ли да следвате потребителя?",
|
||||
"content_warning.hide": "Скриване на публ.",
|
||||
"content_warning.show": "Нека се покаже",
|
||||
"content_warning.show_more": "Показване на още",
|
||||
"conversation.delete": "Изтриване на разговора",
|
||||
"conversation.mark_as_read": "Маркиране като прочетено",
|
||||
"conversation.open": "Преглед на разговора",
|
||||
@@ -211,7 +213,7 @@
|
||||
"disabled_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен.",
|
||||
"dismissable_banner.community_timeline": "Ето най-скорошните публични публикации от хора, чиито акаунти са разположени в {domain}.",
|
||||
"dismissable_banner.dismiss": "Отхвърляне",
|
||||
"dismissable_banner.explore_links": "Това са най-споделяните новини в социалната мрежа днес. По-нови истории, споделени от повече хора се показват по-напред.",
|
||||
"dismissable_banner.explore_links": "Има новинарски истории, които са най-споделяните в социалната мрежа днес. По-нови новинарски истории, публикувани от повече различни хора са класирани по-напред.",
|
||||
"dismissable_banner.explore_statuses": "Има публикации през социалната мрежа, които днес набират популярност. По-новите публикации с повече подсилвания и любими са класирани по-високо.",
|
||||
"dismissable_banner.explore_tags": "Тези хаштагове сега набират популярност сред хората в този и други сървъри на децентрализирата мрежа.",
|
||||
"dismissable_banner.public_timeline": "Ето най-новите обществени публикации от хора в социална мрежа, която хората в {domain} следват.",
|
||||
@@ -221,6 +223,8 @@
|
||||
"domain_block_modal.they_cant_follow": "Никого от този сървър не може да ви последва.",
|
||||
"domain_block_modal.they_wont_know": "Няма да узнаят, че са били блокирани.",
|
||||
"domain_block_modal.title": "Блокирате ли домейн?",
|
||||
"domain_block_modal.you_will_lose_num_followers": "Ще загубите {followersCount, plural, one {{followersCountDisplay} последовател} other {{followersCountDisplay} последователи}} и {followingCount, plural, one {{followingCountDisplay} лице, което следвате} other {{followingCountDisplay} души, които следвате}}.",
|
||||
"domain_block_modal.you_will_lose_relationships": "Ще загубите всичките си последователи и хората, които следвате от този сървър.",
|
||||
"domain_block_modal.you_wont_see_posts": "Няма да виждате публикации или известия от потребителите на този сървър.",
|
||||
"domain_pill.activitypub_lets_connect": "Позволява ви да се свързвате и взаимодействате с хора не само в Mastodon, но и през различни социални приложения.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub е като език на Mastodon, говорещ с други социални мрежи.",
|
||||
@@ -258,16 +262,16 @@
|
||||
"empty_column.account_unavailable": "Профилът не е наличен",
|
||||
"empty_column.blocks": "Още не сте блокирали никакви потребители.",
|
||||
"empty_column.bookmarked_statuses": "Още не сте отметнали публикации. Отметвайки някоя, то тя ще се покаже тук.",
|
||||
"empty_column.community": "Локалният инфопоток е празен. Публикувайте нещо, за да започнете!",
|
||||
"empty_column.community": "Локалната хронология е празна. Напишете нещо публично, за да завъртите процеса!",
|
||||
"empty_column.direct": "Още нямате никакви частни споменавания. Тук ще се показват, изпращайки или получавайки едно.",
|
||||
"empty_column.domain_blocks": "Още няма блокирани домейни.",
|
||||
"empty_column.explore_statuses": "Няма тенденции в момента. Проверете пак по-късно!",
|
||||
"empty_column.explore_statuses": "Няма нищо популярно в момента. Проверете пак по-късно!",
|
||||
"empty_column.favourited_statuses": "Още нямате никакви любими публикации. Правейки любима, то тя ще се покаже тук.",
|
||||
"empty_column.favourites": "Още никого не е слагал публикацията в любими. Когато някой го направи, този човек ще се покаже тук.",
|
||||
"empty_column.follow_requests": "Още нямате заявки за последване. Получавайки такава, то тя ще се покаже тук.",
|
||||
"empty_column.followed_tags": "Още не сте последвали никакви хаштагове. Последваните хаштагове ще се покажат тук.",
|
||||
"empty_column.hashtag": "Още няма нищо в този хаштаг.",
|
||||
"empty_column.home": "Вашата начална часова ос е празна! Последвайте повече хора, за да я запълните. {suggestions}",
|
||||
"empty_column.home": "Вашата начална хронология е празна! Последвайте повече хора, за да се запълни.",
|
||||
"empty_column.list": "Все още списъкът е празен. Членуващите на списъка, публикуващи нови публикации, ще се появят тук.",
|
||||
"empty_column.lists": "Все още нямате списъци. Когато създадете такъв, той ще се покаже тук.",
|
||||
"empty_column.mutes": "Още не сте заглушавали потребители.",
|
||||
@@ -302,6 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Изберете съществуваща категория или създайте нова",
|
||||
"filter_modal.select_filter.title": "Филтриране на публ.",
|
||||
"filter_modal.title.status": "Филтриране на публ.",
|
||||
"filter_warning.matches_filter": "Съвпадащ филтър на “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "От {count, plural, =0 {никого, когото може да познавате} one {едно лице, което може да познавате} other {# души, които може да познавате}}",
|
||||
"filtered_notifications_banner.title": "Филтрирани известия",
|
||||
"firehose.all": "Всичко",
|
||||
@@ -366,13 +371,23 @@
|
||||
"home.pending_critical_update.link": "Преглед на обновяванията",
|
||||
"home.pending_critical_update.title": "Налично критично обновяване на сигурността!",
|
||||
"home.show_announcements": "Показване на оповестяванията",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon не може да осведоми потребители, че сте пренебрегнали известията им. Пренебрегването на известията няма да спре самите съобщения да не бъдат изпращани.",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Вие все още ще може да приемате, отхвърляте или докладвате потребители",
|
||||
"ignore_notifications_modal.filter_to_avoid_confusion": "Прецеждането помага за избягване на възможно объркване",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Може да разгледате отделно филтрираните известия",
|
||||
"ignore_notifications_modal.ignore": "Пренебрегване на известията",
|
||||
"ignore_notifications_modal.limited_accounts_title": "Пренебрегвате ли известията от модерирани акаунти?",
|
||||
"ignore_notifications_modal.new_accounts_title": "Пренебрегвате ли известията от нови акаунти?",
|
||||
"ignore_notifications_modal.not_followers_title": "Пренебрегвате ли известията от хора, които не са ви последвали?",
|
||||
"ignore_notifications_modal.not_following_title": "Пренебрегвате ли известията от хора, които не сте последвали?",
|
||||
"ignore_notifications_modal.private_mentions_title": "Пренебрегвате ли известия от непоискани лични споменавания?",
|
||||
"interaction_modal.description.favourite": "Имайки акаунт в Mastodon, може да сложите тази публикации в любими, за да позволите на автора да узнае, че я цените и да я запазите за по-късно.",
|
||||
"interaction_modal.description.follow": "С акаунт в Mastodon може да последвате {name}, за да получавате публикациите от този акаунт в началния си инфоканал.",
|
||||
"interaction_modal.description.reblog": "С акаунт в Mastodon може да подсилите тази публикация, за да я споделите с последователите си.",
|
||||
"interaction_modal.description.reply": "С акаунт в Mastodon може да добавите отговор към тази публикация.",
|
||||
"interaction_modal.login.action": "Към началото",
|
||||
"interaction_modal.login.prompt": "Домейнът на сървъра ви, примерно, mastodon.social",
|
||||
"interaction_modal.no_account_yet": "Още не е в Мастодон?",
|
||||
"interaction_modal.no_account_yet": "Още ли не сте в Mastodon?",
|
||||
"interaction_modal.on_another_server": "На различен сървър",
|
||||
"interaction_modal.on_this_server": "На този сървър",
|
||||
"interaction_modal.sign_in": "Не сте влезли в този сървър. Къде се хоства акаунтът ви?",
|
||||
@@ -395,12 +410,12 @@
|
||||
"keyboard_shortcuts.enter": "Отваряне на публикация",
|
||||
"keyboard_shortcuts.favourite": "Любима публикация",
|
||||
"keyboard_shortcuts.favourites": "Отваряне на списъка с любими",
|
||||
"keyboard_shortcuts.federated": "Отваряне на федерирания инфопоток",
|
||||
"keyboard_shortcuts.federated": "Отваряне на федералната хронология",
|
||||
"keyboard_shortcuts.heading": "Клавишни съчетания",
|
||||
"keyboard_shortcuts.home": "Отваряне на личния инфопоток",
|
||||
"keyboard_shortcuts.home": "Отваряне на началната хронология",
|
||||
"keyboard_shortcuts.hotkey": "Бърз клавиш",
|
||||
"keyboard_shortcuts.legend": "Показване на тази легенда",
|
||||
"keyboard_shortcuts.local": "Отваряне на локалния инфопоток",
|
||||
"keyboard_shortcuts.local": "Отваряне на локалната хронология",
|
||||
"keyboard_shortcuts.mention": "Споменаване на автора",
|
||||
"keyboard_shortcuts.muted": "Отваряне на списъка със заглушени потребители",
|
||||
"keyboard_shortcuts.my_profile": "Отваряне на профила ви",
|
||||
@@ -421,6 +436,8 @@
|
||||
"lightbox.close": "Затваряне",
|
||||
"lightbox.next": "Напред",
|
||||
"lightbox.previous": "Назад",
|
||||
"lightbox.zoom_in": "Увеличение до действителната големина",
|
||||
"lightbox.zoom_out": "Увеличение до побиране",
|
||||
"limited_account_hint.action": "Показване на профила въпреки това",
|
||||
"limited_account_hint.title": "Този профил е бил скрит от модераторите на {domain}.",
|
||||
"link_preview.author": "От {name}",
|
||||
@@ -442,6 +459,7 @@
|
||||
"lists.subheading": "Вашите списъци",
|
||||
"load_pending": "{count, plural, one {# нов елемент} other {# нови елемента}}",
|
||||
"loading_indicator.label": "Зареждане…",
|
||||
"media_gallery.hide": "Скриване",
|
||||
"moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Скриване от известията",
|
||||
"mute_modal.hide_options": "Скриване на възможностите",
|
||||
@@ -457,7 +475,7 @@
|
||||
"navigation_bar.advanced_interface": "Отваряне в разширен уебинтерфейс",
|
||||
"navigation_bar.blocks": "Блокирани потребители",
|
||||
"navigation_bar.bookmarks": "Отметки",
|
||||
"navigation_bar.community_timeline": "Локален инфопоток",
|
||||
"navigation_bar.community_timeline": "Локална хронология",
|
||||
"navigation_bar.compose": "Съставяне на нова публикация",
|
||||
"navigation_bar.direct": "Частни споменавания",
|
||||
"navigation_bar.discover": "Откриване",
|
||||
@@ -490,7 +508,7 @@
|
||||
"notification.favourite": "{name} направи любима публикацията ви",
|
||||
"notification.favourite.name_and_others_with_link": "{name} и <a>{count, plural, one {# друг} other {# други}}</a> направиха любима ваша публикация",
|
||||
"notification.follow": "{name} ви последва",
|
||||
"notification.follow.name_and_others": "{name} и {count, plural, one {# друг} other {# други}} ви последваха",
|
||||
"notification.follow.name_and_others": "{name} и <a>{count, plural, one {# друг} other {# други}}</a> ви последваха",
|
||||
"notification.follow_request": "{name} поиска да ви последва",
|
||||
"notification.follow_request.name_and_others": "{name} и {count, plural, one {# друг} other {# други}} поискаха да ви последват",
|
||||
"notification.label.mention": "Споменаване",
|
||||
@@ -498,6 +516,7 @@
|
||||
"notification.label.private_reply": "Личен отговор",
|
||||
"notification.label.reply": "Отговор",
|
||||
"notification.mention": "Споменаване",
|
||||
"notification.mentioned_you": "{name} ви спомена",
|
||||
"notification.moderation-warning.learn_more": "Научете повече",
|
||||
"notification.moderation_warning": "Получихте предупреждение за модериране",
|
||||
"notification.moderation_warning.action_delete_statuses": "Някои от публикациите ви са премахнати.",
|
||||
@@ -519,10 +538,15 @@
|
||||
"notification.status": "{name} току-що публикува",
|
||||
"notification.update": "{name} промени публикация",
|
||||
"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.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.title": "Отхвърляте ли заявките за известие?",
|
||||
"notification_requests.dismiss": "Отхвърлям",
|
||||
"notification_requests.dismiss_multiple": "{count, plural, one {Отхвърляне на # заявка…} other {Отхвърляне на # заявки…}}",
|
||||
"notification_requests.edit_selection": "Редактиране",
|
||||
"notification_requests.exit_selection": "Готово",
|
||||
"notification_requests.explainer_for_limited_account": "Известията от този акаунт са прецедени, защото акаунтът е ограничен от модератор.",
|
||||
@@ -543,6 +567,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Лента за бърз филтър",
|
||||
"notifications.column_settings.follow": "Нови последователи:",
|
||||
"notifications.column_settings.follow_request": "Нови заявки за последване:",
|
||||
"notifications.column_settings.group": "Групиране",
|
||||
"notifications.column_settings.mention": "Споменавания:",
|
||||
"notifications.column_settings.poll": "Резултати от анкета:",
|
||||
"notifications.column_settings.push": "Изскачащи известия",
|
||||
@@ -568,6 +593,8 @@
|
||||
"notifications.permission_required": "Известията на работния плот ги няма, щото няма дадено нужното позволение.",
|
||||
"notifications.policy.accept": "Приемам",
|
||||
"notifications.policy.accept_hint": "Показване в известия",
|
||||
"notifications.policy.drop": "Пренебрегване",
|
||||
"notifications.policy.drop_hint": "Изпращане в празнотата, за да не се видим никога пак",
|
||||
"notifications.policy.filter": "Филтър",
|
||||
"notifications.policy.filter_limited_accounts_hint": "Ограничено от модераторите на сървъра",
|
||||
"notifications.policy.filter_limited_accounts_title": "Модерирани акаунти",
|
||||
@@ -588,7 +615,7 @@
|
||||
"onboarding.actions.go_to_explore": "Виж тенденции",
|
||||
"onboarding.actions.go_to_home": "Към началния ми инфоканал",
|
||||
"onboarding.compose.template": "Здравейте, #Mastodon!",
|
||||
"onboarding.follows.empty": "За съжаление, в момента не могат да бъдат показани резултати. Може да опитате да търсите или да разгледате, за да намерите кого да последвате, или опитайте отново по-късно.",
|
||||
"onboarding.follows.empty": "За съжаление, в момента не могат да се показват резултати. Може да опитате посредством търсене или сърфиране да разгледате страницата, за да намерите хора за последване, или опитайте пак по-късно.",
|
||||
"onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!",
|
||||
"onboarding.follows.title": "Популярно в Mastodon",
|
||||
"onboarding.profile.discoverable": "Правене на моя профил откриваем",
|
||||
@@ -596,7 +623,7 @@
|
||||
"onboarding.profile.display_name": "Името на показ",
|
||||
"onboarding.profile.display_name_hint": "Вашето пълно име или псевдоним…",
|
||||
"onboarding.profile.lead": "Винаги може да завършите това по-късно в настройките, където дори има повече възможности за настройване.",
|
||||
"onboarding.profile.note": "Биогр.",
|
||||
"onboarding.profile.note": "Биография",
|
||||
"onboarding.profile.note_hint": "Може да @споменавате други хора или #хаштагове…",
|
||||
"onboarding.profile.save_and_continue": "Запазване и продължаване",
|
||||
"onboarding.profile.title": "Настройване на профила",
|
||||
@@ -613,7 +640,7 @@
|
||||
"onboarding.steps.follow_people.title": "Персонализиране на началния ви инфоканал",
|
||||
"onboarding.steps.publish_status.body": "Поздравете целия свят.",
|
||||
"onboarding.steps.publish_status.title": "Направете първата си публикация",
|
||||
"onboarding.steps.setup_profile.body": "Други са по-вероятно да взаимодействат с вас с попълнения профил.",
|
||||
"onboarding.steps.setup_profile.body": "Подсилете взаимодействията си, имайки изчерпателен профил.",
|
||||
"onboarding.steps.setup_profile.title": "Пригодете профила си",
|
||||
"onboarding.steps.share_profile.body": "Позволете на приятелите си да знаят как да ви намират в Mastodon!",
|
||||
"onboarding.steps.share_profile.title": "Споделяне на профила ви",
|
||||
@@ -684,7 +711,7 @@
|
||||
"report.placeholder": "Допълнителни коментари",
|
||||
"report.reasons.dislike": "Не ми харесва",
|
||||
"report.reasons.dislike_description": "Не е нещо, което искате да виждате",
|
||||
"report.reasons.legal": "Законово е",
|
||||
"report.reasons.legal": "Незаконно е",
|
||||
"report.reasons.legal_description": "Смятате, че това нарушава закона на вашата страна или държавата на сървъра",
|
||||
"report.reasons.other": "Нещо друго е",
|
||||
"report.reasons.other_description": "Проблемът не попада в нито една от останалите категории",
|
||||
@@ -722,7 +749,7 @@
|
||||
"search.quick_action.open_url": "Отваряне на URL адреса в Mastodon",
|
||||
"search.quick_action.status_search": "Съвпадение на публикации {x}",
|
||||
"search.search_or_paste": "Търсене/поставяне на URL",
|
||||
"search_popout.full_text_search_disabled_message": "Не е достъпно на {domain}.",
|
||||
"search_popout.full_text_search_disabled_message": "Не е налично на {domain}.",
|
||||
"search_popout.full_text_search_logged_out_message": "Достъпно само при влизане в системата.",
|
||||
"search_popout.language_code": "Код на езика по ISO",
|
||||
"search_popout.options": "Възможности при търсене",
|
||||
@@ -754,6 +781,7 @@
|
||||
"status.bookmark": "Отмятане",
|
||||
"status.cancel_reblog_private": "Край на подсилването",
|
||||
"status.cannot_reblog": "Публикацията не може да се подсилва",
|
||||
"status.continued_thread": "Продължена нишка",
|
||||
"status.copy": "Копиране на връзката към публикация",
|
||||
"status.delete": "Изтриване",
|
||||
"status.detailed_status": "Подробен изглед на разговора",
|
||||
@@ -762,6 +790,7 @@
|
||||
"status.edit": "Редактиране",
|
||||
"status.edited": "Последно редактирано на {date}",
|
||||
"status.edited_x_times": "Редактирано {count, plural,one {{count} път} other {{count} пъти}}",
|
||||
"status.embed": "Вземане на кода за вграждане",
|
||||
"status.favourite": "Любимо",
|
||||
"status.favourites": "{count, plural, one {любимо} other {любими}}",
|
||||
"status.filter": "Филтриране на публ.",
|
||||
@@ -786,6 +815,7 @@
|
||||
"status.reblogs.empty": "Още никого не е подсилвал публикацията. Подсилващият ще се покаже тук.",
|
||||
"status.redraft": "Изтриване и преработване",
|
||||
"status.remove_bookmark": "Премахване на отметката",
|
||||
"status.replied_in_thread": "Отговорено в нишката",
|
||||
"status.replied_to": "В отговор до {name}",
|
||||
"status.reply": "Отговор",
|
||||
"status.replyAll": "Отговор на нишка",
|
||||
@@ -801,9 +831,9 @@
|
||||
"status.uncached_media_warning": "Онагледяването не е налично",
|
||||
"status.unmute_conversation": "Без заглушаването на разговора",
|
||||
"status.unpin": "Разкачане от профила",
|
||||
"subscribed_languages.lead": "Публикации само на избрани езици ще се явяват в началото ви и в списъка с часови оси след промяната. Изберете \"нищо\", за да получавате публикации на всички езици.",
|
||||
"subscribed_languages.lead": "Публикации само на избрани езици ще се явяват в началото ви и в хронологичните списъци след промяната. Изберете \"нищо\", за да получавате публикации на всички езици.",
|
||||
"subscribed_languages.save": "Запазване на промените",
|
||||
"subscribed_languages.target": "Смяна на езика за {target}",
|
||||
"subscribed_languages.target": "Промяна на абонираните езици за {target}",
|
||||
"tabs_bar.home": "Начало",
|
||||
"tabs_bar.notifications": "Известия",
|
||||
"time_remaining.days": "{number, plural, one {остава # ден} other {остават # дни}}",
|
||||
@@ -823,6 +853,11 @@
|
||||
"upload_error.poll": "Качването на файлове не е позволено с анкети.",
|
||||
"upload_form.audio_description": "Опишете за хора, които са глухи или трудно чуват",
|
||||
"upload_form.description": "Опишете за хора, които са слепи или имат слабо зрение",
|
||||
"upload_form.drag_and_drop.instructions": "Натиснете интервал или enter, за да подберете мултимедийно прикачване. Провлачвайки, ползвайте клавишите със стрелки, за да премествате мултимедията във всяка дадена посока. Натиснете пак интервал или enter, за да се стовари мултимедийното прикачване в новото си положение или натиснете Esc за отмяна.",
|
||||
"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_form.thumbnail": "Промяна на миниобраза",
|
||||
"upload_form.video_description": "Опишете за хора, които са глухи или трудно чуват, слепи или имат слабо зрение",
|
||||
|
||||
@@ -172,6 +172,7 @@
|
||||
"confirmations.reply.message": "Respont bremañ a zilamo ar gemennadenn emaoc'h o skrivañ. Sur e oc'h e fell deoc'h kenderc'hel ganti?",
|
||||
"confirmations.unfollow.confirm": "Diheuliañ",
|
||||
"confirmations.unfollow.message": "Ha sur oc'h e fell deoc'h paouez da heuliañ {name} ?",
|
||||
"content_warning.show_more": "Diskouez muioc'h",
|
||||
"conversation.delete": "Dilemel ar gaozeadenn",
|
||||
"conversation.mark_as_read": "Merkañ evel lennet",
|
||||
"conversation.open": "Gwelout ar gaozeadenn",
|
||||
@@ -250,6 +251,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Implijout ur rummad a zo anezhañ pe krouiñ unan nevez",
|
||||
"filter_modal.select_filter.title": "Silañ an toud-mañ",
|
||||
"filter_modal.title.status": "Silañ un toud",
|
||||
"filter_warning.matches_filter": "A glot gant ar sil “<span>{title}</span>”",
|
||||
"firehose.all": "Pep tra",
|
||||
"firehose.local": "Ar servijer-mañ",
|
||||
"firehose.remote": "Servijerioù all",
|
||||
@@ -385,6 +387,7 @@
|
||||
"notification.admin.report": "Disklêriet eo bet {target} gant {name}",
|
||||
"notification.admin.sign_up": "{name} en·he deus lakaet e·hec'h anv",
|
||||
"notification.follow": "heuliañ a ra {name} ac'hanoc'h",
|
||||
"notification.follow.name_and_others": "{name} <a>{count, plural, one {hag # den all} two {ha # zen all} few {ha # den all} many {ha # den all} other {ha # den all}}</a> zo o heuliañ ac'hanoc'h",
|
||||
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
|
||||
"notification.moderation-warning.learn_more": "Gouzout hiroc'h",
|
||||
"notification.own_poll": "Echu eo ho sontadeg",
|
||||
@@ -399,6 +402,7 @@
|
||||
"notifications.column_settings.favourite": "Muiañ-karet:",
|
||||
"notifications.column_settings.follow": "Heulierien nevez:",
|
||||
"notifications.column_settings.follow_request": "Pedadoù heuliañ nevez :",
|
||||
"notifications.column_settings.group": "Strollañ",
|
||||
"notifications.column_settings.mention": "Menegoù:",
|
||||
"notifications.column_settings.poll": "Disoc'hoù ar sontadeg:",
|
||||
"notifications.column_settings.push": "Kemennoù push",
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Deixar de seguir l'usuari?",
|
||||
"content_warning.hide": "Amaga la publicació",
|
||||
"content_warning.show": "Mostra-la igualment",
|
||||
"content_warning.show_more": "Mostra'n més",
|
||||
"conversation.delete": "Elimina la conversa",
|
||||
"conversation.mark_as_read": "Marca com a llegida",
|
||||
"conversation.open": "Mostra la conversa",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Usa una categoria existent o crea'n una de nova",
|
||||
"filter_modal.select_filter.title": "Filtra aquest tut",
|
||||
"filter_modal.title.status": "Filtra un tut",
|
||||
"filter_warning.matches_filter": "Coincideix amb el filtre “{title}”",
|
||||
"filter_warning.matches_filter": "Coincideix amb el filtre “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {De ningú} one {D'una persona} other {De # persones}} que potser coneixes",
|
||||
"filtered_notifications_banner.title": "Notificacions filtrades",
|
||||
"firehose.all": "Tots",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} ha afavorit el teu tut",
|
||||
"notification.favourite.name_and_others_with_link": "{name} i <a>{count, plural, one {# altre} other {# altres}}</a> han afavorit la vostra publicació",
|
||||
"notification.follow": "{name} et segueix",
|
||||
"notification.follow.name_and_others": "{name} i {count, plural, one {# altre} other {# altres}} us han seguit",
|
||||
"notification.follow.name_and_others": "{name} i <a>{count, plural, one {# altre} other {# altres}}</a> us han seguit",
|
||||
"notification.follow_request": "{name} ha sol·licitat de seguir-te",
|
||||
"notification.follow_request.name_and_others": "{name} i {count, plural, one {# altre} other {# altres}} han demanat de seguir-vos",
|
||||
"notification.label.mention": "Menció",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Resposta en privat",
|
||||
"notification.label.reply": "Resposta",
|
||||
"notification.mention": "Menció",
|
||||
"notification.mentioned_you": "{name} us ha mencionat",
|
||||
"notification.moderation-warning.learn_more": "Per a saber-ne més",
|
||||
"notification.moderation_warning": "Heu rebut un avís de moderació",
|
||||
"notification.moderation_warning.action_delete_statuses": "S'han eliminat algunes de les vostres publicacions.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Barra ràpida de filtres",
|
||||
"notifications.column_settings.follow": "Nous seguidors:",
|
||||
"notifications.column_settings.follow_request": "Noves sol·licituds de seguiment:",
|
||||
"notifications.column_settings.group": "Agrupa",
|
||||
"notifications.column_settings.mention": "Mencions:",
|
||||
"notifications.column_settings.poll": "Resultats de l’enquesta:",
|
||||
"notifications.column_settings.push": "Notificacions push",
|
||||
@@ -612,11 +615,11 @@
|
||||
"onboarding.action.back": "Porta'm enrere",
|
||||
"onboarding.actions.back": "Porta'm enrere",
|
||||
"onboarding.actions.go_to_explore": "Mira què és tendència",
|
||||
"onboarding.actions.go_to_home": "Ves a la teva línia de temps",
|
||||
"onboarding.actions.go_to_home": "Aneu a la vostra pantalla d'inici",
|
||||
"onboarding.compose.template": "Hola Mastodon!",
|
||||
"onboarding.follows.empty": "Malauradament, cap resultat pot ser mostrat ara mateix. Pots provar de fer servir la cerca o visitar la pàgina Explora per a trobar gent a qui seguir o provar-ho de nou més tard.",
|
||||
"onboarding.follows.lead": "La teva línia de temps inici només està a les teves mans. Com més gent segueixis, més activa i interessant serà. Aquests perfils poden ser un bon punt d'inici—sempre pots acabar deixant de seguir-los!:",
|
||||
"onboarding.follows.title": "Personalitza la pantalla d'inci",
|
||||
"onboarding.follows.lead": "La vostra pantalla d'inici és la manera principal d'experimentar Mastodon. Com més gent seguiu, més activa i interessant serà. Per a començar, alguns suggeriments:",
|
||||
"onboarding.follows.title": "Personalitzeu la pantalla d'inci",
|
||||
"onboarding.profile.discoverable": "Fes el meu perfil descobrible",
|
||||
"onboarding.profile.discoverable_hint": "En acceptar d'ésser descobert a Mastodon els teus missatges poden aparèixer dins les tendències i els resultats de cerques, i el teu perfil es pot suggerir a qui tingui interessos semblants als teus.",
|
||||
"onboarding.profile.display_name": "Nom que es mostrarà",
|
||||
@@ -636,7 +639,7 @@
|
||||
"onboarding.start.skip": "Vols saltar-te tota la resta?",
|
||||
"onboarding.start.title": "Llestos!",
|
||||
"onboarding.steps.follow_people.body": "Mastodon va de seguir a gent interessant.",
|
||||
"onboarding.steps.follow_people.title": "Personalitza la pantalla d'inci",
|
||||
"onboarding.steps.follow_people.title": "Personalitzeu la pantalla d'inici",
|
||||
"onboarding.steps.publish_status.body": "Saluda al món amb text, fotos, vídeos o enquestes {emoji}",
|
||||
"onboarding.steps.publish_status.title": "Fes el teu primer tut",
|
||||
"onboarding.steps.setup_profile.body": "És més fàcil que altres interactuïn amb tu si tens un perfil complet.",
|
||||
@@ -675,7 +678,7 @@
|
||||
"recommended": "Recomanat",
|
||||
"refresh": "Actualitza",
|
||||
"regeneration_indicator.label": "Es carrega…",
|
||||
"regeneration_indicator.sublabel": "Es prepara la teva línia de temps d'Inici!",
|
||||
"regeneration_indicator.sublabel": "Es prepara la vostra pantalla d'Inici!",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.full.days": "fa {number, plural, one {# dia} other {# dies}}",
|
||||
"relative_time.full.hours": "fa {number, plural, one {# hora} other {# hores}}",
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
"about.rules": "Rheolau'r gweinydd",
|
||||
"account.account_note_header": "Nodyn personol",
|
||||
"account.add_or_remove_from_list": "Ychwanegu neu Ddileu o'r rhestrau",
|
||||
"account.badges.bot": "Bot",
|
||||
"account.badges.bot": "Awtomataidd",
|
||||
"account.badges.group": "Grŵp",
|
||||
"account.block": "Blocio @{name}",
|
||||
"account.block_domain": "Blocio parth {domain}",
|
||||
@@ -36,7 +36,7 @@
|
||||
"account.followers.empty": "Does neb yn dilyn y defnyddiwr hwn eto.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} dilynwr} two {{counter} ddilynwr} other {{counter} dilynwyr}}",
|
||||
"account.following": "Yn dilyn",
|
||||
"account.following_counter": "{count, plural, one {Yn dilyn {counter}} other {Yn dilyn {counter}}}",
|
||||
"account.following_counter": "{count, plural, one {Yn dilyn {counter}} other {Yn dilyn {counter} arall}}",
|
||||
"account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
|
||||
"account.go_to_profile": "Mynd i'r proffil",
|
||||
"account.hide_reblogs": "Cuddio hybiau gan @{name}",
|
||||
@@ -62,7 +62,7 @@
|
||||
"account.requested_follow": "Mae {name} wedi gwneud cais i'ch dilyn",
|
||||
"account.share": "Rhannwch broffil @{name}",
|
||||
"account.show_reblogs": "Dangos hybiau gan @{name}",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} post} two {{counter} bost} few {{counter} phost} many {{counter} post} other {{counter} post}}",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} postiad} two {{counter} bostiad} few {{counter} phostiad} many {{counter} postiad} other {{counter} postiad}}",
|
||||
"account.unblock": "Dadflocio @{name}",
|
||||
"account.unblock_domain": "Dadflocio parth {domain}",
|
||||
"account.unblock_short": "Dadflocio",
|
||||
@@ -85,12 +85,13 @@
|
||||
"alert.rate_limited.title": "Cyfradd gyfyngedig",
|
||||
"alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
|
||||
"alert.unexpected.title": "Wps!",
|
||||
"alt_text_badge.title": "Testun Amgen",
|
||||
"announcement.announcement": "Cyhoeddiad",
|
||||
"attachments_list.unprocessed": "(heb eu prosesu)",
|
||||
"audio.hide": "Cuddio sain",
|
||||
"block_modal.remote_users_caveat": "Byddwn yn gofyn i'r gweinydd {domain} barchu eich penderfyniad. Fodd bynnag, nid yw cydymffurfiad wedi'i warantu gan y gall rhai gweinyddwyr drin rhwystro mewn ffyrdd gwahanol. Mae'n bosibl y bydd postiadau cyhoeddus yn dal i fod yn weladwy i ddefnyddwyr nad ydynt wedi mewngofnodi.",
|
||||
"block_modal.show_less": "Dangos llai",
|
||||
"block_modal.show_more": "Dangos mwy",
|
||||
"block_modal.show_more": "Dangos rhagor",
|
||||
"block_modal.they_cant_mention": "Nid ydynt yn gallu eich crybwyll na'ch dilyn.",
|
||||
"block_modal.they_cant_see_posts": "Nid ydynt yn gallu gweld eich postiadau ac ni fyddwch yn gweld eu rhai hwy.",
|
||||
"block_modal.they_will_know": "Gallant weld eu bod wedi'u rhwystro.",
|
||||
@@ -162,9 +163,9 @@
|
||||
"compose_form.poll.switch_to_single": "Newid pleidlais i gyfyngu i un dewis",
|
||||
"compose_form.poll.type": "Arddull",
|
||||
"compose_form.publish": "Postiad",
|
||||
"compose_form.publish_form": "Cyhoeddi",
|
||||
"compose_form.publish_form": "Postiad newydd",
|
||||
"compose_form.reply": "Ateb",
|
||||
"compose_form.save_changes": "Diweddariad",
|
||||
"compose_form.save_changes": "Diweddaru",
|
||||
"compose_form.spoiler.marked": "Dileu rhybudd cynnwys",
|
||||
"compose_form.spoiler.unmarked": "Ychwanegu rhybudd cynnwys",
|
||||
"compose_form.spoiler_placeholder": "Rhybudd cynnwys (dewisol)",
|
||||
@@ -196,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Dad-ddilyn defnyddiwr?",
|
||||
"content_warning.hide": "Cuddio'r postiad",
|
||||
"content_warning.show": "Dangos beth bynnag",
|
||||
"content_warning.show_more": "Dangos rhagor",
|
||||
"conversation.delete": "Dileu sgwrs",
|
||||
"conversation.mark_as_read": "Nodi fel wedi'i ddarllen",
|
||||
"conversation.open": "Gweld sgwrs",
|
||||
@@ -221,6 +223,8 @@
|
||||
"domain_block_modal.they_cant_follow": "Ni all neb o'r gweinydd hwn eich dilyn.",
|
||||
"domain_block_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu blocio.",
|
||||
"domain_block_modal.title": "Blocio parth?",
|
||||
"domain_block_modal.you_will_lose_num_followers": "Byddwch yn colli {followersCount, plural, one {{followersCountDisplay} dilynwr} other {{followersCountDisplay} dilynwyr}} a {followingCount, plural, one {{followingCountDisplay} person rydych yn dilyn} other {{followingCountDisplay} o bobl rydych yn eu dilyn}}.",
|
||||
"domain_block_modal.you_will_lose_relationships": "Byddwch yn colli'r holl ddilynwyr a phobl rydych chi'n eu dilyn o'r gweinydd hwn.",
|
||||
"domain_block_modal.you_wont_see_posts": "Fyddwch chi ddim yn gweld postiadau na hysbysiadau gan ddefnyddwyr ar y gweinydd hwn.",
|
||||
"domain_pill.activitypub_lets_connect": "Mae'n caniatáu ichi gysylltu a rhyngweithio â phobl nid yn unig ar Mastodon, ond ar draws gwahanol apiau cymdeithasol hefyd.",
|
||||
"domain_pill.activitypub_like_language": "Mae ActivityPub fel yr iaith y mae Mastodon yn ei siarad â rhwydweithiau cymdeithasol eraill.",
|
||||
@@ -302,8 +306,8 @@
|
||||
"filter_modal.select_filter.subtitle": "Defnyddiwch gategori sy'n bodoli eisoes neu crëu un newydd",
|
||||
"filter_modal.select_filter.title": "Hidlo'r postiad hwn",
|
||||
"filter_modal.title.status": "Hidlo postiad",
|
||||
"filter_warning.matches_filter": "Yn cydweddu'r hidlydd “{title}”",
|
||||
"filtered_notifications_banner.pending_requests": "Gan {count, plural, =0 {no one} one {un person} two {# berson} few {# pherson} other {# person}} efallai eich bod yn eu hadnabod",
|
||||
"filter_warning.matches_filter": "Yn cyd-fynd â'r hidlydd “ <span>{title}</span> ”",
|
||||
"filtered_notifications_banner.pending_requests": "Oddi wrth {count, plural, =0 {no one} one {un person} two {# berson} few {# pherson} other {# person}} efallai eich bod yn eu hadnabod",
|
||||
"filtered_notifications_banner.title": "Hysbysiadau wedi'u hidlo",
|
||||
"firehose.all": "Popeth",
|
||||
"firehose.local": "Gweinydd hwn",
|
||||
@@ -346,12 +350,12 @@
|
||||
"hashtag.column_settings.tag_mode.any": "Unrhyw un o'r rhain",
|
||||
"hashtag.column_settings.tag_mode.none": "Dim o'r rhain",
|
||||
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
||||
"hashtag.counter_by_accounts": "{cyfrif, lluosog, un {{counter} cyfranogwr} arall {{counter} cyfranogwr}}",
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} cyfranogwr} other {{counter} cyfranogwr}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {postiad {counter}} other {postiad {counter}}}",
|
||||
"hashtag.counter_by_uses_today": "{cyfrif, lluosog, un {{counter} postiad} arall {{counter} postiad}} heddiw",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} postiad} other {{counter} postiad}} heddiw",
|
||||
"hashtag.follow": "Dilyn hashnod",
|
||||
"hashtag.unfollow": "Dad-ddilyn hashnod",
|
||||
"hashtags.and_other": "…a {count, plural, other {# more}}",
|
||||
"hashtags.and_other": "…a {count, plural, other {# arall}}",
|
||||
"hints.profiles.followers_may_be_missing": "Mae'n bosibl bod dilynwyr y proffil hwn ar goll.",
|
||||
"hints.profiles.follows_may_be_missing": "Mae'n bosibl bod dilynwyr y proffil hwn ar goll.",
|
||||
"hints.profiles.posts_may_be_missing": "Mae'n bosibl bod rhai postiadau y proffil hwn ar goll.",
|
||||
@@ -439,7 +443,7 @@
|
||||
"limited_account_hint.title": "Mae'r proffil hwn wedi cael ei guddio gan gymedrolwyr {domain}.",
|
||||
"link_preview.author": "Gan {name}",
|
||||
"link_preview.more_from_author": "Mwy gan {name}",
|
||||
"link_preview.shares": "{count, plural, one {{counter} ostiad } two {{counter} bostiad } few {{counter} postiad} many {{counter} postiad} other {{counter} postiad}}",
|
||||
"link_preview.shares": "{count, plural, one {{counter} postiad } two {{counter} bostiad } few {{counter} postiad} many {{counter} postiad} other {{counter} postiad}}",
|
||||
"lists.account.add": "Ychwanegu at restr",
|
||||
"lists.account.remove": "Tynnu o'r rhestr",
|
||||
"lists.delete": "Dileu rhestr",
|
||||
@@ -496,23 +500,24 @@
|
||||
"navigation_bar.security": "Diogelwch",
|
||||
"not_signed_in_indicator.not_signed_in": "Rhaid i chi fewngofnodi i weld yr adnodd hwn.",
|
||||
"notification.admin.report": "Adroddwyd ar {name} {target}",
|
||||
"notification.admin.report_account": "{name} reported {count, plural, one {un postiad} other {# postiad}} from {target} for {category}",
|
||||
"notification.admin.report_account_other": "Adroddodd {name} {count, plural, one {un postiad} two {# bostiad} few {# phost} other {# postiad}} gan {target}",
|
||||
"notification.admin.report_account": "Adroddodd {name} {count, plural, one {un postiad} other {# postiad}} gan {target} oherwydd {category}",
|
||||
"notification.admin.report_account_other": "Adroddodd {name} {count, plural, one {un postiad} two {# bostiad} few {# postiad} other {# postiad}} gan {target}",
|
||||
"notification.admin.report_statuses": "Adroddodd {name} {target} ar gyfer {category}",
|
||||
"notification.admin.report_statuses_other": "Adroddodd {name} {target}",
|
||||
"notification.admin.sign_up": "Cofrestrodd {name}",
|
||||
"notification.admin.sign_up.name_and_others": "Cofrestrodd {name} {count, plural, one {ac # arall} other {a # eraill}}",
|
||||
"notification.admin.sign_up.name_and_others": "Cofrestrodd {name} {count, plural, one {ac # arall} other {a # arall}}",
|
||||
"notification.favourite": "Ffafriodd {name} eich postiad",
|
||||
"notification.favourite.name_and_others_with_link": "Ffafriodd {name} a <a>{count, plural, one {# arall} other {# eraill}}</a> eich postiad",
|
||||
"notification.favourite.name_and_others_with_link": "Ffafriodd {name} a <a>{count, plural, one {# arall} other {# arall}}</a> eich postiad",
|
||||
"notification.follow": "Dilynodd {name} chi",
|
||||
"notification.follow.name_and_others": "Mae {name} a {count, plural, one {# other} other {# others}} wedi'ch dilyn chi",
|
||||
"notification.follow.name_and_others": "Mae {name} a <a>{count, plural, zero {}one {# arall} two {# arall} few {# arall} many {# others} other {# arall}}</a> nawr yn eich dilyn chi",
|
||||
"notification.follow_request": "Mae {name} wedi gwneud cais i'ch dilyn",
|
||||
"notification.follow_request.name_and_others": "Mae {name} a{count, plural, one {# other} other {# others}} wedi gofyn i'ch dilyn chi",
|
||||
"notification.follow_request.name_and_others": "Mae {name} a{count, plural, one {# arall} other {# arall}} wedi gofyn i'ch dilyn chi",
|
||||
"notification.label.mention": "Crybwyll",
|
||||
"notification.label.private_mention": "Crybwyll preifat",
|
||||
"notification.label.private_reply": "Ateb preifat",
|
||||
"notification.label.reply": "Ateb",
|
||||
"notification.mention": "Crybwyll",
|
||||
"notification.mentioned_you": "Rydych wedi'ch crybwyll gan {name}",
|
||||
"notification.moderation-warning.learn_more": "Dysgu mwy",
|
||||
"notification.moderation_warning": "Rydych wedi derbyn rhybudd gan gymedrolwr",
|
||||
"notification.moderation_warning.action_delete_statuses": "Mae rhai o'ch postiadau wedi'u dileu.",
|
||||
@@ -525,7 +530,7 @@
|
||||
"notification.own_poll": "Mae eich pleidlais wedi dod i ben",
|
||||
"notification.poll": "Mae arolwg y gwnaethoch bleidleisio ynddo wedi dod i ben",
|
||||
"notification.reblog": "Hybodd {name} eich post",
|
||||
"notification.reblog.name_and_others_with_link": "Mae {name} a <a>{count, plural, one {# other} other {# others}}</a> wedi hybu eich postiad",
|
||||
"notification.reblog.name_and_others_with_link": "Mae {name} a <a>{count, plural, one {# arall} other {# arall}}</a> wedi hybu eich postiad",
|
||||
"notification.relationships_severance_event": "Wedi colli cysylltiad â {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Mae gweinyddwr o {from} wedi atal {target}, sy'n golygu na allwch dderbyn diweddariadau ganddynt mwyach na rhyngweithio â nhw.",
|
||||
"notification.relationships_severance_event.domain_block": "Mae gweinyddwr o {from} wedi blocio {target}, gan gynnwys {followersCount} o'ch dilynwyr a {followingCount, plural, one {# cyfrif} other {# cyfrif}} arall rydych chi'n ei ddilyn.",
|
||||
@@ -534,9 +539,9 @@
|
||||
"notification.status": "{name} newydd ei bostio",
|
||||
"notification.update": "Golygodd {name} bostiad",
|
||||
"notification_requests.accept": "Derbyn",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {Accept # request…} other {Accept # requests…}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Accept request} other {Accept requests}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Rydych ar fin derbyn {count, plural, one {one notification request} other {# notification requests}}. Ydych chi'n siŵr eich bod am barhau?",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {Derbyn # cais…} other {Derbyn # cais…}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Derbyn cais} other {Derbyn cais}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Rydych ar fin derbyn {count, plural, one {un cais hysbysiad} other {# cais hysbysiad}}. Ydych chi'n siŵr eich bod am barhau?",
|
||||
"notification_requests.confirm_accept_multiple.title": "Derbyn ceisiadau hysbysu?",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Diystyru cais} other {Diystyru ceisiadau}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "Rydych ar fin diystyru {count, plural, one {un cais hysbysu} other {# cais hysbysiad}}. Fyddwch chi ddim yn gallu cyrchu {count, plural, one {it} other {them}} yn hawdd eto. Ydych chi'n yn siŵr eich bod am fwrw ymlaen?",
|
||||
@@ -563,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Bar hidlo cyflym",
|
||||
"notifications.column_settings.follow": "Dilynwyr newydd:",
|
||||
"notifications.column_settings.follow_request": "Ceisiadau dilyn newydd:",
|
||||
"notifications.column_settings.group": "Grŵp",
|
||||
"notifications.column_settings.mention": "Crybwylliadau:",
|
||||
"notifications.column_settings.poll": "Canlyniadau pleidlais:",
|
||||
"notifications.column_settings.push": "Hysbysiadau gwthiadwy",
|
||||
@@ -684,7 +690,7 @@
|
||||
"relative_time.minutes": "{number} munud",
|
||||
"relative_time.seconds": "{number} eiliad",
|
||||
"relative_time.today": "heddiw",
|
||||
"reply_indicator.attachments": "{count, plural, one {# attachment} arall {# attachments}}",
|
||||
"reply_indicator.attachments": "{count, plural, one {# atodiad} other {# atodiad}}",
|
||||
"reply_indicator.cancel": "Canslo",
|
||||
"reply_indicator.poll": "Arolwg",
|
||||
"report.block": "Blocio",
|
||||
@@ -727,7 +733,7 @@
|
||||
"report.thanks.title_actionable": "Diolch am adrodd, byddwn yn ymchwilio i hyn.",
|
||||
"report.unfollow": "Dad-ddilyn @{name}",
|
||||
"report.unfollow_explanation": "Rydych chi'n dilyn y cyfrif hwn. I beidio â gweld eu postiadau yn eich ffrwd gartref mwyach, dad-ddilynwch nhw.",
|
||||
"report_notification.attached_statuses": "{count, plural, one {{count} postiad} arall {{count} postiad}} atodwyd",
|
||||
"report_notification.attached_statuses": "{count, plural, one {{count} postiad} other {{count} postiad}} wedi'i atodi",
|
||||
"report_notification.categories.legal": "Cyfreithiol",
|
||||
"report_notification.categories.legal_sentence": "cynnwys anghyfreithlon",
|
||||
"report_notification.categories.other": "Arall",
|
||||
@@ -807,7 +813,7 @@
|
||||
"status.reblog": "Hybu",
|
||||
"status.reblog_private": "Hybu i'r gynulleidfa wreiddiol",
|
||||
"status.reblogged_by": "Hybodd {name}",
|
||||
"status.reblogs": "{count, plural, one {hwb} other {hwb}}",
|
||||
"status.reblogs": "{count, plural, one {# hwb} other {# hwb}}",
|
||||
"status.reblogs.empty": "Does neb wedi hybio'r post yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.",
|
||||
"status.redraft": "Dileu ac ailddrafftio",
|
||||
"status.remove_bookmark": "Tynnu nod tudalen",
|
||||
@@ -849,6 +855,11 @@
|
||||
"upload_error.poll": "Nid oes modd llwytho ffeiliau â phleidleisiau.",
|
||||
"upload_form.audio_description": "Disgrifio ar gyfer pobl sydd â cholled clyw",
|
||||
"upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
|
||||
"upload_form.drag_and_drop.instructions": "I godi atodiad cyfryngau, pwyswch y space neu enter. Wrth lusgo, defnyddiwch y bysellau saeth i symud yr atodiad cyfryngau i unrhyw gyfeiriad penodol. Pwyswch space neu enter eto i ollwng yr atodiad cyfryngau yn ei safle newydd, neu pwyswch escape i ddiddymu.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Cafodd llusgo ei ddiddymu. Cafodd atodiad cyfryngau {item} ei ollwng.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "Cafodd atodiad cyfryngau {item} ei ollwng.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "Symudwyd atodiad cyfryngau {item}.",
|
||||
"upload_form.drag_and_drop.on_drag_start": "Atodiad cyfryngau godwyd {item}.",
|
||||
"upload_form.edit": "Golygu",
|
||||
"upload_form.thumbnail": "Newid llun bach",
|
||||
"upload_form.video_description": "Disgrifio ar gyfer pobl sydd â cholled clyw neu amhariad golwg",
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Følg ikke længere bruger?",
|
||||
"content_warning.hide": "Skjul indlæg",
|
||||
"content_warning.show": "Vis alligevel",
|
||||
"content_warning.show_more": "Vis flere",
|
||||
"conversation.delete": "Slet samtale",
|
||||
"conversation.mark_as_read": "Markér som læst",
|
||||
"conversation.open": "Vis samtale",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Vælg en eksisterende kategori eller opret en ny",
|
||||
"filter_modal.select_filter.title": "Filtrér dette indlæg",
|
||||
"filter_modal.title.status": "Filtrér et indlæg",
|
||||
"filter_warning.matches_filter": "Matcher filteret “{title}”",
|
||||
"filter_warning.matches_filter": "Matcher filteret “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "Fra {count, plural, =0 {ingen} one {én person} other {# personer}}, man måske kender",
|
||||
"filtered_notifications_banner.title": "Filtrerede notifikationer",
|
||||
"firehose.all": "Alle",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} favoritmarkerede dit indlæg",
|
||||
"notification.favourite.name_and_others_with_link": "{name} og <a>{count, plural, one {# anden} other {# andre}}</a> gjorde dit indlæg til favorit",
|
||||
"notification.follow": "{name} begyndte at følge dig",
|
||||
"notification.follow.name_and_others": "{name} og {count, plural, one {# anden} other {# andre}} følger dig",
|
||||
"notification.follow.name_and_others": "{name} og <a>{count, plural, one {# andre} other {# andre}}</a> begyndte at følge dig",
|
||||
"notification.follow_request": "{name} har anmodet om at følge dig",
|
||||
"notification.follow_request.name_and_others": "{name} og {count, plural, one {# anden} other {# andre}} har anmodet om at følger dig",
|
||||
"notification.label.mention": "Omtale",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Privat svar",
|
||||
"notification.label.reply": "Besvar",
|
||||
"notification.mention": "Omtale",
|
||||
"notification.mentioned_you": "{name} nævnte dig",
|
||||
"notification.moderation-warning.learn_more": "Læs mere",
|
||||
"notification.moderation_warning": "Du er tildelt en moderationsadvarsel",
|
||||
"notification.moderation_warning.action_delete_statuses": "Nogle af dine indlæg er blevet fjernet.",
|
||||
@@ -566,6 +568,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.mention": "Omtaler:",
|
||||
"notifications.column_settings.poll": "Afstemningsresultater:",
|
||||
"notifications.column_settings.push": "Push-notifikationer",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"account.block_domain": "{domain} sperren",
|
||||
"account.block_short": "Blockieren",
|
||||
"account.blocked": "Blockiert",
|
||||
"account.cancel_follow_request": "Folgeanfrage zurückziehen",
|
||||
"account.cancel_follow_request": "Follower-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",
|
||||
@@ -41,7 +41,7 @@
|
||||
"account.go_to_profile": "Profil aufrufen",
|
||||
"account.hide_reblogs": "Geteilte Beiträge von @{name} ausblenden",
|
||||
"account.in_memoriam": "Zum Andenken.",
|
||||
"account.joined_short": "Beigetreten",
|
||||
"account.joined_short": "Mitglied seit",
|
||||
"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.",
|
||||
@@ -94,7 +94,7 @@
|
||||
"block_modal.show_more": "Mehr anzeigen",
|
||||
"block_modal.they_cant_mention": "Das Profil wird dich nicht erwähnen oder dir folgen können.",
|
||||
"block_modal.they_cant_see_posts": "Deine Beiträge können nicht mehr angesehen werden und du wirst deren Beiträge nicht mehr sehen.",
|
||||
"block_modal.they_will_know": "Es wird erkennbar sein, dass dieses Profil blockiert wurde.",
|
||||
"block_modal.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",
|
||||
@@ -157,7 +157,7 @@
|
||||
"compose_form.placeholder": "Was gibt’s Neues?",
|
||||
"compose_form.poll.duration": "Umfragedauer",
|
||||
"compose_form.poll.multiple": "Mehrfachauswahl",
|
||||
"compose_form.poll.option_placeholder": "Option {number}",
|
||||
"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",
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Profil entfolgen?",
|
||||
"content_warning.hide": "Beitrag ausblenden",
|
||||
"content_warning.show": "Trotzdem anzeigen",
|
||||
"content_warning.show_more": "Mehr anzeigen",
|
||||
"conversation.delete": "Unterhaltung löschen",
|
||||
"conversation.mark_as_read": "Als gelesen markieren",
|
||||
"conversation.open": "Unterhaltung anzeigen",
|
||||
@@ -232,7 +233,7 @@
|
||||
"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.username": "Profilname",
|
||||
"domain_pill.whats_in_a_handle": "Was ist Teil der Adresse?",
|
||||
"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_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:",
|
||||
@@ -305,12 +306,12 @@
|
||||
"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": "Übereinstimmend mit dem Filter „{title}“",
|
||||
"filter_warning.matches_filter": "Übereinstimmend mit dem Filter „<span>{title}</span>“",
|
||||
"filtered_notifications_banner.pending_requests": "Von {count, plural, =0 {keinem, den} one {einer Person, die} other {# Personen, die}} du möglicherweise kennst",
|
||||
"filtered_notifications_banner.title": "Gefilterte Benachrichtigungen",
|
||||
"firehose.all": "Alles",
|
||||
"firehose.all": "Alle Server",
|
||||
"firehose.local": "Dieser Server",
|
||||
"firehose.remote": "Andere Server",
|
||||
"firehose.remote": "Externe Server",
|
||||
"follow_request.authorize": "Genehmigen",
|
||||
"follow_request.reject": "Ablehnen",
|
||||
"follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.",
|
||||
@@ -464,12 +465,12 @@
|
||||
"mute_modal.hide_from_notifications": "Benachrichtigungen ausblenden",
|
||||
"mute_modal.hide_options": "Einstellungen ausblenden",
|
||||
"mute_modal.indefinite": "Bis ich die Stummschaltung aufhebe",
|
||||
"mute_modal.show_options": "Einstellungen anzeigen",
|
||||
"mute_modal.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": "Es wird nicht erkennbar sein, dass dieses Profil stummgeschaltet wurde.",
|
||||
"mute_modal.they_wont_know": "Das Profil wird nicht erkennen können, dass du es stummgeschaltet hast.",
|
||||
"mute_modal.title": "Profil stummschalten?",
|
||||
"mute_modal.you_wont_see_mentions": "Du wirst keine Beiträge sehen, die dieses Profil erwähnen.",
|
||||
"mute_modal.you_wont_see_posts": "Deine Beiträge können weiterhin angesehen werden, aber du wirst deren Beiträge nicht mehr sehen.",
|
||||
"mute_modal.you_wont_see_posts": "Deine Beiträge können von diesem stummgeschalteten Profil weiterhin gesehen werden, aber du wirst dessen Beiträge nicht mehr sehen.",
|
||||
"navigation_bar.about": "Über",
|
||||
"navigation_bar.administration": "Administration",
|
||||
"navigation_bar.advanced_interface": "Im erweiterten Webinterface öffnen",
|
||||
@@ -504,18 +505,19 @@
|
||||
"notification.admin.report_statuses": "{name} meldete {target} wegen {category}",
|
||||
"notification.admin.report_statuses_other": "{name} meldete {target}",
|
||||
"notification.admin.sign_up": "{name} registrierte sich",
|
||||
"notification.admin.sign_up.name_and_others": "{name} und {count, plural, one {# weitere Person} other {# weitere Personen}} registrierten sich",
|
||||
"notification.admin.sign_up.name_and_others": "{name} und {count, plural, one {# weiteres Profil} other {# weitere Profile}} registrierten sich",
|
||||
"notification.favourite": "{name} favorisierte deinen Beitrag",
|
||||
"notification.favourite.name_and_others_with_link": "{name} und <a>{count, plural, one {# weitere Person} other {# weitere Personen}}</a> favorisierten deinen Beitrag",
|
||||
"notification.favourite.name_and_others_with_link": "{name} und <a>{count, plural, one {# weiteres Profil} other {# weitere Profile}}</a> favorisierten deinen Beitrag",
|
||||
"notification.follow": "{name} folgt dir",
|
||||
"notification.follow.name_and_others": "{name} und {count, plural, one {# weitere Person} other {# weitere Personen}} folgen dir",
|
||||
"notification.follow.name_and_others": "{name} und <a>{count, plural, one {# weiteres Profil} other {# weitere Profile}}</a> folgen dir",
|
||||
"notification.follow_request": "{name} möchte dir folgen",
|
||||
"notification.follow_request.name_and_others": "{name} und {count, plural, one {# weitere Person} other {# weitere Personen}} möchten dir folgen",
|
||||
"notification.follow_request.name_and_others": "{name} und {count, plural, one {# weiteres Profil} other {# weitere Profile}} möchten dir folgen",
|
||||
"notification.label.mention": "Erwähnung",
|
||||
"notification.label.private_mention": "Private Erwähnung",
|
||||
"notification.label.private_reply": "Private Antwort",
|
||||
"notification.label.reply": "Antwort",
|
||||
"notification.mention": "Erwähnung",
|
||||
"notification.mentioned_you": "{name} erwähnte dich",
|
||||
"notification.moderation-warning.learn_more": "Mehr erfahren",
|
||||
"notification.moderation_warning": "Du wurdest von den Moderator*innen verwarnt",
|
||||
"notification.moderation_warning.action_delete_statuses": "Einige deiner Beiträge sind entfernt worden.",
|
||||
@@ -528,13 +530,13 @@
|
||||
"notification.own_poll": "Deine Umfrage ist beendet",
|
||||
"notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet",
|
||||
"notification.reblog": "{name} teilte deinen Beitrag",
|
||||
"notification.reblog.name_and_others_with_link": "{name} und <a>{count, plural, one {# weitere Person} other {# weitere Personen}}</a> teilten deinen Beitrag",
|
||||
"notification.reblog.name_and_others_with_link": "{name} und <a>{count, plural, one {# weiteres Profil} other {# weitere Profile}}</a> teilten deinen Beitrag",
|
||||
"notification.relationships_severance_event": "Verbindungen mit {name} verloren",
|
||||
"notification.relationships_severance_event.account_suspension": "Ein Admin von {from} hat {target} gesperrt. Du wirst von diesem Profil keine Updates mehr erhalten und auch nicht mit ihm interagieren können.",
|
||||
"notification.relationships_severance_event.domain_block": "Ein Admin von {from} hat {target} blockiert – darunter {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst.",
|
||||
"notification.relationships_severance_event.learn_more": "Mehr erfahren",
|
||||
"notification.relationships_severance_event.user_domain_block": "Du hast {target} blockiert – {followersCount} deiner Follower und {followingCount, plural, one {# Konto, dem} other {# Konten, denen}} du folgst, wurden entfernt.",
|
||||
"notification.status": "{name} hat gerade etwas gepostet",
|
||||
"notification.status": "{name} veröffentlichte gerade",
|
||||
"notification.update": "{name} bearbeitete einen Beitrag",
|
||||
"notification_requests.accept": "Genehmigen",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {# Anfrage genehmigen …} other {# Anfragen genehmigen …}}",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Filterleiste",
|
||||
"notifications.column_settings.follow": "Neue Follower:",
|
||||
"notifications.column_settings.follow_request": "Neue Follower-Anfragen:",
|
||||
"notifications.column_settings.group": "Gruppieren",
|
||||
"notifications.column_settings.mention": "Erwähnungen:",
|
||||
"notifications.column_settings.poll": "Umfrageergebnisse:",
|
||||
"notifications.column_settings.push": "Push-Benachrichtigungen",
|
||||
@@ -596,15 +599,15 @@
|
||||
"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": "Moderierte Konten",
|
||||
"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_new_accounts_title": "neuen Konten",
|
||||
"notifications.policy.filter_not_followers_hint": "Einschließlich Profilen, die dir seit weniger als {days, plural, one {einem Tag} other {# Tagen}} folgen",
|
||||
"notifications.policy.filter_not_followers_title": "Profilen, die mir nicht folgen",
|
||||
"notifications.policy.filter_not_following_hint": "Bis du sie manuell genehmigst",
|
||||
"notifications.policy.filter_not_following_title": "Profilen, denen ich nicht folge",
|
||||
"notifications.policy.filter_private_mentions_hint": "Solange sie keine Antwort auf deine Erwähnung ist oder du dem Profil nicht folgst",
|
||||
"notifications.policy.filter_private_mentions_title": "Unerwünschten privaten Erwähnungen",
|
||||
"notifications.policy.filter_private_mentions_title": "unerwünschten privaten Erwähnungen",
|
||||
"notifications.policy.title": "Benachrichtigungen verwalten von …",
|
||||
"notifications_permission_banner.enable": "Aktiviere Desktop-Benachrichtigungen",
|
||||
"notifications_permission_banner.how_to_control": "Um Benachrichtigungen zu erhalten, wenn Mastodon nicht geöffnet ist, aktiviere die Desktop-Benachrichtigungen. Du kannst genau bestimmen, welche Arten von Interaktionen Desktop-Benachrichtigungen über die {icon} -Taste erzeugen, sobald diese aktiviert sind.",
|
||||
@@ -662,7 +665,7 @@
|
||||
"poll_button.remove_poll": "Umfrage entfernen",
|
||||
"privacy.change": "Sichtbarkeit anpassen",
|
||||
"privacy.direct.long": "Alle in diesem Beitrag erwähnten Profile",
|
||||
"privacy.direct.short": "Bestimmte Profile",
|
||||
"privacy.direct.short": "Ausgewählte Profile",
|
||||
"privacy.private.long": "Nur deine Follower",
|
||||
"privacy.private.short": "Follower",
|
||||
"privacy.public.long": "Alle in und außerhalb von Mastodon",
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"alert.rate_limited.title": "Περιορισμός συχνότητας",
|
||||
"alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.",
|
||||
"alert.unexpected.title": "Ουπς!",
|
||||
"alt_text_badge.title": "Εναλλακτικό κείμενο",
|
||||
"announcement.announcement": "Ανακοίνωση",
|
||||
"attachments_list.unprocessed": "(μη επεξεργασμένο)",
|
||||
"audio.hide": "Απόκρυψη αρχείου ήχου",
|
||||
@@ -196,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Άρση ακολούθησης;",
|
||||
"content_warning.hide": "Απόκρυψη ανάρτησης",
|
||||
"content_warning.show": "Εμφάνιση ούτως ή άλλως",
|
||||
"content_warning.show_more": "Εμφάνιση περισσότερων",
|
||||
"conversation.delete": "Διαγραφή συζήτησης",
|
||||
"conversation.mark_as_read": "Σήμανση ως αναγνωσμένο",
|
||||
"conversation.open": "Προβολή συνομιλίας",
|
||||
@@ -221,6 +223,8 @@
|
||||
"domain_block_modal.they_cant_follow": "Κανείς από αυτόν τον διακομιστή δεν μπορεί να σε ακολουθήσει.",
|
||||
"domain_block_modal.they_wont_know": "Δεν θα ξέρουν ότι έχουν αποκλειστεί.",
|
||||
"domain_block_modal.title": "Αποκλεισμός τομέα;",
|
||||
"domain_block_modal.you_will_lose_num_followers": "Θα χάσετε {followersCount, plural, one {{followersCountDisplay} ακόλουθο} other {{followersCountDisplay} ακόλουθους}} και {followingCount, plural, one {{followingCountDisplay} άτομο που ακολουθείτε} other {{followingCountDisplay} άτομα που ακολουθείτε}}.",
|
||||
"domain_block_modal.you_will_lose_relationships": "Θα χάσετε όλους τους ακόλουθους και τα άτομα που ακολουθείτε από αυτόν τον διακομιστή.",
|
||||
"domain_block_modal.you_wont_see_posts": "Δεν θα βλέπεις αναρτήσεις ή ειδοποιήσεις από χρήστες σε αυτόν το διακομιστή.",
|
||||
"domain_pill.activitypub_lets_connect": "Σού επιτρέπει να συνδεθείς και να αλληλεπιδράσεις με τους ανθρώπους όχι μόνο στο Mastodon, αλλά και σε διαφορετικές κοινωνικές εφαρμογές.",
|
||||
"domain_pill.activitypub_like_language": "Το ActivityPub είναι σαν τη γλώσσα Mastodon μιλάει με άλλα κοινωνικά δίκτυα.",
|
||||
@@ -302,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Χρησιμοποιήστε μια υπάρχουσα κατηγορία ή δημιουργήστε μια νέα",
|
||||
"filter_modal.select_filter.title": "Φιλτράρισμα αυτής της ανάρτησης",
|
||||
"filter_modal.title.status": "Φιλτράρισμα μιας ανάρτησης",
|
||||
"filter_warning.matches_filter": "Ταιριάζει με το φίλτρο “{title}”",
|
||||
"filter_warning.matches_filter": "Ταιριάζει με το φίλτρο “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "Από {count, plural, =0 {κανένα} one {ένα άτομο} other {# άτομα}} που μπορεί να ξέρεις",
|
||||
"filtered_notifications_banner.title": "Φιλτραρισμένες ειδοποιήσεις",
|
||||
"firehose.all": "Όλα",
|
||||
@@ -382,9 +386,9 @@
|
||||
"interaction_modal.description.follow": "Με έναν λογαριασμό Mastodon, μπορείς να ακολουθήσεις τον/την {name} ώστε να λαμβάνεις τις αναρτήσεις του/της στη δική σου ροή.",
|
||||
"interaction_modal.description.reblog": "Με ένα λογαριασμό Mastodon, μπορείς να ενισχύσεις αυτή την ανάρτηση για να τη μοιραστείς με τους δικούς σου ακολούθους.",
|
||||
"interaction_modal.description.reply": "Με ένα λογαριασμό Mastodon, μπορείς να απαντήσεις σε αυτή την ανάρτηση.",
|
||||
"interaction_modal.login.action": "Take me home\nΠήγαινέ με στην αρχική σελίδα",
|
||||
"interaction_modal.login.action": "Πήγαινέ με στην αρχική σελίδα",
|
||||
"interaction_modal.login.prompt": "Τομέας του οικιακού σου διακομιστή, πχ. mastodon.social",
|
||||
"interaction_modal.no_account_yet": "Not on Mastodon?\nΔεν είστε στο Mastodon;",
|
||||
"interaction_modal.no_account_yet": "Δεν είστε στο Mastodon;",
|
||||
"interaction_modal.on_another_server": "Σε διαφορετικό διακομιστή",
|
||||
"interaction_modal.on_this_server": "Σε αυτόν τον διακομιστή",
|
||||
"interaction_modal.sign_in": "Δεν είσαι συνδεδεμένος σε αυτόν το διακομιστή. Πού φιλοξενείται ο λογαριασμός σου;",
|
||||
@@ -505,7 +509,7 @@
|
||||
"notification.favourite": "{name} favorited your post\n{name} προτίμησε την ανάρτηση σου",
|
||||
"notification.favourite.name_and_others_with_link": "{name} και <a>{count, plural, one {# ακόμη} other {# ακόμη}}</a> αγάπησαν την ανάρτησή σου",
|
||||
"notification.follow": "Ο/Η {name} σε ακολούθησε",
|
||||
"notification.follow.name_and_others": "{name} και {count, plural, one {# ακόμη} other {# ακόμη}} σε ακολούθησαν",
|
||||
"notification.follow.name_and_others": "Ο χρήστης {name} και <a>{count, plural, one {# ακόμη} other {# ακόμη}}</a> σε ακολούθησαν",
|
||||
"notification.follow_request": "Ο/H {name} ζήτησε να σε ακολουθήσει",
|
||||
"notification.follow_request.name_and_others": "{name} και {count, plural, one {# άλλος} other {# άλλοι}} ζήτησαν να σε ακολουθήσουν",
|
||||
"notification.label.mention": "Επισήμανση",
|
||||
@@ -513,6 +517,7 @@
|
||||
"notification.label.private_reply": "Ιδιωτική απάντηση",
|
||||
"notification.label.reply": "Απάντηση",
|
||||
"notification.mention": "Επισήμανση",
|
||||
"notification.mentioned_you": "Ο χρήστης {name} σε επισήμανε",
|
||||
"notification.moderation-warning.learn_more": "Μάθε περισσότερα",
|
||||
"notification.moderation_warning": "Έχετε λάβει μία προειδοποίηση συντονισμού",
|
||||
"notification.moderation_warning.action_delete_statuses": "Ορισμένες από τις αναρτήσεις σου έχουν αφαιρεθεί.",
|
||||
@@ -563,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Μπάρα γρήγορου φίλτρου",
|
||||
"notifications.column_settings.follow": "Νέοι ακόλουθοι:",
|
||||
"notifications.column_settings.follow_request": "Νέο αίτημα ακολούθησης:",
|
||||
"notifications.column_settings.group": "Ομάδα",
|
||||
"notifications.column_settings.mention": "Επισημάνσεις:",
|
||||
"notifications.column_settings.poll": "Αποτελέσματα δημοσκόπησης:",
|
||||
"notifications.column_settings.push": "Ειδοποιήσεις Push",
|
||||
@@ -849,6 +855,11 @@
|
||||
"upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.",
|
||||
"upload_form.audio_description": "Περιγραφή για άτομα με προβλήματα ακοής",
|
||||
"upload_form.description": "Περιγραφή για άτομα με προβλήματα όρασης",
|
||||
"upload_form.drag_and_drop.instructions": "Για να επιλέξετε ένα συνημμένο αρχείο πολυμέσων, πατήστε το Space ή το Enter. Ενώ το σέρνετε, χρησιμοποιήστε τα πλήκτρα βέλους για να μετακινήσετε το συνημμένο αρχείο πολυμέσων προς οποιαδήποτε κατεύθυνση. Πατήστε ξανά το 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_form.thumbnail": "Αλλαγή μικρογραφίας",
|
||||
"upload_form.video_description": "Περιγραφή για άτομα με προβλήματα ακοής ή όρασης",
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Unfollow user?",
|
||||
"content_warning.hide": "Hide post",
|
||||
"content_warning.show": "Show anyway",
|
||||
"content_warning.show_more": "Show more",
|
||||
"conversation.delete": "Delete conversation",
|
||||
"conversation.mark_as_read": "Mark as read",
|
||||
"conversation.open": "View conversation",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
|
||||
"filter_modal.select_filter.title": "Filter this post",
|
||||
"filter_modal.title.status": "Filter a post",
|
||||
"filter_warning.matches_filter": "Matches filter “{title}”",
|
||||
"filter_warning.matches_filter": "Matches filter \"<span>{title}</span>\"",
|
||||
"filtered_notifications_banner.pending_requests": "From {count, plural, =0 {no one} one {one person} other {# people}} you may know",
|
||||
"filtered_notifications_banner.title": "Filtered notifications",
|
||||
"firehose.all": "All",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} favourited your post",
|
||||
"notification.favourite.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> favourited your post",
|
||||
"notification.follow": "{name} followed you",
|
||||
"notification.follow.name_and_others": "{name} and {count, plural, one {# other} other {# others}} followed you",
|
||||
"notification.follow.name_and_others": "{name} and <a>{count, plural, one {# other} other {# others}}</a> followed you",
|
||||
"notification.follow_request": "{name} has requested to follow you",
|
||||
"notification.follow_request.name_and_others": "{name} and {count, plural, one {# other} other {# others}} has requested to follow you",
|
||||
"notification.label.mention": "Mention",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Private reply",
|
||||
"notification.label.reply": "Reply",
|
||||
"notification.mention": "Mention",
|
||||
"notification.mentioned_you": "{name} mentioned you",
|
||||
"notification.moderation-warning.learn_more": "Learn more",
|
||||
"notification.moderation_warning": "You have received a moderation warning",
|
||||
"notification.moderation_warning.action_delete_statuses": "Some of your posts have been removed.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Quick filter bar",
|
||||
"notifications.column_settings.follow": "New followers:",
|
||||
"notifications.column_settings.follow_request": "New follow requests:",
|
||||
"notifications.column_settings.group": "Group",
|
||||
"notifications.column_settings.mention": "Mentions:",
|
||||
"notifications.column_settings.poll": "Poll results:",
|
||||
"notifications.column_settings.push": "Push notifications",
|
||||
@@ -791,7 +794,7 @@
|
||||
"status.edited_x_times": "Edited {count, plural, one {{count} time} other {{count} times}}",
|
||||
"status.embed": "Get embed code",
|
||||
"status.favourite": "Favourite",
|
||||
"status.favourites": "{count, plural, one {favorite} other {favorites}}",
|
||||
"status.favourites": "{count, plural, one {favourite} other {favourites}}",
|
||||
"status.filter": "Filter this post",
|
||||
"status.history.created": "{name} created {date}",
|
||||
"status.history.edited": "{name} edited {date}",
|
||||
@@ -852,6 +855,11 @@
|
||||
"upload_error.poll": "File upload not allowed with polls.",
|
||||
"upload_form.audio_description": "Describe for people who are deaf or hard of hearing",
|
||||
"upload_form.description": "Describe for people who are blind or have low vision",
|
||||
"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.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "Media attachment {item} was moved.",
|
||||
"upload_form.drag_and_drop.on_drag_start": "Picked up media attachment {item}.",
|
||||
"upload_form.edit": "Edit",
|
||||
"upload_form.thumbnail": "Change thumbnail",
|
||||
"upload_form.video_description": "Describe for people who are deaf, hard of hearing, blind or have low vision",
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "Unfollow user?",
|
||||
"content_warning.hide": "Hide post",
|
||||
"content_warning.show": "Show anyway",
|
||||
"content_warning.show_more": "Show more",
|
||||
"conversation.delete": "Delete conversation",
|
||||
"conversation.mark_as_read": "Mark as read",
|
||||
"conversation.open": "View conversation",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Use an existing category or create a new one",
|
||||
"filter_modal.select_filter.title": "Filter this post",
|
||||
"filter_modal.title.status": "Filter a post",
|
||||
"filter_warning.matches_filter": "Matches filter “{title}”",
|
||||
"filter_warning.matches_filter": "Matches filter “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "From {count, plural, =0 {no one} one {one person} other {# people}} you may know",
|
||||
"filtered_notifications_banner.title": "Filtered notifications",
|
||||
"firehose.all": "All",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} favorited your post",
|
||||
"notification.favourite.name_and_others_with_link": "{name} and <a>{count, plural, one {# other} other {# others}}</a> favorited your post",
|
||||
"notification.follow": "{name} followed you",
|
||||
"notification.follow.name_and_others": "{name} and {count, plural, one {# other} other {# others}} followed you",
|
||||
"notification.follow.name_and_others": "{name} and <a>{count, plural, one {# other} other {# others}}</a> followed you",
|
||||
"notification.follow_request": "{name} has requested to follow you",
|
||||
"notification.follow_request.name_and_others": "{name} and {count, plural, one {# other} other {# others}} has requested to follow you",
|
||||
"notification.label.mention": "Mention",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Private reply",
|
||||
"notification.label.reply": "Reply",
|
||||
"notification.mention": "Mention",
|
||||
"notification.mentioned_you": "{name} mentioned you",
|
||||
"notification.moderation-warning.learn_more": "Learn more",
|
||||
"notification.moderation_warning": "You have received a moderation warning",
|
||||
"notification.moderation_warning.action_delete_statuses": "Some of your posts have been removed.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Quick filter bar",
|
||||
"notifications.column_settings.follow": "New followers:",
|
||||
"notifications.column_settings.follow_request": "New follow requests:",
|
||||
"notifications.column_settings.group": "Group",
|
||||
"notifications.column_settings.mention": "Mentions:",
|
||||
"notifications.column_settings.poll": "Poll results:",
|
||||
"notifications.column_settings.push": "Push notifications",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"about.blocks": "Administritaj serviloj",
|
||||
"about.contact": "Kontakto:",
|
||||
"about.disclaimer": "Mastodon estas libera, malfermitkoda programo kaj varmarko de la firmao Mastodon gGmbH.",
|
||||
"about.domain_blocks.no_reason_available": "Kialo ne disponebla",
|
||||
"about.domain_blocks.no_reason_available": "Kialo ne disponeblas",
|
||||
"about.domain_blocks.preamble": "Mastodon ĝenerale rajtigas vidi la enhavojn de uzantoj el aliaj serviloj en la fediverso, kaj komuniki kun ili. Jen la limigoj deciditaj de tiu ĉi servilo mem.",
|
||||
"about.domain_blocks.silenced.explanation": "Vi ne ĝenerale vidos profilojn kaj enhavojn de ĉi tiu servilo, krom se vi eksplice trovas aŭ estas permesita de via sekvato.",
|
||||
"about.domain_blocks.silenced.title": "Limigita",
|
||||
@@ -13,7 +13,7 @@
|
||||
"about.rules": "Regularo de la servilo",
|
||||
"account.account_note_header": "Personaj notoj",
|
||||
"account.add_or_remove_from_list": "Aldoni al aŭ forigi el listoj",
|
||||
"account.badges.bot": "Roboto",
|
||||
"account.badges.bot": "Aŭtomata",
|
||||
"account.badges.group": "Grupo",
|
||||
"account.block": "Bloki @{name}",
|
||||
"account.block_domain": "Bloki la domajnon {domain}",
|
||||
@@ -22,10 +22,10 @@
|
||||
"account.cancel_follow_request": "Nuligi peton por sekvado",
|
||||
"account.copy": "Kopii ligilon al profilo",
|
||||
"account.direct": "Private mencii @{name}",
|
||||
"account.disable_notifications": "Ne plu sciigi min, kiam @{name} mesaĝas",
|
||||
"account.disable_notifications": "Ĉesu sciigi min kiam @{name} afiŝas",
|
||||
"account.domain_blocked": "Domajno blokita",
|
||||
"account.edit_profile": "Redakti la profilon",
|
||||
"account.enable_notifications": "Sciigi min, kiam @{name} mesaĝas",
|
||||
"account.enable_notifications": "Sciigu min kiam @{name} afiŝos",
|
||||
"account.endorse": "Rekomendi ĉe via profilo",
|
||||
"account.featured_tags.last_status_at": "Lasta afîŝo je {date}",
|
||||
"account.featured_tags.last_status_never": "Neniu afiŝo",
|
||||
@@ -45,18 +45,18 @@
|
||||
"account.languages": "Ŝanĝi la abonitajn lingvojn",
|
||||
"account.link_verified_on": "Propreco de tiu ligilo estis konfirmita je {date}",
|
||||
"account.locked_info": "Tiu konto estas privatigita. La posedanto mane akceptas tiun, kiu povas sekvi rin.",
|
||||
"account.media": "Plurmedioj",
|
||||
"account.media": "Plurmedio",
|
||||
"account.mention": "Mencii @{name}",
|
||||
"account.moved_to": "{name} indikis, ke ria nova konto estas nun:",
|
||||
"account.mute": "Silentigi @{name}",
|
||||
"account.mute_notifications_short": "Silentigu Sciigojn",
|
||||
"account.mute_notifications_short": "Silentigu sciigojn",
|
||||
"account.mute_short": "Silentigu",
|
||||
"account.muted": "Silentigita",
|
||||
"account.mutual": "Reciproka",
|
||||
"account.no_bio": "Neniu priskribo estas provizita.",
|
||||
"account.open_original_page": "Malfermi la originalan paĝon",
|
||||
"account.posts": "Afiŝoj",
|
||||
"account.posts_with_replies": "Mesaĝoj kaj respondoj",
|
||||
"account.posts_with_replies": "Afiŝoj kaj respondoj",
|
||||
"account.report": "Raporti @{name}",
|
||||
"account.requested": "Atendo de aprobo. Klaku por nuligi la peton por sekvado",
|
||||
"account.requested_follow": "{name} petis sekvi vin",
|
||||
@@ -69,7 +69,7 @@
|
||||
"account.unendorse": "Ne plu rekomendi ĉe la profilo",
|
||||
"account.unfollow": "Ĉesi sekvi",
|
||||
"account.unmute": "Ne plu silentigi @{name}",
|
||||
"account.unmute_notifications_short": "Malsilentigu Sciigojn",
|
||||
"account.unmute_notifications_short": "Malsilentigu sciigojn",
|
||||
"account.unmute_short": "Ne plu silentigi",
|
||||
"account_note.placeholder": "Alklaku por aldoni noton",
|
||||
"admin.dashboard.daily_retention": "Uzantoretenprocento lau tag post registro",
|
||||
@@ -81,12 +81,12 @@
|
||||
"admin.impact_report.instance_followers": "Sekvantojn niaj uzantoj perdus",
|
||||
"admin.impact_report.instance_follows": "Sekvantojn ties uzantoj perdus",
|
||||
"admin.impact_report.title": "Influa reporto",
|
||||
"alert.rate_limited.message": "Bonvolu reprovi post {retry_time, time, medium}.",
|
||||
"alert.rate_limited.message": "Bonvolu reprovi poste {retry_time, time, medium}.",
|
||||
"alert.rate_limited.title": "Mesaĝkvante limigita",
|
||||
"alert.unexpected.message": "Neatendita eraro okazis.",
|
||||
"alert.unexpected.title": "Aj!",
|
||||
"alt_text_badge.title": "Alt-teksto",
|
||||
"announcement.announcement": "Anoncoj",
|
||||
"announcement.announcement": "Anonco",
|
||||
"attachments_list.unprocessed": "(neprilaborita)",
|
||||
"audio.hide": "Kaŝi aŭdion",
|
||||
"block_modal.remote_users_caveat": "Ni petos al la servilo {domain} respekti vian elekton. Tamen, plenumo ne estas garantiita ĉar iuj serviloj eble manipulas blokojn malsame. Publikaj afiŝoj eble ankoraŭ estas videbla por ne-ensalutintaj uzantoj.",
|
||||
@@ -105,13 +105,13 @@
|
||||
"bundle_column_error.error.title": "Ho, ve!",
|
||||
"bundle_column_error.network.body": "Okazis eraro dum ŝarĝado de ĉi tiu paĝo. Tion povas kaŭzi portempa problemo pri via retkonektado aŭ pri ĉi tiu servilo.",
|
||||
"bundle_column_error.network.title": "Eraro de reto",
|
||||
"bundle_column_error.retry": "Provu refoje",
|
||||
"bundle_column_error.retry": "Provu denove",
|
||||
"bundle_column_error.return": "Reiri hejmen",
|
||||
"bundle_column_error.routing.body": "La celita paĝo ne troveblas. Ĉu vi certas, ke la retadreso (URL) en via retfoliumilo estas ĝusta?",
|
||||
"bundle_column_error.routing.title": "404",
|
||||
"bundle_modal_error.close": "Fermi",
|
||||
"bundle_modal_error.message": "Io misfunkciis en la ŝargado de ĉi tiu elemento.",
|
||||
"bundle_modal_error.retry": "Bonvolu reprovi",
|
||||
"bundle_modal_error.retry": "Provu denove",
|
||||
"closed_registrations.other_server_instructions": "Ĉar Mastodon estas malcentraliza, vi povas krei konton ĉe alia servilo kaj ankoraŭ komuniki kun ĉi tiu.",
|
||||
"closed_registrations_modal.description": "Krei konton ĉe {domain} aktuale ne eblas, tamen bonvole rimarku, ke vi ne bezonas konton specife ĉe {domain} por uzi Mastodon.",
|
||||
"closed_registrations_modal.find_another_server": "Trovi alian servilon",
|
||||
@@ -142,7 +142,7 @@
|
||||
"column_header.unpin": "Malfiksi",
|
||||
"column_subheading.settings": "Agordoj",
|
||||
"community.column_settings.local_only": "Nur loka",
|
||||
"community.column_settings.media_only": "Nur plurmedioj",
|
||||
"community.column_settings.media_only": "Nur plurmedio",
|
||||
"community.column_settings.remote_only": "Nur fora",
|
||||
"compose.language.change": "Ŝanĝi lingvon",
|
||||
"compose.language.search": "Serĉi lingvojn...",
|
||||
@@ -163,7 +163,7 @@
|
||||
"compose_form.poll.switch_to_single": "Ŝanĝi la balotenketon por permesi unu solan elekton",
|
||||
"compose_form.poll.type": "Stilo",
|
||||
"compose_form.publish": "Afiŝo",
|
||||
"compose_form.publish_form": "Afiŝi",
|
||||
"compose_form.publish_form": "Nova afiŝo",
|
||||
"compose_form.reply": "Respondi",
|
||||
"compose_form.save_changes": "Ĝisdatigi",
|
||||
"compose_form.spoiler.marked": "Forigi la averton de enhavo",
|
||||
@@ -173,7 +173,7 @@
|
||||
"confirmations.block.confirm": "Bloki",
|
||||
"confirmations.delete.confirm": "Forigi",
|
||||
"confirmations.delete.message": "Ĉu vi certas, ke vi volas forigi ĉi tiun afiŝon?",
|
||||
"confirmations.delete.title": "Ĉu forigi Afiŝon?",
|
||||
"confirmations.delete.title": "Ĉu forigi afiŝon?",
|
||||
"confirmations.delete_list.confirm": "Forigi",
|
||||
"confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?",
|
||||
"confirmations.delete_list.title": "Ĉu forigi liston?",
|
||||
@@ -182,8 +182,8 @@
|
||||
"confirmations.edit.confirm": "Redakti",
|
||||
"confirmations.edit.message": "Redakti nun anstataŭigos la skribatan afiŝon. Ĉu vi certas, ke vi volas daŭrigi?",
|
||||
"confirmations.edit.title": "Ĉu superskribi afiŝon?",
|
||||
"confirmations.logout.confirm": "Adiaŭi",
|
||||
"confirmations.logout.message": "Ĉu vi certas ke vi volas adiaŭi?",
|
||||
"confirmations.logout.confirm": "Elsaluti",
|
||||
"confirmations.logout.message": "Ĉu vi certas, ke vi volas elsaluti?",
|
||||
"confirmations.logout.title": "Ĉu elsaluti?",
|
||||
"confirmations.mute.confirm": "Silentigi",
|
||||
"confirmations.redraft.confirm": "Forigi kaj reskribi",
|
||||
@@ -197,8 +197,9 @@
|
||||
"confirmations.unfollow.title": "Ĉu ĉesi sekvi uzanton?",
|
||||
"content_warning.hide": "Kaŝi afiŝon",
|
||||
"content_warning.show": "Montri ĉiukaze",
|
||||
"content_warning.show_more": "Montri pli",
|
||||
"conversation.delete": "Forigi konversacion",
|
||||
"conversation.mark_as_read": "Marki legita",
|
||||
"conversation.mark_as_read": "Marku kiel legita",
|
||||
"conversation.open": "Vidi konversacion",
|
||||
"conversation.with": "Kun {names}",
|
||||
"copy_icon_button.copied": "Kopiis al kliptabulo",
|
||||
@@ -213,9 +214,9 @@
|
||||
"dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.",
|
||||
"dismissable_banner.dismiss": "Eksigi",
|
||||
"dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.",
|
||||
"dismissable_banner.explore_statuses": "Ĉi tioj estas afiŝoj de socia reto kiu populariĝas hodiau.",
|
||||
"dismissable_banner.explore_statuses": "Jen afiŝoj en la socia reto kiuj populariĝis hodiaŭ. Novaj afiŝoj kun pli da diskonigoj kaj stelumoj aperas pli alte.",
|
||||
"dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.",
|
||||
"dismissable_banner.public_timeline": "Ĉi tioj estas plej lastaj publikaj afiŝoj de personoj ĉe socia reto kiu personoj ĉe {domain} sekvas.",
|
||||
"dismissable_banner.public_timeline": "Ĉi tiuj estas la plej lastatempaj publikaj afiŝoj de homoj en la socia reto, kiujn homoj sur {domain} sekvas.",
|
||||
"domain_block_modal.block": "Bloki servilon",
|
||||
"domain_block_modal.block_account_instead": "Bloki @{name} anstataŭe",
|
||||
"domain_block_modal.they_can_interact_with_old_posts": "Homoj de ĉi tiu servilo povas interagi kun viaj malnovaj afiŝoj.",
|
||||
@@ -247,26 +248,26 @@
|
||||
"emoji_button.food": "Manĝi kaj trinki",
|
||||
"emoji_button.label": "Enmeti emoĝion",
|
||||
"emoji_button.nature": "Naturo",
|
||||
"emoji_button.not_found": "Neniu emoĝio!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.not_found": "Neniuj kongruaj emoĝioj trovitaj",
|
||||
"emoji_button.objects": "Aĵoj",
|
||||
"emoji_button.people": "Homoj",
|
||||
"emoji_button.recent": "Ofte uzataj",
|
||||
"emoji_button.search": "Serĉo…",
|
||||
"emoji_button.search": "Serĉo...",
|
||||
"emoji_button.search_results": "Serĉaj rezultoj",
|
||||
"emoji_button.symbols": "Simboloj",
|
||||
"emoji_button.travel": "Vojaĝoj kaj lokoj",
|
||||
"empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon",
|
||||
"empty_column.account_suspended": "Konto suspendita",
|
||||
"empty_column.account_timeline": "Neniu afiŝo ĉi tie!",
|
||||
"empty_column.account_unavailable": "Profilo ne disponebla",
|
||||
"empty_column.account_timeline": "Neniuj afiŝoj ĉi tie!",
|
||||
"empty_column.account_unavailable": "Profilo nedisponebla",
|
||||
"empty_column.blocks": "Vi ankoraŭ ne blokis uzanton.",
|
||||
"empty_column.bookmarked_statuses": "Vi ankoraŭ ne aldonis afiŝon al viaj legosignoj. Kiam vi aldonos iun, tiu aperos ĉi tie.",
|
||||
"empty_column.community": "La loka templinio estas malplena. Skribu ion por plenigi ĝin!",
|
||||
"empty_column.direct": "Vi ankoraŭ ne havas privatan mencion. Kiam vi sendos aŭ ricevos iun, tiu aperos ĉi tie.",
|
||||
"empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.",
|
||||
"empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!",
|
||||
"empty_column.favourited_statuses": "Vi ankoraŭ ne havas stelumitan afiŝon.",
|
||||
"empty_column.favourites": "Ankoraŭ neniu stelumis tiun afiŝon.",
|
||||
"empty_column.favourited_statuses": "Vi ankoraŭ ne havas plej ŝatatajn afiŝojn. Kiam vi ŝatatas unu, ĝi aperos ĉi tie.",
|
||||
"empty_column.favourites": "Neniu ankoraŭ ŝatis ĉi tiun afiŝon. Kiam iu ŝatos ĝin, ili aperos ĉi tie.",
|
||||
"empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.",
|
||||
"empty_column.followed_tags": "Vi ankoraŭ ne sekvas iujn kradvortojn. Kiam vi faras, ili aperos ĉi tie.",
|
||||
"empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.",
|
||||
@@ -296,7 +297,7 @@
|
||||
"filter_modal.added.review_and_configure": "Por kontroli kaj pli modifi ĉi tiu filtrilkategorio, iru al la {settings_link}.",
|
||||
"filter_modal.added.review_and_configure_title": "Filtrilopcioj",
|
||||
"filter_modal.added.settings_link": "opciopaĝo",
|
||||
"filter_modal.added.short_explanation": "Ĉi tiu mesaĝo aldonitas al la filtrilkategorio: {title}.",
|
||||
"filter_modal.added.short_explanation": "Ĉi tiu afiŝo aldonitas al la filtrilkategorio: {title}.",
|
||||
"filter_modal.added.title": "Filtrilo aldonita!",
|
||||
"filter_modal.select_filter.context_mismatch": "ne kongruas la kuntekston",
|
||||
"filter_modal.select_filter.expired": "eksvalidiĝinta",
|
||||
@@ -304,8 +305,8 @@
|
||||
"filter_modal.select_filter.search": "Serĉi aŭ krei",
|
||||
"filter_modal.select_filter.subtitle": "Uzu ekzistantan kategorion aŭ kreu novan",
|
||||
"filter_modal.select_filter.title": "Filtri ĉi tiun afiŝon",
|
||||
"filter_modal.title.status": "Filtri mesaĝon",
|
||||
"filter_warning.matches_filter": "Filtrilo de kongruoj “{title}”",
|
||||
"filter_modal.title.status": "Filtri afiŝon",
|
||||
"filter_warning.matches_filter": "Filtrilo de kongruoj “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "El {count, plural, =0 {neniu} one {unu persono} other {# homoj}} vi eble konas",
|
||||
"filtered_notifications_banner.title": "Filtritaj sciigoj",
|
||||
"firehose.all": "Ĉiuj",
|
||||
@@ -332,7 +333,7 @@
|
||||
"followed_tags": "Sekvataj kradvortoj",
|
||||
"footer.about": "Pri",
|
||||
"footer.directory": "Profilujo",
|
||||
"footer.get_app": "Akiru la Programon",
|
||||
"footer.get_app": "Akiri la apon",
|
||||
"footer.invite": "Inviti homojn",
|
||||
"footer.keyboard_shortcuts": "Fulmoklavoj",
|
||||
"footer.privacy_policy": "Politiko de privateco",
|
||||
@@ -343,7 +344,7 @@
|
||||
"hashtag.column_header.tag_mode.all": "kaj {additional}",
|
||||
"hashtag.column_header.tag_mode.any": "aŭ {additional}",
|
||||
"hashtag.column_header.tag_mode.none": "sen {additional}",
|
||||
"hashtag.column_settings.select.no_options_message": "Neniu sugesto trovita",
|
||||
"hashtag.column_settings.select.no_options_message": "Neniuj sugestoj trovitaj",
|
||||
"hashtag.column_settings.select.placeholder": "Enmeti kradvortojn…",
|
||||
"hashtag.column_settings.tag_mode.all": "Ĉiuj",
|
||||
"hashtag.column_settings.tag_mode.any": "Iu ajn",
|
||||
@@ -351,7 +352,7 @@
|
||||
"hashtag.column_settings.tag_toggle": "Aldoni pliajn etikedojn por ĉi tiu kolumno",
|
||||
"hashtag.counter_by_accounts": "{count, plural,one {{counter} partoprenanto} other {{counter} partoprenantoj}}",
|
||||
"hashtag.counter_by_uses": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiau",
|
||||
"hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiaŭ",
|
||||
"hashtag.follow": "Sekvi la kradvorton",
|
||||
"hashtag.unfollow": "Ne plu sekvi la kradvorton",
|
||||
"hashtags.and_other": "…kaj {count, plural,other {# pli}}",
|
||||
@@ -381,10 +382,10 @@
|
||||
"ignore_notifications_modal.not_followers_title": "Ĉu ignori sciigojn de homoj, kiuj ne sekvas vin?",
|
||||
"ignore_notifications_modal.not_following_title": "Ĉu ignori sciigojn de homoj, kiujn vi ne sekvas?",
|
||||
"ignore_notifications_modal.private_mentions_title": "Ĉu ignori sciigojn de nepetitaj privataj mencioj?",
|
||||
"interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.",
|
||||
"interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povos sekvi {name} por vidi ties mesaĝojn en via hejmo.",
|
||||
"interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumi ĉi tiun afiŝon por sciigi la afiŝanton ke vi sâtas kaj konservas ĝin por poste.",
|
||||
"interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povas sekvi {name} por ricevi iliajn afiŝojn en via hejma fluo.",
|
||||
"interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.",
|
||||
"interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu mesaĝo.",
|
||||
"interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu afiŝo.",
|
||||
"interaction_modal.login.action": "Prenu min hejmen",
|
||||
"interaction_modal.login.prompt": "Domajno de via hejma servilo, ekz. mastodon.social",
|
||||
"interaction_modal.no_account_yet": "Ĉu ne estas ĉe Mastodon?",
|
||||
@@ -399,40 +400,40 @@
|
||||
"intervals.full.days": "{number, plural, one {# tago} other {# tagoj}}",
|
||||
"intervals.full.hours": "{number, plural, one {# horo} other {# horoj}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutoj}}",
|
||||
"keyboard_shortcuts.back": "reveni",
|
||||
"keyboard_shortcuts.back": "Reiru reen",
|
||||
"keyboard_shortcuts.blocked": "Malfermi la liston de blokitaj uzantoj",
|
||||
"keyboard_shortcuts.boost": "Diskonigi la mesaĝon",
|
||||
"keyboard_shortcuts.column": "fokusi mesaĝon en unu el la kolumnoj",
|
||||
"keyboard_shortcuts.compose": "enfokusigi la tekstujon",
|
||||
"keyboard_shortcuts.column": "Fokusi kolumnon",
|
||||
"keyboard_shortcuts.compose": "Enfokusigi la tekstaron",
|
||||
"keyboard_shortcuts.description": "Priskribo",
|
||||
"keyboard_shortcuts.direct": "por malfermi la kolumnon pri privataj mencioj",
|
||||
"keyboard_shortcuts.down": "iri suben en la listo",
|
||||
"keyboard_shortcuts.enter": "malfermi mesaĝon",
|
||||
"keyboard_shortcuts.down": "Movu malsupren en la listo",
|
||||
"keyboard_shortcuts.enter": "Malfermi afiŝon",
|
||||
"keyboard_shortcuts.favourite": "Stelumi afiŝon",
|
||||
"keyboard_shortcuts.favourites": "Malfermi la liston de la stelumoj",
|
||||
"keyboard_shortcuts.federated": "Malfermi la frataran templinion",
|
||||
"keyboard_shortcuts.heading": "Klavaraj mallongigoj",
|
||||
"keyboard_shortcuts.heading": "Fulmoklavoj",
|
||||
"keyboard_shortcuts.home": "Malfermi la hejman templinion",
|
||||
"keyboard_shortcuts.hotkey": "Rapidklavo",
|
||||
"keyboard_shortcuts.legend": "montri ĉi tiun noton",
|
||||
"keyboard_shortcuts.local": "Malfermi la lokan templinion",
|
||||
"keyboard_shortcuts.mention": "mencii la aŭtoron",
|
||||
"keyboard_shortcuts.muted": "malfermi la liston de silentigitaj uzantoj",
|
||||
"keyboard_shortcuts.my_profile": "malfermi vian profilon",
|
||||
"keyboard_shortcuts.notifications": "malfermi la kolumnon de sciigoj",
|
||||
"keyboard_shortcuts.open_media": "Malfermi plurmedion",
|
||||
"keyboard_shortcuts.pinned": "malfermi la liston de alpinglitaj mesaĝoj",
|
||||
"keyboard_shortcuts.profile": "malfermi la profilon de la aŭtoro",
|
||||
"keyboard_shortcuts.reply": "respondi",
|
||||
"keyboard_shortcuts.legend": "Montru ĉi tiun legendon",
|
||||
"keyboard_shortcuts.local": "Malfermu la lokan templinion",
|
||||
"keyboard_shortcuts.mention": "Menciu aŭtoron",
|
||||
"keyboard_shortcuts.muted": "Malfermu la liston de silentigitaj uzantoj",
|
||||
"keyboard_shortcuts.my_profile": "Malfermu vian profilon",
|
||||
"keyboard_shortcuts.notifications": "Malfermu la sciigajn kolumnon",
|
||||
"keyboard_shortcuts.open_media": "Malfermu plurmedion",
|
||||
"keyboard_shortcuts.pinned": "Malfermu alpinglitajn afiŝojn-liston",
|
||||
"keyboard_shortcuts.profile": "Malfermu la profilon de aŭtoro",
|
||||
"keyboard_shortcuts.reply": "Respondu al afiŝo",
|
||||
"keyboard_shortcuts.requests": "Malfermi la liston de petoj por sekvado",
|
||||
"keyboard_shortcuts.search": "enfokusigi la serĉilon",
|
||||
"keyboard_shortcuts.spoilers": "Montri/kaŝi la kampon de averto de enhavo (\"CW\")",
|
||||
"keyboard_shortcuts.start": "malfermi la kolumnon «por komenci»",
|
||||
"keyboard_shortcuts.toggle_hidden": "Montri/kaŝi tekston malantaŭ la averto de enhavo (\"CW\")",
|
||||
"keyboard_shortcuts.search": "Enfokusigi la serĉbreton",
|
||||
"keyboard_shortcuts.spoilers": "Montri/kaŝi CW-kampon",
|
||||
"keyboard_shortcuts.start": "Malfermu \"por komenci\" kolumnon",
|
||||
"keyboard_shortcuts.toggle_hidden": "Montri/kaŝi tekston malantaŭ CW",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Montri/kaŝi plurmedion",
|
||||
"keyboard_shortcuts.toot": "Krei novan mesaĝon",
|
||||
"keyboard_shortcuts.unfocus": "malenfokusigi la tekstujon aŭ la serĉilon",
|
||||
"keyboard_shortcuts.up": "iri supren en la listo",
|
||||
"keyboard_shortcuts.toot": "Komencu novan afiŝon",
|
||||
"keyboard_shortcuts.unfocus": "Senfokusigi verki tekstareon/serĉon",
|
||||
"keyboard_shortcuts.up": "Movu supren en la listo",
|
||||
"lightbox.close": "Fermi",
|
||||
"lightbox.next": "Antaŭen",
|
||||
"lightbox.previous": "Malantaŭen",
|
||||
@@ -476,9 +477,9 @@
|
||||
"navigation_bar.blocks": "Blokitaj uzantoj",
|
||||
"navigation_bar.bookmarks": "Legosignoj",
|
||||
"navigation_bar.community_timeline": "Loka templinio",
|
||||
"navigation_bar.compose": "Skribi novan mesaĝon",
|
||||
"navigation_bar.compose": "Redakti novan afiŝon",
|
||||
"navigation_bar.direct": "Privataj mencioj",
|
||||
"navigation_bar.discover": "Esplori",
|
||||
"navigation_bar.discover": "Malkovri",
|
||||
"navigation_bar.domain_blocks": "Blokitaj domajnoj",
|
||||
"navigation_bar.explore": "Esplori",
|
||||
"navigation_bar.favourites": "Stelumoj",
|
||||
@@ -487,12 +488,12 @@
|
||||
"navigation_bar.followed_tags": "Sekvataj kradvortoj",
|
||||
"navigation_bar.follows_and_followers": "Sekvatoj kaj sekvantoj",
|
||||
"navigation_bar.lists": "Listoj",
|
||||
"navigation_bar.logout": "Adiaŭi",
|
||||
"navigation_bar.logout": "Elsaluti",
|
||||
"navigation_bar.moderation": "Modereco",
|
||||
"navigation_bar.mutes": "Silentigitaj uzantoj",
|
||||
"navigation_bar.opened_in_classic_interface": "Afiŝoj, kontoj, kaj aliaj specifaj paĝoj kiuj estas malfermititaj defaulta en la klasika reta interfaco.",
|
||||
"navigation_bar.personal": "Persone",
|
||||
"navigation_bar.pins": "Alpinglitaj mesaĝoj",
|
||||
"navigation_bar.pins": "Alpinglitaj afiŝoj",
|
||||
"navigation_bar.preferences": "Preferoj",
|
||||
"navigation_bar.public_timeline": "Fratara templinio",
|
||||
"navigation_bar.search": "Serĉi",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} stelumis vian afiŝon",
|
||||
"notification.favourite.name_and_others_with_link": "{name} kaj <a>{count, plural, one {# alia} other {# aliaj}}</a> ŝatis vian afiŝon",
|
||||
"notification.follow": "{name} eksekvis vin",
|
||||
"notification.follow.name_and_others": "{name} kaj {count, plural, one {# alia} other {# aliaj}} sekvis vin",
|
||||
"notification.follow.name_and_others": "{name} kaj <a>{count, plural, one {# alia} other {# aliaj}}</a> sekvis vin",
|
||||
"notification.follow_request": "{name} petis sekvi vin",
|
||||
"notification.follow_request.name_and_others": "{name} kaj {count, plural, one {# alia} other {# aliaj}} petis sekvi vin",
|
||||
"notification.label.mention": "Mencii",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Privata respondo",
|
||||
"notification.label.reply": "Respondi",
|
||||
"notification.mention": "Mencii",
|
||||
"notification.mentioned_you": "{name} menciis vin",
|
||||
"notification.moderation-warning.learn_more": "Lerni pli",
|
||||
"notification.moderation_warning": "Vi ricevis moderigan averton",
|
||||
"notification.moderation_warning.action_delete_statuses": "Kelkaj el viaj afiŝoj estis forigitaj.",
|
||||
@@ -525,7 +527,7 @@
|
||||
"notification.moderation_warning.action_sensitive": "Viaj afiŝoj estos markitaj kiel sentemaj ekde nun.",
|
||||
"notification.moderation_warning.action_silence": "Via konto estis limigita.",
|
||||
"notification.moderation_warning.action_suspend": "Via konto estas malakceptita.",
|
||||
"notification.own_poll": "Via enketo finiĝis",
|
||||
"notification.own_poll": "Via balotenketo finiĝitis",
|
||||
"notification.poll": "Balotenketo, en kiu vi voĉdonis, finiĝis",
|
||||
"notification.reblog": "{name} diskonigis vian afiŝon",
|
||||
"notification.reblog.name_and_others_with_link": "{name} kaj <a>{count, plural, one {# alia} other {# aliaj}}</a> diskonigis vian afiŝon",
|
||||
@@ -566,13 +568,14 @@
|
||||
"notifications.column_settings.filter_bar.category": "Rapida filtrila breto",
|
||||
"notifications.column_settings.follow": "Novaj sekvantoj:",
|
||||
"notifications.column_settings.follow_request": "Novaj petoj de sekvado:",
|
||||
"notifications.column_settings.group": "Grupigi",
|
||||
"notifications.column_settings.mention": "Mencioj:",
|
||||
"notifications.column_settings.poll": "Balotenketaj rezultoj:",
|
||||
"notifications.column_settings.push": "Puŝsciigoj",
|
||||
"notifications.column_settings.reblog": "Diskonigoj:",
|
||||
"notifications.column_settings.show": "Montri en kolumno",
|
||||
"notifications.column_settings.sound": "Eligi sonon",
|
||||
"notifications.column_settings.status": "Novaj mesaĝoj:",
|
||||
"notifications.column_settings.status": "Novaj afiŝoj:",
|
||||
"notifications.column_settings.unread_notifications.category": "Nelegitaj sciigoj",
|
||||
"notifications.column_settings.unread_notifications.highlight": "Marki nelegitajn sciigojn",
|
||||
"notifications.column_settings.update": "Redaktoj:",
|
||||
@@ -611,8 +614,8 @@
|
||||
"notifications_permission_banner.title": "Neniam preterlasas iun ajn",
|
||||
"onboarding.action.back": "Prenu min reen",
|
||||
"onboarding.actions.back": "Prenu min reen",
|
||||
"onboarding.actions.go_to_explore": "See what's trending",
|
||||
"onboarding.actions.go_to_home": "Go to your home feed",
|
||||
"onboarding.actions.go_to_explore": "Konduku min al tendenco",
|
||||
"onboarding.actions.go_to_home": "Konduku min al mia hejma fluo",
|
||||
"onboarding.compose.template": "Saluton #Mastodon!",
|
||||
"onboarding.follows.empty": "Bedaŭrinde, neniu rezulto estas montrebla nuntempe. Vi povas provi serĉi aŭ foliumi la esploran paĝon por trovi kontojn por sekvi, aŭ retrovi baldaŭ.",
|
||||
"onboarding.follows.lead": "Via hejma fluo estas la ĉefa maniero sperti Mastodon. Ju pli da homoj vi sekvas, des pli aktiva kaj interesa ĝi estos. Por komenci, jen kelkaj sugestoj:",
|
||||
@@ -632,17 +635,17 @@
|
||||
"onboarding.share.message": "Mi estas {username} en #Mastodon! Sekvu min ĉe {url}",
|
||||
"onboarding.share.next_steps": "Eblaj malantauaj paŝoj:",
|
||||
"onboarding.share.title": "Disvastigi vian profilon",
|
||||
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
|
||||
"onboarding.start.skip": "Want to skip right ahead?",
|
||||
"onboarding.start.lead": "Vi nun estas parto de Mastodon, unika, malcentralizita socia amaskomunikilara platformo, kie vi—ne algoritmo—zorgas vian propran sperton. Ni komencu vin sur ĉi tiu nova socia limo:",
|
||||
"onboarding.start.skip": "Ĉu vi ne bezonas helpon por komenci?",
|
||||
"onboarding.start.title": "Vi atingas ĝin!",
|
||||
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
|
||||
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
||||
"onboarding.steps.follow_people.title": "Agordu vian hejman fluon",
|
||||
"onboarding.steps.publish_status.body": "Salutu la mondon per teksto, fotoj, filmetoj aŭ balotenketoj {emoji}",
|
||||
"onboarding.steps.publish_status.title": "Fari vian unuan afiŝon",
|
||||
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
|
||||
"onboarding.steps.setup_profile.title": "Customize your profile",
|
||||
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
|
||||
"onboarding.steps.share_profile.title": "Share your profile",
|
||||
"onboarding.steps.setup_profile.body": "Diskonigu viajn interagojn havante ampleksan profilon.",
|
||||
"onboarding.steps.setup_profile.title": "Agordu vian profilon",
|
||||
"onboarding.steps.share_profile.body": "Sciigu viajn amikojn kiel trovi vin sur Mastodon",
|
||||
"onboarding.steps.share_profile.title": "Kunhavigu vian Mastodon-profilon",
|
||||
"onboarding.tips.2fa": "<strong>Ĉu vi scias?</strong> Vi povas sekurigi vian konton per efektivigi dufaktora autentigo en via kontoagordoj.",
|
||||
"onboarding.tips.accounts_from_other_servers": "<strong>Ĉu vi scias?</strong> Ĉar Mastodon estas sencentra, kelkaj profiloj kiujn vi trovi estas gastigitaj ĉe aliaj serviloj kiuj ne estas via.",
|
||||
"onboarding.tips.migration": "<strong>Ĉu vi scias?</strong> Se vi sentas ke {domain} ne estas bona servilelekto por vi en la estonteco, vi povas translokiĝi al alia servilo de Mastodon sen malgajni viajn sekvantojn.",
|
||||
@@ -656,11 +659,11 @@
|
||||
"poll.total_people": "{count, plural, one {# homo} other {# homoj}}",
|
||||
"poll.total_votes": "{count, plural, one {# voĉdono} other {# voĉdonoj}}",
|
||||
"poll.vote": "Voĉdoni",
|
||||
"poll.voted": "Vi elektis por ĉi tiu respondo",
|
||||
"poll.voted": "Vi voĉdonis por ĉi tiu respondo",
|
||||
"poll.votes": "{votes, plural, one {# voĉdono} other {# voĉdonoj}}",
|
||||
"poll_button.add_poll": "Aldoni balotenketon",
|
||||
"poll_button.remove_poll": "Forigi balotenketon",
|
||||
"privacy.change": "Agordi mesaĝan privatecon",
|
||||
"privacy.change": "Ŝanĝu afiŝan privatecon",
|
||||
"privacy.direct.long": "Ĉiuj menciitaj en la afiŝo",
|
||||
"privacy.direct.short": "Specifaj homoj",
|
||||
"privacy.private.long": "Nur viaj sekvantoj",
|
||||
@@ -769,19 +772,19 @@
|
||||
"server_banner.is_one_of_many": "{domain} estas unu el la multaj sendependaj Mastodon-serviloj, kiujn vi povas uzi por partopreni en la fediverso.",
|
||||
"server_banner.server_stats": "Statistikoj de la servilo:",
|
||||
"sign_in_banner.create_account": "Krei konton",
|
||||
"sign_in_banner.follow_anyone": "Sekvi iun ajn tra la fediverso kaj vidi ĉion en kronologia ordo. Neniuj algoritmoj, reklamoj aŭ klakbetoj videblas.",
|
||||
"sign_in_banner.mastodon_is": "Mastodonto estas la plej bona maniero por resti flank-al-flanke kun kio okazas.",
|
||||
"sign_in_banner.sign_in": "Saluti",
|
||||
"sign_in_banner.follow_anyone": "Sekvu iun ajn tra la fediverso kaj vidu ĉion laŭ templinio. Nul algoritmo, reklamo aŭ kliklogilo ĉeestas.",
|
||||
"sign_in_banner.mastodon_is": "Mastodon estas la plej bona maniero resti ĝisdata pri aktualaĵoj.",
|
||||
"sign_in_banner.sign_in": "Ensaluti",
|
||||
"sign_in_banner.sso_redirect": "Ensalutu aŭ Registriĝi",
|
||||
"status.admin_account": "Malfermi fasadon de moderigado por @{name}",
|
||||
"status.admin_domain": "Malfermu moderigan interfacon por {domain}",
|
||||
"status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco",
|
||||
"status.admin_status": "Malfermi ĉi tiun afiŝon en la kontrola interfaco",
|
||||
"status.block": "Bloki @{name}",
|
||||
"status.bookmark": "Aldoni al la legosignoj",
|
||||
"status.cancel_reblog_private": "Ne plu diskonigi",
|
||||
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
|
||||
"status.continued_thread": "Daŭrigis fadenon",
|
||||
"status.copy": "Kopii la ligilon al la mesaĝo",
|
||||
"status.copy": "Kopii la ligilon al la afiŝo",
|
||||
"status.delete": "Forigi",
|
||||
"status.detailed_status": "Detala konversacia vido",
|
||||
"status.direct": "Private mencii @{name}",
|
||||
@@ -803,9 +806,9 @@
|
||||
"status.more": "Pli",
|
||||
"status.mute": "Silentigi @{name}",
|
||||
"status.mute_conversation": "Silentigi konversacion",
|
||||
"status.open": "Disvolvi la mesaĝon",
|
||||
"status.open": "Pligrandigu ĉi tiun afiŝon",
|
||||
"status.pin": "Alpingli al la profilo",
|
||||
"status.pinned": "Alpinglita mesaĝo",
|
||||
"status.pinned": "Alpinglita afiŝo",
|
||||
"status.read_more": "Legi pli",
|
||||
"status.reblog": "Diskonigi",
|
||||
"status.reblog_private": "Diskonigi kun la sama videbleco",
|
||||
@@ -824,7 +827,7 @@
|
||||
"status.show_less_all": "Montri malpli ĉiun",
|
||||
"status.show_more_all": "Montri pli ĉiun",
|
||||
"status.show_original": "Montru originalon",
|
||||
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
|
||||
"status.title.with_attachments": "{user} afiŝis {attachmentCount, plural, one {aldonaĵon} other {{attachmentCount} aldonaĵojn}}",
|
||||
"status.translate": "Traduki",
|
||||
"status.translated_from_with": "Tradukita el {lang} per {provider}",
|
||||
"status.uncached_media_warning": "Antaŭrigardo ne disponebla",
|
||||
@@ -847,7 +850,7 @@
|
||||
"units.short.million": "{count}M",
|
||||
"units.short.thousand": "{count}K",
|
||||
"upload_area.title": "Altreni kaj lasi por alŝuti",
|
||||
"upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)",
|
||||
"upload_button.label": "Aldonu bildojn, filmeton aŭ sondosieron",
|
||||
"upload_error.limit": "Limo de dosiera alŝutado transpasita.",
|
||||
"upload_error.poll": "Alŝuto de dosiero ne permesita kun balotenketo.",
|
||||
"upload_form.audio_description": "Priskribi por homoj kiuj malfacile aŭdi",
|
||||
@@ -870,17 +873,17 @@
|
||||
"upload_modal.hint": "Klaku aŭ trenu la cirklon en la antaŭvidilo por elekti la fokuspunkton kiu ĉiam videblos en ĉiuj etigitaj bildoj.",
|
||||
"upload_modal.preparing_ocr": "Preparante OSR…",
|
||||
"upload_modal.preview_label": "Antaŭvido ({ratio})",
|
||||
"upload_progress.label": "Alŝutado…",
|
||||
"upload_progress.label": "Alŝutante...",
|
||||
"upload_progress.processing": "Traktante…",
|
||||
"username.taken": "La uzantnomo estas jam posedita. Provu alion",
|
||||
"video.close": "Fermi la videon",
|
||||
"video.close": "Fermu la filmeton",
|
||||
"video.download": "Elŝuti dosieron",
|
||||
"video.exit_fullscreen": "Eksigi plenekrana",
|
||||
"video.expand": "Pligrandigi la videon",
|
||||
"video.fullscreen": "Igi plenekrana",
|
||||
"video.hide": "Kaŝi la videon",
|
||||
"video.hide": "Kaŝu la filmeton",
|
||||
"video.mute": "Silentigi",
|
||||
"video.pause": "Paŭzi",
|
||||
"video.pause": "Paŭzigi",
|
||||
"video.play": "Ekigi",
|
||||
"video.unmute": "Malsilentigi"
|
||||
}
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "¿Dejar de seguir al usuario?",
|
||||
"content_warning.hide": "Ocultar mensaje",
|
||||
"content_warning.show": "Mostrar de todos modos",
|
||||
"content_warning.show_more": "Mostrar más",
|
||||
"conversation.delete": "Eliminar conversación",
|
||||
"conversation.mark_as_read": "Marcar como leída",
|
||||
"conversation.open": "Ver conversación",
|
||||
@@ -249,7 +250,7 @@
|
||||
"emoji_button.nature": "Naturaleza",
|
||||
"emoji_button.not_found": "No se encontraron emojis coincidentes",
|
||||
"emoji_button.objects": "Objetos",
|
||||
"emoji_button.people": "Cuentas",
|
||||
"emoji_button.people": "Gente",
|
||||
"emoji_button.recent": "Usados frecuentemente",
|
||||
"emoji_button.search": "Buscar...",
|
||||
"emoji_button.search_results": "Resultados de búsqueda",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva",
|
||||
"filter_modal.select_filter.title": "Filtrar este mensaje",
|
||||
"filter_modal.title.status": "Filtrar un mensaje",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “{title}”",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nadie} one {una persona} other {# personas}} que podrías conocer",
|
||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||
"firehose.all": "Todos",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} marcó tu mensaje como favorito",
|
||||
"notification.favourite.name_and_others_with_link": "{name} y <a>{count, plural, one {# cuenta más} other {# cuentas más}}</a> marcaron tu mensaje como favorito",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.follow.name_and_others": "{name} y {count, plural, one {# cuenta más} other {# cuentas más}} te están siguiendo",
|
||||
"notification.follow.name_and_others": "{name} y <a>{count, plural, one {# cuenta más} other {# cuentas más}}</a> te están siguiendo",
|
||||
"notification.follow_request": "{name} solicitó seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# cuenta más} other {# cuentas más}} solicitaron seguirte",
|
||||
"notification.label.mention": "Mención",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Respuesta privada",
|
||||
"notification.label.reply": "Respuesta",
|
||||
"notification.mention": "Mención",
|
||||
"notification.mentioned_you": "{name} te mencionó",
|
||||
"notification.moderation-warning.learn_more": "Aprendé más",
|
||||
"notification.moderation_warning": "Recibiste una advertencia de moderación",
|
||||
"notification.moderation_warning.action_delete_statuses": "Se eliminaron algunos de tus mensajes.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
|
||||
"notifications.column_settings.follow": "Nuevos seguidores:",
|
||||
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
|
||||
"notifications.column_settings.group": "Agrupar",
|
||||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.poll": "Resultados de la encuesta:",
|
||||
"notifications.column_settings.push": "Notificaciones push",
|
||||
@@ -854,7 +857,7 @@
|
||||
"upload_form.description": "Agregá una descripción para personas con dificultades visuales",
|
||||
"upload_form.drag_and_drop.instructions": "Para recoger un archivo multimedia, pulsá la barra espaciadora o la tecla Enter. Mientras arrastrás, usá las teclas de flecha para mover el archivo multimedia en cualquier dirección. Volvé a pulsar la barra espaciadora o la tecla Enter para soltar el archivo multimedia en su nueva posición, o pulsá la tecla Escape para cancelar.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Se canceló el arrastre. Se eliminó el archivo adjunto {item}.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} ha sido eliminado.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} fue soltado.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "El archivo adjunto {item} fue movido.",
|
||||
"upload_form.drag_and_drop.on_drag_start": "Se ha recogido el archivo adjunto {item}.",
|
||||
"upload_form.edit": "Editar",
|
||||
|
||||
@@ -159,8 +159,8 @@
|
||||
"compose_form.poll.multiple": "Selección múltiple",
|
||||
"compose_form.poll.option_placeholder": "Opción {number}",
|
||||
"compose_form.poll.single": "Seleccione uno",
|
||||
"compose_form.poll.switch_to_multiple": "Modificar encuesta para permitir múltiples opciones",
|
||||
"compose_form.poll.switch_to_single": "Modificar encuesta para permitir una única opción",
|
||||
"compose_form.poll.switch_to_multiple": "Cambiar la encuesta para permitir múltiples opciones",
|
||||
"compose_form.poll.switch_to_single": "Cambiar la encuesta para permitir una única opción",
|
||||
"compose_form.poll.type": "Estilo",
|
||||
"compose_form.publish": "Publicación",
|
||||
"compose_form.publish_form": "Publicar",
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "¿Dejar de seguir al usuario?",
|
||||
"content_warning.hide": "Ocultar publicación",
|
||||
"content_warning.show": "Mostrar de todos modos",
|
||||
"content_warning.show_more": "Mostrar más",
|
||||
"conversation.delete": "Borrar conversación",
|
||||
"conversation.mark_as_read": "Marcar como leído",
|
||||
"conversation.open": "Ver conversación",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva",
|
||||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||
"filter_modal.title.status": "Filtrar una publicación",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “{title}”",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nadie} one {una persona} other {# people}} que puede que tú conozcas",
|
||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||
"firehose.all": "Todas",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} marcó como favorita tu publicación",
|
||||
"notification.favourite.name_and_others_with_link": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> marcaron tu publicación como favorita",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.follow.name_and_others": "{name} y {count, plural, one {# otro} other {# otros}} te siguieron",
|
||||
"notification.follow.name_and_others": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> te han seguido",
|
||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# otro} other {# otros}} han solicitado seguirte",
|
||||
"notification.label.mention": "Mención",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Respuesta privada",
|
||||
"notification.label.reply": "Respuesta",
|
||||
"notification.mention": "Mención",
|
||||
"notification.mentioned_you": "{name} te mencionó",
|
||||
"notification.moderation-warning.learn_more": "Saber más",
|
||||
"notification.moderation_warning": "Has recibido una advertencia de moderación",
|
||||
"notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
|
||||
"notifications.column_settings.follow": "Nuevos seguidores:",
|
||||
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
|
||||
"notifications.column_settings.group": "Grupo",
|
||||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.poll": "Resultados de la votación:",
|
||||
"notifications.column_settings.push": "Notificaciones push",
|
||||
@@ -643,7 +646,7 @@
|
||||
"onboarding.steps.setup_profile.title": "Personaliza tu perfil",
|
||||
"onboarding.steps.share_profile.body": "Dile a tus amigos cómo encontrarte en Mastodon",
|
||||
"onboarding.steps.share_profile.title": "Comparte tu perfil",
|
||||
"onboarding.tips.2fa": "<strong>¿Sabías que?</strong> Puedes proteger tu cuenta configurando la autenticación de dos factores en la configuración de su cuenta. Funciona con cualquier aplicación TOTP de su elección, ¡no necesitas número de teléfono!",
|
||||
"onboarding.tips.2fa": "<strong>¿Sabías que?</strong> Puedes proteger tu cuenta configurando la autenticación de dos factores en los ajustes de su cuenta. Funciona con cualquier aplicación TOTP que elijas, ¡sin necesidad de número de teléfono!",
|
||||
"onboarding.tips.accounts_from_other_servers": "<strong>¿Sabías que?</strong> Como Mastodon es descentralizado, algunos perfiles que encuentras están alojados en servidores distintos del tuyo. Y sin embargo, ¡puedes interactuar con ellos! ¡Su servidor corresponde a la segunda mitad de su nombre de usuario!",
|
||||
"onboarding.tips.migration": "<strong>¿Sabías que?</strong> Si sientes que {domain} no es una gran elección de servidor para ti en el futuro, puedes moverte a otro servidor de Mastodon sin perder a tus seguidores. ¡Incluso puedes alojar tu propio servidor!",
|
||||
"onboarding.tips.verification": "<strong>¿Sabías que?</strong> Puedes verificar tu cuenta poniendo un enlace a tu perfil de Mastodon en su propio sitio web y añadiendo el sitio web a su perfil. ¡Sin necesidad de comisiones ni documentos!",
|
||||
@@ -852,11 +855,11 @@
|
||||
"upload_error.poll": "Subida de archivos no permitida con encuestas.",
|
||||
"upload_form.audio_description": "Describir para personas con problemas auditivos",
|
||||
"upload_form.description": "Describir para los usuarios con dificultad visual",
|
||||
"upload_form.drag_and_drop.instructions": "Para recoger un archivo multimedia, pulsa la barra espaciadora o la tecla Enter. Mientras arrastras, utiliza las teclas de flecha para mover el archivo multimedia en cualquier dirección. Vuelve a pulsar la barra espaciadora o la tecla Enter para soltar el archivo multimedia en su nueva posición, o pulsa Escape para cancelar.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Se canceló el arrastre. Se eliminó el archivo adjunto {item}.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} ha sido eliminado.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "El archivo adjunto {item} se ha movido.",
|
||||
"upload_form.drag_and_drop.on_drag_start": "Se ha recogido el archivo adjunto {item}.",
|
||||
"upload_form.drag_and_drop.instructions": "Para recoger un archivo adjunto, pulsa la barra espaciadora o la tecla Intro. Mientras arrastras, usa las teclas de flecha para mover el archivo adjunto en cualquier dirección. Vuelve a pulsar la barra espaciadora o la tecla Intro para soltar el archivo adjunto en su nueva posición, o pulsa la tecla Escape para cancelar.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Arrastre cancelado. El archivo adjunto {item} fue eliminado.",
|
||||
"upload_form.drag_and_drop.on_drag_end": "El archivo adjunto {item} fue eliminado.",
|
||||
"upload_form.drag_and_drop.on_drag_over": "El archivo adjunto {item} fue movido.",
|
||||
"upload_form.drag_and_drop.on_drag_start": "Recogidos los archivos adjuntos {item}.",
|
||||
"upload_form.edit": "Editar",
|
||||
"upload_form.thumbnail": "Cambiar miniatura",
|
||||
"upload_form.video_description": "Describir para personas con problemas auditivos o visuales",
|
||||
|
||||
@@ -197,6 +197,7 @@
|
||||
"confirmations.unfollow.title": "¿Dejar de seguir al usuario?",
|
||||
"content_warning.hide": "Ocultar publicación",
|
||||
"content_warning.show": "Mostrar de todos modos",
|
||||
"content_warning.show_more": "Mostrar más",
|
||||
"conversation.delete": "Borrar conversación",
|
||||
"conversation.mark_as_read": "Marcar como leído",
|
||||
"conversation.open": "Ver conversación",
|
||||
@@ -305,7 +306,7 @@
|
||||
"filter_modal.select_filter.subtitle": "Usar una categoría existente o crear una nueva",
|
||||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||
"filter_modal.title.status": "Filtrar una publicación",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “{title}”",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “<span>{title}</span>”",
|
||||
"filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nadie} one {una persona} other {# personas}} que puede que conozcas",
|
||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||
"firehose.all": "Todas",
|
||||
@@ -382,7 +383,7 @@
|
||||
"ignore_notifications_modal.not_following_title": "¿Ignorar notificaciones de personas a las que no sigues?",
|
||||
"ignore_notifications_modal.private_mentions_title": "¿Ignorar notificaciones de menciones privadas no solicitadas?",
|
||||
"interaction_modal.description.favourite": "Con una cuenta en Mastodon, puedes marcar como favorita esta publicación para que el autor sepa que te gusta, y guardala para más adelante.",
|
||||
"interaction_modal.description.follow": "Con una cuenta en Mastodon, puedes seguir {name} para recibir sus publicaciones en tu línea temporal de inicio.",
|
||||
"interaction_modal.description.follow": "Con una cuenta en Mastodon, puedes seguir {name} para recibir sus publicaciones en tu página de inicio.",
|
||||
"interaction_modal.description.reblog": "Con una cuenta en Mastodon, puedes impulsar esta publicación para compartirla con tus propios seguidores.",
|
||||
"interaction_modal.description.reply": "Con una cuenta en Mastodon, puedes responder a esta publicación.",
|
||||
"interaction_modal.login.action": "Ir a Inicio",
|
||||
@@ -508,7 +509,7 @@
|
||||
"notification.favourite": "{name} marcó como favorita tu publicación",
|
||||
"notification.favourite.name_and_others_with_link": "{name} y <a>{count, plural, one {# más} other {# más}}</a> marcaron tu publicación como favorita",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.follow.name_and_others": "{name} y {count, plural, one {# más} other {# más}} te siguieron",
|
||||
"notification.follow.name_and_others": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> te siguieron",
|
||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# más} other {# más}} han solicitado seguirte",
|
||||
"notification.label.mention": "Mención",
|
||||
@@ -516,6 +517,7 @@
|
||||
"notification.label.private_reply": "Respuesta privada",
|
||||
"notification.label.reply": "Respuesta",
|
||||
"notification.mention": "Mención",
|
||||
"notification.mentioned_you": "{name} te ha mencionado",
|
||||
"notification.moderation-warning.learn_more": "Saber más",
|
||||
"notification.moderation_warning": "Has recibido una advertencia de moderación",
|
||||
"notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.",
|
||||
@@ -566,6 +568,7 @@
|
||||
"notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
|
||||
"notifications.column_settings.follow": "Nuevos seguidores:",
|
||||
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
|
||||
"notifications.column_settings.group": "Agrupar",
|
||||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.poll": "Resultados de la votación:",
|
||||
"notifications.column_settings.push": "Notificaciones push",
|
||||
@@ -612,11 +615,11 @@
|
||||
"onboarding.action.back": "Llévame atrás",
|
||||
"onboarding.actions.back": "Llévame atrás",
|
||||
"onboarding.actions.go_to_explore": "Llévame a tendencias",
|
||||
"onboarding.actions.go_to_home": "Ir a mi inicio",
|
||||
"onboarding.actions.go_to_home": "Ir a mi página de inicio",
|
||||
"onboarding.compose.template": "¡Hola #Mastodon!",
|
||||
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar personas a las que seguir, o inténtalo de nuevo más tarde.",
|
||||
"onboarding.follows.lead": "Tu línea de inicio es la forma principal de experimentar Mastodon. Cuanta más personas sigas, más activa e interesante será. Para empezar, aquí hay algunas sugerencias:",
|
||||
"onboarding.follows.title": "Personaliza tu línea de inicio",
|
||||
"onboarding.follows.lead": "Tu página de inicio es la forma principal de experimentar Mastodon. Cuanta más personas sigas, más activa e interesante será. Para empezar, aquí hay algunas sugerencias:",
|
||||
"onboarding.follows.title": "Personaliza tu página de inicio",
|
||||
"onboarding.profile.discoverable": "Hacer que mi perfil aparezca en búsquedas",
|
||||
"onboarding.profile.discoverable_hint": "Cuando permites que tu perfil aparezca en búsquedas en Mastodon, tus publicaciones podrán aparecer en los resultados de búsqueda y en tendencias, y tu perfil podrá recomendarse a gente con intereses similares a los tuyos.",
|
||||
"onboarding.profile.display_name": "Nombre para mostrar",
|
||||
@@ -636,7 +639,7 @@
|
||||
"onboarding.start.skip": "¿No necesitas ayuda para empezar?",
|
||||
"onboarding.start.title": "¡Lo has logrado!",
|
||||
"onboarding.steps.follow_people.body": "Seguir personas interesante es de lo que trata Mastodon.",
|
||||
"onboarding.steps.follow_people.title": "Personaliza tu línea de inicio",
|
||||
"onboarding.steps.follow_people.title": "Personaliza tu página de inicio",
|
||||
"onboarding.steps.publish_status.body": "Di hola al mundo con texto, fotos, vídeos o encuestas {emoji}",
|
||||
"onboarding.steps.publish_status.title": "Escribe tu primera publicación",
|
||||
"onboarding.steps.setup_profile.body": "Aumenta tus interacciones con un perfil completo.",
|
||||
@@ -675,7 +678,7 @@
|
||||
"recommended": "Recomendado",
|
||||
"refresh": "Actualizar",
|
||||
"regeneration_indicator.label": "Cargando…",
|
||||
"regeneration_indicator.sublabel": "¡Tu historia de inicio se está preparando!",
|
||||
"regeneration_indicator.sublabel": "¡Tu página de inicio se está preparando!",
|
||||
"relative_time.days": "{number} d",
|
||||
"relative_time.full.days": "hace {number, plural, one {# día} other {# días}}",
|
||||
"relative_time.full.hours": "hace {number, plural, one {# hora} other {# horas}}",
|
||||
@@ -729,7 +732,7 @@
|
||||
"report.thanks.title": "¿No quieres esto?",
|
||||
"report.thanks.title_actionable": "Gracias por informar, estudiaremos esto.",
|
||||
"report.unfollow": "Dejar de seguir a @{name}",
|
||||
"report.unfollow_explanation": "Estás siguiendo esta cuenta. Para no ver sus publicaciones en tu muro de inicio, deja de seguirla.",
|
||||
"report.unfollow_explanation": "Estás siguiendo esta cuenta. Para dejar de ver sus publicaciones en tu página de inicio, deja de seguirla.",
|
||||
"report_notification.attached_statuses": "{count, plural, one {{count} publicación} other {{count} publicaciones}} adjunta(s)",
|
||||
"report_notification.categories.legal": "Legal",
|
||||
"report_notification.categories.legal_sentence": "contenido ilegal",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user