Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
- Gemfile
- Gemfile.lock
- app/controllers/about_controller.rb
- app/controllers/auth/sessions_controller.rb
main
Thibaut Girka 5 years ago
commit 16ff7c5627

@ -115,6 +115,20 @@ SMTP_FROM_ADDRESS=notifications@example.com
# S3_ENDPOINT=
# S3_SIGNATURE_VERSION=
# Google Cloud Storage (optional)
# Use S3 compatible API. Since GCS does not support Multipart Upload,
# increase the value of S3_MULTIPART_THRESHOLD to disable Multipart Upload.
# The attachment host must allow cross origin request - see the description
# above.
# S3_ENABLED=true
# AWS_ACCESS_KEY_ID=
# AWS_SECRET_ACCESS_KEY=
# S3_REGION=
# S3_PROTOCOL=https
# S3_HOSTNAME=storage.googleapis.com
# S3_ENDPOINT=https://storage.googleapis.com
# S3_MULTIPART_THRESHOLD=52428801 # 50.megabytes
# Swift (optional)
# The attachment host must allow cross origin request - see the description
# above.

@ -1 +1 @@
2.6.1
2.6.4

@ -3,6 +3,239 @@ Changelog
All notable changes to this project will be documented in this file.
## Unreleased
### Added
- Add "not available" label to unloaded media attachments in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11715), [Gargron](https://github.com/tootsuite/mastodon/pull/11745))
- **Add profile directory to web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11688), [mayaeh](https://github.com/tootsuite/mastodon/pull/11872))
- Add profile directory opt-in federation
- Add profile directory REST API
- Add special alert for throttled requests in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11677))
- Add confirmation modal when logging out from the web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11671))
- **Add audio player in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11644), [Gargron](https://github.com/tootsuite/mastodon/pull/11652), [Gargron](https://github.com/tootsuite/mastodon/pull/11654), [ThibG](https://github.com/tootsuite/mastodon/pull/11629))
- **Add autosuggestions for hashtags in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11422), [ThibG](https://github.com/tootsuite/mastodon/pull/11632), [Gargron](https://github.com/tootsuite/mastodon/pull/11764), [Gargron](https://github.com/tootsuite/mastodon/pull/11588), [Gargron](https://github.com/tootsuite/mastodon/pull/11442))
- **Add media editing modal with OCR tool in web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11563), [Gargron](https://github.com/tootsuite/mastodon/pull/11566), [ThibG](https://github.com/tootsuite/mastodon/pull/11575), [ThibG](https://github.com/tootsuite/mastodon/pull/11576), [Gargron](https://github.com/tootsuite/mastodon/pull/11577), [Gargron](https://github.com/tootsuite/mastodon/pull/11573), [Gargron](https://github.com/tootsuite/mastodon/pull/11571))
- Add indicator of unread notifications to window title when web UI is out of focus ([Gargron](https://github.com/tootsuite/mastodon/pull/11560), [Gargron](https://github.com/tootsuite/mastodon/pull/11572))
- Add indicator for which options you voted for in a poll in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11195))
- **Add search results pagination to web UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11409), [ThibG](https://github.com/tootsuite/mastodon/pull/11447))
- **Add option to disable real-time updates in web UI ("slow mode")** ([Gargron](https://github.com/tootsuite/mastodon/pull/9984), [ykzts](https://github.com/tootsuite/mastodon/pull/11880), [ThibG](https://github.com/tootsuite/mastodon/pull/11883), [Gargron](https://github.com/tootsuite/mastodon/pull/11898), [ThibG](https://github.com/tootsuite/mastodon/pull/11859))
- Add option to disable blurhash previews in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11188))
- Add native smooth scrolling when supported in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11207))
- Add search and sort functions to hashtag admin UI ([mayaeh](https://github.com/tootsuite/mastodon/pull/11829), [Gargron](https://github.com/tootsuite/mastodon/pull/11897), [mayaeh](https://github.com/tootsuite/mastodon/pull/11875))
- Add setting for default search engine indexing in admin UI ([brortao](https://github.com/tootsuite/mastodon/pull/11804))
- Add account bio to account view in admin UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11473))
- **Add option to include reported statuses in warning e-mail from admin UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11639), [Gargron](https://github.com/tootsuite/mastodon/pull/11812), [Gargron](https://github.com/tootsuite/mastodon/pull/11741), [Gargron](https://github.com/tootsuite/mastodon/pull/11698), [mayaeh](https://github.com/tootsuite/mastodon/pull/11765))
- Add number of pending accounts and pending hashtags to dashboard in admin UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11514))
- **Add account migration UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11846), [noellabo](https://github.com/tootsuite/mastodon/pull/11905), [noellabo](https://github.com/tootsuite/mastodon/pull/11907), [noellabo](https://github.com/tootsuite/mastodon/pull/11906), [noellabo](https://github.com/tootsuite/mastodon/pull/11902))
- **Add table of contents to about page** ([Gargron](https://github.com/tootsuite/mastodon/pull/11885), [ykzts](https://github.com/tootsuite/mastodon/pull/11941), [ykzts](https://github.com/tootsuite/mastodon/pull/11895), [Kjwon15](https://github.com/tootsuite/mastodon/pull/11916))
- **Add password challenge to 2FA settings, e-mail notifications** ([Gargron](https://github.com/tootsuite/mastodon/pull/11878))
- Add optional invite comments ([ThibG](https://github.com/tootsuite/mastodon/pull/10465))
- **Add optional public list of domain blocks with comments** ([ThibG](https://github.com/tootsuite/mastodon/pull/11298), [ThibG](https://github.com/tootsuite/mastodon/pull/11515), [Gargron](https://github.com/tootsuite/mastodon/pull/11908))
- Add an RSS feed for featured hashtags ([noellabo](https://github.com/tootsuite/mastodon/pull/10502))
- Add explanations to featured hashtags UI and profile ([Gargron](https://github.com/tootsuite/mastodon/pull/11586))
- **Add hashtag trends with admin and user settings** ([Gargron](https://github.com/tootsuite/mastodon/pull/11490), [Gargron](https://github.com/tootsuite/mastodon/pull/11502), [Gargron](https://github.com/tootsuite/mastodon/pull/11641), [Gargron](https://github.com/tootsuite/mastodon/pull/11594), [Gargron](https://github.com/tootsuite/mastodon/pull/11517), [mayaeh](https://github.com/tootsuite/mastodon/pull/11845), [Gargron](https://github.com/tootsuite/mastodon/pull/11774), [Gargron](https://github.com/tootsuite/mastodon/pull/11712), [Gargron](https://github.com/tootsuite/mastodon/pull/11791), [Gargron](https://github.com/tootsuite/mastodon/pull/11743), [Gargron](https://github.com/tootsuite/mastodon/pull/11740), [Gargron](https://github.com/tootsuite/mastodon/pull/11714), [ThibG](https://github.com/tootsuite/mastodon/pull/11631), [Sasha-Sorokin](https://github.com/tootsuite/mastodon/pull/11569), [Gargron](https://github.com/tootsuite/mastodon/pull/11524), [Gargron](https://github.com/tootsuite/mastodon/pull/11513))
- Add hashtag usage breakdown to admin UI
- Add batch actions for hashtags to admin UI
- Add trends to web UI
- Add trends to public pages
- Add user preference to hide trends
- Add admin setting to disable trends
- **Add categories for custom emojis** ([Gargron](https://github.com/tootsuite/mastodon/pull/11196), [Gargron](https://github.com/tootsuite/mastodon/pull/11793), [Gargron](https://github.com/tootsuite/mastodon/pull/11920), [highemerly](https://github.com/tootsuite/mastodon/pull/11876))
- Add custom emoji categories to emoji picker in web UI
- Add `category` to custom emojis in REST API
- Add batch actions for custom emojis in admin UI
- Add max image dimensions to error message ([raboof](https://github.com/tootsuite/mastodon/pull/11552))
- Add aac, m4a, 3gp, amr, wma to allowed audio formats ([Gargron](https://github.com/tootsuite/mastodon/pull/11342), [umonaca](https://github.com/tootsuite/mastodon/pull/11687))
- **Add search syntax for operators and phrases** ([Gargron](https://github.com/tootsuite/mastodon/pull/11411))
- **Add REST API for managing featured hashtags** ([noellabo](https://github.com/tootsuite/mastodon/pull/11778))
- **Add REST API for managing timeline read markers** ([Gargron](https://github.com/tootsuite/mastodon/pull/11762))
- Add `exclude_unreviewed` param to `GET /api/v2/search` REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/11977))
- **Add ActivityPub secure mode** ([Gargron](https://github.com/tootsuite/mastodon/pull/11269), [ThibG](https://github.com/tootsuite/mastodon/pull/11332), [ThibG](https://github.com/tootsuite/mastodon/pull/11295))
- Add HTTP signatures to all outgoing ActivityPub GET requests ([Gargron](https://github.com/tootsuite/mastodon/pull/11284), [ThibG](https://github.com/tootsuite/mastodon/pull/11300))
- Add support for ActivityPub Audio activities ([ThibG](https://github.com/tootsuite/mastodon/pull/11189))
- Add ActivityPub actor representing the entire server ([ThibG](https://github.com/tootsuite/mastodon/pull/11321), [rtucker](https://github.com/tootsuite/mastodon/pull/11400), [ThibG](https://github.com/tootsuite/mastodon/pull/11561), [Gargron](https://github.com/tootsuite/mastodon/pull/11798))
- **Add whitelist mode** ([Gargron](https://github.com/tootsuite/mastodon/pull/11291), [mayaeh](https://github.com/tootsuite/mastodon/pull/11634))
- Add config of multipart threshold for S3 ([ykzts](https://github.com/tootsuite/mastodon/pull/11924), [ykzts](https://github.com/tootsuite/mastodon/pull/11944))
- Add health check endpoint for web ([ykzts](https://github.com/tootsuite/mastodon/pull/11770), [ykzts](https://github.com/tootsuite/mastodon/pull/11947))
- Add HTTP signature keyId to request log ([Gargron](https://github.com/tootsuite/mastodon/pull/11591))
- Add `SMTP_REPLY_TO` environment variable ([hugogameiro](https://github.com/tootsuite/mastodon/pull/11718))
- Add `tootctl preview_cards remove` command ([mayaeh](https://github.com/tootsuite/mastodon/pull/11320))
- Add `tootctl media refresh` command ([Gargron](https://github.com/tootsuite/mastodon/pull/11775))
- Add `tootctl cache recount` command ([Gargron](https://github.com/tootsuite/mastodon/pull/11597))
- Add option to exclude suspended domains from `tootctl domains crawl` ([dariusk](https://github.com/tootsuite/mastodon/pull/11454))
- Add soft delete for statuses for instant deletes through API ([Gargron](https://github.com/tootsuite/mastodon/pull/11623), [Gargron](https://github.com/tootsuite/mastodon/pull/11648))
- Add rails-level JSON caching ([Gargron](https://github.com/tootsuite/mastodon/pull/11333), [Gargron](https://github.com/tootsuite/mastodon/pull/11271))
- **Add request pool to improve delivery performance** ([Gargron](https://github.com/tootsuite/mastodon/pull/10353), [ykzts](https://github.com/tootsuite/mastodon/pull/11756))
- Add concurrent connection attempts to resolved IP addresses ([ThibG](https://github.com/tootsuite/mastodon/pull/11757))
- Add index for remember_token to improve login performance ([abcang](https://github.com/tootsuite/mastodon/pull/11881))
- **Add more accurate hashtag search** ([Gargron](https://github.com/tootsuite/mastodon/pull/11579), [Gargron](https://github.com/tootsuite/mastodon/pull/11427), [Gargron](https://github.com/tootsuite/mastodon/pull/11448))
- **Add more accurate account search** ([Gargron](https://github.com/tootsuite/mastodon/pull/11537), [Gargron](https://github.com/tootsuite/mastodon/pull/11580))
- **Add a spam check** ([Gargron](https://github.com/tootsuite/mastodon/pull/11217), [Gargron](https://github.com/tootsuite/mastodon/pull/11806), [ThibG](https://github.com/tootsuite/mastodon/pull/11296))
### Changed
- **Change conversations UI** ([Gargron](https://github.com/tootsuite/mastodon/pull/11896))
- Change dashboard to short number notation ([noellabo](https://github.com/tootsuite/mastodon/pull/11847), [noellabo](https://github.com/tootsuite/mastodon/pull/11911))
- Change REST API `GET /api/v1/timelines/public` to require authentication when public preview is off ([ThibG](https://github.com/tootsuite/mastodon/pull/11802))
- Change REST API `POST /api/v1/follow_requests/:id/(approve|reject)` to return relationship ([ThibG](https://github.com/tootsuite/mastodon/pull/11800))
- Change rate limit for media proxy ([ykzts](https://github.com/tootsuite/mastodon/pull/11814))
- Change unlisted custom emoji to not appear in autosuggestions ([Gargron](https://github.com/tootsuite/mastodon/pull/11818))
- Change max length of media descriptions from 420 to 1500 characters ([Gargron](https://github.com/tootsuite/mastodon/pull/11819), [ThibG](https://github.com/tootsuite/mastodon/pull/11836))
- **Change deletes to preserve soft-deleted statuses in unresolved reports** ([Gargron](https://github.com/tootsuite/mastodon/pull/11805))
- **Change tootctl to use inline parallelization instead of Sidekiq** ([Gargron](https://github.com/tootsuite/mastodon/pull/11776))
- **Change account deletion page to have better explanations** ([Gargron](https://github.com/tootsuite/mastodon/pull/11753), [Gargron](https://github.com/tootsuite/mastodon/pull/11763))
- Change hashtag component in web UI to show numbers for 2 last days ([Gargron](https://github.com/tootsuite/mastodon/pull/11742), [Gargron](https://github.com/tootsuite/mastodon/pull/11755), [Gargron](https://github.com/tootsuite/mastodon/pull/11754))
- Change OpenGraph description on sign-up page to reflect invite ([Gargron](https://github.com/tootsuite/mastodon/pull/11744))
- Change layout of public profile directory to be the same as in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11705))
- Change detailed status child ordering to sort self-replies on top ([ThibG](https://github.com/tootsuite/mastodon/pull/11686))
- Change window resize handler to switch to/from mobile layout as soon as needed ([ThibG](https://github.com/tootsuite/mastodon/pull/11656))
- Change icon button styles to make hover/focus states more obvious ([ThibG](https://github.com/tootsuite/mastodon/pull/11474))
- Change contrast of status links that are not mentions or hashtags ([ThibG](https://github.com/tootsuite/mastodon/pull/11406))
- **Change hashtags to preserve first-used casing** ([Gargron](https://github.com/tootsuite/mastodon/pull/11416), [Gargron](https://github.com/tootsuite/mastodon/pull/11508), [Gargron](https://github.com/tootsuite/mastodon/pull/11504), [Gargron](https://github.com/tootsuite/mastodon/pull/11507), [Gargron](https://github.com/tootsuite/mastodon/pull/11441))
- **Change unconfirmed user login behaviour** ([Gargron](https://github.com/tootsuite/mastodon/pull/11375), [ThibG](https://github.com/tootsuite/mastodon/pull/11394), [Gargron](https://github.com/tootsuite/mastodon/pull/11860))
- **Change single-column mode to scroll the whole page** ([Gargron](https://github.com/tootsuite/mastodon/pull/11359), [Gargron](https://github.com/tootsuite/mastodon/pull/11894), [Gargron](https://github.com/tootsuite/mastodon/pull/11891), [ThibG](https://github.com/tootsuite/mastodon/pull/11655), [Gargron](https://github.com/tootsuite/mastodon/pull/11463), [Gargron](https://github.com/tootsuite/mastodon/pull/11458), [ThibG](https://github.com/tootsuite/mastodon/pull/11395), [Gargron](https://github.com/tootsuite/mastodon/pull/11418))
- Change `tootctl accounts follow` to only work with local accounts ([angristan](https://github.com/tootsuite/mastodon/pull/11592))
- Change Dockerfile ([Shleeble](https://github.com/tootsuite/mastodon/pull/11710), [ykzts](https://github.com/tootsuite/mastodon/pull/11768), [Shleeble](https://github.com/tootsuite/mastodon/pull/11707))
- Change supported Node versions to include v12 ([abcang](https://github.com/tootsuite/mastodon/pull/11706))
- Change Portuguese language from `pt` to `pt-PT` ([Gargron](https://github.com/tootsuite/mastodon/pull/11820))
- Change domain block silence to always require approval on follow ([ThibG](https://github.com/tootsuite/mastodon/pull/11975))
### Removed
- **Remove OStatus support** ([Gargron](https://github.com/tootsuite/mastodon/pull/11205), [Gargron](https://github.com/tootsuite/mastodon/pull/11303), [Gargron](https://github.com/tootsuite/mastodon/pull/11460), [ThibG](https://github.com/tootsuite/mastodon/pull/11280), [ThibG](https://github.com/tootsuite/mastodon/pull/11278))
- Remove Atom feeds and old URLs in the form of `GET /:username/updates/:id` ([Gargron](https://github.com/tootsuite/mastodon/pull/11247))
- Remove WebP support ([angristan](https://github.com/tootsuite/mastodon/pull/11589))
- Remove deprecated config options from Heroku and Scalingo ([ykzts](https://github.com/tootsuite/mastodon/pull/11925))
- Remove deprecated REST API `GET /api/v1/search` API ([Gargron](https://github.com/tootsuite/mastodon/pull/11823))
- Remove deprecated REST API `GET /api/v1/statuses/:id/card` ([Gargron](https://github.com/tootsuite/mastodon/pull/11213))
- Remove deprecated REST API `POST /api/v1/notifications/dismiss?id=:id` ([Gargron](https://github.com/tootsuite/mastodon/pull/11214))
- Remove deprecated REST API `GET /api/v1/timelines/direct` ([Gargron](https://github.com/tootsuite/mastodon/pull/11212))
### Fixed
- Fix manifest warning ([ykzts](https://github.com/tootsuite/mastodon/pull/11767))
- Fix admin UI for custom emoji not respecting GIF autoplay preference ([ThibG](https://github.com/tootsuite/mastodon/pull/11801))
- Fix page body not being scrollable in admin/settings layout ([Gargron](https://github.com/tootsuite/mastodon/pull/11893))
- Fix placeholder colors for inputs not being explicitly defined ([Gargron](https://github.com/tootsuite/mastodon/pull/11890))
- Fix incorrect enclosure length in RSS ([tsia](https://github.com/tootsuite/mastodon/pull/11889))
- Fix TOTP codes not being filtered from logs during enabling/disabling ([Gargron](https://github.com/tootsuite/mastodon/pull/11877))
- Fix webfinger response not returning 410 when account is suspended ([Gargron](https://github.com/tootsuite/mastodon/pull/11869))
- Fix ActivityPub Move handler queuing jobs that will fail if account is suspended ([Gargron](https://github.com/tootsuite/mastodon/pull/11864))
- Fix SSO login not using existing account when e-mail is verified ([Gargron](https://github.com/tootsuite/mastodon/pull/11862))
- Fix web UI allowing uploads past status limit via drag & drop ([Gargron](https://github.com/tootsuite/mastodon/pull/11863))
- Fix expiring polls not being displayed as such in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11835))
- Fix 2FA challenge and password challenge for non-database users ([Gargron](https://github.com/tootsuite/mastodon/pull/11831), [Gargron](https://github.com/tootsuite/mastodon/pull/11943))
- Fix profile fields overflowing page width in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11828))
- Fix web push subscriptions being deleted on rate limit or timeout ([Gargron](https://github.com/tootsuite/mastodon/pull/11826))
- Fix display of long poll options in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11717), [ThibG](https://github.com/tootsuite/mastodon/pull/11833))
- Fix search API not resolving URL when `type` is given ([Gargron](https://github.com/tootsuite/mastodon/pull/11822))
- Fix hashtags being split by ZWNJ character ([Gargron](https://github.com/tootsuite/mastodon/pull/11821))
- Fix scroll position resetting when opening media modals in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11815))
- Fix duplicate HTML IDs on about page ([ThibG](https://github.com/tootsuite/mastodon/pull/11803))
- Fix admin UI showing superfluous reject media/reports on suspended domain blocks ([ThibG](https://github.com/tootsuite/mastodon/pull/11749))
- Fix ActivityPub context not being dynamically computed ([ThibG](https://github.com/tootsuite/mastodon/pull/11746))
- Fix Mastodon logo style on hover on public pages' footer ([ThibG](https://github.com/tootsuite/mastodon/pull/11735))
- Fix height of dashboard counters ([ThibG](https://github.com/tootsuite/mastodon/pull/11736))
- Fix custom emoji animation on hover in web UI directory bios ([ThibG](https://github.com/tootsuite/mastodon/pull/11716))
- Fix non-numbers being passed to Redis and causing an error ([Gargron](https://github.com/tootsuite/mastodon/pull/11697))
- Fix error in REST API for an account's statuses ([Gargron](https://github.com/tootsuite/mastodon/pull/11700))
- Fix uncaught error when resource param is missing in Webfinger request ([Gargron](https://github.com/tootsuite/mastodon/pull/11701))
- Fix uncaught domain normalization error in remote follow ([Gargron](https://github.com/tootsuite/mastodon/pull/11703))
- Fix uncaught 422 and 500 errors ([Gargron](https://github.com/tootsuite/mastodon/pull/11590), [Gargron](https://github.com/tootsuite/mastodon/pull/11811))
- Fix uncaught parameter missing exceptions and missing error templates ([Gargron](https://github.com/tootsuite/mastodon/pull/11702))
- Fix encoding error when checking e-mail MX records ([Gargron](https://github.com/tootsuite/mastodon/pull/11696))
- Fix items in StatusContent render list not all having a key ([ThibG](https://github.com/tootsuite/mastodon/pull/11645))
- Fix remote and staff-removed statuses leaving media behind for a day ([Gargron](https://github.com/tootsuite/mastodon/pull/11638))
- Fix CSP needlessly allowing blob URLs in script-src ([ThibG](https://github.com/tootsuite/mastodon/pull/11620))
- Fix ignoring whole status because of one invalid hashtag ([Gargron](https://github.com/tootsuite/mastodon/pull/11621))
- Fix hidden statuses losing focus ([ThibG](https://github.com/tootsuite/mastodon/pull/11208))
- Fix loading bar being obscured by other elements in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11598))
- Fix multiple issues with replies collection for pages further than self-replies ([ThibG](https://github.com/tootsuite/mastodon/pull/11582))
- Fix blurhash and autoplay not working on public pages ([Gargron](https://github.com/tootsuite/mastodon/pull/11585))
- Fix 422 being returned instead of 404 when POSTing to unmatched routes ([Gargron](https://github.com/tootsuite/mastodon/pull/11574), [Gargron](https://github.com/tootsuite/mastodon/pull/11704))
- Fix client-side resizing of image uploads ([ThibG](https://github.com/tootsuite/mastodon/pull/11570))
- Fix short number formatting for numbers above million in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11559))
- Fix ActivityPub and REST API queries setting cookies and preventing caching ([ThibG](https://github.com/tootsuite/mastodon/pull/11539), [ThibG](https://github.com/tootsuite/mastodon/pull/11557), [ThibG](https://github.com/tootsuite/mastodon/pull/11336), [ThibG](https://github.com/tootsuite/mastodon/pull/11331))
- Fix some emojis in profile metadata labels are not emojified. ([kedamaDQ](https://github.com/tootsuite/mastodon/pull/11534))
- Fix account search always returning exact match on paginated results ([Gargron](https://github.com/tootsuite/mastodon/pull/11525))
- Fix acct URIs with IDN domains not being resolved ([Gargron](https://github.com/tootsuite/mastodon/pull/11520))
- Fix admin dashboard missing latest features ([Gargron](https://github.com/tootsuite/mastodon/pull/11505))
- Fix jumping of toot date when clicking spoiler button ([ariasuni](https://github.com/tootsuite/mastodon/pull/11449))
- Fix boost to original audience not working on mobile in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11371))
- Fix handling of webfinger redirects in ResolveAccountService ([ThibG](https://github.com/tootsuite/mastodon/pull/11279))
- Fix URLs appearing twice in errors of ActivityPub::DeliveryWorker ([Gargron](https://github.com/tootsuite/mastodon/pull/11231))
- Fix support for HTTP proxies ([ThibG](https://github.com/tootsuite/mastodon/pull/11245))
- Fix HTTP requests to IPv6 hosts ([ThibG](https://github.com/tootsuite/mastodon/pull/11240))
- Fix error in ElasticSearch index import ([mayaeh](https://github.com/tootsuite/mastodon/pull/11192))
- Fix duplicate account error when seeding development database ([ysksn](https://github.com/tootsuite/mastodon/pull/11366))
- Fix performance of session clean-up scheduler ([abcang](https://github.com/tootsuite/mastodon/pull/11871))
- Fix older migrations not running ([zunda](https://github.com/tootsuite/mastodon/pull/11377))
- Fix URLs counting towards RTL detection ([ahangarha](https://github.com/tootsuite/mastodon/pull/11759))
- Fix unnecessary status re-rendering in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11211))
- Fix http_parser.rb gem not being compiled when no network available ([petabyteboy](https://github.com/tootsuite/mastodon/pull/11444))
- Fix muted text color not applying to all text ([trwnh](https://github.com/tootsuite/mastodon/pull/11996))
- Fix follower/following lists resetting on back-navigation in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11986))
## [2.9.3] - 2019-08-10
### Added
- Add GIF and WebP support for custom emojis ([Gargron](https://github.com/tootsuite/mastodon/pull/11519))
- Add logout link to dropdown menu in web UI ([koyuawsmbrtn](https://github.com/tootsuite/mastodon/pull/11353))
- Add indication that text search is unavailable in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11112), [ThibG](https://github.com/tootsuite/mastodon/pull/11202))
- Add `suffix` to `Mastodon::Version` to help forks ([clarfon](https://github.com/tootsuite/mastodon/pull/11407))
- Add on-hover animation to animated custom emoji in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11348), [ThibG](https://github.com/tootsuite/mastodon/pull/11404), [ThibG](https://github.com/tootsuite/mastodon/pull/11522))
- Add custom emoji support in profile metadata labels ([ThibG](https://github.com/tootsuite/mastodon/pull/11350))
### Changed
- Change default interface of web and streaming from 0.0.0.0 to 127.0.0.1 ([Gargron](https://github.com/tootsuite/mastodon/pull/11302), [zunda](https://github.com/tootsuite/mastodon/pull/11378), [Gargron](https://github.com/tootsuite/mastodon/pull/11351), [zunda](https://github.com/tootsuite/mastodon/pull/11326))
- Change the retry limit of web push notifications ([highemerly](https://github.com/tootsuite/mastodon/pull/11292))
- Change ActivityPub deliveries to not retry HTTP 501 errors ([Gargron](https://github.com/tootsuite/mastodon/pull/11233))
- Change language detection to include hashtags as words ([Gargron](https://github.com/tootsuite/mastodon/pull/11341))
- Change terms and privacy policy pages to always be accessible ([Gargron](https://github.com/tootsuite/mastodon/pull/11334))
- Change robots tag to include `noarchive` when user opts out of indexing ([Kjwon15](https://github.com/tootsuite/mastodon/pull/11421))
### Fixed
- Fix account domain block not clearing out notifications ([Gargron](https://github.com/tootsuite/mastodon/pull/11393))
- Fix incorrect locale sometimes being detected for browser ([Gargron](https://github.com/tootsuite/mastodon/pull/8657))
- Fix crash when saving invalid domain name ([Gargron](https://github.com/tootsuite/mastodon/pull/11528))
- Fix pinned statuses REST API returning pagination headers ([Gargron](https://github.com/tootsuite/mastodon/pull/11526))
- Fix "cancel follow request" button having unreadable text in web UI ([Gargron](https://github.com/tootsuite/mastodon/pull/11521))
- Fix image uploads being blank when canvas read access is blocked ([ThibG](https://github.com/tootsuite/mastodon/pull/11499))
- Fix avatars not being animated on hover when not logged in ([ThibG](https://github.com/tootsuite/mastodon/pull/11349))
- Fix overzealous sanitization of HTML lists ([ThibG](https://github.com/tootsuite/mastodon/pull/11354))
- Fix block crashing when a follow request exists ([ThibG](https://github.com/tootsuite/mastodon/pull/11288))
- Fix backup service crashing when an attachment is missing ([ThibG](https://github.com/tootsuite/mastodon/pull/11241))
- Fix account moderation action always sending e-mail notification ([Gargron](https://github.com/tootsuite/mastodon/pull/11242))
- Fix swiping columns on mobile sometimes failing in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11200))
- Fix wrong actor URI being serialized into poll updates ([ThibG](https://github.com/tootsuite/mastodon/pull/11194))
- Fix statsd UDP sockets not being cleaned up in Sidekiq ([Gargron](https://github.com/tootsuite/mastodon/pull/11230))
- Fix expiration date of filters being set to "never" when editing them ([ThibG](https://github.com/tootsuite/mastodon/pull/11204))
- Fix support for MP4 files that are actually M4V files ([Gargron](https://github.com/tootsuite/mastodon/pull/11210))
- Fix `alerts` not being typecast correctly in push subscription in REST API ([Gargron](https://github.com/tootsuite/mastodon/pull/11343))
- Fix some notices staying on unrelated pages ([ThibG](https://github.com/tootsuite/mastodon/pull/11364))
- Fix unboosting sometimes preventing a boost from reappearing on feed ([ThibG](https://github.com/tootsuite/mastodon/pull/11405), [Gargron](https://github.com/tootsuite/mastodon/pull/11450))
- Fix only one middle dot being recognized in hashtags ([Gargron](https://github.com/tootsuite/mastodon/pull/11345), [ThibG](https://github.com/tootsuite/mastodon/pull/11363))
- Fix unnecessary SQL query performed on unauthenticated requests ([Gargron](https://github.com/tootsuite/mastodon/pull/11179))
- Fix incorrect timestamp displayed on featured tags ([Kjwon15](https://github.com/tootsuite/mastodon/pull/11477))
- Fix privacy dropdown active state when dropdown is placed on top of it ([ThibG](https://github.com/tootsuite/mastodon/pull/11495))
- Fix filters not being applied to poll options ([ThibG](https://github.com/tootsuite/mastodon/pull/11174))
- Fix keyboard navigation on various dropdowns ([ThibG](https://github.com/tootsuite/mastodon/pull/11511), [ThibG](https://github.com/tootsuite/mastodon/pull/11492), [ThibG](https://github.com/tootsuite/mastodon/pull/11491))
- Fix keyboard navigation in modals ([ThibG](https://github.com/tootsuite/mastodon/pull/11493))
- Fix image conversation being non-deterministic due to timestamps ([Gargron](https://github.com/tootsuite/mastodon/pull/11408))
- Fix web UI performance ([ThibG](https://github.com/tootsuite/mastodon/pull/11211), [ThibG](https://github.com/tootsuite/mastodon/pull/11234))
- Fix scrolling to compose form when not necessary in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11246), [ThibG](https://github.com/tootsuite/mastodon/pull/11182))
- Fix save button being enabled when list title is empty in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11475))
- Fix poll expiration not being pre-filled on delete & redraft in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11203))
- Fix content warning sometimes being set when not requested in web UI ([ThibG](https://github.com/tootsuite/mastodon/pull/11206))
### Security
- Fix invites not being disabled upon account suspension ([ThibG](https://github.com/tootsuite/mastodon/pull/11412))
- Fix blocked domains still being able to fill database with account records ([Gargron](https://github.com/tootsuite/mastodon/pull/11219))
## [2.9.2] - 2019-06-22
### Added

@ -5,7 +5,7 @@ ruby '>= 2.4.0', '< 2.7.0'
gem 'pkg-config', '~> 1.3'
gem 'puma', '~> 4.1'
gem 'puma', '~> 4.2'
gem 'rails', '~> 5.2.3'
gem 'thor', '~> 0.20'
@ -29,7 +29,7 @@ gem 'bootsnap', '~> 1.4', require: false
gem 'browser'
gem 'charlock_holmes', '~> 0.7.6'
gem 'iso-639'
gem 'chewy', '~> 5.0'
gem 'chewy', '~> 5.1'
gem 'cld3', '~> 3.2.4'
gem 'devise', '~> 4.7'
gem 'devise-two-factor', '~> 3.1'
@ -44,13 +44,13 @@ gem 'omniauth-saml', '~> 1.10'
gem 'omniauth', '~> 1.9'
gem 'discard', '~> 1.1'
gem 'doorkeeper', '~> 5.1'
gem 'doorkeeper', '~> 5.2'
gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'goldfinger', '~> 2.1'
gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.5'
gem 'health_check', '~> 3.0'
gem 'health_check', git: 'https://github.com/ianheggie/health_check', ref: '0b799ead604f900ed50685e9b2d469cd2befba5b'
gem 'html2text'
gem 'htmlentities', '~> 4.3'
gem 'http', '~> 3.3'
@ -118,7 +118,7 @@ end
group :test do
gem 'capybara', '~> 3.29'
gem 'climate_control', '~> 0.2'
gem 'faker', '~> 2.3'
gem 'faker', '~> 2.4'
gem 'microformats', '~> 4.1'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.0'

@ -1,3 +1,11 @@
GIT
remote: https://github.com/ianheggie/health_check
revision: 0b799ead604f900ed50685e9b2d469cd2befba5b
ref: 0b799ead604f900ed50685e9b2d469cd2befba5b
specs:
health_check (4.0.0.pre)
rails (>= 4.0)
GIT
remote: https://github.com/rtomayko/posix-spawn
revision: 58465d2e213991f8afb13b984854a49fcdcc980c
@ -161,7 +169,7 @@ GEM
case_transform (0.2)
activesupport
charlock_holmes (0.7.6)
chewy (5.0.0)
chewy (5.1.0)
activesupport (>= 4.0)
elasticsearch (>= 2.0.0)
elasticsearch-dsl
@ -209,19 +217,19 @@ GEM
docile (1.3.2)
domain_name (0.5.20180417)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.1.0)
doorkeeper (5.2.1)
railties (>= 5)
dotenv (2.7.5)
dotenv-rails (2.7.5)
dotenv (= 2.7.5)
railties (>= 3.2, < 6.1)
elasticsearch (6.0.2)
elasticsearch-api (= 6.0.2)
elasticsearch-transport (= 6.0.2)
elasticsearch-api (6.0.2)
elasticsearch (7.3.0)
elasticsearch-api (= 7.3.0)
elasticsearch-transport (= 7.3.0)
elasticsearch-api (7.3.0)
multi_json
elasticsearch-dsl (0.1.5)
elasticsearch-transport (6.0.2)
elasticsearch-dsl (0.1.8)
elasticsearch-transport (7.3.0)
faraday
multi_json
encryptor (3.0.0)
@ -231,9 +239,9 @@ GEM
tzinfo
excon (0.62.0)
fabrication (2.20.2)
faker (2.3.0)
faker (2.4.0)
i18n (~> 1.6.0)
faraday (0.15.0)
faraday (0.15.4)
multipart-post (>= 1.2, < 3)
fast_blank (1.0.0)
fastimage (2.1.7)
@ -278,8 +286,6 @@ GEM
concurrent-ruby (~> 1.0)
hashdiff (1.0.0)
hashie (3.6.0)
health_check (3.0.0)
railties (>= 5.0)
heapy (0.1.4)
highline (2.0.1)
hiredis (0.6.3)
@ -372,10 +378,10 @@ GEM
mimemagic (0.3.3)
mini_mime (1.0.2)
mini_portile2 (2.4.0)
minitest (5.11.3)
minitest (5.12.0)
msgpack (1.3.1)
multi_json (1.13.1)
multipart-post (2.0.0)
multipart-post (2.1.1)
necromancer (0.5.0)
net-ldap (0.16.1)
net-scp (2.0.0)
@ -447,7 +453,7 @@ GEM
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.1)
puma (4.1.1)
puma (4.2.0)
nio4r (~> 2.0)
pundit (2.1.0)
activesupport (>= 3.0.0)
@ -503,7 +509,7 @@ GEM
rdf-normalize (0.3.3)
rdf (>= 2.2, < 4.0)
redcarpet (3.4.0)
redis (4.1.2)
redis (4.1.3)
redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6)
redis-rack (>= 1, < 3)
@ -593,7 +599,7 @@ GEM
simple_form (4.1.0)
actionpack (>= 5.0)
activemodel (>= 5.0)
simplecov (0.17.0)
simplecov (0.17.1)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
@ -649,7 +655,7 @@ GEM
uniform_notifier (1.12.1)
warden (1.2.8)
rack (>= 2.0.6)
webmock (3.7.3)
webmock (3.7.5)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@ -690,7 +696,7 @@ DEPENDENCIES
capistrano-yarn (~> 2.0)
capybara (~> 3.29)
charlock_holmes (~> 0.7.6)
chewy (~> 5.0)
chewy (~> 5.1)
cld3 (~> 3.2.4)
climate_control (~> 0.2)
concurrent-ruby
@ -700,10 +706,10 @@ DEPENDENCIES
devise-two-factor (~> 3.1)
devise_pam_authenticatable2 (~> 9.2)
discard (~> 1.1)
doorkeeper (~> 5.1)
doorkeeper (~> 5.2)
dotenv-rails (~> 2.7)
fabrication (~> 2.20)
faker (~> 2.3)
faker (~> 2.4)
fast_blank (~> 1.0)
fastimage
fog-core (<= 2.1.0)
@ -711,7 +717,7 @@ DEPENDENCIES
fuubar (~> 2.4)
goldfinger (~> 2.1)
hamlit-rails (~> 0.2)
health_check (~> 3.0)
health_check!
hiredis (~> 0.6)
html2text
htmlentities (~> 4.3)
@ -756,7 +762,7 @@ DEPENDENCIES
private_address_check (~> 0.5)
pry-byebug (~> 3.7)
pry-rails (~> 0.3)
puma (~> 4.1)
puma (~> 4.2)
pundit (~> 2.1)
rack-attack (~> 6.1)
rack-cors (~> 1.0)
@ -798,7 +804,7 @@ DEPENDENCIES
webpush
RUBY VERSION
ruby 2.6.1p33
ruby 2.6.4p104
BUNDLED WITH
1.17.3

@ -13,15 +13,6 @@
"description": "The domain that your Mastodon instance will run on (this can be appname.herokuapp.com or a custom domain)",
"required": true
},
"LOCAL_HTTPS": {
"description": "Will your domain support HTTPS? (Automatic for herokuapp, requires manual configuration for custom domains)",
"value": "false",
"required": true
},
"PAPERCLIP_SECRET": {
"description": "The secret key for storing media files",
"generator": "secret"
},
"SECRET_KEY_BASE": {
"description": "The secret key base",
"generator": "secret"

@ -4,9 +4,7 @@ class AboutController < ApplicationController
before_action :set_pack
layout 'public'
before_action :require_open_federation!, only: [:show, :more, :blocks]
before_action :check_blocklist_enabled, only: [:blocks]
before_action :authenticate_user!, only: [:blocks], if: :blocklist_account_required?
before_action :require_open_federation!, only: [:show, :more]
before_action :set_body_classes, only: :show
before_action :set_instance_presenter
before_action :set_expires_in, only: [:show, :more, :terms]
@ -17,15 +15,20 @@ class AboutController < ApplicationController
def more
flash.now[:notice] = I18n.t('about.instance_actor_flash') if params[:instance_actor]
toc_generator = TOCGenerator.new(@instance_presenter.site_extended_description)
@contents = toc_generator.html
@table_of_contents = toc_generator.toc
@blocks = DomainBlock.with_user_facing_limitations.by_severity if display_blocks?
end
def terms; end
def blocks
@show_rationale = Setting.show_domain_blocks_rationale == 'all'
@show_rationale |= Setting.show_domain_blocks_rationale == 'users' && !current_user.nil? && current_user.functional?
@blocks = DomainBlock.with_user_facing_limitations.order('(CASE severity WHEN 0 THEN 1 WHEN 1 THEN 2 WHEN 2 THEN 0 END), reject_media, domain').to_a
end
helper_method :display_blocks?
helper_method :display_blocks_rationale?
helper_method :public_fetch_mode?
helper_method :new_user
private
@ -33,28 +36,14 @@ class AboutController < ApplicationController
not_found if whitelist_mode?
end
def check_blocklist_enabled
not_found if Setting.show_domain_blocks == 'disabled'
end
def blocklist_account_required?
Setting.show_domain_blocks == 'users'
def display_blocks?
Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?)
end
def block_severity_text(block)
if block.severity == 'suspend'
I18n.t('domain_blocks.suspension')
else
limitations = []
limitations << I18n.t('domain_blocks.media_block') if block.reject_media?
limitations << I18n.t('domain_blocks.silence') if block.severity == 'silence'
limitations.join(', ')
end
def display_blocks_rationale?
Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?)
end
helper_method :block_severity_text
helper_method :public_fetch_mode?
def new_user
User.new.tap do |user|
user.build_account
@ -62,8 +51,6 @@ class AboutController < ApplicationController
end
end
helper_method :new_user
def set_pack
use_pack 'public'
end

@ -10,6 +10,7 @@ class AccountsController < ApplicationController
before_action :set_body_classes
skip_around_action :set_locale, if: -> { request.format == :json }
skip_before_action :require_functional!
def show
respond_to do |format|

@ -33,9 +33,9 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def scope_for_collection
case params[:id]
when 'featured'
@account.statuses.permitted_for(@account, signed_request_account).tap do |scope|
scope.merge!(@account.pinned_statuses)
end
return Status.none if @account.blocking?(signed_request_account)
@account.pinned_statuses
else
raise ActiveRecord::RecordNotFound
end

@ -3,6 +3,7 @@
module Admin
class RelaysController < BaseController
before_action :set_relay, except: [:index, :new, :create]
before_action :require_signatures_enabled!, only: [:new, :create, :enable]
def index
authorize :relay, :update?
@ -11,7 +12,7 @@ module Admin
def new
authorize :relay, :update?
@relay = Relay.new(inbox_url: Relay::PRESET_RELAY)
@relay = Relay.new
end
def create
@ -54,5 +55,9 @@ module Admin
def resource_params
params.require(:relay).permit(:inbox_url)
end
def require_signatures_enabled!
redirect_to admin_relays_path, alert: I18n.t('admin.relays.signatures_not_enabled') if authorized_fetch_mode?
end
end
end

@ -8,6 +8,7 @@ module Admin
authorize @user, :disable_2fa?
@user.disable_two_factor!
log_action :disable_2fa, @user
UserMailer.two_factor_disabled(@user).deliver_later!
redirect_to admin_accounts_path
end

@ -57,6 +57,8 @@ class Api::V1::Accounts::StatusesController < Api::BaseController
end
def pinned_scope
return Status.none if @account.blocking?(current_account)
@account.pinned_statuses
end

@ -33,7 +33,7 @@ class Api::V1::AccountsController < Api::BaseController
def follow
FollowService.new.call(current_user.account, @account, reblogs: truthy_param?(:reblogs))
options = @account.locked? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
options = @account.locked? || current_user.account.silenced? ? {} : { following_map: { @account.id => { reblogs: truthy_param?(:reblogs) } }, requested_map: { @account.id => false } }
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships(options)
end

@ -22,7 +22,7 @@ class Api::V2::SearchController < Api::BaseController
params[:q],
current_account,
limit_param(RESULTS_LIMIT),
search_params.merge(resolve: truthy_param?(:resolve))
search_params.merge(resolve: truthy_param?(:resolve), exclude_unreviewed: truthy_param?(:exclude_unreviewed))
)
end

@ -0,0 +1,22 @@
# frozen_string_literal: true
class Auth::ChallengesController < ApplicationController
include ChallengableConcern
layout 'auth'
before_action :authenticate_user!
skip_before_action :require_functional!
def create
if challenge_passed?
session[:challenge_passed_at] = Time.now.utc
redirect_to challenge_params[:return_to]
else
@challenge = Form::Challenge.new(return_to: challenge_params[:return_to])
flash.now[:alert] = I18n.t('challenge.invalid_password')
render_challenge
end
end
end

@ -9,6 +9,7 @@ class Auth::SessionsController < Devise::SessionsController
skip_before_action :require_functional!
prepend_before_action :set_pack
prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
before_action :set_instance_presenter, only: [:new]
before_action :set_body_classes
@ -22,34 +23,32 @@ class Auth::SessionsController < Devise::SessionsController
end
def create
self.resource = begin
if user_params[:email].blank? && session[:otp_user_id].present?
User.find(session[:otp_user_id])
else
warden.authenticate!(auth_options)
end
end
if resource.otp_required_for_login?
if user_params[:otp_attempt].present? && session[:otp_user_id].present?
authenticate_with_two_factor_via_otp(resource)
else
prompt_for_two_factor(resource)
end
else
authenticate_and_respond(resource)
super do |resource|
remember_me(resource)
flash.delete(:notice)
end
end
def destroy
tmp_stored_location = stored_location_for(:user)
super
session.delete(:challenge_passed_at)
flash.delete(:notice)
store_location_for(:user, tmp_stored_location) if continue_after?
end
protected
def find_user
if session[:otp_user_id]
User.find(session[:otp_user_id])
else
user = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
user ||= User.find_for_authentication(email: user_params[:email])
end
end
def user_params
params.require(:user).permit(:email, :password, :otp_attempt)
end
@ -72,6 +71,10 @@ class Auth::SessionsController < Devise::SessionsController
super
end
def two_factor_enabled?
find_user&.otp_required_for_login?
end
def valid_otp_attempt?(user)
user.validate_and_consume_otp!(user_params[:otp_attempt]) ||
user.invalidate_otp_backup_code!(user_params[:otp_attempt])
@ -79,10 +82,24 @@ class Auth::SessionsController < Devise::SessionsController
false
end
def authenticate_with_two_factor
user = self.resource = find_user
if user_params[:otp_attempt].present? && session[:otp_user_id]
authenticate_with_two_factor_via_otp(user)
elsif user.present? && (user.encrypted_password.blank? || user.valid_password?(user_params[:password]))
# If encrypted_password is blank, we got the user from LDAP or PAM,
# so credentials are already valid
prompt_for_two_factor(user)
end
end
def authenticate_with_two_factor_via_otp(user)
if valid_otp_attempt?(user)
session.delete(:otp_user_id)
authenticate_and_respond(user)
remember_me(user)
sign_in(user)
else
flash.now[:alert] = I18n.t('users.invalid_otp_token')
prompt_for_two_factor(user)
@ -91,16 +108,10 @@ class Auth::SessionsController < Devise::SessionsController
def prompt_for_two_factor(user)
session[:otp_user_id] = user.id
@body_classes = 'lighter'
render :two_factor
end
def authenticate_and_respond(user)
sign_in(user)
remember_me(user)
respond_with user, location: after_sign_in_path_for(user)
end
private
def set_pack
@ -117,11 +128,9 @@ class Auth::SessionsController < Devise::SessionsController
def home_paths(resource)
paths = [about_path]
if single_user_mode? && resource.is_a?(User)
paths << short_account_path(username: resource.account)
end
paths
end

@ -0,0 +1,65 @@
# frozen_string_literal: true
# This concern is inspired by "sudo mode" on GitHub. It
# is a way to re-authenticate a user before allowing them
# to see or perform an action.
#
# Add `before_action :require_challenge!` to actions you
# want to protect.
#
# The user will be shown a page to enter the challenge (which
# is either the password, or just the username when no
# password exists). Upon passing, there is a grace period
# during which no challenge will be asked from the user.
#
# Accessing challenge-protected resources during the grace
# period will refresh the grace period.
module ChallengableConcern
extend ActiveSupport::Concern
CHALLENGE_TIMEOUT = 1.hour.freeze
def require_challenge!
return if skip_challenge?
if challenge_passed_recently?
session[:challenge_passed_at] = Time.now.utc
return
end
@challenge = Form::Challenge.new(return_to: request.url)
if params.key?(:form_challenge)
if challenge_passed?
session[:challenge_passed_at] = Time.now.utc
return
else
flash.now[:alert] = I18n.t('challenge.invalid_password')
render_challenge
end
else
render_challenge
end
end
def render_challenge
@body_classes = 'lighter'
render template: 'auth/challenges/new', layout: 'auth'
end
def challenge_passed?
current_user.valid_password?(challenge_params[:current_password])
end
def skip_challenge?
current_user.encrypted_password.blank?
end
def challenge_passed_recently?
session[:challenge_passed_at].present? && session[:challenge_passed_at] >= CHALLENGE_TIMEOUT.ago
end
def challenge_params
params.require(:form_challenge).permit(:current_password, :return_to)
end
end

@ -5,7 +5,10 @@ module ExportControllerConcern
included do
before_action :authenticate_user!
before_action :require_not_suspended!
before_action :load_export
skip_before_action :require_functional!
end
private
@ -27,4 +30,8 @@ module ExportControllerConcern
def export_filename
"#{controller_name}.csv"
end
def require_not_suspended!
forbidden if current_account.suspended?
end
end

@ -2,6 +2,7 @@
class CustomCssController < ApplicationController
skip_before_action :store_current_location
skip_before_action :require_functional!
before_action :set_cache_headers

@ -10,6 +10,8 @@ class DirectoriesController < ApplicationController
before_action :set_accounts
before_action :set_pack
skip_before_action :require_functional!
def index
render :index
end

@ -8,6 +8,7 @@ class FollowerAccountsController < ApplicationController
before_action :set_cache_headers
skip_around_action :set_locale, if: -> { request.format == :json }
skip_before_action :require_functional!
def index
respond_to do |format|

@ -8,6 +8,7 @@ class FollowingAccountsController < ApplicationController
before_action :set_cache_headers
skip_around_action :set_locale, if: -> { request.format == :json }
skip_before_action :require_functional!
def index
respond_to do |format|

@ -2,6 +2,7 @@
class ManifestsController < ApplicationController
skip_before_action :store_current_location
skip_before_action :require_functional!
def show
expires_in 3.minutes, public: true

@ -4,6 +4,7 @@ class MediaController < ApplicationController
include Authorization
skip_before_action :store_current_location
skip_before_action :require_functional!
before_action :authenticate_user!, if: :whitelist_mode?
before_action :set_media_attachment

@ -4,6 +4,7 @@ class MediaProxyController < ApplicationController
include RoutingHelper
skip_before_action :store_current_location
skip_before_action :require_functional!
before_action :authenticate_user!, if: :whitelist_mode?

@ -8,6 +8,8 @@ class RemoteFollowController < ApplicationController
before_action :set_pack
before_action :set_body_classes
skip_before_action :require_functional!
def new
@remote_follow = RemoteFollow.new(session_params)
end

@ -11,6 +11,8 @@ class RemoteInteractionController < ApplicationController
before_action :set_body_classes
before_action :set_pack
skip_before_action :require_functional!
def new
@remote_follow = RemoteFollow.new(session_params)
end

@ -0,0 +1,43 @@
# frozen_string_literal: true
class Settings::AliasesController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :set_aliases, except: :destroy
before_action :set_alias, only: :destroy
def index
@alias = current_account.aliases.build
end
def create
@alias = current_account.aliases.build(resource_params)
if @alias.save
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
redirect_to settings_aliases_path, notice: I18n.t('aliases.created_msg')
else
render :index
end
end
def destroy
@alias.destroy!
redirect_to settings_aliases_path, notice: I18n.t('aliases.deleted_msg')
end
private
def resource_params
params.require(:account_alias).permit(:acct)
end
def set_alias
@alias = current_account.aliases.find(params[:id])
end
def set_aliases
@aliases = current_account.aliases.order(id: :desc).reject(&:new_record?)
end
end

@ -6,6 +6,9 @@ class Settings::ExportsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :require_not_suspended!
skip_before_action :require_functional!
def show
@export = Export.new(current_account)
@ -34,4 +37,8 @@ class Settings::ExportsController < Settings::BaseController
def lock_options
{ redis: Redis.current, key: "backup:#{current_user.id}" }
end
def require_not_suspended!
forbidden if current_account.suspended?
end
end

@ -0,0 +1,45 @@
# frozen_string_literal: true
class Settings::Migration::RedirectsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :require_not_suspended!
skip_before_action :require_functional!
def new
@redirect = Form::Redirect.new
end
def create
@redirect = Form::Redirect.new(resource_params.merge(account: current_account))
if @redirect.valid_with_challenge?(current_user)
current_account.update!(moved_to_account: @redirect.target_account)
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
redirect_to settings_migration_path, notice: I18n.t('migrations.moved_msg', acct: current_account.moved_to_account.acct)
else
render :new
end
end
def destroy
if current_account.moved_to_account_id.present?
current_account.update!(moved_to_account: nil)
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
end
redirect_to settings_migration_path, notice: I18n.t('migrations.cancelled_msg')
end
private
def resource_params
params.require(:form_redirect).permit(:acct, :current_password, :current_username)
end
def require_not_suspended!
forbidden if current_account.suspended?
end
end

@ -4,31 +4,48 @@ class Settings::MigrationsController < Settings::BaseController
layout 'admin'
before_action :authenticate_user!
before_action :require_not_suspended!
before_action :set_migrations
before_action :set_cooldown
skip_before_action :require_functional!
def show
@migration = Form::Migration.new(account: current_account.moved_to_account)
@migration = current_account.migrations.build
end
def update
@migration = Form::Migration.new(resource_params)
def create
@migration = current_account.migrations.build(resource_params)
if @migration.valid? && migration_account_changed?
current_account.update!(moved_to_account: @migration.account)
ActivityPub::UpdateDistributionWorker.perform_async(current_account.id)
redirect_to settings_migration_path, notice: I18n.t('migrations.updated_msg')
if @migration.save_with_challenge(current_user)
MoveService.new.call(@migration)
redirect_to settings_migration_path, notice: I18n.t('migrations.moved_msg', acct: current_account.moved_to_account.acct)
else
render :show
end
end
helper_method :on_cooldown?
private
def resource_params
params.require(:migration).permit(:acct)
params.require(:account_migration).permit(:acct, :current_password, :current_username)
end
def set_migrations
@migrations = current_account.migrations.includes(:target_account).order(id: :desc).reject(&:new_record?)
end
def set_cooldown
@cooldown = current_account.migrations.within_cooldown.first
end
def on_cooldown?
@cooldown.present?
end
def migration_account_changed?
current_account.moved_to_account_id != @migration.account&.id &&
current_account.id != @migration.account&.id
def require_not_suspended!
forbidden if current_account.suspended?
end
end

@ -3,9 +3,12 @@
module Settings
module TwoFactorAuthentication
class ConfirmationsController < BaseController
include ChallengableConcern
layout 'admin'
before_action :authenticate_user!
before_action :require_challenge!
before_action :ensure_otp_secret
skip_before_action :require_functional!
@ -22,6 +25,8 @@ module Settings
@recovery_codes = current_user.generate_otp_backup_codes!
current_user.save!
UserMailer.two_factor_enabled(current_user).deliver_later!
render 'settings/two_factor_authentication/recovery_codes/index'
else
flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code')

@ -3,16 +3,22 @@
module Settings
module TwoFactorAuthentication
class RecoveryCodesController < BaseController
include ChallengableConcern
layout 'admin'
before_action :authenticate_user!
before_action :require_challenge!, on: :create
skip_before_action :require_functional!
def create
@recovery_codes = current_user.generate_otp_backup_codes!
current_user.save!
UserMailer.two_factor_recovery_codes_changed(current_user).deliver_later!
flash.now[:notice] = I18n.t('two_factor_authentication.recovery_codes_regenerated')
render :index
end
end

@ -2,10 +2,13 @@
module Settings
class TwoFactorAuthenticationsController < BaseController
include ChallengableConcern
layout 'admin'
before_action :authenticate_user!
before_action :verify_otp_required, only: [:create]
before_action :require_challenge!, only: [:create]
skip_before_action :require_functional!
@ -23,6 +26,7 @@ module Settings
if acceptable_code?
current_user.otp_required_for_login = false
current_user.save!
UserMailer.two_factor_disabled(current_user).deliver_later!
redirect_to settings_two_factor_authentication_path
else
flash.now[:alert] = I18n.t('two_factor_authentication.wrong_code')

@ -19,6 +19,7 @@ class StatusesController < ApplicationController
before_action :set_autoplay, only: :embed
skip_around_action :set_locale, if: -> { request.format == :json }
skip_before_action :require_functional!, only: [:show, :embed]
content_security_policy only: :embed do |p|
p.frame_ancestors(false)

@ -13,6 +13,8 @@ class TagsController < ApplicationController
before_action :set_body_classes
before_action :set_instance_presenter
skip_before_action :require_functional!
def show
respond_to do |format|
format.html do

@ -0,0 +1,19 @@
# frozen_string_literal: true
module WellKnown
class NodeInfoController < ActionController::Base
include CacheConcern
before_action { response.headers['Vary'] = 'Accept' }
def index
expires_in 3.days, public: true
render_with_cache json: {}, serializer: NodeInfo::DiscoverySerializer, adapter: NodeInfo::Adapter, expires_in: 3.days, root: 'nodeinfo'
end
def show
expires_in 30.minutes, public: true
render_with_cache json: {}, serializer: NodeInfo::Serializer, adapter: NodeInfo::Adapter, expires_in: 30.minutes, root: 'nodeinfo'
end
end
end

@ -87,4 +87,12 @@ module SettingsHelper
'desktop'
end
end
def compact_account_link_to(account)
return if account.nil?
link_to ActivityPub::TagManager.instance.url_for(account), class: 'name-tag', title: account.acct do
safe_join([image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'), content_tag(:span, account.acct, class: 'username')], ' ')
end
end
end

@ -1,6 +1,7 @@
import api, { getLinks } from '../api';
import { fetchRelationships } from './accounts';
import { importFetchedAccounts } from './importer';
import { openModal } from './modal';
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
export const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
@ -10,6 +11,8 @@ export const BLOCKS_EXPAND_REQUEST = 'BLOCKS_EXPAND_REQUEST';
export const BLOCKS_EXPAND_SUCCESS = 'BLOCKS_EXPAND_SUCCESS';
export const BLOCKS_EXPAND_FAIL = 'BLOCKS_EXPAND_FAIL';
export const BLOCKS_INIT_MODAL = 'BLOCKS_INIT_MODAL';
export function fetchBlocks() {
return (dispatch, getState) => {
dispatch(fetchBlocksRequest());
@ -83,3 +86,14 @@ export function expandBlocksFail(error) {
error,
};
};
export function initBlockModal(account) {
return dispatch => {
dispatch({
type: BLOCKS_INIT_MODAL,
account,
});
dispatch(openModal('BLOCK'));
};
}

@ -234,7 +234,7 @@ export function uploadCompose(files) {
progress[i] = loaded;
dispatch(uploadComposeProgress(progress.reduce((a, v) => a + v, 0), total));
},
}).then(({ data }) => dispatch(uploadComposeSuccess(data)));
}).then(({ data }) => dispatch(uploadComposeSuccess(data, f)));
}).catch(error => dispatch(uploadComposeFail(error)));
};
};
@ -289,10 +289,11 @@ export function uploadComposeProgress(loaded, total) {
};
};
export function uploadComposeSuccess(media) {
export function uploadComposeSuccess(media, file) {
return {
type: COMPOSE_UPLOAD_SUCCESS,
media: media,
file: file,
skipLoading: true,
};
};
@ -368,6 +369,7 @@ const fetchComposeSuggestionsTags = throttle((dispatch, getState, token) => {
q: token.slice(1),
resolve: false,
limit: 4,
exclude_unreviewed: true,
},
}).then(({ data }) => {
dispatch(readyComposeSuggestionsTags(token, data.hashtags));

@ -15,6 +15,10 @@ export const CONVERSATIONS_UPDATE = 'CONVERSATIONS_UPDATE';
export const CONVERSATIONS_READ = 'CONVERSATIONS_READ';
export const CONVERSATIONS_DELETE_REQUEST = 'CONVERSATIONS_DELETE_REQUEST';
export const CONVERSATIONS_DELETE_SUCCESS = 'CONVERSATIONS_DELETE_SUCCESS';
export const CONVERSATIONS_DELETE_FAIL = 'CONVERSATIONS_DELETE_FAIL';
export const mountConversations = () => ({
type: CONVERSATIONS_MOUNT,
});
@ -82,3 +86,27 @@ export const updateConversations = conversation => dispatch => {
conversation,
});
};
export const deleteConversation = conversationId => (dispatch, getState) => {
dispatch(deleteConversationRequest(conversationId));
api(getState).delete(`/api/v1/conversations/${conversationId}`)
.then(() => dispatch(deleteConversationSuccess(conversationId)))
.catch(error => dispatch(deleteConversationFail(conversationId, error)));
};
export const deleteConversationRequest = id => ({
type: CONVERSATIONS_DELETE_REQUEST,
id,
});
export const deleteConversationSuccess = id => ({
type: CONVERSATIONS_DELETE_SUCCESS,
id,
});
export const deleteConversationFail = (id, error) => ({
type: CONVERSATIONS_DELETE_FAIL,
id,
error,
});

@ -73,8 +73,9 @@ export function normalizePoll(poll) {
const emojiMap = makeEmojiMap(normalPoll);
normalPoll.options = poll.options.map(option => ({
normalPoll.options = poll.options.map((option, index) => ({
...option,
voted: poll.own_votes && poll.own_votes.includes(index),
title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap),
}));

@ -28,6 +28,9 @@ export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR';
export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
export const NOTIFICATIONS_LOAD_PENDING = 'NOTIFICATIONS_LOAD_PENDING';
export const NOTIFICATIONS_MOUNT = 'NOTIFICATIONS_MOUNT';
export const NOTIFICATIONS_UNMOUNT = 'NOTIFICATIONS_UNMOUNT';
defineMessages({
mention: { id: 'notification.mention', defaultMessage: '{name} mentioned you' },
group: { id: 'notifications.group', defaultMessage: '{count} notifications' },
@ -215,3 +218,11 @@ export function setFilter (filterType) {
dispatch(saveSettings());
};
};
export const mountNotifications = () => ({
type: NOTIFICATIONS_MOUNT,
});
export const unmountNotifications = () => ({
type: NOTIFICATIONS_UNMOUNT,
});

@ -35,35 +35,35 @@ export default class AvatarComposite extends React.PureComponent {
if (size === 2) {
if (index === 0) {
right = '2px';
right = '1px';
} else {
left = '2px';
left = '1px';
}
} else if (size === 3) {
if (index === 0) {
right = '2px';
right = '1px';
} else if (index > 0) {
left = '2px';
left = '1px';
}
if (index === 1) {
bottom = '2px';
bottom = '1px';
} else if (index > 1) {
top = '2px';
top = '1px';
}
} else if (size === 4) {
if (index === 0 || index === 2) {
right = '2px';
right = '1px';
}
if (index === 1 || index === 3) {
left = '2px';
left = '1px';
}
if (index < 2) {
bottom = '2px';
bottom = '1px';
} else {
top = '2px';
top = '1px';
}
}
@ -88,7 +88,13 @@ export default class AvatarComposite extends React.PureComponent {
return (
<div className='account__avatar-composite' style={{ width: `${size}px`, height: `${size}px` }}>
{accounts.take(4).map((account, i) => this.renderItem(account, accounts.size, i))}
{accounts.take(4).map((account, i) => this.renderItem(account, Math.min(accounts.size, 4), i))}
{accounts.size > 4 && (
<span className='account__avatar-composite__label'>
+{accounts.size - 4}
</span>
)}
</div>
);
}

@ -120,7 +120,7 @@ class ColumnHeader extends React.PureComponent {
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='text-btn column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
</div>
);
} else if (multiColumn) {
} else if (multiColumn && this.props.onPin) {
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
}
@ -142,7 +142,7 @@ class ColumnHeader extends React.PureComponent {
collapsedContent.push(pinButton);
}
if (children || multiColumn) {
if (children || (multiColumn && this.props.onPin)) {
collapseButton = <button className={collapsibleButtonClassName} title={formatMessage(collapsed ? messages.show : messages.hide)} aria-label={formatMessage(collapsed ? messages.show : messages.hide)} aria-pressed={collapsed ? 'false' : 'true'} onClick={this.handleToggleClick}><Icon id='sliders' /></button>;
}

@ -10,9 +10,11 @@ import spring from 'react-motion/lib/spring';
import escapeTextContentForBrowser from 'escape-html';
import emojify from 'mastodon/features/emoji/emoji';
import RelativeTimestamp from './relative_timestamp';
import Icon from 'mastodon/components/icon';
const messages = defineMessages({
closed: { id: 'poll.closed', defaultMessage: 'Closed' },
voted: { id: 'poll.voted', defaultMessage: 'You voted for this answer', description: 'Tooltip of the "voted" checkmark in polls' },
});
const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => {
@ -99,10 +101,12 @@ class Poll extends ImmutablePureComponent {
};
renderOption (option, optionIndex, showResults) {
const { poll, disabled } = this.props;
const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100;
const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count'));
const active = !!this.state.selected[`${optionIndex}`];
const { poll, disabled, intl } = this.props;
const pollVotesCount = poll.get('voters_count') || poll.get('votes_count');
const percent = pollVotesCount === 0 ? 0 : (option.get('votes_count') / pollVotesCount) * 100;
const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') >= other.get('votes_count'));
const active = !!this.state.selected[`${optionIndex}`];
const voted = option.get('voted') || (poll.get('own_votes') && poll.get('own_votes').includes(optionIndex));
let titleEmojified = option.get('title_emojified');
if (!titleEmojified) {
@ -131,7 +135,10 @@ class Poll extends ImmutablePureComponent {
/>
{!showResults && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />}
{showResults && <span className='poll__number'>{Math.round(percent)}%</span>}
{showResults && <span className='poll__number'>
{!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
{Math.round(percent)}%
</span>}
<span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
</label>
@ -151,6 +158,14 @@ class Poll extends ImmutablePureComponent {
const showResults = poll.get('voted') || expired;
const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item);
let votesCount = null;
if (poll.get('voters_count') !== null && poll.get('voters_count') !== undefined) {
votesCount = <FormattedMessage id='poll.total_people' defaultMessage='{count, plural, one {# person} other {# people}}' values={{ count: poll.get('voters_count') }} />;
} else {
votesCount = <FormattedMessage id='poll.total_votes' defaultMessage='{count, plural, one {# vote} other {# votes}}' values={{ count: poll.get('votes_count') }} />;
}
return (
<div className='poll'>
<ul>
@ -160,7 +175,7 @@ class Poll extends ImmutablePureComponent {
<div className='poll__footer'>
{!showResults && <button className='button button-secondary' disabled={disabled} onClick={this.handleVote}><FormattedMessage id='poll.vote' defaultMessage='Vote' /></button>}
{showResults && !this.props.disabled && <span><button className='poll__link' onClick={this.handleRefresh}><FormattedMessage id='poll.refresh' defaultMessage='Refresh' /></button> · </span>}
<FormattedMessage id='poll.total_votes' defaultMessage='{count, plural, one {# vote} other {# votes}}' values={{ count: poll.get('votes_count') }} />
{votesCount}
{poll.get('expires_at') && <span> · {timeRemaining}</span>}
</div>
</div>

@ -199,6 +199,7 @@ export default class ScrollableList extends PureComponent {
this.clearMouseIdleTimer();
this.detachScrollListener();
this.detachIntersectionObserver();
detachFullscreenListener(this.onFullScreenChange);
}

@ -2,17 +2,17 @@ import React, { PureComponent, Fragment } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { IntlProvider, addLocaleData } from 'react-intl';
import { getLocale } from '../locales';
import MediaGallery from '../components/media_gallery';
import Video from '../features/video';
import Card from '../features/status/components/card';
import { List as ImmutableList, fromJS } from 'immutable';
import { getLocale } from 'mastodon/locales';
import { getScrollbarWidth } from 'mastodon/utils/scrollbar';
import MediaGallery from 'mastodon/components/media_gallery';
import Poll from 'mastodon/components/poll';
import Hashtag from 'mastodon/components/hashtag';
import ModalRoot from 'mastodon/components/modal_root';
import MediaModal from 'mastodon/features/ui/components/media_modal';
import Video from 'mastodon/features/video';
import Card from 'mastodon/features/status/components/card';
import Audio from 'mastodon/features/audio';
import ModalRoot from '../components/modal_root';
import { getScrollbarWidth } from '../features/ui/components/modal_root';
import MediaModal from '../features/ui/components/media_modal';
import { List as ImmutableList, fromJS } from 'immutable';
const { localeData, messages } = getLocale();
addLocaleData(localeData);

@ -1,4 +1,3 @@
import React from 'react';
import { connect } from 'react-redux';
import Status from '../components/status';
import { makeGetStatus } from '../selectors';
@ -15,7 +14,6 @@ import {
pin,
unpin,
} from '../actions/interactions';
import { blockAccount } from '../actions/accounts';
import {
muteStatus,
unmuteStatus,
@ -24,9 +22,10 @@ import {
revealStatus,
} from '../actions/statuses';
import { initMuteModal } from '../actions/mutes';
import { initBlockModal } from '../actions/blocks';
import { initReport } from '../actions/reports';
import { openModal } from '../actions/modal';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl';
import { boostModal, deleteModal } from '../initial_state';
import { showAlertForError } from '../actions/alerts';
@ -35,10 +34,8 @@ const messages = defineMessages({
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
});
const makeMapStateToProps = () => {
@ -56,6 +53,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onReply (status, router) {
dispatch((_, getState) => {
let state = getState();
if (state.getIn(['compose', 'text']).trim().length !== 0) {
dispatch(openModal('CONFIRM', {
message: intl.formatMessage(messages.replyMessage),
@ -137,16 +135,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onBlock (status) {
const account = status.get('account');
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.get('id'))),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.get('id')));
dispatch(initReport(account, status));
},
}));
dispatch(initBlockModal(account));
},
onReport (status) {

@ -5,7 +5,6 @@ import Header from '../components/header';
import {
followAccount,
unfollowAccount,
blockAccount,
unblockAccount,
unmuteAccount,
pinAccount,
@ -16,6 +15,7 @@ import {
directCompose,
} from '../../../actions/compose';
import { initMuteModal } from '../../../actions/mutes';
import { initBlockModal } from '../../../actions/blocks';
import { initReport } from '../../../actions/reports';
import { openModal } from '../../../actions/modal';
import { blockDomain, unblockDomain } from '../../../actions/domain_blocks';
@ -25,9 +25,7 @@ import { List as ImmutableList } from 'immutable';
const messages = defineMessages({
unfollowConfirm: { id: 'confirmations.unfollow.confirm', defaultMessage: 'Unfollow' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
});
const makeMapStateToProps = () => {
@ -64,16 +62,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
if (account.getIn(['relationship', 'blocking'])) {
dispatch(unblockAccount(account.get('id')));
} else {
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.get('id'))),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.get('id')));
dispatch(initReport(account));
},
}));
dispatch(initBlockModal(account));
}
},

@ -2,9 +2,28 @@ import React from 'react';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import StatusContainer from '../../../containers/status_container';
import StatusContent from 'mastodon/components/status_content';
import AttachmentList from 'mastodon/components/attachment_list';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
import AvatarComposite from 'mastodon/components/avatar_composite';
import Permalink from 'mastodon/components/permalink';
import IconButton from 'mastodon/components/icon_button';
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
import { HotKeys } from 'react-hotkeys';
export default class Conversation extends ImmutablePureComponent {
const messages = defineMessages({
more: { id: 'status.more', defaultMessage: 'More' },
open: { id: 'conversation.open', defaultMessage: 'View conversation' },
reply: { id: 'status.reply', defaultMessage: 'Reply' },
markAsRead: { id: 'conversation.mark_as_read', defaultMessage: 'Mark as read' },
delete: { id: 'conversation.delete', defaultMessage: 'Delete conversation' },
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
});
export default @injectIntl
class Conversation extends ImmutablePureComponent {
static contextTypes = {
router: PropTypes.object,
@ -13,11 +32,12 @@ export default class Conversation extends ImmutablePureComponent {
static propTypes = {
conversationId: PropTypes.string.isRequired,
accounts: ImmutablePropTypes.list.isRequired,
lastStatusId: PropTypes.string,
lastStatus: ImmutablePropTypes.map,
unread:PropTypes.bool.isRequired,
onMoveUp: PropTypes.func,
onMoveDown: PropTypes.func,
markRead: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleClick = () => {
@ -25,13 +45,25 @@ export default class Conversation extends ImmutablePureComponent {
return;
}
const { lastStatusId, unread, markRead } = this.props;
const { lastStatus, unread, markRead } = this.props;
if (unread) {
markRead();
}
this.context.router.history.push(`/statuses/${lastStatusId}`);
this.context.router.history.push(`/statuses/${lastStatus.get('id')}`);
}
handleMarkAsRead = () => {
this.props.markRead();
}
handleReply = () => {
this.props.reply(this.props.lastStatus, this.context.router.history);
}
handleDelete = () => {
this.props.delete();
}
handleHotkeyMoveUp = () => {
@ -42,22 +74,88 @@ export default class Conversation extends ImmutablePureComponent {
this.props.onMoveDown(this.props.conversationId);
}
handleConversationMute = () => {
this.props.onMute(this.props.lastStatus);
}
handleShowMore = () => {
this.props.onToggleHidden(this.props.lastStatus);
}
render () {
const { accounts, lastStatusId, unread } = this.props;
const { accounts, lastStatus, unread, intl } = this.props;
if (lastStatusId === null) {
if (lastStatus === null) {
return null;
}
const menu = [
{ text: intl.formatMessage(messages.open), action: this.handleClick },
null,
];
menu.push({ text: intl.formatMessage(lastStatus.get('muted') ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMute });
if (unread) {
menu.push({ text: intl.formatMessage(messages.markAsRead), action: this.handleMarkAsRead });
menu.push(null);
}
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete });
const names = accounts.map(a => <Permalink to={`/accounts/${a.get('id')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]);
const handlers = {
reply: this.handleReply,
open: this.handleClick,
moveUp: this.handleHotkeyMoveUp,
moveDown: this.handleHotkeyMoveDown,
toggleHidden: this.handleShowMore,
};
return (
<StatusContainer
id={lastStatusId}
unread={unread}
otherAccounts={accounts}
onMoveUp={this.handleHotkeyMoveUp}
onMoveDown={this.handleHotkeyMoveDown}
onClick={this.handleClick}
/>
<HotKeys handlers={handlers}>
<div className='conversation focusable muted' tabIndex='0'>
<div className='conversation__avatar'>
<AvatarComposite accounts={accounts} size={48} />
</div>
<div className='conversation__content'>
<div className='conversation__content__info'>
<div className='conversation__content__relative-time'>
<RelativeTimestamp timestamp={lastStatus.get('created_at')} />
</div>
<div className='conversation__content__names'>
<FormattedMessage id='conversation.with' defaultMessage='With {names}' values={{ names: <span>{names}</span> }} />
</div>
</div>
<StatusContent
status={lastStatus}
onClick={this.handleClick}
expanded={!lastStatus.get('hidden')}
onExpandedToggle={this.handleShowMore}
collapsable
/>
{lastStatus.get('media_attachments').size > 0 && (
<AttachmentList
compact
media={lastStatus.get('media_attachments')}
/>
)}
<div className='status__action-bar'>
<IconButton className='status__action-bar-button' title={intl.formatMessage(messages.reply)} icon='reply' onClick={this.handleReply} />
<div className='status__action-bar-dropdown'>
<DropdownMenuContainer status={lastStatus} items={menu} icon='ellipsis-h' size={18} direction='right' title={intl.formatMessage(messages.more)} />
</div>
</div>
</div>
</div>
</HotKeys>
);
}

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

@ -99,4 +99,4 @@ export const buildCustomEmojis = (customEmojis) => {
return emojis;
};
export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set());
export const categoriesFromEmojis = customEmojis => customEmojis.reduce((set, emoji) => set.add(emoji.get('category') ? `custom-${emoji.get('category')}` : 'custom'), new Set(['custom']));

@ -27,7 +27,9 @@ class Favourites extends ImmutablePureComponent {
};
componentWillMount () {
this.props.dispatch(fetchFavourites(this.props.params.statusId));
if (!this.props.accountIds) {
this.props.dispatch(fetchFavourites(this.props.params.statusId));
}
}
componentWillReceiveProps (nextProps) {

@ -40,8 +40,10 @@ class Followers extends ImmutablePureComponent {
};
componentWillMount () {
this.props.dispatch(fetchAccount(this.props.params.accountId));
this.props.dispatch(fetchFollowers(this.props.params.accountId));
if (!this.props.accountIds) {
this.props.dispatch(fetchAccount(this.props.params.accountId));
this.props.dispatch(fetchFollowers(this.props.params.accountId));
}
}
componentWillReceiveProps (nextProps) {

@ -40,8 +40,10 @@ class Following extends ImmutablePureComponent {
};
componentWillMount () {
this.props.dispatch(fetchAccount(this.props.params.accountId));
this.props.dispatch(fetchFollowing(this.props.params.accountId));
if (!this.props.accountIds) {
this.props.dispatch(fetchAccount(this.props.params.accountId));
this.props.dispatch(fetchFollowing(this.props.params.accountId));
}
}
componentWillReceiveProps (nextProps) {

@ -77,16 +77,14 @@ class GettingStarted extends ImmutablePureComponent {
};
componentDidMount () {
const { myAccount, fetchFollowRequests, multiColumn } = this.props;
const { fetchFollowRequests, multiColumn } = this.props;
if (!multiColumn && window.innerWidth >= NAVIGATION_PANEL_BREAKPOINT) {
this.context.router.history.replace('/timelines/home');
return;
}
if (myAccount.get('locked')) {
fetchFollowRequests();
}
fetchFollowRequests();
}
render () {
@ -134,7 +132,7 @@ class GettingStarted extends ImmutablePureComponent {
height += 48*3;
if (myAccount.get('locked')) {
if (myAccount.get('locked') || unreadFollowRequests > 0) {
navItems.push(<ColumnLink key={i++} icon='user-plus' text={intl.formatMessage(messages.follow_requests)} badge={badgeDisplay(unreadFollowRequests, 40)} to='/follow_requests' />);
height += 48;
}

@ -64,7 +64,7 @@ class FilterBar extends React.PureComponent {
onClick={this.onClick('mention')}
title={intl.formatMessage(tooltips.mentions)}
>
<Icon id='at' fixedWidth />
<Icon id='reply-all' fixedWidth />
</button>
<button
className={selectedFilter === 'favourite' ? 'active' : ''}

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from '../../components/column';
import ColumnHeader from '../../components/column_header';
import { expandNotifications, scrollTopNotifications, loadPending } from '../../actions/notifications';
import { expandNotifications, scrollTopNotifications, loadPending, mountNotifications, unmountNotifications } from '../../actions/notifications';
import { addColumn, removeColumn, moveColumn } from '../../actions/columns';
import NotificationContainer from './containers/notification_container';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
@ -66,11 +66,16 @@ class Notifications extends React.PureComponent {
trackScroll: true,
};
componentWillMount() {
this.props.dispatch(mountNotifications());
}
componentWillUnmount () {
this.handleLoadOlder.cancel();
this.handleScrollToTop.cancel();
this.handleScroll.cancel();
this.props.dispatch(scrollTopNotifications(false));
this.props.dispatch(unmountNotifications());
}
handleLoadGap = (maxId) => {

@ -27,7 +27,9 @@ class Reblogs extends ImmutablePureComponent {
};
componentWillMount () {
this.props.dispatch(fetchReblogs(this.props.params.statusId));
if (!this.props.accountIds) {
this.props.dispatch(fetchReblogs(this.props.params.statusId));
}
}
componentWillReceiveProps(nextProps) {

@ -1,4 +1,3 @@
import React from 'react';
import { connect } from 'react-redux';
import DetailedStatus from '../components/detailed_status';
import { makeGetStatus } from '../../../selectors';
@ -15,7 +14,6 @@ import {
pin,
unpin,
} from '../../../actions/interactions';
import { blockAccount } from '../../../actions/accounts';
import {
muteStatus,
unmuteStatus,
@ -24,9 +22,10 @@ import {
revealStatus,
} from '../../../actions/statuses';
import { initMuteModal } from '../../../actions/mutes';
import { initBlockModal } from '../../../actions/blocks';
import { initReport } from '../../../actions/reports';
import { openModal } from '../../../actions/modal';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl';
import { boostModal, deleteModal } from '../../../initial_state';
import { showAlertForError } from '../../../actions/alerts';
@ -35,10 +34,8 @@ const messages = defineMessages({
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
});
const makeMapStateToProps = () => {
@ -138,16 +135,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onBlock (status) {
const account = status.get('account');
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.get('id'))),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.get('id')));
dispatch(initReport(account, status));
},
}));
dispatch(initBlockModal(account));
},
onReport (status) {

@ -23,7 +23,6 @@ import {
mentionCompose,
directCompose,
} from '../../actions/compose';
import { blockAccount } from '../../actions/accounts';
import {
muteStatus,
unmuteStatus,
@ -32,6 +31,7 @@ import {
revealStatus,
} from '../../actions/statuses';
import { initMuteModal } from '../../actions/mutes';
import { initBlockModal } from '../../actions/blocks';
import { initReport } from '../../actions/reports';
import { makeGetStatus } from '../../selectors';
import { ScrollContainer } from 'react-router-scroll-4';
@ -39,7 +39,7 @@ import ColumnBackButton from '../../components/column_back_button';
import ColumnHeader from '../../components/column_header';
import StatusContainer from '../../containers/status_container';
import { openModal } from '../../actions/modal';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { HotKeys } from 'react-hotkeys';
import { boostModal, deleteModal } from '../../initial_state';
@ -52,13 +52,11 @@ const messages = defineMessages({
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' },
redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.' },
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
hideAll: { id: 'status.show_less_all', defaultMessage: 'Show less for all' },
detailedStatus: { id: 'status.detailed_status', defaultMessage: 'Detailed conversation view' },
replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' },
replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' },
blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' },
});
const makeMapStateToProps = () => {
@ -296,19 +294,9 @@ class Status extends ImmutablePureComponent {
}
handleBlockClick = (status) => {
const { dispatch, intl } = this.props;
const { dispatch } = this.props;
const account = status.get('account');
dispatch(openModal('CONFIRM', {
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.blockConfirm),
onConfirm: () => dispatch(blockAccount(account.get('id'))),
secondary: intl.formatMessage(messages.blockAndReport),
onSecondary: () => {
dispatch(blockAccount(account.get('id')));
dispatch(initReport(account, status));
},
}));
dispatch(initBlockModal(account));
}
handleReport = (status) => {

@ -0,0 +1,103 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage } from 'react-intl';
import { makeGetAccount } from '../../../selectors';
import Button from '../../../components/button';
import { closeModal } from '../../../actions/modal';
import { blockAccount } from '../../../actions/accounts';
import { initReport } from '../../../actions/reports';
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
const mapStateToProps = state => ({
account: getAccount(state, state.getIn(['blocks', 'new', 'account_id'])),
});
return mapStateToProps;
};
const mapDispatchToProps = dispatch => {
return {
onConfirm(account) {
dispatch(blockAccount(account.get('id')));
},
onBlockAndReport(account) {
dispatch(blockAccount(account.get('id')));
dispatch(initReport(account));
},
onClose() {
dispatch(closeModal());
},
};
};
export default @connect(makeMapStateToProps, mapDispatchToProps)
@injectIntl
class BlockModal extends React.PureComponent {
static propTypes = {
account: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
onBlockAndReport: PropTypes.func.isRequired,
onConfirm: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
componentDidMount() {
this.button.focus();
}
handleClick = () => {
this.props.onClose();
this.props.onConfirm(this.props.account);
}
handleSecondary = () => {
this.props.onClose();
this.props.onBlockAndReport(this.props.account);
}
handleCancel = () => {
this.props.onClose();
}
setRef = (c) => {
this.button = c;
}
render () {
const { account } = this.props;
return (
<div className='modal-root__modal block-modal'>
<div className='block-modal__container'>
<p>
<FormattedMessage
id='confirmations.block.message'
defaultMessage='Are you sure you want to block {name}?'
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
</p>
</div>
<div className='block-modal__action-bar'>
<Button onClick={this.handleCancel} className='block-modal__cancel-button'>
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
</Button>
<Button onClick={this.handleSecondary} className='confirmation-modal__secondary-button'>
<FormattedMessage id='confirmations.block.block_and_report' defaultMessage='Block & Report' />
</Button>
<Button onClick={this.handleClick} ref={this.setRef}>
<FormattedMessage id='confirmations.block.confirm' defaultMessage='Block' />
</Button>
</div>
</div>
);
}
}

@ -173,7 +173,17 @@ class FocalPointModal extends ImmutablePureComponent {
langPath: `${assetHost}/ocr/lang-data`,
});
worker.recognize(media.get('url'))
let media_url = media.get('file');
if (window.URL && URL.createObjectURL) {
try {
media_url = URL.createObjectURL(media.get('file'));
} catch (error) {
console.error(error);
}
}
worker.recognize(media_url)
.progress(({ progress }) => this.setState({ progress }))
.finally(() => worker.terminate())
.then(({ text }) => this.setState({ description: removeExtraLineBreaks(text), dirty: true, detecting: false }))

@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import Base from '../../../components/modal_root';
import { getScrollbarWidth } from 'mastodon/utils/scrollbar';
import Base from 'mastodon/components/modal_root';
import BundleContainer from '../containers/bundle_container';
import BundleModalError from './bundle_modal_error';
import ModalLoading from './modal_loading';
@ -12,6 +13,7 @@ import ConfirmationModal from './confirmation_modal';
import FocalPointModal from './focal_point_modal';
import {
MuteModal,
BlockModal,
ReportModal,
EmbedModal,
ListEditor,
@ -24,6 +26,7 @@ const MODAL_COMPONENTS = {
'BOOST': () => Promise.resolve({ default: BoostModal }),
'CONFIRM': () => Promise.resolve({ default: ConfirmationModal }),
'MUTE': MuteModal,
'BLOCK': BlockModal,
'REPORT': ReportModal,
'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
'EMBED': EmbedModal,
@ -32,28 +35,6 @@ const MODAL_COMPONENTS = {
'LIST_ADDER':ListAdder,
};
let cachedScrollbarWidth = null;
export const getScrollbarWidth = () => {
if (cachedScrollbarWidth !== null) {
return cachedScrollbarWidth;
}
const outer = document.createElement('div');
outer.style.visibility = 'hidden';
outer.style.overflow = 'scroll';
document.body.appendChild(outer);
const inner = document.createElement('div');
outer.appendChild(inner);
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
cachedScrollbarWidth = scrollbarWidth;
outer.parentNode.removeChild(outer);
return scrollbarWidth;
};
export default class ModalRoot extends React.PureComponent {
static propTypes = {

@ -11,7 +11,6 @@ import { toggleHideNotifications } from '../../../actions/mutes';
const mapStateToProps = state => {
return {
isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
account: state.getIn(['mutes', 'new', 'account']),
notifications: state.getIn(['mutes', 'new', 'notifications']),
};
@ -38,7 +37,6 @@ export default @connect(mapStateToProps, mapDispatchToProps)
class MuteModal extends React.PureComponent {
static propTypes = {
isSubmitting: PropTypes.bool.isRequired,
account: PropTypes.object.isRequired,
notifications: PropTypes.bool.isRequired,
onClose: PropTypes.func.isRequired,
@ -81,11 +79,16 @@ class MuteModal extends React.PureComponent {
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
</p>
<div>
<label htmlFor='mute-modal__hide-notifications-checkbox'>
<p className='mute-modal__explanation'>
<FormattedMessage
id='confirmations.mute.explanation'
defaultMessage='This will hide posts from them and posts mentioning them, but it will still allow them to see your posts follow you.'
/>
</p>
<div className='setting-toggle'>
<Toggle id='mute-modal__hide-notifications-checkbox' checked={notifications} onChange={this.toggleNotifications} />
<label className='setting-toggle__label' htmlFor='mute-modal__hide-notifications-checkbox'>
<FormattedMessage id='mute_modal.hide_notifications' defaultMessage='Hide notifications from this user?' />
{' '}
<Toggle id='mute-modal__hide-notifications-checkbox' checked={notifications} onChange={this.toggleNotifications} />
</label>
</div>
</div>

@ -106,6 +106,10 @@ export function MuteModal () {
return import(/* webpackChunkName: "modals/mute_modal" */'../components/mute_modal');
}
export function BlockModal () {
return import(/* webpackChunkName: "modals/block_modal" */'../components/block_modal');
}
export function ReportModal () {
return import(/* webpackChunkName: "modals/report_modal" */'../components/report_modal');
}

@ -7,7 +7,7 @@
"account.cancel_follow_request": "إلغاء طلب المتابَعة",
"account.direct": "رسالة خاصة إلى @{name}",
"account.domain_blocked": "النطاق مخفي",
"account.edit_profile": "تعديل الملف الشخصي",
"account.edit_profile": "تعديل الملف التعريفي",
"account.endorse": "أوصِ به على صفحتك",
"account.follow": "تابِع",
"account.followers": "متابعون",
@ -30,11 +30,11 @@
"account.posts_with_replies": "التبويقات و الردود",
"account.report": "ابلِغ عن @{name}",
"account.requested": "في انتظار الموافقة. اضْغَطْ/ي لإلغاء طلب المتابعة",
"account.share": "مشاركة حساب @{name}",
"account.share": "شارك ملف تعريف @{name}",
"account.show_reblogs": "اعرض ترقيات @{name}",
"account.unblock": "إلغاء الحظر عن @{name}",
"account.unblock_domain": "فك الخْفى عن {domain}",
"account.unendorse": "أزل ترويجه مِن الملف الشخصي",
"account.unendorse": "أزل ترويجه مِن الملف التعريفي",
"account.unfollow": "إلغاء المتابعة",
"account.unmute": "إلغاء الكتم عن @{name}",
"account.unmute_notifications": "إلغاء كتم إخطارات @{name}",
@ -53,7 +53,7 @@
"column.blocks": "الحسابات المحجوبة",
"column.community": "الخيط العام المحلي",
"column.direct": "الرسائل المباشرة",
"column.directory": "Browse profiles",
"column.directory": "استعرض الملفات التعريفية",
"column.domain_blocks": "النطاقات المخفية",
"column.favourites": "المفضلة",
"column.follow_requests": "طلبات المتابعة",
@ -63,7 +63,7 @@
"column.notifications": "الإخطارات",
"column.pins": "التبويقات المثبتة",
"column.public": "الخيط العام الموحد",
"column.status": "Toot",
"column.status": "تبويق",
"column_back_button.label": "العودة",
"column_header.hide_settings": "إخفاء الإعدادات",
"column_header.moveLeft_settings": "نقل القائمة إلى اليسار",
@ -111,6 +111,10 @@
"confirmations.reply.message": "الرد في الحين سوف يُعيد كتابة الرسالة التي أنت بصدد كتابتها. متأكد من أنك تريد المواصلة؟",
"confirmations.unfollow.confirm": "إلغاء المتابعة",
"confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ؟",
"conversation.delete": "احذف المحادثة",
"conversation.mark_as_read": "اعتبرها كمقروءة",
"conversation.open": "اعرض المحادثة",
"conversation.with": "بـ {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "الوافدون الجُدد",
@ -132,7 +136,7 @@
"emoji_button.symbols": "رموز",
"emoji_button.travel": "الأماكن والسفر",
"empty_column.account_timeline": "ليس هناك تبويقات!",
"empty_column.account_unavailable": "الملف الشخصي غير متوفر",
"empty_column.account_unavailable": "الملف التعريفي غير متوفر",
"empty_column.blocks": "لم تقم بحظر أي مستخدِم بعد.",
"empty_column.community": "الخط العام المحلي فارغ. أكتب شيئا ما للعامة كبداية!",
"empty_column.direct": "لم تتلق أية رسالة خاصة مباشِرة بعد. سوف يتم عرض الرسائل المباشرة هنا إن قمت بإرسال واحدة أو تلقيت البعض منها.",
@ -151,7 +155,7 @@
"follow_request.authorize": "ترخيص",
"follow_request.reject": "رفض",
"getting_started.developers": "المُطوِّرون",
"getting_started.directory": "دليل المستخدِمين والمستخدِمات",
"getting_started.directory": "دليل الصفحات التعريفية",
"getting_started.documentation": "الدليل",
"getting_started.heading": "استعدّ للبدء",
"getting_started.invite": "دعوة أشخاص",
@ -190,7 +194,7 @@
"introduction.interactions.reply.text": "يمكنكم الرد على تبويقاتكم و تبويقات الآخرين على شكل سلسلة محادثة.",
"introduction.welcome.action": "هيا بنا!",
"introduction.welcome.headline": "الخطوات الأولى",
"introduction.welcome.text": "مرحبا بكم على الفديفرس! بعد لحظات قليلة ، سيكون بمقدوركم بث رسائل والتحدث إلى أصدقائكم عبر تشكيلة واسعة من الخوادم المختلفة. هذا الخادم ، {domain} ، يستضيف ملفكم الشخصي ، لذا يجب تذكر اسمه جيدا.",
"introduction.welcome.text": "مرحبا بكم على الفديفرس! بعد لحظات قليلة ، سيكون بمقدوركم بث رسائل والتحدث إلى أصدقائكم عبر تشكيلة واسعة من الخوادم المختلفة. هذا الخادم ، {domain} ، يستضيف صفحتكم التعريفية ، لذا يجب تذكر اسمه جيدا.",
"keyboard_shortcuts.back": "للعودة",
"keyboard_shortcuts.blocked": "لفتح قائمة المستخدمين المحظورين",
"keyboard_shortcuts.boost": "للترقية",
@ -210,10 +214,10 @@
"keyboard_shortcuts.local": "لفتح الخيط العام المحلي",
"keyboard_shortcuts.mention": "لذِكر الناشر",
"keyboard_shortcuts.muted": "لفتح قائمة المستخدِمين المكتومين",
"keyboard_shortcuts.my_profile": "لفتح ملفك الشخصي",
"keyboard_shortcuts.my_profile": "لفتح ملفك التعريفي",
"keyboard_shortcuts.notifications": "لفتح عمود الإشعارات",
"keyboard_shortcuts.pinned": "لفتح قائمة التبويقات المدبسة",
"keyboard_shortcuts.profile": "لفتح رابط الناشر",
"keyboard_shortcuts.profile": "لفتح الملف التعريفي للناشر",
"keyboard_shortcuts.reply": "للردّ",
"keyboard_shortcuts.requests": "لفتح قائمة طلبات المتابعة",
"keyboard_shortcuts.search": "للتركيز على البحث",
@ -249,7 +253,7 @@
"navigation_bar.direct": "الرسائل المباشِرة",
"navigation_bar.discover": "اكتشف",
"navigation_bar.domain_blocks": "النطاقات المخفية",
"navigation_bar.edit_profile": "تعديل الملف الشخصي",
"navigation_bar.edit_profile": "عدّل الملف التعريفي",
"navigation_bar.favourites": "المفضلة",
"navigation_bar.filters": "الكلمات المكتومة",
"navigation_bar.follow_requests": "طلبات المتابعة",
@ -295,6 +299,7 @@
"poll.refresh": "تحديث",
"poll.total_votes": "{count, plural, one {# صوت} other {# أصوات}}",
"poll.vote": "صَوّت",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "إضافة استطلاع للرأي",
"poll_button.remove_poll": "إزالة استطلاع الرأي",
"privacy.change": "اضبط خصوصية المنشور",
@ -351,7 +356,7 @@
"status.mute": "أكتم @{name}",
"status.mute_conversation": "كتم المحادثة",
"status.open": "وسع هذه المشاركة",
"status.pin": "تدبيس على الملف الشخصي",
"status.pin": "دبّسه على الصفحة التعريفية",
"status.pinned": "تبويق مثبَّت",
"status.read_more": "اقرأ المزيد",
"status.reblog": "رَقِّي",
@ -371,7 +376,7 @@
"status.show_thread": "الكشف عن المحادثة",
"status.uncached_media_warning": "غير متوفر",
"status.unmute_conversation": "فك الكتم عن المحادثة",
"status.unpin": "فك التدبيس من الملف الشخصي",
"status.unpin": "فك التدبيس من الصفحة التعريفية",
"suggestions.dismiss": "إلغاء الاقتراح",
"suggestions.header": "يمكن أن يهمك…",
"tabs_bar.federated_timeline": "الموحَّد",
@ -400,7 +405,7 @@
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "تعديل الوسائط",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_modal.preview_label": "معاينة ({ratio})",
"upload_progress.label": "يرفع...",
"video.close": "إغلاق الفيديو",
"video.exit_fullscreen": "الخروج من وضع الشاشة المليئة",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",

@ -1,12 +1,12 @@
{
"account.add_or_remove_from_list": "Add or Remove from lists",
"account.badges.bot": "Bot",
"account.add_or_remove_from_list": "Добави или премахни от списъците",
"account.badges.bot": "бот",
"account.block": "Блокирай",
"account.block_domain": "Hide everything from {domain}",
"account.blocked": "Blocked",
"account.block_domain": "скрий всичко от (домейн)",
"account.blocked": "Блокирани",
"account.cancel_follow_request": "Cancel follow request",
"account.direct": "Direct Message @{name}",
"account.domain_blocked": "Domain hidden",
"account.domain_blocked": "Скрит домейн",
"account.edit_profile": "Редактирай профила си",
"account.endorse": "Feature on profile",
"account.follow": "Последвай",
@ -45,7 +45,7 @@
"autosuggest_hashtag.per_week": "{count} per week",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",
"bundle_column_error.retry": "Опитай отново",
"bundle_column_error.title": "Network error",
"bundle_modal_error.close": "Close",
"bundle_modal_error.message": "Something went wrong while loading this component.",
@ -58,7 +58,7 @@
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Начало",
"column.lists": "Lists",
"column.lists": "Списъци",
"column.mutes": "Muted users",
"column.notifications": "Известия",
"column.pins": "Pinned toot",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",

@ -111,6 +111,10 @@
"confirmations.reply.message": "এখন মতামত লিখতে গেলে আপনার এখন যেটা লিখছেন সেটা মুছে যাবে। আপনি নি নিশ্চিত এটা করতে চান ?",
"confirmations.unfollow.confirm": "অনুসরণ করা বাতিল করতে",
"confirmations.unfollow.message": "আপনি কি নিশ্চিত {name} কে আর অনুসরণ করতে চান না ?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "বদলেছে কিনা দেখতে",
"poll.total_votes": "{count, plural, one {# ভোট} other {# ভোট}}",
"poll.vote": "ভোট",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "একটা নির্বাচন যোগ করতে",
"poll_button.remove_poll": "নির্বাচন বাদ দিতে",
"privacy.change": "লেখার গোপনীয়তা অবস্থা ঠিক করতে",

@ -1,60 +1,60 @@
{
"account.add_or_remove_from_list": "Add or Remove from lists",
"account.badges.bot": "Bot",
"account.block": "Block @{name}",
"account.block_domain": "Hide everything from {domain}",
"account.blocked": "Blocked",
"account.cancel_follow_request": "Cancel follow request",
"account.direct": "Direct message @{name}",
"account.domain_blocked": "Domain hidden",
"account.edit_profile": "Edit profile",
"account.endorse": "Feature on profile",
"account.follow": "Follow",
"account.followers": "Followers",
"account.followers.empty": "No one follows this user yet.",
"account.follows": "Follows",
"account.add_or_remove_from_list": "Ouzhpenn pe lemel ag ar listennadoù",
"account.badges.bot": "Robot",
"account.block": "Stankañ @{name}",
"account.block_domain": "Kuzh kement tra a {domain}",
"account.blocked": "Stanket",
"account.cancel_follow_request": "Nullañ ar pedad heuliañ",
"account.direct": "Kas ur c'hemennad da @{name}",
"account.domain_blocked": "Domani kuzhet",
"account.edit_profile": "Aozañ ar profil",
"account.endorse": "Lakaat war-wel war ar profil",
"account.follow": "Heuliañ",
"account.followers": "Heilour·ezed·ion",
"account.followers.empty": "Den na heul an implijour-mañ c'hoazh.",
"account.follows": "Koumanantoù",
"account.follows.empty": "This user doesn't follow anyone yet.",
"account.follows_you": "Follows you",
"account.hide_reblogs": "Hide boosts from @{name}",
"account.last_status": "Last active",
"account.follows_you": "Ho heul",
"account.hide_reblogs": "Kuzh toudoù skignet gant @{name}",
"account.last_status": "Oberiantiz zivezhañ",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
"account.media": "Media",
"account.mention": "Mention @{name}",
"account.moved_to": "{name} has moved to:",
"account.mute": "Mute @{name}",
"account.mute_notifications": "Mute notifications from @{name}",
"account.muted": "Muted",
"account.never_active": "Never",
"account.posts": "Toots",
"account.posts_with_replies": "Toots and replies",
"account.report": "Report @{name}",
"account.mention": "Menegiñ @{name}",
"account.moved_to": "Dilojet en·he deus {name} da:",
"account.mute": "Kuzhat @{name}",
"account.mute_notifications": "Kuzh kemennoù a @{name}",
"account.muted": "Kuzhet",
"account.never_active": "Birviken",
"account.posts": "Toudoù",
"account.posts_with_replies": "Toudoù ha respontoù",
"account.report": "Disklêriañ @{name}",
"account.requested": "Awaiting approval",
"account.share": "Share @{name}'s profile",
"account.show_reblogs": "Show boosts from @{name}",
"account.unblock": "Unblock @{name}",
"account.unblock_domain": "Unhide {domain}",
"account.share": "Skignañ profil @{name}",
"account.show_reblogs": "Diskouez toudoù a @{name}",
"account.unblock": "Distankañ @{name}",
"account.unblock_domain": "Diguzh {domain}",
"account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}",
"account.unmute_notifications": "Unmute notifications from @{name}",
"account.unfollow": "Diheuliañ",
"account.unmute": "Diguzhat @{name}",
"account.unmute_notifications": "Diguzhat kemennoù a @{name}",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"autosuggest_hashtag.per_week": "{count} per week",
"alert.unexpected.message": "Ur fazi dic'hortozet zo degouezhet.",
"alert.unexpected.title": "C'hem !",
"autosuggest_hashtag.per_week": "{count} bep sizhun",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",
"bundle_column_error.title": "Network error",
"bundle_modal_error.close": "Close",
"bundle_column_error.retry": "Klask endro",
"bundle_column_error.title": "Fazi rouedad",
"bundle_modal_error.close": "Serriñ",
"bundle_modal_error.message": "Something went wrong while loading this component.",
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.directory": "Browse profiles",
"column.domain_blocks": "Hidden domains",
"bundle_modal_error.retry": "Klask endro",
"column.blocks": "Implijour·ezed·ion stanket",
"column.community": "Red-amzer lec'hel",
"column.direct": "Kemennadoù prevez",
"column.directory": "Mont a-dreuz ar profiloù",
"column.domain_blocks": "Domani kuzhet",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Responen ara es sobreescriurà el missatge que estàs editant. Estàs segur que vols continuar?",
"confirmations.unfollow.confirm": "Deixa de seguir",
"confirmations.unfollow.message": "Estàs segur que vols deixar de seguir {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Actualitza",
"poll.total_votes": "{count, plural, one {# vot} other {# vots}}",
"poll.vote": "Vota",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Afegeix una enquesta",
"poll_button.remove_poll": "Elimina l'enquesta",
"privacy.change": "Ajusta l'estat de privacitat",

@ -63,7 +63,7 @@
"column.notifications": "Nutificazione",
"column.pins": "Statuti puntarulati",
"column.public": "Linea pubblica glubale",
"column.status": "Toot",
"column.status": "Statutu",
"column_back_button.label": "Ritornu",
"column_header.hide_settings": "Piattà i parametri",
"column_header.moveLeft_settings": "Spiazzà à manca",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Risponde avà sguasserà u missaghju chì scrivite. Site sicuru·a chì vulete cuntinuà?",
"confirmations.unfollow.confirm": "Disabbunassi",
"confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?",
"conversation.delete": "Sguassà a cunversazione",
"conversation.mark_as_read": "Marcà cum'è lettu",
"conversation.open": "Vede a cunversazione",
"conversation.with": "Cù {names}",
"directory.federated": "Da u fediverse cunisciutu",
"directory.local": "Solu da {domain}",
"directory.new_arrivals": "Ultimi arrivi",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Bàsichi",
"home.column_settings.show_reblogs": "Vede e spartere",
"home.column_settings.show_replies": "Vede e risposte",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Attualizà in tempu reale",
"intervals.full.days": "{number, plural, one {# ghjornu} other {# ghjorni}}",
"intervals.full.hours": "{number, plural, one {# ora} other {# ore}}",
"intervals.full.minutes": "{number, plural, one {# minuta} other {# minute}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Preferenze",
"navigation_bar.public_timeline": "Linea pubblica glubale",
"navigation_bar.security": "Sicurità",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "è {count, plural, one {# altru} other {# altri}}",
"notification.favourite": "{name} hà aghjuntu u vostru statutu à i so favuriti",
"notification.follow": "{name} v'hà seguitatu",
"notification.mention": "{name} v'hà mintuvatu",
@ -295,6 +299,7 @@
"poll.refresh": "Attualizà",
"poll.total_votes": "{count, plural, one {# votu} other {# voti}}",
"poll.vote": "Vutà",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Aghjunghje",
"poll_button.remove_poll": "Toglie u scandagliu",
"privacy.change": "Mudificà a cunfidenzialità di u statutu",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Odpovězením nyní přepíšete zprávu, kterou aktuálně píšete. Jste si jistý/á, že chcete pokračovat?",
"confirmations.unfollow.confirm": "Přestat sledovat",
"confirmations.unfollow.message": "jste si jistý/á, že chcete přestat sledovat uživatele {name}?",
"conversation.delete": "Smazat konverzaci",
"conversation.mark_as_read": "Označit jako přečtenou",
"conversation.open": "Zobrazit konverzaci",
"conversation.with": "S {names}",
"directory.federated": "Ze známého fedivesmíru",
"directory.local": "Pouze z {domain}",
"directory.new_arrivals": "Nově příchozí",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Základní",
"home.column_settings.show_reblogs": "Zobrazit boosty",
"home.column_settings.show_replies": "Zobrazit odpovědi",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Aktualizovat v reálném čase",
"intervals.full.days": "{number, plural, one {# den} few {# dny} many {# dne} other {# dní}}",
"intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodiny} other {# hodin}}",
"intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minuty} other {# minut}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Předvolby",
"navigation_bar.public_timeline": "Federovaná časová osa",
"navigation_bar.security": "Zabezpečení",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "a {count, plural, one {# další} few {# další} many {# dalších} other {# dalších}}",
"notification.favourite": "{name} si oblíbil/a váš toot",
"notification.follow": "{name} vás začal/a sledovat",
"notification.mention": "{name} vás zmínil/a",
@ -295,6 +299,7 @@
"poll.refresh": "Obnovit",
"poll.total_votes": "{count, plural, one {# hlas} few {# hlasy} many {# hlasu} other {# hlasů}}",
"poll.vote": "Hlasovat",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Přidat anketu",
"poll_button.remove_poll": "Odstranit anketu",
"privacy.change": "Změnit soukromí tootu",

@ -4,7 +4,7 @@
"account.block": "Blocio @{name}",
"account.block_domain": "Cuddio popeth rhag {domain}",
"account.blocked": "Blociwyd",
"account.cancel_follow_request": "Cancel follow request",
"account.cancel_follow_request": "Canslo cais dilyn",
"account.direct": "Neges breifat @{name}",
"account.domain_blocked": "Parth wedi ei guddio",
"account.edit_profile": "Golygu proffil",
@ -16,7 +16,7 @@
"account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
"account.follows_you": "Yn eich dilyn chi",
"account.hide_reblogs": "Cuddio bwstiau o @{name}",
"account.last_status": "Last active",
"account.last_status": "Gweithredol olaf",
"account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}",
"account.locked_info": "Mae'r statws preifatrwydd cyfrif hwn wedi'i osod i gloi. Mae'r perchennog yn adolygu'r sawl sy'n gallu eu dilyn.",
"account.media": "Cyfryngau",
@ -25,7 +25,7 @@
"account.mute": "Tawelu @{name}",
"account.mute_notifications": "Cuddio hysbysiadau o @{name}",
"account.muted": "Distewyd",
"account.never_active": "Never",
"account.never_active": "Byth",
"account.posts": "Tŵtiau",
"account.posts_with_replies": "Tŵtiau ac atebion",
"account.report": "Adrodd @{name}",
@ -38,11 +38,11 @@
"account.unfollow": "Dad-ddilyn",
"account.unmute": "Dad-dawelu @{name}",
"account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.rate_limited.message": "Ceisiwch eto ar ôl {retry_time, time, medium}.",
"alert.rate_limited.title": "Cyfradd gyfyngedig",
"alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
"alert.unexpected.title": "Wps!",
"autosuggest_hashtag.per_week": "{count} per week",
"autosuggest_hashtag.per_week": "{count} yr wythnos",
"boost_modal.combo": "Mae modd gwasgu {combo} er mwyn sgipio hyn tro nesa",
"bundle_column_error.body": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
"bundle_column_error.retry": "Ceisiwch eto",
@ -53,7 +53,7 @@
"column.blocks": "Defnyddwyr a flociwyd",
"column.community": "Ffrwd lleol",
"column.direct": "Negeseuon preifat",
"column.directory": "Browse profiles",
"column.directory": "Pori proffiliau",
"column.domain_blocks": "Parthau cuddiedig",
"column.favourites": "Ffefrynnau",
"column.follow_requests": "Ceisiadau dilyn",
@ -63,7 +63,7 @@
"column.notifications": "Hysbysiadau",
"column.pins": "Tŵtiau wedi eu pinio",
"column.public": "Ffrwd y ffederasiwn",
"column.status": "Toot",
"column.status": "Tŵt",
"column_back_button.label": "Nôl",
"column_header.hide_settings": "Cuddio dewisiadau",
"column_header.moveLeft_settings": "Symud y golofn i'r chwith",
@ -101,8 +101,8 @@
"confirmations.delete_list.message": "Ydych chi'n sicr eich bod eisiau dileu y rhestr hwn am byth?",
"confirmations.domain_block.confirm": "Cuddio parth cyfan",
"confirmations.domain_block.message": "A ydych yn hollol, hollol sicr eich bod am flocio y {domain} cyfan? Yn y nifer helaeth o achosion mae blocio neu tawelu ambell gyfrif yn ddigonol ac yn well. Ni fyddwch yn gweld cynnwys o'r parth hwnnw mewn unrhyw ffrydiau cyhoeddus na chwaith yn eich hysbysiadau. Bydd hyn yn cael gwared o'ch dilynwyr o'r parth hwnnw.",
"confirmations.logout.confirm": "Log out",
"confirmations.logout.message": "Are you sure you want to log out?",
"confirmations.logout.confirm": "Allgofnodi",
"confirmations.logout.message": "Ydych chi'n siŵr eich bod am allgofnodi?",
"confirmations.mute.confirm": "Tawelu",
"confirmations.mute.message": "Ydych chi'n sicr eich bod am ddistewi {name}?",
"confirmations.redraft.confirm": "Dileu & ailddrafftio",
@ -111,10 +111,14 @@
"confirmations.reply.message": "Bydd ateb nawr yn cymryd lle y neges yr ydych yn cyfansoddi ar hyn o bryd. Ydych chi'n sicr yr ydych am barhau?",
"confirmations.unfollow.confirm": "Dad-ddilynwch",
"confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
"directory.recently_active": "Recently active",
"conversation.delete": "Dileu sgwrs",
"conversation.mark_as_read": "Nodi fel wedi'i ddarllen",
"conversation.open": "Gweld sgwrs",
"conversation.with": "Gyda {names}",
"directory.federated": "O ffedysawd hysbys",
"directory.local": "O {domain} yn unig",
"directory.new_arrivals": "Newydd-ddyfodiaid",
"directory.recently_active": "Yn weithredol yn ddiweddar",
"embed.instructions": "Mewnblannwch y tŵt hwn ar eich gwefan drwy gopïo'r côd isod.",
"embed.preview": "Dyma sut olwg fydd arno:",
"emoji_button.activity": "Gweithgarwch",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Syml",
"home.column_settings.show_reblogs": "Dangos bŵstiau",
"home.column_settings.show_replies": "Dangos ymatebion",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Diweddariad mewn amser real",
"intervals.full.days": "{number, plural, one {# ddydd} other {# o ddyddiau}}",
"intervals.full.hours": "{number, plural, one {# awr} other {# o oriau}}",
"intervals.full.minutes": "{number, plural, one {# funud} other {# o funudau}}",
@ -236,7 +240,7 @@
"lists.new.title_placeholder": "Teitl rhestr newydd",
"lists.search": "Chwilio ymysg pobl yr ydych yn ei ddilyn",
"lists.subheading": "Eich rhestrau",
"load_pending": "{count, plural, one {# new item} other {# new items}}",
"load_pending": "{count, plural, one {# eitem newydd} other {# eitemau newydd}}",
"loading_indicator.label": "Llwytho...",
"media_gallery.toggle_visible": "Toglo gwelededd",
"missing_indicator.label": "Heb ei ganfod",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Dewisiadau",
"navigation_bar.public_timeline": "Ffrwd y ffederasiwn",
"navigation_bar.security": "Diogelwch",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "a {count, plural, one {# arall} other {# eraill}}",
"notification.favourite": "hoffodd {name} eich tŵt",
"notification.follow": "dilynodd {name} chi",
"notification.mention": "Soniodd {name} amdanoch chi",
@ -295,6 +299,7 @@
"poll.refresh": "Adnewyddu",
"poll.total_votes": "{count, plural, one {# bleidlais} other {# o bleidleisiau}}",
"poll.vote": "Pleidleisio",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Ychwanegu pleidlais",
"poll_button.remove_poll": "Tynnu pleidlais",
"privacy.change": "Addasu preifatrwdd y tŵt",
@ -330,7 +335,7 @@
"search_results.accounts": "Pobl",
"search_results.hashtags": "Hanshnodau",
"search_results.statuses": "Tŵtiau",
"search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.",
"search_results.statuses_fts_disabled": "Nid yw chwilio Tŵtiau yn ôl eu cynnwys wedi'i alluogi ar y gweinydd Mastodon hwn.",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"status.admin_account": "Agor rhyngwyneb goruwchwylio ar gyfer @{name}",
"status.admin_status": "Agor y tŵt yn y rhyngwyneb goruwchwylio",
@ -369,7 +374,7 @@
"status.show_more": "Dangos mwy",
"status.show_more_all": "Dangos mwy i bawb",
"status.show_thread": "Dangos edefyn",
"status.uncached_media_warning": "Not available",
"status.uncached_media_warning": "Dim ar gael",
"status.unmute_conversation": "Dad-dawelu sgwrs",
"status.unpin": "Dadbinio o'r proffil",
"suggestions.dismiss": "Diswyddo",
@ -385,22 +390,22 @@
"time_remaining.moments": "Munudau ar ôl",
"time_remaining.seconds": "{number, plural, one {# eiliad} other {# o eiliadau}} ar ôl",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} yn siarad",
"trends.trending_now": "Trending now",
"trends.trending_now": "Yn tueddu nawr",
"ui.beforeunload": "Mi fyddwch yn colli eich drafft os gadewch Mastodon.",
"upload_area.title": "Llusgwch & gollwing i uwchlwytho",
"upload_button.label": "Ychwanegwch gyfryngau (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_error.limit": "Wedi mynd heibio'r uchafswm terfyn uwchlwytho.",
"upload_error.poll": "Nid oes modd uwchlwytho ffeiliau â phleidleisiau.",
"upload_form.description": "Disgrifio i'r rheini a nam ar ei golwg",
"upload_form.edit": "Edit",
"upload_form.edit": "Golygu",
"upload_form.undo": "Dileu",
"upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.apply": "Apply",
"upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "Edit media",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_modal.analyzing_picture": "Dadansoddi llun…",
"upload_modal.apply": "Gweithredu",
"upload_modal.description_placeholder": "Mae ei phen bach llawn jocs, 'run peth a fy nghot golff, rhai dyddiau",
"upload_modal.detect_text": "Canfod testun o'r llun",
"upload_modal.edit_media": "Golygu cyfryngau",
"upload_modal.hint": "Cliciwch neu llusgwch y cylch ar y rhagolwg i ddewis y canolbwynt a fydd bob amser i'w weld ar bob mân-lunau.",
"upload_modal.preview_label": "Rhagolwg ({ratio})",
"upload_progress.label": "Uwchlwytho...",
"video.close": "Cau fideo",
"video.exit_fullscreen": "Gadael sgrîn llawn",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Hvis du svarer nu vil du overskrive den besked du er ved at skrive. Er du sikker på, du vil fortsætte?",
"confirmations.unfollow.confirm": "Følg ikke længere",
"confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "Fra kendt fedivers",
"directory.local": "Kun fra {domain}",
"directory.new_arrivals": "Nye ankomster",
@ -295,6 +299,7 @@
"poll.refresh": "Opdatér",
"poll.total_votes": "{count, plural, one {# stemme} other {# stemmer}}",
"poll.vote": "Stem",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Tilføj en afstemning",
"poll_button.remove_poll": "Fjern afstemning",
"privacy.change": "Skift status visningsindstillinger",

@ -63,7 +63,7 @@
"column.notifications": "Mitteilungen",
"column.pins": "Angeheftete Beiträge",
"column.public": "Föderierte Zeitleiste",
"column.status": "Toot",
"column.status": "Beitrag",
"column_back_button.label": "Zurück",
"column_header.hide_settings": "Einstellungen verbergen",
"column_header.moveLeft_settings": "Spalte nach links verschieben",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Wenn du jetzt antwortest wird es die gesamte Nachricht verwerfen, die du gerade schreibst. Möchtest du wirklich fortfahren?",
"confirmations.unfollow.confirm": "Entfolgen",
"confirmations.unfollow.message": "Bist du dir sicher, dass du {name} entfolgen möchtest?",
"conversation.delete": "Unterhaltung löschen",
"conversation.mark_as_read": "Als gelesen markieren",
"conversation.open": "Unterhaltung anzeigen",
"conversation.with": "Mit {names}",
"directory.federated": "Aus dem Fediverse",
"directory.local": "Nur von {domain}",
"directory.new_arrivals": "Neue Benutzer",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Einfach",
"home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen",
"home.column_settings.show_replies": "Antworten anzeigen",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "In Echtzeit aktualisieren",
"intervals.full.days": "{number, plural, one {# Tag} other {# Tage}}",
"intervals.full.hours": "{number, plural, one {# Stunde} other {# Stunden}}",
"intervals.full.minutes": "{number, plural, one {# Minute} other {# Minuten}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Einstellungen",
"navigation_bar.public_timeline": "Föderierte Zeitleiste",
"navigation_bar.security": "Sicherheit",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "und {count, plural, one {# andere Person} other {# andere Personen}}",
"notification.favourite": "{name} hat deinen Beitrag favorisiert",
"notification.follow": "{name} folgt dir",
"notification.mention": "{name} hat dich erwähnt",
@ -295,6 +299,7 @@
"poll.refresh": "Aktualisieren",
"poll.total_votes": "{count, plural, one {# Stimme} other {# Stimmen}}",
"poll.vote": "Abstimmen",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Eine Umfrage erstellen",
"poll_button.remove_poll": "Umfrage entfernen",
"privacy.change": "Sichtbarkeit des Beitrags anpassen",

@ -233,6 +233,11 @@
"defaultMessage": "Closed",
"id": "poll.closed"
},
{
"defaultMessage": "You voted for this answer",
"description": "Tooltip of the \"voted\" checkmark in polls",
"id": "poll.voted"
},
{
"defaultMessage": "Vote",
"id": "poll.vote"
@ -1264,6 +1269,56 @@
],
"path": "app/javascript/mastodon/features/compose/index.json"
},
{
"descriptors": [
{
"defaultMessage": "More",
"id": "status.more"
},
{
"defaultMessage": "View conversation",
"id": "conversation.open"
},
{
"defaultMessage": "Reply",
"id": "status.reply"
},
{
"defaultMessage": "Mark as read",
"id": "conversation.mark_as_read"
},
{
"defaultMessage": "Delete conversation",
"id": "conversation.delete"
},
{
"defaultMessage": "Mute conversation",
"id": "status.mute_conversation"
},
{
"defaultMessage": "Unmute conversation",
"id": "status.unmute_conversation"
},
{
"defaultMessage": "With {names}",
"id": "conversation.with"
}
],
"path": "app/javascript/mastodon/features/direct_timeline/components/conversation.json"
},
{
"descriptors": [
{
"defaultMessage": "Reply",
"id": "confirmations.reply.confirm"
},
{
"defaultMessage": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"id": "confirmations.reply.message"
}
],
"path": "app/javascript/mastodon/features/direct_timeline/containers/conversation_container.json"
},
{
"descriptors": [
{

@ -1,7 +1,7 @@
{
"account.add_or_remove_from_list": "Προσθήκη ή Αφαίρεση από λίστες",
"account.badges.bot": "Μποτ",
"account.block": "Αποκλισμός @{name}",
"account.block": "Αποκλεισμός @{name}",
"account.block_domain": "Απόκρυψε τα πάντα από το {domain}",
"account.blocked": "Αποκλεισμένος/η",
"account.cancel_follow_request": "Ακύρωση αιτήματος παρακολούθησης",
@ -63,7 +63,7 @@
"column.notifications": "Ειδοποιήσεις",
"column.pins": "Καρφιτσωμένα τουτ",
"column.public": "Ομοσπονδιακή ροή",
"column.status": "Toot",
"column.status": "Τουτ",
"column_back_button.label": "Πίσω",
"column_header.hide_settings": "Απόκρυψη ρυθμίσεων",
"column_header.moveLeft_settings": "Μεταφορά κολώνας αριστερά",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Απαντώντας τώρα θα αντικαταστήσεις το κείμενο που ήδη γράφεις. Σίγουρα θέλεις να συνεχίσεις;",
"confirmations.unfollow.confirm": "Διακοπή παρακολούθησης",
"confirmations.unfollow.message": "Σίγουρα θες να πάψεις να ακολουθείς τον/την {name};",
"conversation.delete": "Διαγραφή συζήτησης",
"conversation.mark_as_read": "Σήμανση ως αναγνωσμένο",
"conversation.open": "Προβολή συνομιλίας",
"conversation.with": "Με {names}",
"directory.federated": "Από το γνωστό fediverse",
"directory.local": "Μόνο από {domain}",
"directory.new_arrivals": "Νέες αφίξεις",
@ -127,7 +131,7 @@
"emoji_button.objects": "Αντικείμενα",
"emoji_button.people": "Άνθρωποι",
"emoji_button.recent": "Δημοφιλή",
"emoji_button.search": "Αναζήτηση",
"emoji_button.search": "Αναζήτηση...",
"emoji_button.search_results": "Αποτελέσματα αναζήτησης",
"emoji_button.symbols": "Σύμβολα",
"emoji_button.travel": "Ταξίδια & Τοποθεσίες",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Βασικές ρυθμίσεις",
"home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων",
"home.column_settings.show_replies": "Εμφάνιση απαντήσεων",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Ενημέρωση σε πραγματικό χρόνο",
"intervals.full.days": "{number, plural, one {# μέρα} other {# μέρες}}",
"intervals.full.hours": "{number, plural, one {# ώρα} other {# ώρες}}",
"intervals.full.minutes": "{number, plural, one {# λεπτό} other {# λεπτά}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Προτιμήσεις",
"navigation_bar.public_timeline": "Ομοσπονδιακή ροή",
"navigation_bar.security": "Ασφάλεια",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "και {count, plural, one {# άλλη} other {# άλλες}}",
"notification.favourite": "Ο/Η {name} σημείωσε ως αγαπημένη την κατάστασή σου",
"notification.follow": "Ο/Η {name} σε ακολούθησε",
"notification.mention": "Ο/Η {name} σε ανέφερε",
@ -295,6 +299,7 @@
"poll.refresh": "Ανανέωση",
"poll.total_votes": "{count, plural, one {# ψήφος} other {# ψήφοι}}",
"poll.vote": "Ψήφισε",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Προσθήκη δημοσκόπησης",
"poll_button.remove_poll": "Αφαίρεση δημοσκόπησης",
"privacy.change": "Προσαρμογή ιδιωτικότητας δημοσίευσης",
@ -388,7 +393,7 @@
"trends.trending_now": "Δημοφιλή τώρα",
"ui.beforeunload": "Το προσχέδιό σου θα χαθεί αν φύγεις από το Mastodon.",
"upload_area.title": "Drag & drop για να ανεβάσεις",
"upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_button.label": "Πρόσθεσε πολυμέσα ({formats})",
"upload_error.limit": "Υπέρβαση ορίου μεγέθους ανεβασμένων αρχείων.",
"upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.",
"upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",

@ -115,6 +115,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -300,6 +304,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",

@ -4,7 +4,7 @@
"account.block": "Bloki @{name}",
"account.block_domain": "Kaŝi ĉion de {domain}",
"account.blocked": "Blokita",
"account.cancel_follow_request": "Nuligi peto de sekvado",
"account.cancel_follow_request": "Nuligi peton de sekvado",
"account.direct": "Rekte mesaĝi @{name}",
"account.domain_blocked": "Domajno kaŝita",
"account.edit_profile": "Redakti profilon",
@ -16,14 +16,14 @@
"account.follows.empty": "Tiu uzanto ankoraŭ ne sekvas iun.",
"account.follows_you": "Sekvas vin",
"account.hide_reblogs": "Kaŝi diskonigojn de @{name}",
"account.last_status": "Lasta aktiva",
"account.last_status": "Laste aktiva",
"account.link_verified_on": "La posedanto de tiu ligilo estis kontrolita je {date}",
"account.locked_info": "La privateco de tiu konto estas elektita kiel fermita. La posedanto povas mane akcepti tiun, kiu povas sekvi rin.",
"account.media": "Aŭdovidaĵoj",
"account.mention": "Mencii @{name}",
"account.moved_to": "{name} moviĝis al:",
"account.mute": "Silentigi @{name}",
"account.mute_notifications": "Silentigi sciigojn el @{name}",
"account.mute_notifications": "Silentigi sciigojn de @{name}",
"account.muted": "Silentigita",
"account.never_active": "Neniam",
"account.posts": "Mesaĝoj",
@ -38,8 +38,8 @@
"account.unfollow": "Ne plu sekvi",
"account.unmute": "Malsilentigi @{name}",
"account.unmute_notifications": "Malsilentigi sciigojn de @{name}",
"alert.rate_limited.message": "Bonvolu reprovi poste {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.rate_limited.message": "Bonvolu reprovi post {retry_time, time, medium}.",
"alert.rate_limited.title": "Mesaĝkvante limigita",
"alert.unexpected.message": "Neatendita eraro okazis.",
"alert.unexpected.title": "Ups!",
"autosuggest_hashtag.per_week": "{count} semajne",
@ -53,7 +53,7 @@
"column.blocks": "Blokitaj uzantoj",
"column.community": "Loka tempolinio",
"column.direct": "Rektaj mesaĝoj",
"column.directory": "Browse profiles",
"column.directory": "Trarigardi profilojn",
"column.domain_blocks": "Kaŝitaj domajnoj",
"column.favourites": "Stelumoj",
"column.follow_requests": "Petoj de sekvado",
@ -63,7 +63,7 @@
"column.notifications": "Sciigoj",
"column.pins": "Alpinglitaj mesaĝoj",
"column.public": "Fratara tempolinio",
"column.status": "Toot",
"column.status": "Mesaĝo",
"column_back_button.label": "Reveni",
"column_header.hide_settings": "Kaŝi agordojn",
"column_header.moveLeft_settings": "Movi kolumnon maldekstren",
@ -79,10 +79,10 @@
"compose_form.lock_disclaimer": "Via konta ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn, kiuj estas nur por sekvantoj.",
"compose_form.lock_disclaimer.lock": "ŝlosita",
"compose_form.placeholder": "Pri kio vi pensas?",
"compose_form.poll.add_option": "Aldoni elekto",
"compose_form.poll.add_option": "Aldoni elekteblon",
"compose_form.poll.duration": "Balotenketa daŭro",
"compose_form.poll.option_placeholder": "elekto {number}",
"compose_form.poll.remove_option": "Forigi ĉi tiu elekton",
"compose_form.poll.option_placeholder": "Elekteblo {number}",
"compose_form.poll.remove_option": "Forigi ĉi tiu elekteblon",
"compose_form.publish": "Hup",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.hide": "Marki la aŭdovidaĵojn kiel tiklaj",
@ -92,7 +92,7 @@
"compose_form.spoiler.unmarked": "Teksto ne kaŝita",
"compose_form.spoiler_placeholder": "Skribu vian averton ĉi tie",
"confirmation_modal.cancel": "Nuligi",
"confirmations.block.block_and_report": "Bloki & Signali",
"confirmations.block.block_and_report": "Bloki kaj signali",
"confirmations.block.confirm": "Bloki",
"confirmations.block.message": "Ĉu vi certas, ke vi volas bloki {name}?",
"confirmations.delete.confirm": "Forigi",
@ -111,10 +111,14 @@
"confirmations.reply.message": "Respondi nun anstataŭigos la mesaĝon, kiun vi nun skribas. Ĉu vi certas, ke vi volas daŭrigi?",
"confirmations.unfollow.confirm": "Ne plu sekvi",
"confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?",
"conversation.delete": "Forigi konversacion",
"conversation.mark_as_read": "Marki legita",
"conversation.open": "Vidi konversacion",
"conversation.with": "Kun {names}",
"directory.federated": "El konata fediverso",
"directory.local": "Nur de {domain}",
"directory.new_arrivals": "Novaj veniĝoj",
"directory.recently_active": "Recently active",
"directory.new_arrivals": "Novaj alvenoj",
"directory.recently_active": "Lastatempe aktiva",
"embed.instructions": "Enkorpigu ĉi tiun mesaĝon en vian retejon per kopio de la suba kodo.",
"embed.preview": "Ĝi aperos tiel:",
"emoji_button.activity": "Agadoj",
@ -166,18 +170,18 @@
"hashtag.column_settings.tag_mode.all": "Ĉiuj",
"hashtag.column_settings.tag_mode.any": "Iu ajn",
"hashtag.column_settings.tag_mode.none": "Neniu",
"hashtag.column_settings.tag_toggle": "Inkluzivi pluajn etikedojn por ĉi tiu kolumno",
"hashtag.column_settings.tag_toggle": "Aldoni pliajn etikedojn por ĉi tiu kolumno",
"home.column_settings.basic": "Bazaj agordoj",
"home.column_settings.show_reblogs": "Montri diskonigojn",
"home.column_settings.show_replies": "Montri respondojn",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Tuje ĝisdatigi",
"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}}",
"introduction.federation.action": "Sekva",
"introduction.federation.federated.headline": "Federacio",
"introduction.federation.federated.headline": "Fratara",
"introduction.federation.federated.text": "Publikaj mesaĝoj el aliaj serviloj de la Fediverse aperos en la fratara tempolinio.",
"introduction.federation.home.headline": "Heimo",
"introduction.federation.home.headline": "Hejmo",
"introduction.federation.home.text": "Mesaĝoj de homoj, kiujn vi sekvas, aperos en via hejma fluo. Vi povas sekvi iun ajn de ajna servilo!",
"introduction.federation.local.headline": "Loka",
"introduction.federation.local.text": "Publikaj mesaĝoj de homoj de via servilo aperos en la loka tempolinio.",
@ -226,7 +230,7 @@
"lightbox.close": "Fermi",
"lightbox.next": "Sekva",
"lightbox.previous": "Antaŭa",
"lightbox.view_context": "Vidi kontekston",
"lightbox.view_context": "Vidi kuntekston",
"lists.account.add": "Aldoni al la listo",
"lists.account.remove": "Forigi de la listo",
"lists.delete": "Forigi la liston",
@ -236,12 +240,12 @@
"lists.new.title_placeholder": "Titolo de la nova listo",
"lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
"lists.subheading": "Viaj listoj",
"load_pending": "{count,plural, one {# nova ero} other {# novaj eroj}}",
"load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}",
"loading_indicator.label": "Ŝargado…",
"media_gallery.toggle_visible": "Baskuligi videblecon",
"missing_indicator.label": "Ne trovita",
"missing_indicator.sublabel": "Ĉi tiu elemento ne estis trovita",
"mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn el ĉi tiu uzanto?",
"mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn de ĉi tiu uzanto?",
"navigation_bar.apps": "Telefonaj aplikaĵoj",
"navigation_bar.blocks": "Blokitaj uzantoj",
"navigation_bar.community_timeline": "Loka tempolinio",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Preferoj",
"navigation_bar.public_timeline": "Fratara tempolinio",
"navigation_bar.security": "Sekureco",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "kaj {count, plural, one {# alia} other {# aliaj}}",
"notification.favourite": "{name} stelumis vian mesaĝon",
"notification.follow": "{name} eksekvis vin",
"notification.mention": "{name} menciis vin",
@ -295,6 +299,7 @@
"poll.refresh": "Aktualigi",
"poll.total_votes": "{count, plural, one {# voĉdono} other {# voĉdonoj}}",
"poll.vote": "Voĉdoni",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Aldoni balotenketon",
"poll_button.remove_poll": "Forigi balotenketon",
"privacy.change": "Agordi mesaĝan privatecon",
@ -335,7 +340,7 @@
"status.admin_account": "Malfermi la kontrolan interfacon por @{name}",
"status.admin_status": "Malfermi ĉi tiun mesaĝon en la kontrola interfaco",
"status.block": "Bloki @{name}",
"status.cancel_reblog_private": "Eksdiskonigi",
"status.cancel_reblog_private": "Ne plu diskonigi",
"status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",
"status.copy": "Kopii la ligilon al la mesaĝo",
"status.delete": "Forigi",
@ -394,19 +399,19 @@
"upload_form.description": "Priskribi por misvidantaj homoj",
"upload_form.edit": "Redakti",
"upload_form.undo": "Forigi",
"upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.analyzing_picture": "Bilda analizado…",
"upload_modal.apply": "Apliki",
"upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "Redakti aŭdvidaĵo",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.description_placeholder": "Laŭ Ludoviko Zamenhof bongustas freŝa ĉeĥa manĝaĵo kun spicoj",
"upload_modal.detect_text": "Detekti tekston de la bildo",
"upload_modal.edit_media": "Redakti aŭdovidaĵon",
"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.preview_label": "Antaŭvido ({ratio})",
"upload_progress.label": "Alŝutado…",
"video.close": "Fermi videon",
"video.close": "Fermi la videon",
"video.exit_fullscreen": "Eksigi plenekrana",
"video.expand": "Grandigi videon",
"video.expand": "Grandigi la videon",
"video.fullscreen": "Igi plenekrana",
"video.hide": "Kaŝi videon",
"video.hide": "Kaŝi la videon",
"video.mute": "Silentigi",
"video.pause": "Paŭzi",
"video.play": "Ekigi",

@ -0,0 +1,419 @@
{
"account.add_or_remove_from_list": "Agregar o quitar de las listas",
"account.badges.bot": "Bot",
"account.block": "Bloquear a @{name}",
"account.block_domain": "Ocultar todo de {domain}",
"account.blocked": "Bloqueado",
"account.cancel_follow_request": "Cancelar la solicitud de seguimiento",
"account.direct": "Mensaje directo a @{name}",
"account.domain_blocked": "Dominio oculto",
"account.edit_profile": "Editar perfil",
"account.endorse": "Destacar en el perfil",
"account.follow": "Seguir",
"account.followers": "Seguidores",
"account.followers.empty": "Todavía nadie sigue a este usuario.",
"account.follows": "Sigue",
"account.follows.empty": "Todavía este usuario no sigue a nadie.",
"account.follows_you": "Te sigue",
"account.hide_reblogs": "Ocultar retoots de @{name}",
"account.last_status": "Última actividad",
"account.link_verified_on": "La propiedad de este enlace fue verificada el {date}",
"account.locked_info": "El estado de privacidad de esta cuenta está establecido como bloqueado. El propietario manualmente revisa quién puede seguirle.",
"account.media": "Medios",
"account.mention": "Mencionar a @{name}",
"account.moved_to": "{name} se ha muó a:",
"account.mute": "Silenciar a @{name}",
"account.mute_notifications": "Silenciar notificaciones de @{name}",
"account.muted": "Silenciado",
"account.never_active": "Nunca",
"account.posts": "Toots",
"account.posts_with_replies": "Toots con respuestas",
"account.report": "Denunciar a @{name}",
"account.requested": "Esperando aprobación. Hacé clic para cancelar la solicitud de seguimiento.",
"account.share": "Compartir el perfil de @{name}",
"account.show_reblogs": "Mostrar retoots de @{name}",
"account.unblock": "Desbloquear a @{name}",
"account.unblock_domain": "Mostrar {domain}",
"account.unendorse": "No destacar en el perfil",
"account.unfollow": "Dejar de seguir",
"account.unmute": "Dejar de silenciar a @{name}",
"account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
"alert.rate_limited.message": "Por favor, reintentá después de las {retry_time, time, medium}.",
"alert.rate_limited.title": "Tarifa limitada",
"alert.unexpected.message": "Ocurrió un error inesperado.",
"alert.unexpected.title": "¡Epa!",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Podés hacer clic en {combo} para saltar esto la próxima vez",
"bundle_column_error.body": "Algo salió mal al cargar este componente.",
"bundle_column_error.retry": "Intentá de nuevo",
"bundle_column_error.title": "Error de red",
"bundle_modal_error.close": "Cerrar",
"bundle_modal_error.message": "Algo salió mal al cargar este componente.",
"bundle_modal_error.retry": "Intentá de nuevo",
"column.blocks": "Usuarios bloqueados",
"column.community": "Línea temporal local",
"column.direct": "Mensajes directos",
"column.directory": "Explorar perfiles",
"column.domain_blocks": "Dominios ocultos",
"column.favourites": "Favoritos",
"column.follow_requests": "Solicitudes de seguimiento",
"column.home": "Principal",
"column.lists": "Listas",
"column.mutes": "Usuarios silenciados",
"column.notifications": "Notificaciones",
"column.pins": "Toots fijados",
"column.public": "Línea temporal federada",
"column.status": "Toot",
"column_back_button.label": "Volver",
"column_header.hide_settings": "Ocultar configuración",
"column_header.moveLeft_settings": "Mover columna a la izquierda",
"column_header.moveRight_settings": "Mover columna a la derecha",
"column_header.pin": "Fijar",
"column_header.show_settings": "Mostrar configuración",
"column_header.unpin": "Dejar de fijar",
"column_subheading.settings": "Configuración",
"community.column_settings.media_only": "Sólo medios",
"compose_form.direct_message_warning": "Este toot sólo será enviado a los usuarios mencionados.",
"compose_form.direct_message_warning_learn_more": "Aprendé más",
"compose_form.hashtag_warning": "Este toot no se mostrará bajo hashtags porque no es público. Sólo los toots públicos se pueden buscar por hashtag.",
"compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus toots marcados como \"sólo para seguidores\".",
"compose_form.lock_disclaimer.lock": "bloqueada",
"compose_form.placeholder": "¿Qué onda?",
"compose_form.poll.add_option": "Agregá una opción",
"compose_form.poll.duration": "Duración de la encuesta",
"compose_form.poll.option_placeholder": "Opción {number}",
"compose_form.poll.remove_option": "Quitá esta opción",
"compose_form.publish": "Tootear",
"compose_form.publish_loud": "¡{publish}!",
"compose_form.sensitive.hide": "Marcar medio como sensible",
"compose_form.sensitive.marked": "El medio se marcó como sensible",
"compose_form.sensitive.unmarked": "El medio no está marcado como sensible",
"compose_form.spoiler.marked": "El texto está oculto detrás de la advertencia",
"compose_form.spoiler.unmarked": "El texto no está oculto",
"compose_form.spoiler_placeholder": "Escribí tu advertencia acá",
"confirmation_modal.cancel": "Cancelar",
"confirmations.block.block_and_report": "Bloquear y denunciar",
"confirmations.block.confirm": "Bloquear",
"confirmations.block.message": "¿Estás seguro que querés bloquear a {name}?",
"confirmations.delete.confirm": "Eliminar",
"confirmations.delete.message": "¿Estás seguro que querés eliminar este estado?",
"confirmations.delete_list.confirm": "Eliminar",
"confirmations.delete_list.message": "¿Estás seguro que querés eliminar permanentemente esta lista?",
"confirmations.domain_block.confirm": "Ocultar dominio entero",
"confirmations.domain_block.message": "¿Estás completamente seguro que querés bloquear el {domain} entero? En la mayoría de los casos, unos cuantos bloqueos y silenciados puntuales son suficientes y preferibles. No vas a ver contenido de ese dominio en ninguna de tus líneas temporales o en tus notificaciones. Tus seguidores de ese dominio serán quitados.",
"confirmations.logout.confirm": "Cerrar sesión",
"confirmations.logout.message": "¿Estás seguro que querés cerrar la sesión?",
"confirmations.mute.confirm": "Silenciar",
"confirmations.mute.message": "¿Estás seguro que querés silenciar a {name}?",
"confirmations.redraft.confirm": "Eliminar toot original y editarlo",
"confirmations.redraft.message": "¿Estás seguro que querés eliminar este estado y volverlo a editarlo? Se perderán las veces marcadas como favoritos y los retoots, y las respuestas a la publicación original quedarán huérfanas.",
"confirmations.reply.confirm": "Responder",
"confirmations.reply.message": "Responder ahora sobreescribirá el mensaje que estás redactando actualmente. ¿Estás seguro que querés seguir?",
"confirmations.unfollow.confirm": "Dejar de seguir",
"confirmations.unfollow.message": "¿Estás seguro que querés dejar de seguir a {name}?",
"conversation.delete": "Eliminar conversación",
"conversation.mark_as_read": "Marcar como leído",
"conversation.open": "Ver conversación",
"conversation.with": "Con {names}",
"directory.federated": "Desde fediverso conocido",
"directory.local": "Sólo de {domain}",
"directory.new_arrivals": "Recién llegados",
"directory.recently_active": "Recientemente activo",
"embed.instructions": "Insertá este toot a tu sitio web copiando el código de abajo.",
"embed.preview": "Así es cómo se verá:",
"emoji_button.activity": "Actividad",
"emoji_button.custom": "Personalizado",
"emoji_button.flags": "Banderas",
"emoji_button.food": "Comida y bebida",
"emoji_button.label": "Insertar emoji",
"emoji_button.nature": "Naturaleza",
"emoji_button.not_found": "¡¡No emojos!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objetos",
"emoji_button.people": "Gente",
"emoji_button.recent": "Usados frecuentemente",
"emoji_button.search": "Buscar…",
"emoji_button.search_results": "Resultados de búsqueda",
"emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Viajes y lugares",
"empty_column.account_timeline": "¡No hay toots aquí!",
"empty_column.account_unavailable": "Perfil no disponible",
"empty_column.blocks": "Todavía no bloqueaste a ningún usuario.",
"empty_column.community": "La línea temporal local está vacía. ¡Escribí algo en modo público para que se empiece a correr la bola!",
"empty_column.direct": "Todavía no tenés ningún mensaje directo. Cuando enviés o recibás uno, se mostrará acá.",
"empty_column.domain_blocks": "Todavía no hay dominios ocultos.",
"empty_column.favourited_statuses": "Todavía no tenés toots favoritos. Cuando marqués uno como favorito, se mostrará acá.",
"empty_column.favourites": "Todavía nadie marcó este toot como favorito. Cuando alguien lo haga, se mostrará acá.",
"empty_column.follow_requests": "Todavía no tenés ninguna solicitud de seguimiento. Cuando recibás una, se mostrará acá.",
"empty_column.hashtag": "Todavía no hay nada con esta etiqueta.",
"empty_column.home": "¡Tu línea temporal principal está vacía! Visitá {public} o usá la búsqueda para comenzar y encontrar a otros usuarios.",
"empty_column.home.public_timeline": "la línea temporal pública",
"empty_column.list": "Todavía no hay nada en esta lista. Cuando miembros de esta lista envíen nuevos toots, se mostrarán acá.",
"empty_column.lists": "Todavía no tienes ninguna lista. Cuando creés una, se mostrará acá.",
"empty_column.mutes": "Todavía no silenciaste a ningún usuario.",
"empty_column.notifications": "Todavía no tenés ninguna notificación. Interactuá con otros para iniciar la conversación.",
"empty_column.public": "¡Naranja! Escribí algo públicamente, o seguí usuarios manualmente de otros servidores para ir llenando esta línea temporal.",
"follow_request.authorize": "Autorizar",
"follow_request.reject": "Rechazar",
"getting_started.developers": "Desarrolladores",
"getting_started.directory": "Directorio de perfiles",
"getting_started.documentation": "Documentación",
"getting_started.heading": "Introducción",
"getting_started.invite": "Invitar usuarios",
"getting_started.open_source_notice": "Mastodon es software libre. Podés contribuir o informar errores en {github}.",
"getting_started.security": "Seguridad",
"getting_started.terms": "Términos del servicio",
"hashtag.column_header.tag_mode.all": "y {additional}",
"hashtag.column_header.tag_mode.any": "o {additional}",
"hashtag.column_header.tag_mode.none": "sin {additional}",
"hashtag.column_settings.select.no_options_message": "No se encontraron sugerencias",
"hashtag.column_settings.select.placeholder": "Introducí etiquetas…",
"hashtag.column_settings.tag_mode.all": "Todas estas",
"hashtag.column_settings.tag_mode.any": "Cualquiera de estas",
"hashtag.column_settings.tag_mode.none": "Ninguna de estas",
"hashtag.column_settings.tag_toggle": "Incluir etiquetas adicionales para esta columna",
"home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar retoots",
"home.column_settings.show_replies": "Mostrar respuestas",
"home.column_settings.update_live": "Actualizar en tiempo real",
"intervals.full.days": "{number, plural, one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
"introduction.federation.action": "Siguiente",
"introduction.federation.federated.headline": "Federado",
"introduction.federation.federated.text": "Los toots públicos de otros servidores del fediverso aparecerán en la línea temporal federada.",
"introduction.federation.home.headline": "Principal",
"introduction.federation.home.text": "Los toots de las personas que seguíss aparecerán en tu línea temporal principal. ¡Podés seguir a cualquiera en cualquier servidor!",
"introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Los toots públicos de las personas en el mismo servidor aparecerán en la línea temporal local.",
"introduction.interactions.action": "¡Terminar tutorial!",
"introduction.interactions.favourite.headline": "Favorito",
"introduction.interactions.favourite.text": "Podés guardar un toot para más tarde, y hacerle saber al autor que te gustó, marcándolo como favorito.",
"introduction.interactions.reblog.headline": "Retootear",
"introduction.interactions.reblog.text": "Podés compartir los toots de otras personas con tus seguidores retooteando los mismos.",
"introduction.interactions.reply.headline": "Responder",
"introduction.interactions.reply.text": "Podés responder a tus propios toots y los de otras personas, que se encadenarán juntos en una conversación.",
"introduction.welcome.action": "¡Dale!",
"introduction.welcome.headline": "Primeros pasos",
"introduction.welcome.text": "¡Bienvenido al fediverso! En unos pocos minutos, vas a poder transmitir mensajes y hablar con tus amigos a través de una amplia variedad de servidores. Pero este servidor, {domain}, es especial: aloja tu perfil, así que acordate de su nombre.",
"keyboard_shortcuts.back": "para volver",
"keyboard_shortcuts.blocked": "para abrir la lista de usuarios bloqueados",
"keyboard_shortcuts.boost": "para retootear",
"keyboard_shortcuts.column": "para enfocar un estado en una de las columnas",
"keyboard_shortcuts.compose": "para enfocar el área de texto de redacción",
"keyboard_shortcuts.description": "Descripción",
"keyboard_shortcuts.direct": "para abrir columna de mensajes directos",
"keyboard_shortcuts.down": "para bajar en la lista",
"keyboard_shortcuts.enter": "para abrir el estado",
"keyboard_shortcuts.favourite": "para marcar como favorito",
"keyboard_shortcuts.favourites": "para abrir la lista de favoritos",
"keyboard_shortcuts.federated": "para abrir la línea temporal federada",
"keyboard_shortcuts.heading": "Atajos de teclado",
"keyboard_shortcuts.home": "para abrir la línea temporal principal",
"keyboard_shortcuts.hotkey": "Combinación",
"keyboard_shortcuts.legend": "para mostrar este texto",
"keyboard_shortcuts.local": "para abrir la línea temporal local",
"keyboard_shortcuts.mention": "para mencionar al autor",
"keyboard_shortcuts.muted": "abrir la lista de usuarios silenciados",
"keyboard_shortcuts.my_profile": "para abrir tu perfil",
"keyboard_shortcuts.notifications": "para abrir la columna de notificaciones",
"keyboard_shortcuts.pinned": "para abrir lista de toots fijados",
"keyboard_shortcuts.profile": "para abrir el perfil del autor",
"keyboard_shortcuts.reply": "para responder",
"keyboard_shortcuts.requests": "para abrir la lista de solicitudes de seguimiento",
"keyboard_shortcuts.search": "para enfocar la búsqueda",
"keyboard_shortcuts.start": "para abrir la columna \"Introducción\"",
"keyboard_shortcuts.toggle_hidden": "para mostrar/ocultar el texto detrás de la advertencia de contenido",
"keyboard_shortcuts.toggle_sensitivity": "para mostrar/ocultar los medios",
"keyboard_shortcuts.toot": "para comenzar un toot nuevo",
"keyboard_shortcuts.unfocus": "para quitar el enfoque del área de texto de redacción o de búsqueda",
"keyboard_shortcuts.up": "para subir en la lista",
"lightbox.close": "Cerrar",
"lightbox.next": "Siguiente",
"lightbox.previous": "Anterior",
"lightbox.view_context": "Ver contexto",
"lists.account.add": "Agregar a lista",
"lists.account.remove": "Quitar de lista",
"lists.delete": "Eliminar lista",
"lists.edit": "Editar lista",
"lists.edit.submit": "Cambiar título",
"lists.new.create": "Agregar lista",
"lists.new.title_placeholder": "Nuevo título de lista",
"lists.search": "Buscar entre la gente que seguís",
"lists.subheading": "Tus listas",
"load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}",
"loading_indicator.label": "Cargando…",
"media_gallery.toggle_visible": "Cambiar visibilidad",
"missing_indicator.label": "No se encontró",
"missing_indicator.sublabel": "No se encontró este recurso",
"mute_modal.hide_notifications": "¿Querés ocultar las notificaciones de este usuario?",
"navigation_bar.apps": "Aplicaciones móviles",
"navigation_bar.blocks": "Usuarios bloqueados",
"navigation_bar.community_timeline": "Línea temporal local",
"navigation_bar.compose": "Redactar un nuevo toot",
"navigation_bar.direct": "Mensajes directos",
"navigation_bar.discover": "Descubrir",
"navigation_bar.domain_blocks": "Dominios ocultos",
"navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Palabras silenciadas",
"navigation_bar.follow_requests": "Solicitudes de seguimiento",
"navigation_bar.follows_and_followers": "Personas seguidas y seguidores",
"navigation_bar.info": "Acerca de este servidor",
"navigation_bar.keyboard_shortcuts": "Atajos",
"navigation_bar.lists": "Listas",
"navigation_bar.logout": "Cerrar sesión",
"navigation_bar.mutes": "Usuarios silenciados",
"navigation_bar.personal": "Personal",
"navigation_bar.pins": "Toots fijados",
"navigation_bar.preferences": "Configuración",
"navigation_bar.public_timeline": "Línea temporal federada",
"navigation_bar.security": "Seguridad",
"notification.and_n_others": "y {count, plural, one {# otro} other {# otros}}",
"notification.favourite": "{name} marcó tu estado como favorito",
"notification.follow": "{name} te empezó a seguir",
"notification.mention": "{name} te mencionó",
"notification.poll": "Finalizó una encuesta en la que votaste",
"notification.reblog": "{name} retooteó tu estado",
"notifications.clear": "Limpiar notificaciones",
"notifications.clear_confirmation": "¿Estás seguro que querés limpiar todas tus notificaciones permanentemente?",
"notifications.column_settings.alert": "Notificaciones de escritorio",
"notifications.column_settings.favourite": "Favoritos:",
"notifications.column_settings.filter_bar.advanced": "Mostrar todas las categorías",
"notifications.column_settings.filter_bar.category": "Barra de filtrado rápido",
"notifications.column_settings.filter_bar.show": "Mostrar",
"notifications.column_settings.follow": "Nuevos seguidores:",
"notifications.column_settings.mention": "Menciones:",
"notifications.column_settings.poll": "Resultados de la encuesta:",
"notifications.column_settings.push": "Notificaciones push",
"notifications.column_settings.reblog": "Retoots:",
"notifications.column_settings.show": "Mostrar en columna",
"notifications.column_settings.sound": "Reproducir sonido",
"notifications.filter.all": "Todas",
"notifications.filter.boosts": "Retoots",
"notifications.filter.favourites": "Favoritos",
"notifications.filter.follows": "Seguidores",
"notifications.filter.mentions": "Menciones",
"notifications.filter.polls": "Resultados de la encuesta",
"notifications.group": "{count} notificaciones",
"poll.closed": "Cerrada",
"poll.refresh": "Refrescar",
"poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
"poll.vote": "Votar",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",
"privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only",
"privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel",
"report.forward": "Forward to {target}",
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
"report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
"report.target": "Report {target}",
"search.placeholder": "Search",
"search_popout.search_format": "Advanced search format",
"search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user",
"search_results.accounts": "People",
"search_results.hashtags": "Hashtags",
"search_results.statuses": "Toots",
"search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.copy": "Copy link to status",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",
"status.filtered": "Filtered",
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.more": "More",
"status.mute": "Mute @{name}",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.read_more": "Read more",
"status.reblog": "Boost",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} boosted",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.reply": "Reply",
"status.replyAll": "Reply to thread",
"status.report": "Report @{name}",
"status.sensitive_warning": "Sensitive content",
"status.share": "Share",
"status.show_less": "Show less",
"status.show_less_all": "Show less for all",
"status.show_more": "Show more",
"status.show_more_all": "Show more for all",
"status.show_thread": "Show thread",
"status.uncached_media_warning": "Not available",
"status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile",
"suggestions.dismiss": "Dismiss suggestion",
"suggestions.header": "You might be interested in…",
"tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home",
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
"time_remaining.days": "{number, plural, one {# day} other {# days}} left",
"time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
"time_remaining.moments": "Moments remaining",
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"trends.trending_now": "Trending now",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media ({formats})",
"upload_error.limit": "File upload limit exceeded.",
"upload_error.poll": "File upload not allowed with polls.",
"upload_form.description": "Describe for the visually impaired",
"upload_form.edit": "Edit",
"upload_form.undo": "Delete",
"upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.apply": "Apply",
"upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "Edit media",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_progress.label": "Uploading...",
"video.close": "Close video",
"video.exit_fullscreen": "Exit full screen",
"video.expand": "Expand video",
"video.fullscreen": "Full screen",
"video.hide": "Hide video",
"video.mute": "Mute sound",
"video.pause": "Pause",
"video.play": "Play",
"video.unmute": "Unmute sound"
}

@ -38,11 +38,11 @@
"account.unfollow": "Dejar de seguir",
"account.unmute": "Dejar de silenciar a @{name}",
"account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.message": "Por favor reintente después de {retry_time, time, medium}.",
"alert.rate_limited.title": "Tarifa limitada",
"alert.unexpected.message": "Hubo un error inesperado.",
"alert.unexpected.title": "¡Ups!",
"autosuggest_hashtag.per_week": "{count} per week",
"autosuggest_hashtag.per_week": "{count} por semana",
"boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez",
"bundle_column_error.body": "Algo salió mal al cargar este componente.",
"bundle_column_error.retry": "Inténtalo de nuevo",
@ -111,6 +111,10 @@
"confirmations.reply.message": "Responder sobrescribirá el mensaje que estás escribiendo. ¿Estás seguro de que deseas continuar?",
"confirmations.unfollow.confirm": "Dejar de seguir",
"confirmations.unfollow.message": "¿Estás seguro de que quieres dejar de seguir a {name}?",
"conversation.delete": "Borrar conversación",
"conversation.mark_as_read": "Marcar como leído",
"conversation.open": "Ver conversación",
"conversation.with": "Con {names}",
"directory.federated": "Desde el fediverso conocido",
"directory.local": "Sólo de {domain}",
"directory.new_arrivals": "Recién llegados",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar retoots",
"home.column_settings.show_replies": "Mostrar respuestas",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Actualizar en tiempo real",
"intervals.full.days": "{number, plural, one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Preferencias",
"navigation_bar.public_timeline": "Historia federada",
"navigation_bar.security": "Seguridad",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "y {count, plural, one {# otro} other {# otros}}",
"notification.favourite": "{name} marcó tu estado como favorito",
"notification.follow": "{name} te empezó a seguir",
"notification.mention": "{name} te ha mencionado",
@ -295,6 +299,7 @@
"poll.refresh": "Actualizar",
"poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
"poll.vote": "Votar",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Añadir una encuesta",
"poll_button.remove_poll": "Eliminar encuesta",
"privacy.change": "Ajustar privacidad",
@ -400,7 +405,7 @@
"upload_modal.detect_text": "Detectar texto de la imagen",
"upload_modal.edit_media": "Editar multimedia",
"upload_modal.hint": "Haga clic o arrastre el círculo en la vista previa para elegir el punto focal que siempre estará a la vista en todas las miniaturas.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_modal.preview_label": "Vista previa ({ratio})",
"upload_progress.label": "Subiendo…",
"video.close": "Cerrar video",
"video.exit_fullscreen": "Salir de pantalla completa",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Kohene vastamine kirjutab üle sõnumi, mida hetkel koostad. Oled kindel, et soovid jätkata?",
"confirmations.unfollow.confirm": "Ära jälgi",
"confirmations.unfollow.message": "Oled kindel, et ei soovi jälgida {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Värskenda",
"poll.total_votes": "{count, plural, one {# hääl} other {# hääli}}",
"poll.vote": "Hääleta",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Lisa küsitlus",
"poll_button.remove_poll": "Eemalda küsitlus",
"privacy.change": "Muuda staatuse privaatsust",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Orain erantzuteak idazten ari zaren mezua gainidatziko du. Ziur jarraitu nahi duzula?",
"confirmations.unfollow.confirm": "Utzi jarraitzeari",
"confirmations.unfollow.message": "Ziur {name} jarraitzeari utzi nahi diozula?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "Fedibertso ezagunekoak",
"directory.local": "{domain} domeinukoak soilik",
"directory.new_arrivals": "Iritsi berriak",
@ -295,6 +299,7 @@
"poll.refresh": "Berritu",
"poll.total_votes": "{count, plural, one {boto #} other {# boto}}",
"poll.vote": "Bozkatu",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Gehitu inkesta bat",
"poll_button.remove_poll": "Kendu inkesta",
"privacy.change": "Doitu mezuaren pribatutasuna",

@ -3,7 +3,7 @@
"account.badges.bot": "ربات",
"account.block": "مسدودسازی @{name}",
"account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}",
"account.blocked": "مسدودشده",
"account.blocked": "مسدود شده",
"account.cancel_follow_request": "لغو درخواست پیگیری",
"account.direct": "پیغام خصوصی به @{name}",
"account.domain_blocked": "دامین پنهان‌شده",
@ -16,7 +16,7 @@
"account.follows.empty": "این کاربر هنوز هیچ کسی را پی نمی‌گیرد.",
"account.follows_you": "پیگیر شماست",
"account.hide_reblogs": "پنهان کردن بازبوق‌های @{name}",
"account.last_status": "Last active",
"account.last_status": "آخرین فعالیت",
"account.link_verified_on": "مالکیت این نشانی در تاریخ {date} بررسی شد",
"account.locked_info": "این حساب خصوصی است. صاحب این حساب تصمیم می‌گیرد که چه کسی می‌تواند پیگیرش باشد.",
"account.media": "عکس و ویدیو",
@ -25,7 +25,7 @@
"account.mute": "بی‌صدا کردن @{name}",
"account.mute_notifications": "بی‌صداکردن اعلان‌ها از طرف @{name}",
"account.muted": "بی‌صداشده",
"account.never_active": "Never",
"account.never_active": "هرگز",
"account.posts": "نوشته‌ها",
"account.posts_with_replies": "نوشته‌ها و پاسخ‌ها",
"account.report": "گزارش @{name}",
@ -38,8 +38,8 @@
"account.unfollow": "پایان پیگیری",
"account.unmute": "باصدا کردن @{name}",
"account.unmute_notifications": "باصداکردن اعلان‌ها از طرف @{name}",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.rate_limited.message": "لطفاً پس از {retry_time, time, medium} دوباره تلاش کنید.",
"alert.rate_limited.title": "محدودیت تعداد",
"alert.unexpected.message": "خطای پیش‌بینی‌نشده‌ای رخ داد.",
"alert.unexpected.title": "ای وای!",
"autosuggest_hashtag.per_week": "{count} در هفته",
@ -53,7 +53,7 @@
"column.blocks": "کاربران مسدودشده",
"column.community": "نوشته‌های محلی",
"column.direct": "پیغام‌های خصوصی",
"column.directory": "Browse profiles",
"column.directory": "مرور نمایه‌ها",
"column.domain_blocks": "دامین‌های پنهان‌شده",
"column.favourites": "پسندیده‌ها",
"column.follow_requests": "درخواست‌های پیگیری",
@ -63,7 +63,7 @@
"column.notifications": "اعلان‌ها",
"column.pins": "نوشته‌های ثابت",
"column.public": "نوشته‌های همه‌جا",
"column.status": "Toot",
"column.status": "بوق",
"column_back_button.label": "بازگشت",
"column_header.hide_settings": "نهفتن تنظیمات",
"column_header.moveLeft_settings": "انتقال ستون به راست",
@ -101,8 +101,8 @@
"confirmations.delete_list.message": "آیا واقعاً می‌خواهید این فهرست را برای همیشه پاک کنید؟",
"confirmations.domain_block.confirm": "پنهان‌سازی کل دامین",
"confirmations.domain_block.message": "آیا جدی جدی می‌خواهید کل دامین {domain} را مسدود کنید؟ بیشتر وقت‌ها مسدودکردن یا بی‌صداکردن چند حساب کاربری خاص کافی است و توصیه می‌شود. پس از این کار شما هیچ نوشته‌ای را از این دامین در فهرست نوشته‌های عمومی یا اعلان‌هایتان نخواهید دید. پیگیران شما از این دامین هم حذف خواهد شد.",
"confirmations.logout.confirm": "Log out",
"confirmations.logout.message": "Are you sure you want to log out?",
"confirmations.logout.confirm": "خروج",
"confirmations.logout.message": "آیا مطمئنید که می‌خواهید خارج شوید؟",
"confirmations.mute.confirm": "بی‌صدا کن",
"confirmations.mute.message": "آیا واقعاً می‌خواهید {name} را بی‌صدا کنید؟",
"confirmations.redraft.confirm": "پاک‌کردن و بازنویسی",
@ -111,10 +111,14 @@
"confirmations.reply.message": "اگر الان پاسخ دهید، چیزی که در حال نوشتنش بودید پاک خواهد شد. آیا همین را می‌خواهید؟",
"confirmations.unfollow.confirm": "لغو پیگیری",
"confirmations.unfollow.message": "آیا واقعاً می‌خواهید به پیگیری از {name} پایان دهید؟",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
"directory.recently_active": "Recently active",
"conversation.delete": "حذف گفتگو",
"conversation.mark_as_read": "علامت‌گذاری به عنوان خوانده شده",
"conversation.open": "دیدن گفتگو",
"conversation.with": "با {names}",
"directory.federated": "از سرورهای همسایه",
"directory.local": "تنها از {domain}",
"directory.new_arrivals": "تازه‌واردان",
"directory.recently_active": "کاربران فعال اخیر",
"embed.instructions": "برای جاگذاری این نوشته در سایت خودتان، کد زیر را کپی کنید.",
"embed.preview": "نوشتهٔ جاگذاری‌شده این گونه به نظر خواهد رسید:",
"emoji_button.activity": "فعالیت",
@ -170,7 +174,7 @@
"home.column_settings.basic": "اصلی",
"home.column_settings.show_reblogs": "نمایش بازبوق‌ها",
"home.column_settings.show_replies": "نمایش پاسخ‌ها",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "به‌روزرسانی لحظه‌ای",
"intervals.full.days": "{number, plural, one {# روز} other {# روز}}",
"intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}",
"intervals.full.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "ترجیحات",
"navigation_bar.public_timeline": "نوشته‌های همه‌جا",
"navigation_bar.security": "امنیت",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "و {count, plural, one {# اعلان دیگر} other {# اعلان دیگر}}",
"notification.favourite": "{name} نوشتهٔ شما را پسندید",
"notification.follow": "{name} پیگیر شما شد",
"notification.mention": "{name} از شما نام برد",
@ -295,6 +299,7 @@
"poll.refresh": "به‌روزرسانی",
"poll.total_votes": "{count, plural, one {# رأی} other {# رأی}}",
"poll.vote": "رأی",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "افزودن نظرسنجی",
"poll_button.remove_poll": "حذف نظرسنجی",
"privacy.change": "تنظیم حریم خصوصی نوشته‌ها",
@ -369,7 +374,7 @@
"status.show_more": "نمایش",
"status.show_more_all": "نمایش بیشتر همه",
"status.show_thread": "نمایش گفتگو",
"status.uncached_media_warning": "Not available",
"status.uncached_media_warning": "ناموجود",
"status.unmute_conversation": "باصداکردن گفتگو",
"status.unpin": "برداشتن نوشتهٔ ثابت نمایه",
"suggestions.dismiss": "پیشنهاد را نادیده بگیر",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Jos vastaat nyt, vastaus korvaa tällä hetkellä työstämäsi viestin. Oletko varma, että haluat jatkaa?",
"confirmations.unfollow.confirm": "Lakkaa seuraamasta",
"confirmations.unfollow.message": "Haluatko varmasti lakata seuraamasta käyttäjää {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Säädä tuuttauksen näkyvyyttä",

@ -39,7 +39,7 @@
"account.unmute": "Ne plus masquer @{name}",
"account.unmute_notifications": "Réactiver les notifications de @{name}",
"alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.",
"alert.rate_limited.title": "Taux limité",
"alert.rate_limited.title": "Débit limité",
"alert.unexpected.message": "Une erreur inattendue sest produite.",
"alert.unexpected.title": "Oups!",
"autosuggest_hashtag.per_week": "{count} par semaine",
@ -63,19 +63,19 @@
"column.notifications": "Notifications",
"column.pins": "Pouets épinglés",
"column.public": "Fil public global",
"column.status": "Toot",
"column.status": "Pouet",
"column_back_button.label": "Retour",
"column_header.hide_settings": "Masquer les paramètres",
"column_header.moveLeft_settings": "Déplacer la colonne vers la gauche",
"column_header.moveRight_settings": "Déplacer la colonne vers la droite",
"column_header.pin": "Épingler",
"column_header.show_settings": "Afficher les paramètres",
"column_header.unpin": "Retirer",
"column_header.unpin": "Désépingler",
"column_subheading.settings": "Paramètres",
"community.column_settings.media_only": "Média uniquement",
"compose_form.direct_message_warning": "Ce pouet sera uniquement envoyé aux personnes mentionnées. Cependant, ladministration de votre instance et des instances réceptrices pourront inspecter ce message.",
"compose_form.direct_message_warning_learn_more": "En savoir plus",
"compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur \"non listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par hashtag.",
"compose_form.direct_message_warning_learn_more": "Plus d'informations",
"compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par mot-clé car sa visibilité est réglée sur \"non listé\". Seuls les pouets avec une visibilité \"publique\" peuvent être recherchés par mot-clé.",
"compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
"compose_form.lock_disclaimer.lock": "verrouillé",
"compose_form.placeholder": "Quavez-vous en tête?",
@ -87,7 +87,7 @@
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.hide": "Marquer le média comme sensible",
"compose_form.sensitive.marked": "Média marqué comme sensible",
"compose_form.sensitive.unmarked": "Média non marqué comme sensible",
"compose_form.sensitive.unmarked": "Le média n'est pas marqué comme sensible",
"compose_form.spoiler.marked": "Le texte est caché derrière un avertissement",
"compose_form.spoiler.unmarked": "Le texte nest pas caché",
"compose_form.spoiler_placeholder": "Écrivez ici votre avertissement",
@ -104,13 +104,17 @@
"confirmations.logout.confirm": "Déconnexion",
"confirmations.logout.message": "Êtes-vous sûr de vouloir vous déconnecter ?",
"confirmations.mute.confirm": "Masquer",
"confirmations.mute.message": "Confirmez-vous le masquage de {name}?",
"confirmations.mute.message": "Êtes-vous sûr·e de vouloir masquer {name} ?",
"confirmations.redraft.confirm": "Effacer et ré-écrire",
"confirmations.redraft.message": "Êtes-vous sûr·e de vouloir effacer ce statut pour le ré-écrire? Ses partages ainsi que ses mises en favori seront perdu·e·s et ses réponses seront orphelines.",
"confirmations.reply.confirm": "Répondre",
"confirmations.reply.message": "Répondre maintenant écrasera le message que vous êtes en train de composer. Voulez-vous vraiment continuer ?",
"confirmations.unfollow.confirm": "Ne plus suivre",
"confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name}?",
"conversation.delete": "Supprimer la conversation",
"conversation.mark_as_read": "Marquer comme lu",
"conversation.open": "Afficher la conversation",
"conversation.with": "Avec {names}",
"directory.federated": "De la fédiverse connue",
"directory.local": "De {domain} seulement",
"directory.new_arrivals": "Nouveaux arrivants",
@ -147,7 +151,7 @@
"empty_column.lists": "Vous navez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.",
"empty_column.mutes": "Vous navez pas encore mis d'utilisateur·rice·s en silence.",
"empty_column.notifications": "Vous navez pas encore de notification. Interagissez avec dautres personnes pour débuter la conversation.",
"empty_column.public": "Il ny a rien ici! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes dautres instances pour remplir le fil public",
"empty_column.public": "Il ny a rien ici! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes dautres instances pour le remplir",
"follow_request.authorize": "Accepter",
"follow_request.reject": "Rejeter",
"getting_started.developers": "Développeur·euse·s",
@ -162,15 +166,15 @@
"hashtag.column_header.tag_mode.any": "ou {additional}",
"hashtag.column_header.tag_mode.none": "sans {additional}",
"hashtag.column_settings.select.no_options_message": "Aucune suggestion trouvée",
"hashtag.column_settings.select.placeholder": "Ajouter des hashtags…",
"hashtag.column_settings.select.placeholder": "Ajouter des mots-clés…",
"hashtag.column_settings.tag_mode.all": "Tous ces éléments",
"hashtag.column_settings.tag_mode.any": "Au moins un de ces éléments",
"hashtag.column_settings.tag_mode.none": "Aucun de ces éléments",
"hashtag.column_settings.tag_toggle": "Inclure des tags additionnels dans cette colonne",
"home.column_settings.basic": "Basique",
"hashtag.column_settings.tag_toggle": "Inclure des mots-clés additionnels dans cette colonne",
"home.column_settings.basic": "Base",
"home.column_settings.show_reblogs": "Afficher les partages",
"home.column_settings.show_replies": "Afficher les réponses",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Mettre à jour en temps réel",
"intervals.full.days": "{number, plural, one {# jour} other {# jours}}",
"intervals.full.hours": "{number, plural, one {# heure} other {# heures}}",
"intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
@ -195,7 +199,7 @@
"keyboard_shortcuts.blocked": "pour ouvrir une liste dutilisateur·rice·s bloqué·e·s",
"keyboard_shortcuts.boost": "pour partager",
"keyboard_shortcuts.column": "pour focaliser un statut dans lune des colonnes",
"keyboard_shortcuts.compose": "pour centrer la zone de rédaction",
"keyboard_shortcuts.compose": "pour focaliser la zone de rédaction",
"keyboard_shortcuts.description": "Description",
"keyboard_shortcuts.direct": "pour ouvrir une colonne des messages directs",
"keyboard_shortcuts.down": "pour descendre dans la liste",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Préférences",
"navigation_bar.public_timeline": "Fil public global",
"navigation_bar.security": "Sécurité",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "et {count, plural, one {# autre} other {# autres}}",
"notification.favourite": "{name} a ajouté à ses favoris:",
"notification.follow": "{name} vous suit",
"notification.mention": "{name} vous a mentionné:",
@ -295,6 +299,7 @@
"poll.refresh": "Actualiser",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Voter",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Ajouter un sondage",
"poll_button.remove_poll": "Supprimer le sondage",
"privacy.change": "Ajuster la confidentialité du message",

@ -1 +1,419 @@
{}
{
"account.add_or_remove_from_list": "Add or Remove from lists",
"account.badges.bot": "Bot",
"account.block": "Block @{name}",
"account.block_domain": "Hide everything from {domain}",
"account.blocked": "Blocked",
"account.cancel_follow_request": "Cancel follow request",
"account.direct": "Direct message @{name}",
"account.domain_blocked": "Domain hidden",
"account.edit_profile": "Edit profile",
"account.endorse": "Feature on profile",
"account.follow": "Follow",
"account.followers": "Followers",
"account.followers.empty": "No one follows this user yet.",
"account.follows": "Follows",
"account.follows.empty": "This user doesn't follow anyone yet.",
"account.follows_you": "Follows you",
"account.hide_reblogs": "Hide boosts from @{name}",
"account.last_status": "Last active",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
"account.media": "Media",
"account.mention": "Mention @{name}",
"account.moved_to": "{name} has moved to:",
"account.mute": "Mute @{name}",
"account.mute_notifications": "Mute notifications from @{name}",
"account.muted": "Muted",
"account.never_active": "Never",
"account.posts": "Toots",
"account.posts_with_replies": "Toots and replies",
"account.report": "Report @{name}",
"account.requested": "Awaiting approval",
"account.share": "Share @{name}'s profile",
"account.show_reblogs": "Show boosts from @{name}",
"account.unblock": "Unblock @{name}",
"account.unblock_domain": "Unhide {domain}",
"account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}",
"account.unmute_notifications": "Unmute notifications from @{name}",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"autosuggest_hashtag.per_week": "{count} per week",
"boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again",
"bundle_column_error.title": "Network error",
"bundle_modal_error.close": "Close",
"bundle_modal_error.message": "Something went wrong while loading this component.",
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.directory": "Browse profiles",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
"column.lists": "Lists",
"column.mutes": "Muted users",
"column.notifications": "Notifications",
"column.pins": "Pinned toot",
"column.public": "Federated timeline",
"column.status": "Toot",
"column_back_button.label": "Back",
"column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left",
"column_header.moveRight_settings": "Move column to the right",
"column_header.pin": "Pin",
"column_header.show_settings": "Show settings",
"column_header.unpin": "Unpin",
"column_subheading.settings": "Settings",
"community.column_settings.media_only": "Media only",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.",
"compose_form.direct_message_warning_learn_more": "Learn more",
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "locked",
"compose_form.placeholder": "What is on your mind?",
"compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice",
"compose_form.publish": "Toot",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.hide": "Mark media as sensitive",
"compose_form.sensitive.marked": "Media is marked as sensitive",
"compose_form.sensitive.unmarked": "Media is not marked as sensitive",
"compose_form.spoiler.marked": "Text is hidden behind warning",
"compose_form.spoiler.unmarked": "Text is not hidden",
"compose_form.spoiler_placeholder": "Write your warning here",
"confirmation_modal.cancel": "Cancel",
"confirmations.block.block_and_report": "Block & Report",
"confirmations.block.confirm": "Block",
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
"confirmations.delete_list.confirm": "Delete",
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
"confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
"confirmations.logout.confirm": "Log out",
"confirmations.logout.message": "Are you sure you want to log out?",
"confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"confirmations.redraft.confirm": "Delete & redraft",
"confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
"confirmations.reply.confirm": "Reply",
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
"directory.recently_active": "Recently active",
"embed.instructions": "Embed this status on your website by copying the code below.",
"embed.preview": "Here is what it will look like:",
"emoji_button.activity": "Activity",
"emoji_button.custom": "Custom",
"emoji_button.flags": "Flags",
"emoji_button.food": "Food & Drink",
"emoji_button.label": "Insert emoji",
"emoji_button.nature": "Nature",
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objects",
"emoji_button.people": "People",
"emoji_button.recent": "Frequently used",
"emoji_button.search": "Search...",
"emoji_button.search_results": "Search results",
"emoji_button.symbols": "Symbols",
"emoji_button.travel": "Travel & Places",
"empty_column.account_timeline": "No toots here!",
"empty_column.account_unavailable": "Profile unavailable",
"empty_column.blocks": "You haven't blocked any users yet.",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.domain_blocks": "There are no hidden domains yet.",
"empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
"empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
"empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.public_timeline": "the public timeline",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.",
"empty_column.mutes": "You haven't muted any users yet.",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up",
"follow_request.authorize": "Authorize",
"follow_request.reject": "Reject",
"getting_started.developers": "Developers",
"getting_started.directory": "Profile directory",
"getting_started.documentation": "Documentation",
"getting_started.heading": "Getting started",
"getting_started.invite": "Invite people",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
"getting_started.security": "Security",
"getting_started.terms": "Terms of service",
"hashtag.column_header.tag_mode.all": "and {additional}",
"hashtag.column_header.tag_mode.any": "or {additional}",
"hashtag.column_header.tag_mode.none": "without {additional}",
"hashtag.column_settings.select.no_options_message": "No suggestions found",
"hashtag.column_settings.select.placeholder": "Enter hashtags…",
"hashtag.column_settings.tag_mode.all": "All of these",
"hashtag.column_settings.tag_mode.any": "Any of these",
"hashtag.column_settings.tag_mode.none": "None of these",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"home.column_settings.basic": "Basic",
"home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies",
"home.column_settings.update_live": "Update in real-time",
"intervals.full.days": "{number, plural, one {# day} other {# days}}",
"intervals.full.hours": "{number, plural, one {# hour} other {# hours}}",
"intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
"introduction.federation.action": "Next",
"introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
"introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
"introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
"introduction.interactions.action": "Finish toot-orial!",
"introduction.interactions.favourite.headline": "Favourite",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
"introduction.interactions.reblog.headline": "Boost",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
"introduction.interactions.reply.headline": "Reply",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
"introduction.welcome.action": "Let's go!",
"introduction.welcome.headline": "First steps",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
"keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.column": "to focus a status in one of the columns",
"keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "Description",
"keyboard_shortcuts.direct": "to open direct messages column",
"keyboard_shortcuts.down": "to move down in the list",
"keyboard_shortcuts.enter": "to open status",
"keyboard_shortcuts.favourite": "to favourite",
"keyboard_shortcuts.favourites": "to open favourites list",
"keyboard_shortcuts.federated": "to open federated timeline",
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
"keyboard_shortcuts.home": "to open home timeline",
"keyboard_shortcuts.hotkey": "Hotkey",
"keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author",
"keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column",
"keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.reply": "to reply",
"keyboard_shortcuts.requests": "to open follow requests list",
"keyboard_shortcuts.search": "to focus search",
"keyboard_shortcuts.start": "to open \"get started\" column",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
"keyboard_shortcuts.toot": "to start a brand new toot",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "Close",
"lightbox.next": "Next",
"lightbox.previous": "Previous",
"lightbox.view_context": "View context",
"lists.account.add": "Add to list",
"lists.account.remove": "Remove from list",
"lists.delete": "Delete list",
"lists.edit": "Edit list",
"lists.edit.submit": "Change title",
"lists.new.create": "Add list",
"lists.new.title_placeholder": "New list title",
"lists.search": "Search among people you follow",
"lists.subheading": "Your lists",
"load_pending": "{count, plural, one {# new item} other {# new items}}",
"loading_indicator.label": "Loading...",
"media_gallery.toggle_visible": "Toggle visibility",
"missing_indicator.label": "Not found",
"missing_indicator.sublabel": "This resource could not be found",
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
"navigation_bar.filters": "Muted words",
"navigation_bar.follow_requests": "Follow requests",
"navigation_bar.follows_and_followers": "Follows and followers",
"navigation_bar.info": "About this server",
"navigation_bar.keyboard_shortcuts": "Hotkeys",
"navigation_bar.lists": "Lists",
"navigation_bar.logout": "Logout",
"navigation_bar.mutes": "Muted users",
"navigation_bar.personal": "Personal",
"navigation_bar.pins": "Pinned toots",
"navigation_bar.preferences": "Preferences",
"navigation_bar.public_timeline": "Federated timeline",
"navigation_bar.security": "Security",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.favourite": "{name} favourited your status",
"notification.follow": "{name} followed you",
"notification.mention": "{name} mentioned you",
"notification.poll": "A poll you have voted in has ended",
"notification.reblog": "{name} boosted your status",
"notifications.clear": "Clear notifications",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
"notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favourites:",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.filter_bar.show": "Show",
"notifications.column_settings.follow": "New followers:",
"notifications.column_settings.mention": "Mentions:",
"notifications.column_settings.poll": "Poll results:",
"notifications.column_settings.push": "Push notifications",
"notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column",
"notifications.column_settings.sound": "Play sound",
"notifications.filter.all": "All",
"notifications.filter.boosts": "Boosts",
"notifications.filter.favourites": "Favourites",
"notifications.filter.follows": "Follows",
"notifications.filter.mentions": "Mentions",
"notifications.filter.polls": "Poll results",
"notifications.group": "{count} notifications",
"poll.closed": "Closed",
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",
"privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only",
"privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel",
"report.forward": "Forward to {target}",
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
"report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:",
"report.placeholder": "Additional comments",
"report.submit": "Submit",
"report.target": "Report {target}",
"search.placeholder": "Search",
"search_popout.search_format": "Advanced search format",
"search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
"search_popout.tips.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user",
"search_results.accounts": "People",
"search_results.hashtags": "Hashtags",
"search_results.statuses": "Toots",
"search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.copy": "Copy link to status",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",
"status.filtered": "Filtered",
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.more": "More",
"status.mute": "Mute @{name}",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.read_more": "Read more",
"status.reblog": "Boost",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} boosted",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.reply": "Reply",
"status.replyAll": "Reply to thread",
"status.report": "Report @{name}",
"status.sensitive_warning": "Sensitive content",
"status.share": "Share",
"status.show_less": "Show less",
"status.show_less_all": "Show less for all",
"status.show_more": "Show more",
"status.show_more_all": "Show more for all",
"status.show_thread": "Show thread",
"status.uncached_media_warning": "Not available",
"status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile",
"suggestions.dismiss": "Dismiss suggestion",
"suggestions.header": "You might be interested in…",
"tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home",
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
"time_remaining.days": "{number, plural, one {# day} other {# days}} left",
"time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left",
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left",
"time_remaining.moments": "Moments remaining",
"time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"trends.trending_now": "Trending now",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media ({formats})",
"upload_error.limit": "File upload limit exceeded.",
"upload_error.poll": "File upload not allowed with polls.",
"upload_form.description": "Describe for the visually impaired",
"upload_form.edit": "Edit",
"upload_form.undo": "Delete",
"upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.apply": "Apply",
"upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "Edit media",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_progress.label": "Uploading...",
"video.close": "Close video",
"video.exit_fullscreen": "Exit full screen",
"video.expand": "Expand video",
"video.fullscreen": "Full screen",
"video.hide": "Hide video",
"video.mute": "Mute sound",
"video.pause": "Pause",
"video.play": "Play",
"video.unmute": "Unmute sound"
}

@ -111,6 +111,10 @@
"confirmations.reply.message": "Respostando agora sobreescribirá a mensaxe que está a compoñer. Segura de querer proceder?",
"confirmations.unfollow.confirm": "Deixar de seguir",
"confirmations.unfollow.message": "Quere deixar de seguir a {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "Desde o fediverso coñecido",
"directory.local": "Só desde {domain}",
"directory.new_arrivals": "Novas achegas",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar repeticións",
"home.column_settings.show_replies": "Mostrar respostas",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Actualizar en tempo real",
"intervals.full.days": "{number, plural,one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Preferencias",
"navigation_bar.public_timeline": "Liña temporal federada",
"navigation_bar.security": "Seguridade",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "e {count, plural, one {# outro} other {# outros}}",
"notification.favourite": "{name} marcou como favorito o seu estado",
"notification.follow": "{name} está a seguila",
"notification.mention": "{name} mencionoute",
@ -295,6 +299,7 @@
"poll.refresh": "Actualizar",
"poll.total_votes": "{count, plural, one {# voto} outros {# votos}}",
"poll.vote": "Votar",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Engadir sondaxe",
"poll_button.remove_poll": "Eliminar sondaxe",
"privacy.change": "Axustar a intimidade do estado",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "להפסיק מעקב",
"confirmations.unfollow.message": "להפסיק מעקב אחרי {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "שינוי פרטיות ההודעה",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Adjust status privacy",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Podesi status privatnosti",

@ -4,7 +4,7 @@
"account.block": "@{name} letiltása",
"account.block_domain": "Minden elrejtése innen: {domain}",
"account.blocked": "Letiltva",
"account.cancel_follow_request": "Cancel follow request",
"account.cancel_follow_request": "Követési kérelem törlése",
"account.direct": "Közvetlen üzenet @{name} számára",
"account.domain_blocked": "Rejtett domain",
"account.edit_profile": "Profil szerkesztése",
@ -16,7 +16,7 @@
"account.follows.empty": "Ez a felhasználó még senkit sem követ.",
"account.follows_you": "Követ téged",
"account.hide_reblogs": "@{name} megtolásainak némítása",
"account.last_status": "Last active",
"account.last_status": "Utoljára aktív",
"account.link_verified_on": "A linket ellenőriztük: {date}",
"account.locked_info": "Ez a fiók zárt. A tulaj engedélyezi, ki követheti őt.",
"account.media": "Média",
@ -25,7 +25,7 @@
"account.mute": "@{name} némítása",
"account.mute_notifications": "@{name} értesítéseinek némítása",
"account.muted": "Némítva",
"account.never_active": "Never",
"account.never_active": "Soha",
"account.posts": "Tülkölés",
"account.posts_with_replies": "Tülkölés válaszokkal",
"account.report": "@{name} jelentése",
@ -38,11 +38,11 @@
"account.unfollow": "Követés vége",
"account.unmute": "@{name} némítás feloldása",
"account.unmute_notifications": "@{name} némított értesítéseinek feloldása",
"alert.rate_limited.message": "Please retry after {retry_time, time, medium}.",
"alert.rate_limited.title": "Rate limited",
"alert.rate_limited.message": "Kérlek, próbáld újra {retry_time, time, medium}.",
"alert.rate_limited.title": "Forgalomkorlátozás",
"alert.unexpected.message": "Váratlan hiba történt.",
"alert.unexpected.title": "Hoppá!",
"autosuggest_hashtag.per_week": "{count} per week",
"autosuggest_hashtag.per_week": "{count}/hét",
"boost_modal.combo": "Hogy átugord ezt következő alkalommal, használd {combo}",
"bundle_column_error.body": "Hiba történt a komponens betöltése közben.",
"bundle_column_error.retry": "Próbáld újra",
@ -53,7 +53,7 @@
"column.blocks": "Letiltott felhasználók",
"column.community": "Helyi idővonal",
"column.direct": "Közvetlen üzenetek",
"column.directory": "Browse profiles",
"column.directory": "Profilok böngészése",
"column.domain_blocks": "Rejtett domainek",
"column.favourites": "Kedvencek",
"column.follow_requests": "Követési kérelmek",
@ -63,7 +63,7 @@
"column.notifications": "Értesítések",
"column.pins": "Kitűzött tülkök",
"column.public": "Nyilvános idővonal",
"column.status": "Toot",
"column.status": "Tülk",
"column_back_button.label": "Vissza",
"column_header.hide_settings": "Beállítások elrejtése",
"column_header.moveLeft_settings": "Oszlop elmozdítása balra",
@ -101,8 +101,8 @@
"confirmations.delete_list.message": "Biztos, hogy véglegesen törölni szeretnéd ezt a listát?",
"confirmations.domain_block.confirm": "Teljes domain elrejtése",
"confirmations.domain_block.message": "Egészen biztos, hogy le szeretnéd tiltani a teljes {domain}-t? A legtöbb esetben néhány célzott tiltás vagy némítás elegendő és kívánatosabb megoldás. Semmilyen tartalmat nem fogsz látni ebből a domainből se idővonalakon, se értesítésekben. Az ebben a domainben lévő követőidet is eltávolítjuk.",
"confirmations.logout.confirm": "Log out",
"confirmations.logout.message": "Are you sure you want to log out?",
"confirmations.logout.confirm": "Kijelentkezés",
"confirmations.logout.message": "Biztosan ki akar jelentkezni?",
"confirmations.mute.confirm": "Némítás",
"confirmations.mute.message": "Biztos, hogy némítani szeretnéd {name}?",
"confirmations.redraft.confirm": "Törlés és újraírás",
@ -111,10 +111,14 @@
"confirmations.reply.message": "Ha most válaszolsz, ez felülírja a most szerkesztés alatt álló üzenetet. Mégis ezt szeretnéd?",
"confirmations.unfollow.confirm": "Követés visszavonása",
"confirmations.unfollow.message": "Biztos, hogy vissza szeretnéd vonni {name} követését?",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
"directory.recently_active": "Recently active",
"conversation.delete": "Beszélgetés törlése",
"conversation.mark_as_read": "Megjelölés olvasottként",
"conversation.open": "Beszélgetés megtekintése",
"conversation.with": "{names}-el/al",
"directory.federated": "Az ismert fediverzumból",
"directory.local": "Csak {domain}-ból/ből",
"directory.new_arrivals": "Új csatlakozók",
"directory.recently_active": "Nemrég aktív",
"embed.instructions": "Ágyazd be ezt a tülköt a weboldaladba az alábbi kód kimásolásával.",
"embed.preview": "Így fog kinézni:",
"emoji_button.activity": "Aktivitás",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Alapértelmezések",
"home.column_settings.show_reblogs": "Megtolások mutatása",
"home.column_settings.show_replies": "Válaszok mutatása",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Frissítés valós időben",
"intervals.full.days": "{number, plural, one {# nap} other {# nap}}",
"intervals.full.hours": "{number, plural, one {# óra} other {# óra}}",
"intervals.full.minutes": "{number, plural, one {# perc} other {# perc}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Beállítások",
"navigation_bar.public_timeline": "Föderációs idővonal",
"navigation_bar.security": "Biztonság",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "és {count, plural, one {# másik} other {# másik}}",
"notification.favourite": "{name} kedvencnek jelölte egy tülködet",
"notification.follow": "{name} követ téged",
"notification.mention": "{name} megemlített",
@ -295,6 +299,7 @@
"poll.refresh": "Frissítés",
"poll.total_votes": "{count, plural, one {# szavazat} other {# szavazat}}",
"poll.vote": "Szavazás",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Új szavazás",
"poll_button.remove_poll": "Szavazás törlése",
"privacy.change": "Tülk láthatóságának módosítása",
@ -369,7 +374,7 @@
"status.show_more": "Többet",
"status.show_more_all": "Többet mindenhol",
"status.show_thread": "Szál mutatása",
"status.uncached_media_warning": "Not available",
"status.uncached_media_warning": "Nem elérhető",
"status.unmute_conversation": "Beszélgetés némításának kikapcsolása",
"status.unpin": "Kitűzés eltávolítása a profilodról",
"suggestions.dismiss": "Javaslat elvetése",
@ -385,22 +390,22 @@
"time_remaining.moments": "Pillanatok vannak hátra",
"time_remaining.seconds": "{number, plural, one {# másodperc} other {# másodperc}} van hátra",
"trends.count_by_accounts": "{count} {rawCount, plural, one {résztvevő} other {résztvevő}} beszélget",
"trends.trending_now": "Trending now",
"trends.trending_now": "Most trendi",
"ui.beforeunload": "A piszkozatod el fog veszni, ha elhagyod a Mastodon-t.",
"upload_area.title": "Húzd ide a feltöltéshez",
"upload_button.label": "Média hozzáadása (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_error.limit": "Túllépted a fájl feltöltési limitet.",
"upload_error.poll": "Szavazásnál nem lehet fájlt feltölteni.",
"upload_form.description": "Leírás látáskorlátozottak számára",
"upload_form.edit": "Edit",
"upload_form.edit": "Szerkesztés",
"upload_form.undo": "Mégsem",
"upload_modal.analyzing_picture": "Analyzing picture…",
"upload_modal.apply": "Apply",
"upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog",
"upload_modal.detect_text": "Detect text from picture",
"upload_modal.edit_media": "Edit media",
"upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.",
"upload_modal.preview_label": "Preview ({ratio})",
"upload_modal.analyzing_picture": "Kép elemzése…",
"upload_modal.apply": "Alkalmazás",
"upload_modal.description_placeholder": "A gyors, barna róka átugrik a lusta kutya fölött",
"upload_modal.detect_text": "Szöveg felismerése a képről",
"upload_modal.edit_media": "Média szerkesztése",
"upload_modal.hint": "Kattints vagy húzd a kört az előnézetben arra a fókuszpontra, mely minden megjelenített bélyegképen látható kell, legyen.",
"upload_modal.preview_label": "Előnézet ({ratio})",
"upload_progress.label": "Feltöltés...",
"video.close": "Videó bezárása",
"video.exit_fullscreen": "Kilépés teljes képernyőből",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Ապահետեւել",
"confirmations.unfollow.message": "Վստա՞հ ես, որ ուզում ես այլեւս չհետեւել {name}֊ին։",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Կարգավորել թթի գաղտնիությունը",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?",
"confirmations.unfollow.confirm": "Berhenti mengikuti",
"confirmations.unfollow.message": "Apakah anda ingin berhenti mengikuti {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Tentukan privasi status",

@ -111,6 +111,10 @@
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"conversation.delete": "Delete conversation",
"conversation.mark_as_read": "Mark as read",
"conversation.open": "View conversation",
"conversation.with": "With {names}",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
@ -295,6 +299,7 @@
"poll.refresh": "Refresh",
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
"poll.vote": "Vote",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Add a poll",
"poll_button.remove_poll": "Remove poll",
"privacy.change": "Aranjar privateso di mesaji",

@ -16,7 +16,7 @@
"account.follows.empty": "Questo utente non segue ancora nessuno.",
"account.follows_you": "Ti segue",
"account.hide_reblogs": "Nascondi condivisioni da @{name}",
"account.last_status": "Last active",
"account.last_status": "Ultima attività",
"account.link_verified_on": "La proprietà di questo link è stata controllata il {date}",
"account.locked_info": "Il livello di privacy di questo account è impostato a \"bloccato\". Il proprietario esamina manualmente le richieste di seguirlo.",
"account.media": "Media",
@ -25,7 +25,7 @@
"account.mute": "Silenzia @{name}",
"account.mute_notifications": "Silenzia notifiche da @{name}",
"account.muted": "Silenziato",
"account.never_active": "Never",
"account.never_active": "Mai",
"account.posts": "Toot",
"account.posts_with_replies": "Toot e risposte",
"account.report": "Segnala @{name}",
@ -53,7 +53,7 @@
"column.blocks": "Utenti bloccati",
"column.community": "Timeline locale",
"column.direct": "Messaggi diretti",
"column.directory": "Browse profiles",
"column.directory": "Sfoglia profili",
"column.domain_blocks": "Domini nascosti",
"column.favourites": "Apprezzati",
"column.follow_requests": "Richieste di amicizia",
@ -101,8 +101,8 @@
"confirmations.delete_list.message": "Sei sicuro di voler cancellare definitivamente questa lista?",
"confirmations.domain_block.confirm": "Nascondi intero dominio",
"confirmations.domain_block.message": "Sei davvero sicuro che vuoi bloccare l'intero {domain}? Nella maggior parte dei casi, pochi blocchi o silenziamenti mirati sono sufficienti e preferibili. Non vedrai nessun contenuto di quel dominio né nelle timeline pubbliche né nelle notifiche. I tuoi seguaci di quel dominio saranno eliminati.",
"confirmations.logout.confirm": "Log out",
"confirmations.logout.message": "Are you sure you want to log out?",
"confirmations.logout.confirm": "Esci",
"confirmations.logout.message": "Sei sicuro di voler uscire?",
"confirmations.mute.confirm": "Silenzia",
"confirmations.mute.message": "Sei sicuro di voler silenziare {name}?",
"confirmations.redraft.confirm": "Cancella e riscrivi",
@ -111,10 +111,14 @@
"confirmations.reply.message": "Se rispondi ora, il messaggio che stai componendo sarà sovrascritto. Sei sicuro di voler continuare?",
"confirmations.unfollow.confirm": "Smetti di seguire",
"confirmations.unfollow.message": "Sei sicuro che non vuoi più seguire {name}?",
"directory.federated": "From known fediverse",
"directory.local": "From {domain} only",
"directory.new_arrivals": "New arrivals",
"directory.recently_active": "Recently active",
"conversation.delete": "Elimina conversazione",
"conversation.mark_as_read": "Segna come letto",
"conversation.open": "Visualizza conversazione",
"conversation.with": "Con {names}",
"directory.federated": "Da un fediverso noto",
"directory.local": "Solo da {domain}",
"directory.new_arrivals": "Nuovi arrivi",
"directory.recently_active": "Attivo di recente",
"embed.instructions": "Inserisci questo status nel tuo sito copiando il codice qui sotto.",
"embed.preview": "Ecco come apparirà:",
"emoji_button.activity": "Attività",
@ -170,7 +174,7 @@
"home.column_settings.basic": "Semplice",
"home.column_settings.show_reblogs": "Mostra post condivisi",
"home.column_settings.show_replies": "Mostra risposte",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "Aggiorna in tempo reale",
"intervals.full.days": "{number, plural, one {# giorno} other {# giorni}}",
"intervals.full.hours": "{number, plural, one {# ora} other {# ore}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",
@ -264,7 +268,7 @@
"navigation_bar.preferences": "Impostazioni",
"navigation_bar.public_timeline": "Timeline federata",
"navigation_bar.security": "Sicurezza",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "e {count, plural, one {# other} other {# others}}",
"notification.favourite": "{name} ha apprezzato il tuo post",
"notification.follow": "{name} ha iniziato a seguirti",
"notification.mention": "{name} ti ha menzionato",
@ -295,6 +299,7 @@
"poll.refresh": "Aggiorna",
"poll.total_votes": "{count, plural, one {# voto} other {# voti}}",
"poll.vote": "Vota",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "Aggiungi un sondaggio",
"poll_button.remove_poll": "Rimuovi sondaggio",
"privacy.change": "Modifica privacy del post",
@ -369,7 +374,7 @@
"status.show_more": "Mostra di più",
"status.show_more_all": "Mostra di più per tutti",
"status.show_thread": "Mostra thread",
"status.uncached_media_warning": "Not available",
"status.uncached_media_warning": "Non disponibile",
"status.unmute_conversation": "Annulla silenzia conversazione",
"status.unpin": "Non fissare in cima al profilo",
"suggestions.dismiss": "Elimina suggerimento",

@ -38,7 +38,7 @@
"account.unfollow": "フォロー解除",
"account.unmute": "@{name}さんのミュートを解除",
"account.unmute_notifications": "@{name}さんからの通知を受け取るようにする",
"alert.rate_limited.message": "{retry_time, time, medium} に再試行してください。",
"alert.rate_limited.message": "{retry_time, time, medium} 以降に再試行してください。",
"alert.rate_limited.title": "制限に達しました",
"alert.unexpected.message": "不明なエラーが発生しました。",
"alert.unexpected.title": "エラー!",
@ -53,7 +53,7 @@
"column.blocks": "ブロックしたユーザー",
"column.community": "ローカルタイムライン",
"column.direct": "ダイレクトメッセージ",
"column.directory": "Browse profiles",
"column.directory": "ディレクトリ",
"column.domain_blocks": "非表示にしたドメイン",
"column.favourites": "お気に入り",
"column.follow_requests": "フォローリクエスト",
@ -63,7 +63,7 @@
"column.notifications": "通知",
"column.pins": "固定されたトゥート",
"column.public": "連合タイムライン",
"column.status": "Toot",
"column.status": "トゥート",
"column_back_button.label": "戻る",
"column_header.hide_settings": "設定を隠す",
"column_header.moveLeft_settings": "カラムを左に移動する",
@ -115,7 +115,11 @@
"confirmations.reply.message": "今返信すると現在作成中のメッセージが上書きされます。本当に実行しますか?",
"confirmations.unfollow.confirm": "フォロー解除",
"confirmations.unfollow.message": "本当に{name}さんのフォローを解除しますか?",
"directory.federated": "既知の連合全体",
"conversation.delete": "このやりとりを削除",
"conversation.mark_as_read": "既読にする",
"conversation.open": "会話を表示",
"conversation.with": "{names}",
"directory.federated": "既知の連合より",
"directory.local": "{domain} のみ",
"directory.new_arrivals": "新着順",
"directory.recently_active": "最近の活動順",
@ -174,7 +178,7 @@
"home.column_settings.basic": "基本設定",
"home.column_settings.show_reblogs": "ブースト表示",
"home.column_settings.show_replies": "返信表示",
"home.column_settings.update_live": "Update in real-time",
"home.column_settings.update_live": "リアルタイムで更新",
"intervals.full.days": "{number}日",
"intervals.full.hours": "{number}時間",
"intervals.full.minutes": "{number}分",
@ -269,7 +273,7 @@
"navigation_bar.public_timeline": "連合タイムライン",
"navigation_bar.misc": "その他",
"navigation_bar.security": "セキュリティ",
"notification.and_n_others": "and {count, plural, one {# other} other {# others}}",
"notification.and_n_others": "と、他 {count} 件",
"notification.favourite": "{name}さんがあなたのトゥートをお気に入りに登録しました",
"notification.follow": "{name}さんにフォローされました",
"notification.mention": "{name}さんがあなたに返信しました",
@ -300,6 +304,7 @@
"poll.refresh": "更新",
"poll.total_votes": "{count}票",
"poll.vote": "投票",
"poll.voted": "You voted for this answer",
"poll_button.add_poll": "アンケートを追加",
"poll_button.remove_poll": "アンケートを削除",
"privacy.change": "公開範囲を変更",
@ -390,7 +395,7 @@
"time_remaining.moments": "まもなく終了",
"time_remaining.seconds": "残り{number}秒",
"trends.count_by_accounts": "{count}人がトゥート",
"trends.trending_now": "トレンドタグ",
"trends.trending_now": "トレンド",
"ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。",
"upload_area.title": "ドラッグ&ドロップでアップロード",
"upload_button.label": "メディアを追加 ({formats})",
@ -404,7 +409,7 @@
"upload_modal.description_placeholder": "素早い茶色の狐はのろまな犬を飛び越える",
"upload_modal.detect_text": "画像からテキストを検出",
"upload_modal.edit_media": "メディアを編集",
"upload_modal.hint": "画像をクリックするか円をドラッグすると全てのサムネイルで注目する場所を選ぶことができます",
"upload_modal.hint": "画像をクリックするか円をドラッグすると全てのサムネイルの中心点を決めることができます",
"upload_modal.preview_label": "プレビュー ({ratio})",
"upload_progress.label": "アップロード中...",
"video.close": "動画を閉じる",

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

Loading…
Cancel
Save