Compare commits

..

98 Commits

Author SHA1 Message Date
Essem 11900689bf
Use a consumer for identity 1 month ago
Essem 9b54b27bf7
Fix reaction picker dropdown appearance 1 month ago
Essem 40ae5aed66
Merge fixes 1 month ago
Essem 13c9fa62fa
Hydrate reactions on streaming API 1 month ago
Essem ba37843ec2
Purge status reactions on account delete 1 month ago
Essem b07f5f89d4
Fix rubocop lint issue 1 month ago
Essem aae6e1b1fd
Refactor status reactions query
This was done to announcement reactions in 1b0cb3b54d. Might as well do it here too.
1 month ago
Essem a12b2ad57a
Simplify reactions API controller 1 month ago
Essem d54affc107
Update reaction emails
Reaction icon made by t3rminus@calamity.world
1 month ago
Essem 0d68ecf75d
Revert variant selector normalization
Probably worth tackling later, but for now it's not worth worrying about; some other implementations (e.g. Misskey's) look to have the same behavior anyways.
1 month ago
Essem 4311fff076
Move reaction normalization to API controller 1 month ago
Essem a2ab3f541c
Quick fixes 1 month ago
Essem 11bebd28a2
Make name of like content parser function more general 1 month ago
Essem 09b64d761a
Normalize emojis with variant selectors 1 month ago
Essem 0838432237
Check for content attribute in Misskey likes 1 month ago
Essem a27b838741
Fix rubocop complaint 1 month ago
Essem 4d832522b9
Add reaction notification column settings
This was in a previous PR. Not quite sure how it didn't carry over.
1 month ago
Essem 03ea7618ad
More cleanup 1 month ago
Essem 22fc82dfee
Linting fixes 1 month ago
Essem 938175d5e8
Refactor react services 1 month ago
Essem 28ecb2a4be
Fix reblog reactions 1 month ago
Essem 14c0e46ef4
Add notification emails for reactions 1 month ago
Essem 227a8d71b3
Add support for emoji reactions
Squashed, modified, and rebased from glitch-soc/mastodon#2221.

Co-authored-by: fef <owo@fef.moe>
Co-authored-by: Jeremy Kescher <jeremy@kescher.at>
Co-authored-by: neatchee <neatchee@gmail.com>
Co-authored-by: Ivan Rodriguez <104603218+IRod22@users.noreply.github.com>
Co-authored-by: Plastikmensch <plastikmensch@users.noreply.github.com>
1 month ago
Claire c8e5e13c89
Merge pull request #2691 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to 0cea7a623b
1 month ago
Eugen Rochko 91531e9586 [Glitch] Add ability to reorder uploaded media before posting in web UI
Port 8e7e86ee35 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Eugen Rochko fc533cfad3 [Glitch] Fix background and icon on notification requests in web UI
Port 0cea7a623b to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Eugen Rochko b55bbfa2b3 [Glitch] Change design of notification about lost connections in web UI
Port 29f9dc742e to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Eugen Rochko 1ae08ae257 [Glitch] Change out-of-band hashtags design in web UI
Port dd061291b1 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 0e76b919b5 Merge commit '0cea7a623be470c51d7a162265f44f5a3e149275' into glitch-soc/merge-upstream 1 month ago
Claire a844a6a577 [Glitch] Change `AccountRelationshipSeveranceEvent` model to store lost followers and following counts separately
Port dfa43707eb to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire c3a128f31e Remove strings already defined upstream 1 month ago
Claire afaad0755f [Glitch] Remove setting for unfollow confirmation modal, and make it unconditional
Port 37ca59815c to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 1d1c3a808a Merge commit '6c381f20b1d52c96525cbd5c41b0c972c3394a48' into glitch-soc/merge-upstream
Conflicts:
- `app/models/user_settings.rb`:
  Upstream removed a setting textually adjacent to a glitch-soc-only setting.
  Removed the setting glitch-soc removed.
1 month ago
Claire f635cde756 [Glitch] Change new modals to allow vertical scrolling
Port de6c9e0fcd to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 0f8b33238f [Glitch] Change icon of severed relationships notifications
Port 387c78ddf9 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Renaud Chaput 576c085ea0 [Glitch] Add the role ID to the badge component
Port ec1e770fea to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 777984faeb Merge commit '119c7aa0df1e1d26bdee1701250d23a7af9e9136' into glitch-soc/merge-upstream 1 month ago
Claire f14b6f3d99 [Glitch] Fix duplicate translation string for severed relationships
Port 885d0faf83 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 903dc53522 Merge commit '05eda8d19330a9c27c0cf07de19a87edff269057' into glitch-soc/merge-upstream 1 month ago
Eugen Rochko 375af259a2 [Glitch] Change back button to always appear in advanced web UI
Port be52633ee4 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire 67842ffb22 Merge commit '01464074c91f9b7a720928fc4ee912be3d8002d2' into glitch-soc/merge-upstream 1 month ago
Claire 0f966209ca [Glitch] Add notifications of severed relationships
Port 44bf7b8128 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
1 month ago
Claire f2b23aa5f3 Merge commit '954b470fbce3fbe4b9b42992b03425fa24d6a2ad' into glitch-soc/merge-upstream
Conflicts:
- `config/navigation.rb`:
  Upstream added a navigation item while glitch-soc had an additional one.
  Ported upstream changes.
1 month ago
Eugen Rochko 0cea7a623b
Fix background and icon on notification requests in web UI (#29706) 2 months ago
Eugen Rochko 29f9dc742e
Change design of notification about lost connections in web UI (#29731) 2 months ago
Eugen Rochko dd061291b1
Change out-of-band hashtags design in web UI (#29732) 2 months ago
renovate[bot] 766c1fea20
Update devDependencies (non-major) (#29746)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 55e2c827bd
Update DefinitelyTyped types (non-major) (#29743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 45f8364cd1
Update dependency typescript to v5.4.3 (#29744)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] bbf36836b6
Update formatjs monorepo (#29733)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
github-actions[bot] 799e3be9bd
New Crowdin Translations (automated) (#29726)
Co-authored-by: GitHub Actions <noreply@github.com>
2 months ago
Eugen Rochko 8e7e86ee35
Add ability to reorder uploaded media before posting in web UI (#28456) 2 months ago
Renaud Chaput 6c381f20b1
Restore advanced filter bar setting (#29737) 2 months ago
Claire 81a04ac25c
Improve specs for severed relationships (#29688) 2 months ago
Claire 37ca59815c
Remove setting for unfollow confirmation modal, and make it unconditional (#29373) 2 months ago
renovate[bot] 119c7aa0df
Update dependency rails-i18n to v7.0.9 (#29564)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
Claire 58376eedda
Remove obsolete `admin` and `moderator` columns from `users` table (#29718) 2 months ago
Claire d71d26a3c9
Reattribute notification-related records if possible when merging accounts (#29694) 2 months ago
Claire de6c9e0fcd
Change new modals to allow vertical scrolling (#29644) 2 months ago
Claire 387c78ddf9
Change icon of severed relationships notifications (#29712) 2 months ago
Claire dfa43707eb
Change `AccountRelationshipSeveranceEvent` model to store lost followers and following counts separately (#29714) 2 months ago
Matt Jankowski 34f293475e
Fix results/query in `api/v1/featured_tags/suggestions` (#29597) 2 months ago
github-actions[bot] 5db5fa879b
New Crowdin Translations (automated) (#29708)
Co-authored-by: GitHub Actions <noreply@github.com>
2 months ago
Matt Jankowski 8c1d29df7e
Use `has_many through` instead of `delegate` for ARSE<>SR (#29672) 2 months ago
Renaud Chaput ec1e770fea
Add the role ID to the badge component (#29707) 2 months ago
Claire 05eda8d193
Remove severed relationship notifications for single account suspensions (#29700) 2 months ago
Claire 70a8fcf07d
Fix notification policy migration not preserving `filter_private_mentions` correctly (#29699) 2 months ago
Matt Jankowski 142c018cfa
Add ruby 3.3 to CI test matrix (#29705) 2 months ago
renovate[bot] ec6d016da1
Update dependency ox to v2.14.18 (#29701)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 7f5e930bd2
Update dependency strong_migrations to v1.8.0 (#29556)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] f5444c8fe4
Update dependency rspec-rails to v6.1.2 (#29691)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 05abefe989
Update RuboCop (non-major) to v1.62.1 (#29692)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
Claire 814a48517f
Add some more tests for notification policies (#29698) 2 months ago
Matt Jankowski a59f5694fe
Add empty line after magic frozen string comment (#29696) 2 months ago
Claire 75f34b80a8
Clean up notification requests when deleting accounts (#29693) 2 months ago
renovate[bot] 1df00d4e76
Update dependency pino-pretty to v11 (#29662)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 2ec3fcaffe
Update dependency rack to v2.2.9 (#29685)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] a506b09de0
Update dependency @reduxjs/toolkit to v2.2.2 (#29681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 1feb228275
Update dependency express to v4.19.1 (#29663)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
Nick Schonning d13cdced1e
Add Renovate grouped updates for RSpec and RuboCop (#29621) 2 months ago
Claire 885d0faf83
Fix duplicate translation string for severed relationships (#29689) 2 months ago
github-actions[bot] c007dd5dd2
New Crowdin Translations (automated) (#29687)
Co-authored-by: GitHub Actions <noreply@github.com>
2 months ago
Matt Jankowski 77897cd24c
Use existing `SeveredRelationship.about_local_account` scope in more places (#29673) 2 months ago
Matt Jankowski 718ee72c80
Use `db_table_exists?` method in new cli/maintenance area (#29677) 2 months ago
Matt Jankowski cdd168f5d3
Update `enum` away from deprecated (#29678) 2 months ago
renovate[bot] 01464074c9
Update dependency autoprefixer to v10.4.19 (#29682)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 3f363c61bc
Update dependency postcss to v8.4.38 (#29684)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
Claire 7434c9c276
Fix the relationships controller spec, since it requires an extra model now (#29671) 2 months ago
Matt Jankowski 39bac24cb7
Remove reference to deleted haml lint todo file (#29675) 2 months ago
Matt Jankowski 62722238c9
Lock `i18n` gem to version `1.14.1` (#29674) 2 months ago
Eugen Rochko be52633ee4
Change back button to always appear in advanced web UI (#29669) 2 months ago
Claire f4d753aedf
Fix error in severed relationship event serializer (#29670) 2 months ago
Claire 98a2bb8be2
Fix issue with severed relationships notifications (#29668) 2 months ago
Claire 954b470fbc
Fix error when attempting to delete posts that triggered a notification request (#29666) 2 months ago
Claire d4449cc682
Fix account_relationship_severance_events unique indexes (#29665) 2 months ago
renovate[bot] 99c9db5f67
Update babel monorepo to v7.24.3 (#29660)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
renovate[bot] 27a6fa7b0e
Update dependency cssnano to v6.1.1 (#29661)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2 months ago
Claire 44bf7b8128
Add notifications of severed relationships (#27511) 2 months ago

@ -125,6 +125,22 @@
],
groupName: null, // We dont want them to belong to any group
},
{
// Group all RuboCop packages with `rubocop` in the same PR
matchManagers: ['bundler'],
matchPackageNames: ['rubocop'],
matchPackagePrefixes: ['rubocop-'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'RuboCop (non-major)',
},
{
// Group all RSpec packages with `rspec` in the same PR
matchManagers: ['bundler'],
matchPackageNames: ['rspec'],
matchPackagePrefixes: ['rspec-'],
matchUpdateTypes: ['patch', 'minor'],
groupName: 'RSpec (non-major)',
},
// Add labels depending on package manager
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },

@ -114,6 +114,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
- '3.3'
steps:
- uses: actions/checkout@v4
@ -189,6 +190,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
- '3.3'
steps:
- uses: actions/checkout@v4
@ -288,6 +290,7 @@ jobs:
- '3.0'
- '3.1'
- '.ruby-version'
- '3.3'
search-image:
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
include:

@ -1,5 +1,3 @@
inherits_from: .haml-lint_todo.yml
exclude:
- 'vendor/**/*'
- lib/templates/haml/scaffold/_form.html.haml

@ -58,6 +58,7 @@ gem 'htmlentities', '~> 4.3'
gem 'http', '~> 5.1'
gem 'http_accept_language', '~> 2.1'
gem 'httplog', '~> 1.6.2'
gem 'i18n', '1.14.1' # TODO: Remove version when resolved: https://github.com/glebm/i18n-tasks/issues/552 / https://github.com/ruby-i18n/i18n/pull/688
gem 'idn-ruby', require: 'idn'
gem 'inline_svg'
gem 'kaminari', '~> 1.2'
@ -89,7 +90,7 @@ gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2'
gem 'stoplight', '~> 3.0.1'
gem 'strong_migrations', '1.7.0'
gem 'strong_migrations', '1.8.0'
gem 'tty-prompt', '~> 0.23', require: false
gem 'twitter-text', '~> 3.1.0'
gem 'tzinfo-data', '~> 1.2023'

@ -139,7 +139,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
bigdecimal (3.1.6)
bigdecimal (3.1.7)
bindata (2.4.15)
binding_of_caller (1.0.0)
debug_inspector (>= 0.0.1)
@ -213,7 +213,7 @@ GEM
devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0)
rpam2 (~> 4.0)
diff-lcs (1.5.0)
diff-lcs (1.5.1)
discard (1.3.0)
activerecord (>= 4.2, < 8)
docile (1.4.0)
@ -225,8 +225,7 @@ GEM
dotenv-rails (2.8.1)
dotenv (= 2.8.1)
railties (>= 3.2)
drb (2.2.0)
ruby2_keywords
drb (2.2.1)
ed25519 (1.3.0)
elasticsearch (7.13.3)
elasticsearch-api (= 7.13.3)
@ -438,7 +437,7 @@ GEM
mime-types-data (3.2023.1205)
mini_mime (1.1.5)
mini_portile2 (2.8.5)
minitest (5.21.2)
minitest (5.22.3)
msgpack (1.7.2)
multi_json (1.15.0)
multipart-post (2.3.0)
@ -500,7 +499,7 @@ GEM
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
orm_adapter (0.5.0)
ox (2.14.17)
ox (2.14.18)
parallel (1.24.0)
parser (3.3.0.5)
ast (~> 2.4.1)
@ -535,7 +534,7 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.7.3)
rack (2.2.8.1)
rack (2.2.9)
rack-attack (6.7.0)
rack (>= 1.0, < 4)
rack-cors (2.0.2)
@ -583,7 +582,7 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rails-i18n (7.0.8)
rails-i18n (7.0.9)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.3.2)
@ -601,7 +600,7 @@ GEM
link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.7.0)
rdf (~> 3.3)
rdoc (6.6.2)
rdoc (6.6.3.1)
psych (>= 4.0.0)
redcarpet (3.6.0)
redis (4.8.1)
@ -635,21 +634,21 @@ GEM
rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (6.1.1)
rspec-rails (6.1.2)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.12)
rspec-expectations (~> 3.12)
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-sidekiq (4.1.0)
rspec-core (~> 3.0)
rspec-expectations (~> 3.0)
rspec-mocks (~> 3.0)
sidekiq (>= 5, < 8)
rspec-support (3.13.1)
rubocop (1.60.2)
rubocop (1.62.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
@ -657,24 +656,24 @@ GEM
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml (>= 3.2.5, < 4.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.30.0)
parser (>= 3.2.1.0)
rubocop-ast (1.31.2)
parser (>= 3.3.0.4)
rubocop-capybara (2.20.0)
rubocop (~> 1.41)
rubocop-factory_bot (2.25.0)
rubocop (~> 1.33)
rubocop-factory_bot (2.25.1)
rubocop (~> 1.41)
rubocop-performance (1.20.2)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rails (2.23.1)
rubocop-rails (2.24.0)
activesupport (>= 4.2.0)
rack (>= 1.1)
rubocop (>= 1.33.0, < 2.0)
rubocop-ast (>= 1.30.0, < 2.0)
rubocop-rspec (2.26.1)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rspec (2.27.1)
rubocop (~> 1.40)
rubocop-capybara (~> 2.17)
rubocop-factory_bot (~> 2.22)
@ -735,7 +734,7 @@ GEM
stoplight (3.0.2)
redlock (~> 1.0)
stringio (3.1.0)
strong_migrations (1.7.0)
strong_migrations (1.8.0)
activerecord (>= 5.2)
swd (1.3.0)
activesupport (>= 3)
@ -866,6 +865,7 @@ DEPENDENCIES
http (~> 5.1)
http_accept_language (~> 2.1)
httplog (~> 1.6.2)
i18n (= 1.14.1)
i18n-tasks (~> 1.0)
idn-ruby
inline_svg
@ -940,7 +940,7 @@ DEPENDENCIES
simplecov-lcov (~> 0.8)
stackprof
stoplight (~> 3.0.1)
strong_migrations (= 1.7.0)
strong_migrations (= 1.8.0)
test-prof
thor (~> 1.2)
tty-prompt (~> 0.23)

@ -12,6 +12,10 @@ class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController
private
def set_recently_used_tags
@recently_used_tags = Tag.recently_used(current_account).where.not(id: current_account.featured_tags).limit(10)
@recently_used_tags = Tag.recently_used(current_account).where.not(id: featured_tag_ids).limit(10)
end
def featured_tag_ids
current_account.featured_tags.pluck(:tag_id)
end
end

@ -0,0 +1,61 @@
# frozen_string_literal: true
class SeveredRelationshipsController < ApplicationController
layout 'admin'
before_action :authenticate_user!
before_action :set_body_classes
before_action :set_cache_headers
before_action :set_event, only: [:following, :followers]
def index
@events = AccountRelationshipSeveranceEvent.where(account: current_account)
end
def following
respond_to do |format|
format.csv { send_data following_data, filename: "following-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
end
end
def followers
respond_to do |format|
format.csv { send_data followers_data, filename: "followers-#{@event.target_name}-#{@event.created_at.to_date.iso8601}.csv" }
end
end
private
def set_event
@event = AccountRelationshipSeveranceEvent.find(params[:id])
end
def following_data
CSV.generate(headers: ['Account address', 'Show boosts', 'Notify on new posts', 'Languages'], write_headers: true) do |csv|
@event.severed_relationships.active.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
csv << [acct(follow.target_account), follow.show_reblogs, follow.notify, follow.languages&.join(', ')]
end
end
end
def followers_data
CSV.generate(headers: ['Account address'], write_headers: true) do |csv|
@event.severed_relationships.passive.about_local_account(current_account).includes(:remote_account).reorder(id: :desc).each do |follow|
csv << [acct(follow.account)]
end
end
end
def acct(account)
account.local? ? account.local_username_and_domain : account.acct
end
def set_body_classes
@body_classes = 'admin'
end
def set_cache_headers
response.cache_control.replace(private: true, no_store: true)
end
end

@ -81,6 +81,7 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL';
export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION';
export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS';
export const COMPOSE_CHANGE_MEDIA_ORDER = 'COMPOSE_CHANGE_MEDIA_ORDER';
export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
export const COMPOSE_FOCUS = 'COMPOSE_FOCUS';
@ -845,3 +846,9 @@ export function changePollSettings(expiresIn, isMultiple) {
isMultiple,
};
}
export const changeMediaOrder = (a, b) => ({
type: COMPOSE_CHANGE_MEDIA_ORDER,
a,
b,
});

@ -7,8 +7,8 @@ import PersonIcon from '@/material-icons/400-24px/person.svg?react';
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
export const Badge = ({ icon, label, domain }) => (
<div className='account-role'>
export const Badge = ({ icon, label, domain, roleId }) => (
<div className='account-role' data-account-role-id={roleId}>
{icon}
{label}
{domain && <span className='account-role__domain'>{domain}</span>}
@ -19,6 +19,7 @@ Badge.propTypes = {
icon: PropTypes.node,
label: PropTypes.node,
domain: PropTypes.node,
roleId: PropTypes.string
};
Badge.defaultProps = {

@ -13,7 +13,7 @@ import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { ButtonInTabsBar, useColumnsContext } from 'flavours/glitch/features/ui/util/columns_context';
import { ButtonInTabsBar } from 'flavours/glitch/features/ui/util/columns_context';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
import { useAppHistory } from './router';
@ -26,10 +26,9 @@ const messages = defineMessages({
back: { id: 'column_back_button.label', defaultMessage: 'Back' },
});
const BackButton = ({ pinned, show, onlyIcon }) => {
const BackButton = ({ onlyIcon }) => {
const history = useAppHistory();
const intl = useIntl();
const { multiColumn } = useColumnsContext();
const handleBackClick = useCallback(() => {
if (history.location?.state?.fromMastodon) {
@ -39,10 +38,6 @@ const BackButton = ({ pinned, show, onlyIcon }) => {
}
}, [history]);
const showButton = history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || show);
if (!showButton) return null;
return (
<button onClick={handleBackClick} className={classNames('column-header__back-button', { 'compact': onlyIcon })} aria-label={intl.formatMessage(messages.back)}>
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
@ -52,8 +47,6 @@ const BackButton = ({ pinned, show, onlyIcon }) => {
};
BackButton.propTypes = {
pinned: PropTypes.bool,
show: PropTypes.bool,
onlyIcon: PropTypes.bool,
};
@ -118,7 +111,7 @@ class ColumnHeader extends PureComponent {
};
render () {
const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props;
const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props;
const { collapsed, animating } = this.state;
const wrapperClassName = classNames('column-header__wrapper', {
@ -161,7 +154,9 @@ class ColumnHeader extends PureComponent {
pinButton = <button className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
}
backButton = <BackButton pinned={pinned} show={showBackButton} onlyIcon={!!title} />;
if (history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) {
backButton = <BackButton onlyIcon={!!title} />;
}
const collapsedContent = [
extraContent,
@ -199,16 +194,16 @@ class ColumnHeader extends PureComponent {
<h1 className={buttonClassName}>
{hasTitle && (
<>
{showBackButton && backButton}
{backButton}
<button onClick={this.handleTitleClick} className='column-header__title'>
{!showBackButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
{!backButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
{title}
</button>
</>
)}
{!hasTitle && showBackButton && backButton}
{!hasTitle && backButton}
<div className='column-header__buttons'>
{extraButton}

@ -13,7 +13,6 @@ import {
import { openModal } from '../actions/modal';
import { initMuteModal } from '../actions/mutes';
import Account from '../components/account';
import { unfollowModal } from '../initial_state';
import { makeGetAccount } from '../selectors';
const messages = defineMessages({
@ -34,18 +33,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow (account) {
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -329,7 +329,7 @@ class Header extends ImmutablePureComponent {
}
account.get('roles', []).forEach((role) => {
badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} />);
badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} roleId={role.get('id')} />);
});
return (

@ -19,7 +19,6 @@ import { initDomainBlockModal, unblockDomain } from '../../../actions/domain_blo
import { openModal } from '../../../actions/modal';
import { initMuteModal } from '../../../actions/mutes';
import { initReport } from '../../../actions/reports';
import { unfollowModal } from '../../../initial_state';
import { makeGetAccount, getAccountHidden } from '../../../selectors';
import Header from '../components/header';
@ -45,31 +44,23 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow (account) {
if (account.getIn(['relationship', 'following'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else if (account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -21,7 +21,6 @@ import PollButtonContainer from '../containers/poll_button_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import SpoilerButtonContainer from '../containers/spoiler_button_container';
import UploadButtonContainer from '../containers/upload_button_container';
import UploadFormContainer from '../containers/upload_form_container';
import WarningContainer from '../containers/warning_container';
import { countableText } from '../util/counter';
@ -34,6 +33,7 @@ import { PollForm } from "./poll_form";
import { ReplyIndicator } from './reply_indicator';
import { SecondaryPrivacyButton } from './secondary_privacy_button';
import { ThreadModeButton } from './thread_mode_button';
import { UploadForm } from './upload_form';
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
@ -308,7 +308,7 @@ class ComposeForm extends ImmutablePureComponent {
/>
</div>
<UploadFormContainer />
<UploadForm />
<PollForm />
<div className='compose-form__footer'>

@ -1,77 +1,81 @@
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { useDispatch, useSelector } from 'react-redux';
import spring from 'react-motion/lib/spring';
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
import { undoUploadCompose, initMediaEditModal } from 'flavours/glitch/actions/compose';
import { Blurhash } from 'flavours/glitch/components/blurhash';
import { Icon } from 'flavours/glitch/components/icon';
import Motion from 'flavours/glitch/features/ui/util/optional_motion';
import Motion from '../../ui/util/optional_motion';
export default class Upload extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
sensitive: PropTypes.bool,
onUndo: PropTypes.func.isRequired,
onOpenFocalPoint: PropTypes.func.isRequired,
};
handleUndoClick = e => {
e.stopPropagation();
this.props.onUndo(this.props.media.get('id'));
};
handleFocalPointClick = e => {
e.stopPropagation();
this.props.onOpenFocalPoint(this.props.media.get('id'));
};
render () {
const { media, sensitive } = this.props;
if (!media) {
return null;
}
const focusX = media.getIn(['meta', 'focus', 'x']);
const focusY = media.getIn(['meta', 'focus', 'y']);
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
const missingDescription = (media.get('description') || '').length === 0;
return (
<div className='compose-form__upload'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload__thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: !sensitive ? `url(${media.get('preview_url')})` : null, backgroundPosition: `${x}% ${y}%` }}>
{sensitive && <Blurhash
hash={media.get('blurhash')}
className='compose-form__upload__preview'
/>}
<div className='compose-form__upload__actions'>
<button type='button' className='icon-button compose-form__upload__delete' onClick={this.handleUndoClick}><Icon icon={CloseIcon} /></button>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
<div className='compose-form__upload__warning'>
<button type='button' className={classNames('icon-button', { active: missingDescription })} onClick={this.handleFocalPointClick}>{missingDescription && <Icon icon={WarningIcon} />} ALT</button>
</div>
</div>
)}
</Motion>
</div>
);
export const Upload = ({ id, onDragStart, onDragEnter, onDragEnd }) => {
const dispatch = useDispatch();
const media = useSelector(state => state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id));
const sensitive = useSelector(state => state.getIn(['compose', 'sensitive']));
const handleUndoClick = useCallback(() => {
dispatch(undoUploadCompose(id));
}, [dispatch, id]);
const handleFocalPointClick = useCallback(() => {
dispatch(initMediaEditModal(id));
}, [dispatch, id]);
const handleDragStart = useCallback(() => {
onDragStart(id);
}, [onDragStart, id]);
const handleDragEnter = useCallback(() => {
onDragEnter(id);
}, [onDragEnter, id]);
if (!media) {
return null;
}
}
const focusX = media.getIn(['meta', 'focus', 'x']);
const focusY = media.getIn(['meta', 'focus', 'y']);
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
const missingDescription = (media.get('description') || '').length === 0;
return (
<div className='compose-form__upload' draggable onDragStart={handleDragStart} onDragEnter={handleDragEnter} onDragEnd={onDragEnd}>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload__thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: !sensitive ? `url(${media.get('preview_url')})` : null, backgroundPosition: `${x}% ${y}%` }}>
{sensitive && <Blurhash
hash={media.get('blurhash')}
className='compose-form__upload__preview'
/>}
<div className='compose-form__upload__actions'>
<button type='button' className='icon-button compose-form__upload__delete' onClick={handleUndoClick}><Icon icon={CloseIcon} /></button>
<button type='button' className='icon-button' onClick={handleFocalPointClick}><Icon icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
<div className='compose-form__upload__warning'>
<button type='button' className={classNames('icon-button', { active: missingDescription })} onClick={handleFocalPointClick}>{missingDescription && <Icon icon={WarningIcon} />} ALT</button>
</div>
</div>
)}
</Motion>
</div>
);
};
Upload.propTypes = {
id: PropTypes.string,
onDragEnter: PropTypes.func,
onDragStart: PropTypes.func,
onDragEnd: PropTypes.func,
};

@ -1,35 +1,56 @@
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { useRef, useCallback } from 'react';
import UploadContainer from '../containers/upload_container';
import UploadProgressContainer from '../containers/upload_progress_container';
import { useSelector, useDispatch } from 'react-redux';
import { SensitiveButton } from './sensitive_button';
export default class UploadForm extends ImmutablePureComponent {
static propTypes = {
mediaIds: ImmutablePropTypes.list.isRequired,
};
render () {
const { mediaIds } = this.props;
import { changeMediaOrder } from 'flavours/glitch/actions/compose';
return (
<>
<UploadProgressContainer />
{mediaIds.size > 0 && (
<div className='compose-form__uploads'>
{mediaIds.map(id => (
<UploadContainer id={id} key={id} />
))}
</div>
)}
{!mediaIds.isEmpty() && <SensitiveButton />}
</>
);
}
}
import { SensitiveButton } from './sensitive_button';
import { Upload } from './upload';
import { UploadProgress } from './upload_progress';
export const UploadForm = () => {
const dispatch = useDispatch();
const mediaIds = useSelector(state => state.getIn(['compose', 'media_attachments']).map(item => item.get('id')));
const active = useSelector(state => state.getIn(['compose', 'is_uploading']));
const progress = useSelector(state => state.getIn(['compose', 'progress']));
const isProcessing = useSelector(state => state.getIn(['compose', 'is_processing']));
const dragItem = useRef();
const dragOverItem = useRef();
const handleDragStart = useCallback(id => {
dragItem.current = id;
}, [dragItem]);
const handleDragEnter = useCallback(id => {
dragOverItem.current = id;
}, [dragOverItem]);
const handleDragEnd = useCallback(() => {
dispatch(changeMediaOrder(dragItem.current, dragOverItem.current));
dragItem.current = null;
dragOverItem.current = null;
}, [dispatch, dragItem, dragOverItem]);
return (
<>
<UploadProgress active={active} progress={progress} isProcessing={isProcessing} />
{mediaIds.size > 0 && (
<div className='compose-form__uploads'>
{mediaIds.map(id => (
<Upload
key={id}
id={id}
onDragStart={handleDragStart}
onDragEnter={handleDragEnter}
onDragEnd={handleDragEnd}
/>
))}
</div>
)}
{!mediaIds.isEmpty() && <SensitiveButton />}
</>
);
};

@ -1,5 +1,4 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { FormattedMessage } from 'react-intl';
@ -10,46 +9,40 @@ import { Icon } from 'flavours/glitch/components/icon';
import Motion from '../../ui/util/optional_motion';
export default class UploadProgress extends PureComponent {
static propTypes = {
active: PropTypes.bool,
progress: PropTypes.number,
isProcessing: PropTypes.bool,
};
render () {
const { active, progress, isProcessing } = this.props;
if (!active) {
return null;
}
export const UploadProgress = ({ active, progress, isProcessing }) => {
if (!active) {
return null;
}
let message;
let message;
if (isProcessing) {
message = <FormattedMessage id='upload_progress.processing' defaultMessage='Processing…' />;
} else {
message = <FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />;
}
if (isProcessing) {
message = <FormattedMessage id='upload_progress.processing' defaultMessage='Processing…' />;
} else {
message = <FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />;
}
return (
<div className='upload-progress'>
<Icon id='upload' icon={UploadFileIcon} />
return (
<div className='upload-progress'>
<Icon id='upload' icon={UploadFileIcon} />
<div className='upload-progress__message'>
{message}
<div className='upload-progress__message'>
{message}
<div className='upload-progress__backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
}
</Motion>
</div>
<div className='upload-progress__backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
}
</Motion>
</div>
</div>
);
}
}
</div>
);
};
UploadProgress.propTypes = {
active: PropTypes.bool,
progress: PropTypes.number,
isProcessing: PropTypes.bool,
};

@ -1,27 +0,0 @@
import { connect } from 'react-redux';
import { undoUploadCompose, initMediaEditModal, submitCompose } from '../../../actions/compose';
import Upload from '../components/upload';
const mapStateToProps = (state, { id }) => ({
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
sensitive: state.getIn(['compose', 'sensitive']),
});
const mapDispatchToProps = dispatch => ({
onUndo: id => {
dispatch(undoUploadCompose(id));
},
onOpenFocalPoint: id => {
dispatch(initMediaEditModal(id));
},
onSubmit (router) {
dispatch(submitCompose(router));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Upload);

@ -1,9 +0,0 @@
import { connect } from 'react-redux';
import UploadForm from '../components/upload_form';
const mapStateToProps = state => ({
mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')),
});
export default connect(mapStateToProps)(UploadForm);

@ -1,11 +0,0 @@
import { connect } from 'react-redux';
import UploadProgress from '../components/upload_progress';
const mapStateToProps = state => ({
active: state.getIn(['compose', 'is_uploading']),
progress: state.getIn(['compose', 'progress']),
isProcessing: state.getIn(['compose', 'is_processing']),
});
export default connect(mapStateToProps)(UploadProgress);

@ -21,7 +21,7 @@ import { DisplayName } from 'flavours/glitch/components/display_name';
import { IconButton } from 'flavours/glitch/components/icon_button';
import { Permalink } from 'flavours/glitch/components/permalink';
import { ShortNumber } from 'flavours/glitch/components/short_number';
import { autoPlayGif, me, unfollowModal } from 'flavours/glitch/initial_state';
import { autoPlayGif, me } from 'flavours/glitch/initial_state';
import { makeGetAccount } from 'flavours/glitch/selectors';
const messages = defineMessages({
@ -50,38 +50,30 @@ const makeMapStateToProps = () => {
const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow(account) {
if (account.getIn(['relationship', 'following'])) {
if (unfollowModal) {
dispatch(
openModal({
modalType: 'CONFIRM',
modalProps: {
message: (
<FormattedMessage
id='confirmations.unfollow.message'
defaultMessage='Are you sure you want to unfollow {name}?'
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
),
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
} }),
);
} else {
dispatch(unfollowAccount(account.get('id')));
}
} else if (account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
dispatch(
openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
message: (
<FormattedMessage
id='confirmations.unfollow.message'
defaultMessage='Are you sure you want to unfollow {name}?'
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
),
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
} }),
);
} else if (account.getIn(['relationship', 'requested'])) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -68,7 +68,7 @@ class FollowRequests extends ImmutablePureComponent {
);
return (
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)}>
<ScrollableList
scrollKey='follow_requests'
onLoadMore={this.handleLoadMore}

@ -41,7 +41,8 @@ export const FilteredNotificationsBanner = () => {
</div>
<div className='filtered-notifications-banner__badge'>
{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}
<div className='filtered-notifications-banner__badge__badge'>{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}</div>
<FormattedMessage id='filtered_notifications_banner.private_mentions' defaultMessage='{count, plural, one {private mention} other {private mentions}}' values={{ count: policy.getIn(['summary', 'pending_notifications_count']) }} />
</div>
</Link>
);

@ -22,12 +22,14 @@ import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
import FollowRequestContainer from '../containers/follow_request_container';
import NotificationOverlayContainer from '../containers/overlay_container';
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
import Report from './report';
const messages = defineMessages({
follow: { id: 'notification.follow', defaultMessage: '{name} followed you' },
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
});
const notificationForScreenReader = (intl, message, timestamp) => {
@ -328,6 +330,29 @@ class Notification extends ImmutablePureComponent {
);
}
renderRelationshipsSevered (notification) {
const { intl, unread, hidden } = this.props;
const event = notification.get('event');
if (!event) {
return null;
}
return (
<HotKeys handlers={this.getHandlers()}>
<div className={classNames('notification notification-severed-relationships focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.relationshipsSevered, { name: notification.getIn(['event', 'target_name']) }), notification.get('created_at'))}>
<RelationshipsSeveranceEvent
type={event.get('type')}
target={event.get('target_name')}
followersCount={event.get('followers_count')}
followingCount={event.get('following_count')}
hidden={hidden}
/>
</div>
</HotKeys>
);
}
renderAdminSignUp (notification, account, link) {
const { intl, unread } = this.props;
@ -423,6 +448,8 @@ class Notification extends ImmutablePureComponent {
return this.renderUpdate(notification);
case 'poll':
return this.renderPoll(notification);
case 'severed_relationships':
return this.renderRelationshipsSevered(notification);
case 'admin.sign_up':
return this.renderAdminSignUp(notification, account, link);
case 'admin.report':

@ -7,8 +7,8 @@ import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
import DoneIcon from '@/material-icons/400-24px/done.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
import { acceptNotificationRequest, dismissNotificationRequest } from 'flavours/glitch/actions/notifications';
import { Avatar } from 'flavours/glitch/components/avatar';
import { IconButton } from 'flavours/glitch/components/icon_button';
@ -51,7 +51,7 @@ export const NotificationRequest = ({ id, accountId, notificationsCount }) => {
</Link>
<div className='notification-request__actions'>
<IconButton iconComponent={VolumeOffIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton iconComponent={DeleteIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton iconComponent={DoneIcon} onClick={handleAccept} title={intl.formatMessage(messages.accept)} />
</div>
</div>

@ -0,0 +1,45 @@
import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react';
import { Icon } from 'flavours/glitch/components/icon';
import { domain } from 'flavours/glitch/initial_state';
// This needs to be kept in sync with app/models/relationships_severance_event.rb
const messages = defineMessages({
account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' },
domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
});
export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden }) => {
const intl = useIntl();
if (hidden) {
return null;
}
return (
<a href='/severed_relationships' target='_blank' rel='noopener noreferrer' className='notification__relationships-severance-event'>
<Icon id='heart_broken' icon={HeartBrokenIcon} />
<div className='notification__relationships-severance-event__content'>
<p>{intl.formatMessage(messages[type], { from: <strong>{domain}</strong>, target: <strong>{target}</strong>, followingCount, followersCount })}</p>
<span className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></span>
</div>
</a>
);
};
RelationshipsSeveranceEvent.propTypes = {
type: PropTypes.oneOf([
'account_suspension',
'domain_block',
'user_domain_block',
]).isRequired,
target: PropTypes.string.isRequired,
followersCount: PropTypes.number.isRequired,
followingCount: PropTypes.number.isRequired,
hidden: PropTypes.bool,
};

@ -22,7 +22,7 @@ import { GIFV } from 'flavours/glitch/components/gifv';
import { IconButton } from 'flavours/glitch/components/icon_button';
import Audio from 'flavours/glitch/features/audio';
import { CharacterCounter } from 'flavours/glitch/features/compose/components/character_counter';
import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress';
import { UploadProgress } from 'flavours/glitch/features/compose/components/upload_progress';
import { Tesseract as fetchTesseract } from 'flavours/glitch/features/ui/util/async-components';
import { me } from 'flavours/glitch/initial_state';
import { assetHost } from 'flavours/glitch/utils/config';

@ -122,7 +122,6 @@ export const source_url = getMeta('source_url');
export const timelinePreview = getMeta('timeline_preview');
export const title = getMeta('title');
export const trendsAsLanding = getMeta('trends_as_landing_page');
export const unfollowModal = getMeta('unfollow_modal');
export const useBlurhash = getMeta('use_blurhash');
export const usePendingItems = getMeta('use_pending_items');
export const version = getMeta('version');

@ -65,8 +65,6 @@
"notification_purge.btn_invert": "Invert\nselection",
"notification_purge.btn_none": "Select\nnone",
"notification_purge.start": "Enter notification cleaning mode",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.filter_bar.show_bar": "Show filter bar",
"notifications.column_settings.reaction": "Reactions:",
"notifications.filter.reactions": "Reactions",

@ -48,6 +48,7 @@ import {
INIT_MEDIA_EDIT_MODAL,
COMPOSE_CHANGE_MEDIA_DESCRIPTION,
COMPOSE_CHANGE_MEDIA_FOCUS,
COMPOSE_CHANGE_MEDIA_ORDER,
COMPOSE_SET_STATUS,
COMPOSE_FOCUS,
} from '../actions/compose';
@ -656,6 +657,14 @@ export default function compose(state = initialState, action) {
return state.set('language', action.language);
case COMPOSE_FOCUS:
return state.set('focusDate', new Date()).update('text', text => text.length > 0 ? text : action.defaultText);
case COMPOSE_CHANGE_MEDIA_ORDER:
return state.update('media_attachments', list => {
const indexA = list.findIndex(x => x.get('id') === action.a);
const moveItem = list.get(indexA);
const indexB = list.findIndex(x => x.get('id') === action.b);
return list.splice(indexA, 1).splice(indexB, 0, moveItem);
});
default:
return state;
}

@ -61,6 +61,7 @@ export const notificationToMap = (notification, markForDelete = false) => Immuta
markedForDelete: markForDelete,
status: notification.status ? notification.status.id : null,
report: notification.report ? fromJS(notification.report) : null,
event: notification.event ? fromJS(notification.event) : null,
});
const normalizeNotification = (state, notification, usePendingItems) => {

@ -2392,6 +2392,44 @@ a.account__display-name {
}
}
.notification__relationships-severance-event {
display: flex;
gap: 16px;
color: $secondary-text-color;
text-decoration: none;
align-items: flex-start;
padding: 16px 32px;
border-bottom: 1px solid var(--background-border-color);
&:hover {
color: $primary-text-color;
}
.icon {
padding: 2px;
color: $highlight-text-color;
}
&__content {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
flex-grow: 1;
font-size: 16px;
line-height: 24px;
strong {
font-weight: 700;
}
.link-button {
font-size: inherit;
line-height: inherit;
}
}
}
.notification__message {
padding: 8px 14px; // glitch: reduced padding
padding-bottom: 0;
@ -9430,8 +9468,9 @@ noscript {
.safety-action-modal,
.interaction-modal {
max-width: 90vw;
max-width: 100vw;
width: 600px;
overflow-y: auto;
}
.interaction-modal {
@ -10340,18 +10379,24 @@ noscript {
margin-top: 16px;
display: flex;
flex-wrap: wrap;
font-size: 14px;
line-height: 18px;
gap: 4px;
font-size: 12px;
line-height: 16px;
gap: 6px;
color: $darker-text-color;
a {
display: inline-flex;
color: inherit;
text-decoration: none;
padding: 4px 12px;
background: $ui-base-color;
border-radius: 4px;
font-weight: 500;
&:hover span {
text-decoration: underline;
&:hover,
&:focus,
&:active {
background: lighten($ui-base-color, 4%);
}
}
@ -10567,10 +10612,10 @@ noscript {
.filtered-notifications-banner {
display: flex;
align-items: center;
background: $ui-base-color;
border-bottom: 1px solid lighten($ui-base-color, 8%);
padding: 15px;
gap: 15px;
border: 1px solid var(--background-border-color);
border-top: 0;
padding: 24px 32px;
gap: 16px;
color: $darker-text-color;
text-decoration: none;
@ -10578,15 +10623,12 @@ noscript {
&:active,
&:focus {
color: $secondary-text-color;
.filtered-notifications-banner__badge {
background: $secondary-text-color;
}
}
.icon {
width: 24px;
height: 24px;
padding: 2px;
}
&__text {
@ -10602,13 +10644,24 @@ noscript {
}
&__badge {
background: $darker-text-color;
color: $ui-base-color;
border-radius: 100px;
padding: 2px 8px;
display: flex;
align-items: center;
border-radius: 999px;
background: var(--background-border-color);
color: $darker-text-color;
padding: 4px;
padding-inline-end: 8px;
gap: 6px;
font-weight: 500;
font-size: 11px;
line-height: 16px;
&__badge {
background: $ui-button-background-color;
color: $white;
border-radius: 100px;
padding: 2px 8px;
}
}
}
@ -10617,7 +10670,7 @@ noscript {
align-items: center;
gap: 16px;
padding: 15px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
border-bottom: 1px solid var(--background-border-color);
&__link {
display: flex;
@ -10665,7 +10718,7 @@ noscript {
.icon-button {
border-radius: 4px;
border: 1px solid lighten($ui-base-color, 8%);
border: 1px solid var(--background-border-color);
padding: 5px;
}
}

@ -75,6 +75,7 @@ export const INIT_MEDIA_EDIT_MODAL = 'INIT_MEDIA_EDIT_MODAL';
export const COMPOSE_CHANGE_MEDIA_DESCRIPTION = 'COMPOSE_CHANGE_MEDIA_DESCRIPTION';
export const COMPOSE_CHANGE_MEDIA_FOCUS = 'COMPOSE_CHANGE_MEDIA_FOCUS';
export const COMPOSE_CHANGE_MEDIA_ORDER = 'COMPOSE_CHANGE_MEDIA_ORDER';
export const COMPOSE_SET_STATUS = 'COMPOSE_SET_STATUS';
export const COMPOSE_FOCUS = 'COMPOSE_FOCUS';
@ -811,3 +812,9 @@ export function changePollSettings(expiresIn, isMultiple) {
isMultiple,
};
}
export const changeMediaOrder = (a, b) => ({
type: COMPOSE_CHANGE_MEDIA_ORDER,
a,
b,
});

@ -7,8 +7,8 @@ import PersonIcon from '@/material-icons/400-24px/person.svg?react';
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
export const Badge = ({ icon, label, domain }) => (
<div className='account-role'>
export const Badge = ({ icon, label, domain, roleId }) => (
<div className='account-role' data-account-role-id={roleId}>
{icon}
{label}
{domain && <span className='account-role__domain'>{domain}</span>}
@ -19,6 +19,7 @@ Badge.propTypes = {
icon: PropTypes.node,
label: PropTypes.node,
domain: PropTypes.node,
roleId: PropTypes.string
};
Badge.defaultProps = {

@ -13,7 +13,7 @@ import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
import { Icon } from 'mastodon/components/icon';
import { ButtonInTabsBar, useColumnsContext } from 'mastodon/features/ui/util/columns_context';
import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import { useAppHistory } from './router';
@ -26,10 +26,9 @@ const messages = defineMessages({
back: { id: 'column_back_button.label', defaultMessage: 'Back' },
});
const BackButton = ({ pinned, show, onlyIcon }) => {
const BackButton = ({ onlyIcon }) => {
const history = useAppHistory();
const intl = useIntl();
const { multiColumn } = useColumnsContext();
const handleBackClick = useCallback(() => {
if (history.location?.state?.fromMastodon) {
@ -39,10 +38,6 @@ const BackButton = ({ pinned, show, onlyIcon }) => {
}
}, [history]);
const showButton = history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || show);
if (!showButton) return null;
return (
<button onClick={handleBackClick} className={classNames('column-header__back-button', { 'compact': onlyIcon })} aria-label={intl.formatMessage(messages.back)}>
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
@ -52,8 +47,6 @@ const BackButton = ({ pinned, show, onlyIcon }) => {
};
BackButton.propTypes = {
pinned: PropTypes.bool,
show: PropTypes.bool,
onlyIcon: PropTypes.bool,
};
@ -118,7 +111,7 @@ class ColumnHeader extends PureComponent {
};
render () {
const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props;
const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props;
const { collapsed, animating } = this.state;
const wrapperClassName = classNames('column-header__wrapper', {
@ -161,7 +154,9 @@ class ColumnHeader extends PureComponent {
pinButton = <button className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
}
backButton = <BackButton pinned={pinned} show={showBackButton} onlyIcon={!!title} />;
if (history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) {
backButton = <BackButton onlyIcon={!!title} />;
}
const collapsedContent = [
extraContent,
@ -199,16 +194,16 @@ class ColumnHeader extends PureComponent {
<h1 className={buttonClassName}>
{hasTitle && (
<>
{showBackButton && backButton}
{backButton}
<button onClick={this.handleTitleClick} className='column-header__title'>
{!showBackButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
{!backButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
{title}
</button>
</>
)}
{!hasTitle && showBackButton && backButton}
{!hasTitle && backButton}
<div className='column-header__buttons'>
{extraButton}

@ -13,7 +13,6 @@ import {
import { openModal } from '../actions/modal';
import { initMuteModal } from '../actions/mutes';
import Account from '../components/account';
import { unfollowModal } from '../initial_state';
import { makeGetAccount } from '../selectors';
const messages = defineMessages({
@ -34,18 +33,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow (account) {
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -408,7 +408,7 @@ class Header extends ImmutablePureComponent {
}
account.get('roles', []).forEach((role) => {
badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} />);
badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} roleId={role.get('id')} />);
});
return (

@ -21,7 +21,6 @@ import { initDomainBlockModal, unblockDomain } from '../../../actions/domain_blo
import { openModal } from '../../../actions/modal';
import { initMuteModal } from '../../../actions/mutes';
import { initReport } from '../../../actions/reports';
import { unfollowModal } from '../../../initial_state';
import { makeGetAccount, getAccountHidden } from '../../../selectors';
import Header from '../components/header';
@ -47,31 +46,23 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow (account) {
if (account.getIn(['relationship', 'following'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else if (account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -21,7 +21,6 @@ import PollButtonContainer from '../containers/poll_button_container';
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
import SpoilerButtonContainer from '../containers/spoiler_button_container';
import UploadButtonContainer from '../containers/upload_button_container';
import UploadFormContainer from '../containers/upload_form_container';
import WarningContainer from '../containers/warning_container';
import { countableText } from '../util/counter';
@ -30,6 +29,7 @@ import { EditIndicator } from './edit_indicator';
import { NavigationBar } from './navigation_bar';
import { PollForm } from "./poll_form";
import { ReplyIndicator } from './reply_indicator';
import { UploadForm } from './upload_form';
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
@ -283,7 +283,7 @@ class ComposeForm extends ImmutablePureComponent {
/>
</div>
<UploadFormContainer />
<UploadForm />
<PollForm />
<div className='compose-form__footer'>

@ -1,77 +1,81 @@
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { useDispatch, useSelector } from 'react-redux';
import spring from 'react-motion/lib/spring';
import CloseIcon from '@/material-icons/400-20px/close.svg?react';
import EditIcon from '@/material-icons/400-24px/edit.svg?react';
import WarningIcon from '@/material-icons/400-24px/warning.svg?react';
import { undoUploadCompose, initMediaEditModal } from 'mastodon/actions/compose';
import { Blurhash } from 'mastodon/components/blurhash';
import { Icon } from 'mastodon/components/icon';
import Motion from 'mastodon/features/ui/util/optional_motion';
import Motion from '../../ui/util/optional_motion';
export default class Upload extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
sensitive: PropTypes.bool,
onUndo: PropTypes.func.isRequired,
onOpenFocalPoint: PropTypes.func.isRequired,
};
handleUndoClick = e => {
e.stopPropagation();
this.props.onUndo(this.props.media.get('id'));
};
handleFocalPointClick = e => {
e.stopPropagation();
this.props.onOpenFocalPoint(this.props.media.get('id'));
};
render () {
const { media, sensitive } = this.props;
if (!media) {
return null;
}
const focusX = media.getIn(['meta', 'focus', 'x']);
const focusY = media.getIn(['meta', 'focus', 'y']);
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
const missingDescription = (media.get('description') || '').length === 0;
return (
<div className='compose-form__upload'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload__thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: !sensitive ? `url(${media.get('preview_url')})` : null, backgroundPosition: `${x}% ${y}%` }}>
{sensitive && <Blurhash
hash={media.get('blurhash')}
className='compose-form__upload__preview'
/>}
<div className='compose-form__upload__actions'>
<button type='button' className='icon-button compose-form__upload__delete' onClick={this.handleUndoClick}><Icon icon={CloseIcon} /></button>
<button type='button' className='icon-button' onClick={this.handleFocalPointClick}><Icon icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
<div className='compose-form__upload__warning'>
<button type='button' className={classNames('icon-button', { active: missingDescription })} onClick={this.handleFocalPointClick}>{missingDescription && <Icon icon={WarningIcon} />} ALT</button>
</div>
</div>
)}
</Motion>
</div>
);
export const Upload = ({ id, onDragStart, onDragEnter, onDragEnd }) => {
const dispatch = useDispatch();
const media = useSelector(state => state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id));
const sensitive = useSelector(state => state.getIn(['compose', 'spoiler']));
const handleUndoClick = useCallback(() => {
dispatch(undoUploadCompose(id));
}, [dispatch, id]);
const handleFocalPointClick = useCallback(() => {
dispatch(initMediaEditModal(id));
}, [dispatch, id]);
const handleDragStart = useCallback(() => {
onDragStart(id);
}, [onDragStart, id]);
const handleDragEnter = useCallback(() => {
onDragEnter(id);
}, [onDragEnter, id]);
if (!media) {
return null;
}
}
const focusX = media.getIn(['meta', 'focus', 'x']);
const focusY = media.getIn(['meta', 'focus', 'y']);
const x = ((focusX / 2) + .5) * 100;
const y = ((focusY / -2) + .5) * 100;
const missingDescription = (media.get('description') || '').length === 0;
return (
<div className='compose-form__upload' draggable onDragStart={handleDragStart} onDragEnter={handleDragEnter} onDragEnd={onDragEnd}>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload__thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: !sensitive ? `url(${media.get('preview_url')})` : null, backgroundPosition: `${x}% ${y}%` }}>
{sensitive && <Blurhash
hash={media.get('blurhash')}
className='compose-form__upload__preview'
/>}
<div className='compose-form__upload__actions'>
<button type='button' className='icon-button compose-form__upload__delete' onClick={handleUndoClick}><Icon icon={CloseIcon} /></button>
<button type='button' className='icon-button' onClick={handleFocalPointClick}><Icon icon={EditIcon} /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
<div className='compose-form__upload__warning'>
<button type='button' className={classNames('icon-button', { active: missingDescription })} onClick={handleFocalPointClick}>{missingDescription && <Icon icon={WarningIcon} />} ALT</button>
</div>
</div>
)}
</Motion>
</div>
);
};
Upload.propTypes = {
id: PropTypes.string,
onDragEnter: PropTypes.func,
onDragStart: PropTypes.func,
onDragEnd: PropTypes.func,
};

@ -1,31 +1,53 @@
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { useRef, useCallback } from 'react';
import UploadContainer from '../containers/upload_container';
import UploadProgressContainer from '../containers/upload_progress_container';
import { useSelector, useDispatch } from 'react-redux';
export default class UploadForm extends ImmutablePureComponent {
import { changeMediaOrder } from 'mastodon/actions/compose';
static propTypes = {
mediaIds: ImmutablePropTypes.list.isRequired,
};
import { Upload } from './upload';
import { UploadProgress } from './upload_progress';
render () {
const { mediaIds } = this.props;
export const UploadForm = () => {
const dispatch = useDispatch();
const mediaIds = useSelector(state => state.getIn(['compose', 'media_attachments']).map(item => item.get('id')));
const active = useSelector(state => state.getIn(['compose', 'is_uploading']));
const progress = useSelector(state => state.getIn(['compose', 'progress']));
const isProcessing = useSelector(state => state.getIn(['compose', 'is_processing']));
return (
<>
<UploadProgressContainer />
const dragItem = useRef();
const dragOverItem = useRef();
{mediaIds.size > 0 && (
<div className='compose-form__uploads'>
{mediaIds.map(id => (
<UploadContainer id={id} key={id} />
))}
</div>
)}
</>
);
}
const handleDragStart = useCallback(id => {
dragItem.current = id;
}, [dragItem]);
}
const handleDragEnter = useCallback(id => {
dragOverItem.current = id;
}, [dragOverItem]);
const handleDragEnd = useCallback(() => {
dispatch(changeMediaOrder(dragItem.current, dragOverItem.current));
dragItem.current = null;
dragOverItem.current = null;
}, [dispatch, dragItem, dragOverItem]);
return (
<>
<UploadProgress active={active} progress={progress} isProcessing={isProcessing} />
{mediaIds.size > 0 && (
<div className='compose-form__uploads'>
{mediaIds.map(id => (
<Upload
key={id}
id={id}
onDragStart={handleDragStart}
onDragEnter={handleDragEnter}
onDragEnd={handleDragEnd}
/>
))}
</div>
)}
</>
);
};

@ -1,5 +1,4 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import { FormattedMessage } from 'react-intl';
@ -10,46 +9,40 @@ import { Icon } from 'mastodon/components/icon';
import Motion from '../../ui/util/optional_motion';
export default class UploadProgress extends PureComponent {
static propTypes = {
active: PropTypes.bool,
progress: PropTypes.number,
isProcessing: PropTypes.bool,
};
render () {
const { active, progress, isProcessing } = this.props;
if (!active) {
return null;
}
export const UploadProgress = ({ active, progress, isProcessing }) => {
if (!active) {
return null;
}
let message;
let message;
if (isProcessing) {
message = <FormattedMessage id='upload_progress.processing' defaultMessage='Processing…' />;
} else {
message = <FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />;
}
if (isProcessing) {
message = <FormattedMessage id='upload_progress.processing' defaultMessage='Processing…' />;
} else {
message = <FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />;
}
return (
<div className='upload-progress'>
<Icon id='upload' icon={UploadFileIcon} />
return (
<div className='upload-progress'>
<Icon id='upload' icon={UploadFileIcon} />
<div className='upload-progress__message'>
{message}
<div className='upload-progress__message'>
{message}
<div className='upload-progress__backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
}
</Motion>
</div>
<div className='upload-progress__backdrop'>
<Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>
{({ width }) =>
<div className='upload-progress__tracker' style={{ width: `${width}%` }} />
}
</Motion>
</div>
</div>
);
}
}
</div>
);
};
UploadProgress.propTypes = {
active: PropTypes.bool,
progress: PropTypes.number,
isProcessing: PropTypes.bool,
};

@ -1,27 +0,0 @@
import { connect } from 'react-redux';
import { undoUploadCompose, initMediaEditModal, submitCompose } from '../../../actions/compose';
import Upload from '../components/upload';
const mapStateToProps = (state, { id }) => ({
media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id),
sensitive: state.getIn(['compose', 'spoiler']),
});
const mapDispatchToProps = dispatch => ({
onUndo: id => {
dispatch(undoUploadCompose(id));
},
onOpenFocalPoint: id => {
dispatch(initMediaEditModal(id));
},
onSubmit (router) {
dispatch(submitCompose(router));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(Upload);

@ -1,9 +0,0 @@
import { connect } from 'react-redux';
import UploadForm from '../components/upload_form';
const mapStateToProps = state => ({
mediaIds: state.getIn(['compose', 'media_attachments']).map(item => item.get('id')),
});
export default connect(mapStateToProps)(UploadForm);

@ -1,11 +0,0 @@
import { connect } from 'react-redux';
import UploadProgress from '../components/upload_progress';
const mapStateToProps = state => ({
active: state.getIn(['compose', 'is_uploading']),
progress: state.getIn(['compose', 'progress']),
isProcessing: state.getIn(['compose', 'is_processing']),
});
export default connect(mapStateToProps)(UploadProgress);

@ -20,7 +20,7 @@ import { Avatar } from 'mastodon/components/avatar';
import { Button } from 'mastodon/components/button';
import { DisplayName } from 'mastodon/components/display_name';
import { ShortNumber } from 'mastodon/components/short_number';
import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state';
import { autoPlayGif, me } from 'mastodon/initial_state';
import { makeGetAccount } from 'mastodon/selectors';
const messages = defineMessages({
@ -48,38 +48,30 @@ const makeMapStateToProps = () => {
const mapDispatchToProps = (dispatch, { intl }) => ({
onFollow(account) {
if (account.getIn(['relationship', 'following'])) {
if (unfollowModal) {
dispatch(
openModal({
modalType: 'CONFIRM',
modalProps: {
message: (
<FormattedMessage
id='confirmations.unfollow.message'
defaultMessage='Are you sure you want to unfollow {name}?'
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
),
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
} }),
);
} else {
dispatch(unfollowAccount(account.get('id')));
}
} else if (account.getIn(['relationship', 'requested'])) {
if (unfollowModal) {
dispatch(openModal({
dispatch(
openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
message: (
<FormattedMessage
id='confirmations.unfollow.message'
defaultMessage='Are you sure you want to unfollow {name}?'
values={{ name: <strong>@{account.get('acct')}</strong> }}
/>
),
confirm: intl.formatMessage(messages.unfollowConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(unfollowAccount(account.get('id')));
}
} }),
);
} else if (account.getIn(['relationship', 'requested'])) {
dispatch(openModal({
modalType: 'CONFIRM',
modalProps: {
message: <FormattedMessage id='confirmations.cancel_follow_request.message' defaultMessage='Are you sure you want to withdraw your request to follow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
confirm: intl.formatMessage(messages.cancelFollowRequestConfirm),
onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
},
}));
} else {
dispatch(followAccount(account.get('id')));
}

@ -68,7 +68,7 @@ class FollowRequests extends ImmutablePureComponent {
);
return (
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)}>
<ScrollableList
scrollKey='follow_requests'
onLoadMore={this.handleLoadMore}

@ -54,6 +54,7 @@ export default class ColumnSettings extends PureComponent {
render () {
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission, notificationPolicy } = this.props;
const filterAdvancedStr = <FormattedMessage id='notifications.column_settings.filter_bar.advanced' defaultMessage='Display all categories' />;
const unreadMarkersShowStr = <FormattedMessage id='notifications.column_settings.unread_notifications.highlight' defaultMessage='Highlight unread notifications' />;
const alertStr = <FormattedMessage id='notifications.column_settings.alert' defaultMessage='Desktop notifications' />;
const showStr = <FormattedMessage id='notifications.column_settings.show' defaultMessage='Show in column' />;
@ -116,6 +117,16 @@ export default class ColumnSettings extends PureComponent {
</div>
</section>
<section role='group' aria-labelledby='notifications-filter-bar'>
<h3 id='notifications-filter-bar'>
<FormattedMessage id='notifications.column_settings.filter_bar.category' defaultMessage='Quick filter bar' />
</h3>
<div className='column-settings__row'>
<SettingToggle id='advanced-filter-bar' prefix='notifications' settings={settings} settingPath={['quickFilter', 'advanced']} onChange={onChange} label={filterAdvancedStr} />
</div>
</section>
<section role='group' aria-labelledby='notifications-follow'>
<h3 id='notifications-follow'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></h3>

@ -41,7 +41,8 @@ export const FilteredNotificationsBanner = () => {
</div>
<div className='filtered-notifications-banner__badge'>
{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}
<div className='filtered-notifications-banner__badge__badge'>{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}</div>
<FormattedMessage id='filtered_notifications_banner.private_mentions' defaultMessage='{count, plural, one {private mention} other {private mentions}}' values={{ count: policy.getIn(['summary', 'pending_notifications_count']) }} />
</div>
</Link>
);

@ -26,6 +26,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router';
import FollowRequestContainer from '../containers/follow_request_container';
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
import Report from './report';
const messages = defineMessages({
@ -38,6 +39,7 @@ const messages = defineMessages({
update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
});
const notificationForScreenReader = (intl, message, timestamp) => {
@ -358,6 +360,29 @@ class Notification extends ImmutablePureComponent {
);
}
renderRelationshipsSevered (notification) {
const { intl, unread, hidden } = this.props;
const event = notification.get('event');
if (!event) {
return null;
}
return (
<HotKeys handlers={this.getHandlers()}>
<div className={classNames('notification notification-severed-relationships focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.relationshipsSevered, { name: notification.getIn(['event', 'target_name']) }), notification.get('created_at'))}>
<RelationshipsSeveranceEvent
type={event.get('type')}
target={event.get('target_name')}
followersCount={event.get('followers_count')}
followingCount={event.get('following_count')}
hidden={hidden}
/>
</div>
</HotKeys>
);
}
renderAdminSignUp (notification, account, link) {
const { intl, unread } = this.props;
@ -429,6 +454,8 @@ class Notification extends ImmutablePureComponent {
return this.renderUpdate(notification, link);
case 'poll':
return this.renderPoll(notification, account);
case 'severed_relationships':
return this.renderRelationshipsSevered(notification);
case 'admin.sign_up':
return this.renderAdminSignUp(notification, account, link);
case 'admin.report':

@ -7,8 +7,8 @@ import { Link } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import DeleteIcon from '@/material-icons/400-24px/delete.svg?react';
import DoneIcon from '@/material-icons/400-24px/done.svg?react';
import VolumeOffIcon from '@/material-icons/400-24px/volume_off.svg?react';
import { acceptNotificationRequest, dismissNotificationRequest } from 'mastodon/actions/notifications';
import { Avatar } from 'mastodon/components/avatar';
import { IconButton } from 'mastodon/components/icon_button';
@ -51,7 +51,7 @@ export const NotificationRequest = ({ id, accountId, notificationsCount }) => {
</Link>
<div className='notification-request__actions'>
<IconButton iconComponent={VolumeOffIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton iconComponent={DeleteIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
<IconButton iconComponent={DoneIcon} onClick={handleAccept} title={intl.formatMessage(messages.accept)} />
</div>
</div>

@ -0,0 +1,45 @@
import PropTypes from 'prop-types';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import HeartBrokenIcon from '@/material-icons/400-24px/heart_broken-fill.svg?react';
import { Icon } from 'mastodon/components/icon';
import { domain } from 'mastodon/initial_state';
// This needs to be kept in sync with app/models/relationships_severance_event.rb
const messages = defineMessages({
account_suspension: { id: 'notification.relationships_severance_event.account_suspension', defaultMessage: 'An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.' },
domain_block: { id: 'notification.relationships_severance_event.domain_block', defaultMessage: 'An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
user_domain_block: { id: 'notification.relationships_severance_event.user_domain_block', defaultMessage: 'You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.' },
});
export const RelationshipsSeveranceEvent = ({ type, target, followingCount, followersCount, hidden }) => {
const intl = useIntl();
if (hidden) {
return null;
}
return (
<a href='/severed_relationships' target='_blank' rel='noopener noreferrer' className='notification__relationships-severance-event'>
<Icon id='heart_broken' icon={HeartBrokenIcon} />
<div className='notification__relationships-severance-event__content'>
<p>{intl.formatMessage(messages[type], { from: <strong>{domain}</strong>, target: <strong>{target}</strong>, followingCount, followersCount })}</p>
<span className='link-button'><FormattedMessage id='notification.relationships_severance_event.learn_more' defaultMessage='Learn more' /></span>
</div>
</a>
);
};
RelationshipsSeveranceEvent.propTypes = {
type: PropTypes.oneOf([
'account_suspension',
'domain_block',
'user_domain_block',
]).isRequired,
target: PropTypes.string.isRequired,
followersCount: PropTypes.number.isRequired,
followingCount: PropTypes.number.isRequired,
hidden: PropTypes.bool,
};

@ -5,7 +5,7 @@ import FilterBar from '../components/filter_bar';
const makeMapStateToProps = state => ({
selectedFilter: state.getIn(['settings', 'notifications', 'quickFilter', 'active']),
advancedMode: false,
advancedMode: state.getIn(['settings', 'notifications', 'quickFilter', 'advanced']),
});
const mapDispatchToProps = (dispatch) => ({

@ -22,7 +22,7 @@ import { GIFV } from 'mastodon/components/gifv';
import { IconButton } from 'mastodon/components/icon_button';
import Audio from 'mastodon/features/audio';
import { CharacterCounter } from 'mastodon/features/compose/components/character_counter';
import UploadProgress from 'mastodon/features/compose/components/upload_progress';
import { UploadProgress } from 'mastodon/features/compose/components/upload_progress';
import { Tesseract as fetchTesseract } from 'mastodon/features/ui/util/async-components';
import { me } from 'mastodon/initial_state';
import { assetHost } from 'mastodon/utils/config';

@ -38,7 +38,6 @@
* @property {string} title
* @property {boolean} show_trends
* @property {boolean} trends_as_landing_page
* @property {boolean} unfollow_modal
* @property {boolean} use_blurhash
* @property {boolean=} use_pending_items
* @property {string} version
@ -99,7 +98,6 @@ export const source_url = getMeta('source_url');
export const timelinePreview = getMeta('timeline_preview');
export const title = getMeta('title');
export const trendsAsLanding = getMeta('trends_as_landing_page');
export const unfollowModal = getMeta('unfollow_modal');
export const useBlurhash = getMeta('use_blurhash');
export const usePendingItems = getMeta('use_pending_items');
export const version = getMeta('version');

@ -89,6 +89,7 @@
"announcement.announcement": "إعلان",
"attachments_list.unprocessed": "(غير معالَج)",
"audio.hide": "إخفاء المقطع الصوتي",
"block_modal.remote_users_caveat": "Do ti kërkojmë shërbyesit {domain} të respektojë vendimin tuaj. Por, pajtimi sështë i garantuar, ngaqë disa shërbyes mund ti trajtojnë ndryshe bllokimet. Psotimet publike mundet të jenë ende të dukshme për përdorues pa bërë hyrje në llogari.",
"boost_modal.combo": "يُمكنك الضّغط على {combo} لتخطي هذا في المرة المُقبلة",
"bundle_column_error.copy_stacktrace": "انسخ تقرير الخطأ",
"bundle_column_error.error.body": "لا يمكن تقديم الصفحة المطلوبة. قد يكون بسبب خطأ في التعليمات البرمجية، أو مشكلة توافق المتصفح.",

@ -471,6 +471,7 @@
"notification.own_poll": "Ваша апытанне скончылася",
"notification.poll": "Апытанне, дзе вы прынялі ўдзел, скончылася",
"notification.reblog": "{name} пашырыў ваш допіс",
"notification.severed_relationships": "Зносіны з {name} былі разарваныя",
"notification.status": "Новы допіс ад {name}",
"notification.update": "Допіс {name} адрэдагаваны",
"notification_requests.accept": "Прыняць",
@ -483,6 +484,7 @@
"notifications.column_settings.admin.sign_up": "Новыя ўваходы:",
"notifications.column_settings.alert": "Апавяшчэнні на працоўным стале",
"notifications.column_settings.favourite": "Упадабанае:",
"notifications.column_settings.filter_bar.advanced": "Паказаць усе катэгорыі",
"notifications.column_settings.follow": "Новыя падпісчыкі:",
"notifications.column_settings.follow_request": "Новыя запыты на падпіску:",
"notifications.column_settings.mention": "Згадванні:",
@ -587,6 +589,8 @@
"refresh": "Абнавiць",
"regeneration_indicator.label": "Загрузка…",
"regeneration_indicator.sublabel": "Пачакайце, рыхтуем вашу стужку!",
"relationship_severance_notification.types.user_domain_block": "Вы заблакіравалі гэты дамен",
"relationship_severance_notification.view": "Праглядзець",
"relative_time.days": "{number} д",
"relative_time.full.days": "{number, plural, one {# дзень} few {# дні} many {# дзён} other {# дня}} таму",
"relative_time.full.hours": "{number, plural, one {# гадзіна} few {# гадзіны} many {# гадзін} other {# гадзіны}} таму",

@ -434,7 +434,7 @@
"mute_modal.they_can_mention_and_follow": "Могат да ви споменават и последват, но няма да ги виждате.",
"mute_modal.they_wont_know": "Няма да узнаят, че са били заглушени.",
"mute_modal.title": "Заглушавате ли потребител?",
"mute_modal.you_wont_see_mentions": "Няма да виждате споменаващи ги публикации.",
"mute_modal.you_wont_see_mentions": "Няма да виждате споменаващите ги публикации.",
"mute_modal.you_wont_see_posts": "Още могат да виждат публикациите ви, но вие техните не.",
"navigation_bar.about": "Относно",
"navigation_bar.advanced_interface": "Отваряне в разширен уебинтерфейс",
@ -471,6 +471,7 @@
"notification.own_poll": "Анкетата ви приключи",
"notification.poll": "Анкета, в която гласувахте, приключи",
"notification.reblog": "{name} подсили ваша публикация",
"notification.severed_relationships": "Връзката с {name} е прекъсната",
"notification.status": "{name} току-що публикува",
"notification.update": "{name} промени публикация",
"notification_requests.accept": "Приемам",
@ -587,6 +588,12 @@
"refresh": "Опресняване",
"regeneration_indicator.label": "Зареждане…",
"regeneration_indicator.sublabel": "Подготовка на началния ви инфоканал!",
"relationship_severance_notification.purged_data": "прочистено от администраторите",
"relationship_severance_notification.relationships": "{count, plural, one {# връзка} other {# връзки}}",
"relationship_severance_notification.types.account_suspension": "Акаунтът е спрян",
"relationship_severance_notification.types.domain_block": "Домейнът е спрян",
"relationship_severance_notification.types.user_domain_block": "Блокирахте този домейн",
"relationship_severance_notification.view": "Преглед",
"relative_time.days": "{number} д.",
"relative_time.full.days": "преди {number, plural, one {# ден} other {# дни}}",
"relative_time.full.hours": "преди {number, plural, one {# час} other {# часа}}",

@ -471,6 +471,7 @@
"notification.own_poll": "La teva enquesta ha finalitzat",
"notification.poll": "Ha finalitzat una enquesta en què has votat",
"notification.reblog": "{name} t'ha impulsat",
"notification.severed_relationships": "S'han eliminat les relacions amb {name}",
"notification.status": "{name} acaba de publicar",
"notification.update": "{name} ha editat un tut",
"notification_requests.accept": "Accepta",
@ -587,6 +588,12 @@
"refresh": "Actualitza",
"regeneration_indicator.label": "Es carrega…",
"regeneration_indicator.sublabel": "Es prepara la teva línia de temps d'Inici!",
"relationship_severance_notification.purged_data": "purgat pels administradors",
"relationship_severance_notification.relationships": "{count, plural, one {# relació} other {# relacions}}",
"relationship_severance_notification.types.account_suspension": "S'ha suspès el compte",
"relationship_severance_notification.types.domain_block": "S'ha suspès el domini",
"relationship_severance_notification.types.user_domain_block": "Heu blocat aquest domini",
"relationship_severance_notification.view": "Visualitza",
"relative_time.days": "{number}d",
"relative_time.full.days": "fa {number, plural, one {# dia} other {# dies}}",
"relative_time.full.hours": "fa {number, plural, one {# hora} other {# hores}}",

@ -220,7 +220,7 @@
"domain_pill.activitypub_lets_connect": "Det muliggør at komme i forbindelse og interagere med folk ikke kun på Mastodon, men også på tværs af forskellige sociale apps.",
"domain_pill.activitypub_like_language": "ActivityPub er \"sproget\", Mastodon taler med andre sociale netværk.",
"domain_pill.server": "Server",
"domain_pill.their_handle": "Deres handle:",
"domain_pill.their_handle": "Vedkommendes handle:",
"domain_pill.username": "Brugernavn",
"domain_pill.whats_in_a_handle": "Hvad er der i et handle (@brugernavn)?",
"domain_pill.who_they_are": "Da et handle fortæller, hvem nogen er, og hvor de er, kan man interagere med folk på tværs af det sociale net af <button>ActivityPub-drevne platforme</button>.",
@ -481,6 +481,8 @@
"notifications.column_settings.admin.sign_up": "Nye tilmeldinger:",
"notifications.column_settings.alert": "Computernotifikationer",
"notifications.column_settings.favourite": "Favoritter:",
"notifications.column_settings.filter_bar.advanced": "Vis alle kategorier",
"notifications.column_settings.filter_bar.category": "Hurtigfiltreringsbjælke",
"notifications.column_settings.follow": "Nye følgere:",
"notifications.column_settings.follow_request": "Nye følgeanmodninger:",
"notifications.column_settings.mention": "Omtaler:",
@ -585,6 +587,12 @@
"refresh": "Genindlæs",
"regeneration_indicator.label": "Indlæser…",
"regeneration_indicator.sublabel": "Din hjemmetidslinje klargøres!",
"relationship_severance_notification.purged_data": "renset af administratorer",
"relationship_severance_notification.relationships": "{count, plural, one {# forhold} other {# forhold}}",
"relationship_severance_notification.types.account_suspension": "Konto er blevet suspenderet",
"relationship_severance_notification.types.domain_block": "Domæne er blevet suspenderet",
"relationship_severance_notification.types.user_domain_block": "Dette domæne blev blokeret",
"relationship_severance_notification.view": "Vis",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# dag} other {# dage}} siden",
"relative_time.full.hours": "{number, plural, one {# time} other {# timer}} siden",

@ -471,6 +471,7 @@
"notification.own_poll": "Deine Umfrage ist beendet",
"notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet",
"notification.reblog": "{name} teilte deinen Beitrag",
"notification.severed_relationships": "Beziehungen zu {name} getrennt",
"notification.status": "{name} hat gerade etwas gepostet",
"notification.update": "{name} bearbeitete einen Beitrag",
"notification_requests.accept": "Akzeptieren",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Neue Registrierungen:",
"notifications.column_settings.alert": "Desktop-Benachrichtigungen",
"notifications.column_settings.favourite": "Favoriten:",
"notifications.column_settings.filter_bar.advanced": "Alle Filterkategorien anzeigen",
"notifications.column_settings.filter_bar.category": "Filterleiste",
"notifications.column_settings.follow": "Neue Follower:",
"notifications.column_settings.follow_request": "Neue Follower-Anfragen:",
"notifications.column_settings.mention": "Erwähnungen:",
@ -587,6 +590,12 @@
"refresh": "Aktualisieren",
"regeneration_indicator.label": "Wird geladen …",
"regeneration_indicator.sublabel": "Deine Startseite wird gerade vorbereitet!",
"relationship_severance_notification.purged_data": "von Administrator*innen entfernt",
"relationship_severance_notification.relationships": "{count, plural, one {# Beziehung} other {# Beziehungen}}",
"relationship_severance_notification.types.account_suspension": "Konto wurde gesperrt",
"relationship_severance_notification.types.domain_block": "Domain wurde gesperrt",
"relationship_severance_notification.types.user_domain_block": "Du hast diese Domain blockiert",
"relationship_severance_notification.view": "Anzeigen",
"relative_time.days": "{number} T.",
"relative_time.full.days": "vor {number, plural, one {# Tag} other {# Tagen}}",
"relative_time.full.hours": "vor {number, plural, one {# Stunde} other {# Stunden}}",

@ -298,6 +298,7 @@
"filter_modal.select_filter.title": "Filter this post",
"filter_modal.title.status": "Filter a post",
"filtered_notifications_banner.pending_requests": "Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know",
"filtered_notifications_banner.private_mentions": "{count, plural, one {private mention} other {private mentions}}",
"filtered_notifications_banner.title": "Filtered notifications",
"firehose.all": "All",
"firehose.local": "This server",
@ -471,6 +472,11 @@
"notification.own_poll": "Your poll has ended",
"notification.poll": "A poll you have voted in has ended",
"notification.reblog": "{name} boosted your post",
"notification.relationships_severance_event": "Lost connections with {name}",
"notification.relationships_severance_event.account_suspension": "An admin from {from} has suspended {target}, which means you can no longer receive updates from them or interact with them.",
"notification.relationships_severance_event.domain_block": "An admin from {from} has blocked {target}, including {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
"notification.relationships_severance_event.learn_more": "Learn more",
"notification.relationships_severance_event.user_domain_block": "You have blocked {target}, removing {followersCount} of your followers and {followingCount, plural, one {# account} other {# accounts}} you follow.",
"notification.status": "{name} just posted",
"notification.update": "{name} edited a post",
"notification_requests.accept": "Accept",
@ -483,6 +489,8 @@
"notifications.column_settings.admin.sign_up": "New sign-ups:",
"notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favorites:",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.follow": "New followers:",
"notifications.column_settings.follow_request": "New follow requests:",
"notifications.column_settings.mention": "Mentions:",

@ -427,7 +427,7 @@
"loading_indicator.label": "Cargando…",
"media_gallery.toggle_visible": "Ocultar {number, plural, one {imagen} other {imágenes}}",
"moved_to_account_banner.text": "Tu cuenta {disabledAccount} está actualmente deshabilitada porque te mudaste a {movedToAccount}.",
"mute_modal.hide_from_notifications": "Ocultar de las notificaciones",
"mute_modal.hide_from_notifications": "Ocultar en las notificaciones",
"mute_modal.hide_options": "Ocultar opciones",
"mute_modal.indefinite": "Hasta que deje de silenciarlos",
"mute_modal.show_options": "Mostrar opciones",
@ -471,6 +471,7 @@
"notification.own_poll": "Tu encuesta finalizó",
"notification.poll": "Finalizó una encuesta en la que votaste",
"notification.reblog": "{name} adhirió a tu mensaje",
"notification.severed_relationships": "Relaciones con {name} cortadas",
"notification.status": "{name} acaba de enviar un mensaje",
"notification.update": "{name} editó un mensaje",
"notification_requests.accept": "Aceptar",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nuevos registros:",
"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.follow": "Nuevos seguidores:",
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
"notifications.column_settings.mention": "Menciones:",
@ -587,6 +590,12 @@
"refresh": "Refrescar",
"regeneration_indicator.label": "Cargando…",
"regeneration_indicator.sublabel": "¡Se está preparando tu línea temporal principal!",
"relationship_severance_notification.purged_data": "purgada por administradores",
"relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relaciones}}",
"relationship_severance_notification.types.account_suspension": "La cuenta fue suspendida",
"relationship_severance_notification.types.domain_block": "El dominio fue suspendido",
"relationship_severance_notification.types.user_domain_block": "Bloqueaste este dominio",
"relationship_severance_notification.view": "Ver",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural,one {hace # día} other {hace # días}}",
"relative_time.full.hours": "{number, plural,one {hace # hora} other {hace # horas}}",

@ -471,6 +471,7 @@
"notification.own_poll": "Tu encuesta ha terminado",
"notification.poll": "Una encuesta en la que has votado ha terminado",
"notification.reblog": "{name} ha retooteado tu estado",
"notification.severed_relationships": "Se han cortado las relaciones con {name}",
"notification.status": "{name} acaba de publicar",
"notification.update": "{name} editó una publicación",
"notification_requests.accept": "Aceptar",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Registros nuevos:",
"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.follow": "Nuevos seguidores:",
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
"notifications.column_settings.mention": "Menciones:",
@ -587,6 +590,12 @@
"refresh": "Actualizar",
"regeneration_indicator.label": "Cargando…",
"regeneration_indicator.sublabel": "¡Tu historia de inicio se está preparando!",
"relationship_severance_notification.purged_data": "purgado por administradores",
"relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relaciones}}",
"relationship_severance_notification.types.account_suspension": "La cuenta ha sido suspendida",
"relationship_severance_notification.types.domain_block": "El dominio ha sido suspendido",
"relationship_severance_notification.types.user_domain_block": "Bloqueaste este dominio",
"relationship_severance_notification.view": "Ver",
"relative_time.days": "{number} d",
"relative_time.full.days": "{number, plural, one {# día} other {# días hace}}",
"relative_time.full.hours": "{number, plural, one {# hora} other {# horas}} hace",

@ -471,6 +471,7 @@
"notification.own_poll": "Tu encuesta ha terminado",
"notification.poll": "Una encuesta en la que has votado ha terminado",
"notification.reblog": "{name} ha impulsado tu publicación",
"notification.severed_relationships": "Se han cortado las relaciones con {name}",
"notification.status": "{name} acaba de publicar",
"notification.update": "{name} editó una publicación",
"notification_requests.accept": "Aceptar",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nuevos registros:",
"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.follow": "Nuevos seguidores:",
"notifications.column_settings.follow_request": "Nuevas solicitudes de seguimiento:",
"notifications.column_settings.mention": "Menciones:",
@ -587,6 +590,12 @@
"refresh": "Actualizar",
"regeneration_indicator.label": "Cargando…",
"regeneration_indicator.sublabel": "¡Tu historia de inicio se está preparando!",
"relationship_severance_notification.purged_data": "purgado por administradores",
"relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relaciones}}",
"relationship_severance_notification.types.account_suspension": "La cuenta ha sido suspendida",
"relationship_severance_notification.types.domain_block": "El dominio ha sido suspendido",
"relationship_severance_notification.types.user_domain_block": "Bloqueaste este dominio",
"relationship_severance_notification.view": "Ver",
"relative_time.days": "{number} d",
"relative_time.full.days": "hace {number, plural, one {# día} other {# días}}",
"relative_time.full.hours": "hace {number, plural, one {# hora} other {# horas}}",

@ -471,6 +471,7 @@
"notification.own_poll": "Zure inkesta amaitu da",
"notification.poll": "Zuk erantzun duzun inkesta bat bukatu da",
"notification.reblog": "{name}(e)k bultzada eman dio zure bidalketari",
"notification.severed_relationships": "{name} erabiltzailearekin zenuen erlazioa galdu da",
"notification.status": "{name} erabiltzaileak bidalketa egin berri du",
"notification.update": "{name} erabiltzaileak bidalketa bat editatu du",
"notification_requests.accept": "Onartu",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Izen-emate berriak:",
"notifications.column_settings.alert": "Mahaigaineko jakinarazpenak",
"notifications.column_settings.favourite": "Gogokoak:",
"notifications.column_settings.filter_bar.advanced": "Bistaratu kategoria guztiak",
"notifications.column_settings.filter_bar.category": "Iragazki-barra bizkorra",
"notifications.column_settings.follow": "Jarraitzaile berriak:",
"notifications.column_settings.follow_request": "Jarraitzeko eskaera berriak:",
"notifications.column_settings.mention": "Aipamenak:",
@ -587,6 +590,12 @@
"refresh": "Berritu",
"regeneration_indicator.label": "Kargatzen…",
"regeneration_indicator.sublabel": "Zure hasiera-jarioa prestatzen ari da!",
"relationship_severance_notification.purged_data": "administratzaileek kendua",
"relationship_severance_notification.relationships": "{count, plural, one {Erlazio #} other {# erlazio}}",
"relationship_severance_notification.types.account_suspension": "Kontua bertan behera utzi da",
"relationship_severance_notification.types.domain_block": "Domeinua bertan behera utzi da",
"relationship_severance_notification.types.user_domain_block": "Domeinu hau blokeatu duzu",
"relationship_severance_notification.view": "Ikusi",
"relative_time.days": "{number}e",
"relative_time.full.days": "Duela {number, plural, one {egun #} other {# egun}}",
"relative_time.full.hours": "Duela {number, plural, one {ordu #} other {# ordu}}",

@ -462,6 +462,8 @@
"notifications.permission_denied": "آگاهی‌های میزکار به دلیل رد کردن درخواست اجازهٔ پیشین مرورگر، در دسترس نیستند",
"notifications.permission_denied_alert": "از آن‌جا که پیش از این اجازهٔ مرورگر رد شده است، آگاهی‌های میزکار نمی‌توانند به کار بیفتند",
"notifications.permission_required": "آگاهی‌های میزکار در دسترس نیستند زیرا اجازه‌های لازم، اعطا نشده.",
"notifications.policy.filter_not_followers_title": "کسانی که شما را دنبال میکنند",
"notifications.policy.filter_not_following_hint": "",
"notifications_permission_banner.enable": "به کار انداختن آگاهی‌های میزکار",
"notifications_permission_banner.how_to_control": "برای دریافت آگاهی‌ها هنگام باز نبودن ماستودون، آگاهی‌های میزکار را به کار بیندازید. پس از به کار افتادنشان می‌توانید گونه‌های دقیق برهم‌کنش‌هایی که آگاهی‌های میزکار تولید می‌کنند را از {icon} بالا واپایید.",
"notifications_permission_banner.title": "هرگز چیزی را از دست ندهید",

@ -471,6 +471,7 @@
"notification.own_poll": "Äänestyksesi on päättynyt",
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
"notification.reblog": "{name} tehosti julkaisuasi",
"notification.severed_relationships": "Suhteet palvelimeen {name} katkenneet",
"notification.status": "{name} julkaisi juuri",
"notification.update": "{name} muokkasi julkaisua",
"notification_requests.accept": "Hyväksy",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Uudet rekisteröitymiset:",
"notifications.column_settings.alert": "Työpöytäilmoitukset",
"notifications.column_settings.favourite": "Suosikit:",
"notifications.column_settings.filter_bar.advanced": "Näytä kaikki luokat",
"notifications.column_settings.filter_bar.category": "Pikasuodatuspalkki",
"notifications.column_settings.follow": "Uudet seuraajat:",
"notifications.column_settings.follow_request": "Uudet seuraamispyynnöt:",
"notifications.column_settings.mention": "Maininnat:",
@ -587,6 +590,12 @@
"refresh": "Päivitä",
"regeneration_indicator.label": "Ladataan…",
"regeneration_indicator.sublabel": "Kotisyötettäsi valmistellaan!",
"relationship_severance_notification.purged_data": "ylläpitäjien tyhjentämä",
"relationship_severance_notification.relationships": "{count, plural, one {# suhde} other {# suhdetta}}",
"relationship_severance_notification.types.account_suspension": "Tili on jäädytetty",
"relationship_severance_notification.types.domain_block": "Verkkotunnus on jäädytetty",
"relationship_severance_notification.types.user_domain_block": "Estit tämän verkkotunnuksen",
"relationship_severance_notification.view": "Näytä",
"relative_time.days": "{number} pv",
"relative_time.full.days": "{number, plural, one {# päivä} other {# päivää}} sitten",
"relative_time.full.hours": "{number, plural, one {# tunti} other {# tuntia}} sitten",

@ -471,6 +471,7 @@
"notification.own_poll": "Tín atkvøðugreiðsla er endað",
"notification.poll": "Ein atkvøðugreiðsla, har tú hevur atkvøtt, er endað",
"notification.reblog": "{name} lyfti tín post",
"notification.severed_relationships": "Tilknýti við {name} avbrotið",
"notification.status": "{name} hevur júst postað",
"notification.update": "{name} rættaði ein post",
"notification_requests.accept": "Góðtak",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nýggjar tilmeldingar:",
"notifications.column_settings.alert": "Skriviborðsfráboðanir",
"notifications.column_settings.favourite": "Dámdir postar:",
"notifications.column_settings.filter_bar.advanced": "Vís allar bólkar",
"notifications.column_settings.filter_bar.category": "Skjótfilturbjálki",
"notifications.column_settings.follow": "Nýggir fylgjarar:",
"notifications.column_settings.follow_request": "Nýggjar umbønir um at fylgja:",
"notifications.column_settings.mention": "Umrøður:",
@ -587,6 +590,12 @@
"refresh": "Endurles",
"regeneration_indicator.label": "Innlesur…",
"regeneration_indicator.sublabel": "Tín heimarás verður gjørd klár!",
"relationship_severance_notification.purged_data": "reinsað av umsitarum",
"relationship_severance_notification.relationships": "{count, plural, one {# tilknýti} other {# tilknýti}}",
"relationship_severance_notification.types.account_suspension": "Kontan er ógildað",
"relationship_severance_notification.types.domain_block": "Økisnavn er ógildað",
"relationship_severance_notification.types.user_domain_block": "Tú hevur forðað hesum økisnavni",
"relationship_severance_notification.view": "Vís",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# dagur} other {# dagar}} síðani",
"relative_time.full.hours": "{number, plural, one {# tími} other {# tímar}} síðani",

@ -89,6 +89,14 @@
"announcement.announcement": "Annonce",
"attachments_list.unprocessed": "(non traité)",
"audio.hide": "Masquer l'audio",
"block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateurs non connectés.",
"block_modal.show_less": "Afficher moins",
"block_modal.show_more": "Afficher plus",
"block_modal.they_cant_mention": "Il ne peut pas vous mentionner ou vous suivre.",
"block_modal.they_cant_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.",
"block_modal.they_will_know": "Il peut voir qu'il est bloqué.",
"block_modal.title": "Bloquer l'utilisateur ?",
"block_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour sauter ceci la prochaine fois",
"bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur",
"bundle_column_error.error.body": "La page demandée n'a pas pu être affichée. Cela pourrait être dû à un bogue dans notre code, ou à un problème de compatibilité avec le navigateur.",
@ -169,6 +177,7 @@
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste?",
"confirmations.discard_edit_media.confirm": "Rejeter",
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, voulez-vous quand même les supprimer?",
"confirmations.domain_block.confirm": "Bloquer le serveur",
"confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans vos fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
"confirmations.edit.confirm": "Éditer",
"confirmations.edit.message": "Modifier maintenant écrasera votre message en cours de rédaction. Voulez-vous vraiment continuer ?",
@ -200,6 +209,27 @@
"dismissable_banner.explore_statuses": "Voici des publications venant de tout le web social gagnant en popularité aujourdhui. Les nouvelles publications avec plus de boosts et de favoris sont classés plus haut.",
"dismissable_banner.explore_tags": "Ces hashtags sont présentement en train de gagner de l'ampleur parmi des personnes sur les serveurs du réseau décentralisé dont celui-ci.",
"dismissable_banner.public_timeline": "Ce sont les messages publics les plus récents de personnes sur le web social que les gens de {domain} suivent.",
"domain_block_modal.block": "Bloquer le serveur",
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciennes publications.",
"domain_block_modal.they_cant_follow": "Personne de ce serveur ne peut vous suivre.",
"domain_block_modal.they_wont_know": "Il ne saura pas qu'il a été bloqué.",
"domain_block_modal.title": "Bloquer le domaine ?",
"domain_block_modal.you_will_lose_followers": "Tous vos abonnés de ce serveur seront supprimés.",
"domain_block_modal.you_wont_see_posts": "Vous ne verrez plus les publications ou les notifications des utilisateurs de ce serveur.",
"domain_pill.activitypub_lets_connect": "Cela vous permet de vous connecter et d'interagir avec les autres non seulement sur Mastodon, mais également sur d'autres applications de réseaux sociaux.",
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
"domain_pill.server": "Serveur",
"domain_pill.their_handle": "Son identifiant :",
"domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.",
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateurs avec le même nom sur différents serveurs.",
"domain_pill.username": "Nom dutilisateur",
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec <button>les autres plateformes sociales implémentant ActivityPub</button>.",
"domain_pill.your_handle": "Votre identifiant :",
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de trouver des utilisateurs ayant le même nom d'utilisateur sur différents serveurs.",
"embed.instructions": "Intégrez cette publication à votre site en copiant le code ci-dessous.",
"embed.preview": "Voici comment il apparaîtra:",
"emoji_button.activity": "Activité",
@ -236,6 +266,7 @@
"empty_column.list": "Il ny a rien dans cette liste pour linstant. Quand des membres de cette liste publieront de nouvelles publications, elles apparaîtront ici.",
"empty_column.lists": "Vous navez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.",
"empty_column.mutes": "Vous navez masqué aucun compte pour le moment.",
"empty_column.notification_requests": "C'est fini ! Il n'y a plus rien ici. Lorsque vous recevez de nouvelles notifications, elles apparaitront ici conformément à vos préférences.",
"empty_column.notifications": "Vous n'avez pas encore de notifications. Quand d'autres personnes interagissent avec vous, vous en verrez ici.",
"empty_column.public": "Il ny a rien ici! Écrivez quelque chose publiquement, ou bien suivez manuellement des personnes dautres serveurs pour remplir le fil public",
"error.unexpected_crash.explanation": "En raison dun bogue dans notre code ou dun problème de compatibilité avec votre navigateur, cette page na pas pu être affichée correctement.",
@ -396,6 +427,15 @@
"loading_indicator.label": "Chargement…",
"media_gallery.toggle_visible": "{number, plural, one {Cacher limage} other {Cacher les images}}",
"moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé parce que vous avez déménagé sur {movedToAccount}.",
"mute_modal.hide_from_notifications": "Cacher des notifications",
"mute_modal.hide_options": "Masquer les options",
"mute_modal.indefinite": "Jusqu'à ce que je les réactive",
"mute_modal.show_options": "Afficher les options",
"mute_modal.they_can_mention_and_follow": "Ils peuvent vous mentionner et vous suivre, mais vous ne les verrez pas.",
"mute_modal.they_wont_know": "Ils ne sauront pas qu'ils ont été rendus silencieux.",
"mute_modal.title": "Rendre cet utilisateur silencieux ?",
"mute_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.",
"mute_modal.you_wont_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.",
"navigation_bar.about": "À propos",
"navigation_bar.advanced_interface": "Ouvrir dans linterface avancée",
"navigation_bar.blocks": "Comptes bloqués",
@ -431,8 +471,13 @@
"notification.own_poll": "Votre sondage est terminé",
"notification.poll": "Un sondage auquel vous avez participé est terminé",
"notification.reblog": "{name} a boosté votre message",
"notification.severed_relationships": "Relation avec {name} rompues",
"notification.status": "{name} vient de publier",
"notification.update": "{name} a modifié une publication",
"notification_requests.accept": "Accepter",
"notification_requests.dismiss": "Rejeter",
"notification_requests.notifications_from": "Notifications de {name}",
"notification_requests.title": "Notifications filtrées",
"notifications.clear": "Effacer notifications",
"notifications.clear_confirmation": "Voulez-vous vraiment effacer toutes vos notifications?",
"notifications.column_settings.admin.report": "Nouveaux signalements:",
@ -464,6 +509,15 @@
"notifications.permission_denied": "Les notifications de bureau ne sont pas disponibles en raison d'une demande de permission de navigateur précédemment refusée",
"notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas être activées, car lautorisation du navigateur a précedemment été refusée",
"notifications.permission_required": "Les notifications de bureau ne sont pas disponibles car lautorisation requise na pas été accordée.",
"notifications.policy.filter_new_accounts.hint": "Créés au cours des derniers {days, plural, one {un jour} other {# jours}}",
"notifications.policy.filter_new_accounts_title": "Nouveaux comptes",
"notifications.policy.filter_not_followers_hint": "Incluant les personnes qui vous suivent depuis moins de {days, plural, one {un jour} other {# jours}}",
"notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas",
"notifications.policy.filter_not_following_hint": "Jusqu'à ce que vous les validiez manuellement",
"notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas",
"notifications.policy.filter_private_mentions_hint": "Filtré sauf si c'est en réponse à une mention de vous ou si vous suivez l'expéditeur",
"notifications.policy.filter_private_mentions_title": "Mentions privées non sollicitées",
"notifications.policy.title": "Filtrer les notifications de…",
"notifications_permission_banner.enable": "Activer les notifications de bureau",
"notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon nest pas ouvert, activez les notifications de bureau. Vous pouvez contrôler précisément quels types dinteractions génèrent des notifications de bureau via le bouton {icon} ci-dessus une fois quelles sont activées.",
"notifications_permission_banner.title": "Ne rien rater",
@ -534,6 +588,12 @@
"refresh": "Actualiser",
"regeneration_indicator.label": "Chargement…",
"regeneration_indicator.sublabel": "Votre fil d'accueil est en cours de préparation!",
"relationship_severance_notification.purged_data": "supprimées par les administrateurs",
"relationship_severance_notification.relationships": "{count, plural, one {# relation} other {# relations}}",
"relationship_severance_notification.types.account_suspension": "Le compte a été suspendu",
"relationship_severance_notification.types.domain_block": "Le domaine a été suspendu",
"relationship_severance_notification.types.user_domain_block": "Vous avez bloqué ce domaine",
"relationship_severance_notification.view": "Afficher",
"relative_time.days": "{number} j",
"relative_time.full.days": "il y a {number, plural, one {# jour} other {# jours}}",
"relative_time.full.hours": "il y a {number, plural, one {# heure} other {# heures}}",
@ -640,9 +700,11 @@
"status.direct": "Mention privée @{name}",
"status.direct_indicator": "Mention privée",
"status.edit": "Modifier",
"status.edited": "Dernière modification le {date}",
"status.edited_x_times": "Modifiée {count, plural, one {{count} fois} other {{count} fois}}",
"status.embed": "Intégrer",
"status.favourite": "Ajouter aux favoris",
"status.favourites": "{count, plural, one {favori} other {favoris}}",
"status.filter": "Filtrer cette publication",
"status.filtered": "Filtrée",
"status.hide": "Masquer le message",
@ -663,6 +725,7 @@
"status.reblog": "Booster",
"status.reblog_private": "Booster avec visibilité originale",
"status.reblogged_by": "{name} a boosté",
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
"status.reblogs.empty": "Personne na encore boosté cette publication. Lorsque quelquun le fera, elle apparaîtra ici.",
"status.redraft": "Supprimer et réécrire",
"status.remove_bookmark": "Retirer des signets",

@ -89,6 +89,14 @@
"announcement.announcement": "Annonce",
"attachments_list.unprocessed": "(non traité)",
"audio.hide": "Masquer l'audio",
"block_modal.remote_users_caveat": "Nous allons demander au serveur {domain} de respecter votre décision. Cependant, ce respect n'est pas garanti, car certains serveurs peuvent gérer différemment les blocages. Les messages publics peuvent rester visibles par les utilisateurs non connectés.",
"block_modal.show_less": "Afficher moins",
"block_modal.show_more": "Afficher plus",
"block_modal.they_cant_mention": "Il ne peut pas vous mentionner ou vous suivre.",
"block_modal.they_cant_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.",
"block_modal.they_will_know": "Il peut voir qu'il est bloqué.",
"block_modal.title": "Bloquer l'utilisateur ?",
"block_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.",
"boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci la prochaine fois",
"bundle_column_error.copy_stacktrace": "Copier le rapport d'erreur",
"bundle_column_error.error.body": "La page demandée n'a pas pu être affichée. Cela peut être dû à un bogue dans notre code, ou à un problème de compatibilité avec le navigateur.",
@ -169,6 +177,7 @@
"confirmations.delete_list.message": "Voulez-vous vraiment supprimer définitivement cette liste?",
"confirmations.discard_edit_media.confirm": "Rejeter",
"confirmations.discard_edit_media.message": "Vous avez des modifications non enregistrées de la description ou de l'aperçu du média, les supprimer quand même ?",
"confirmations.domain_block.confirm": "Bloquer le serveur",
"confirmations.domain_block.message": "Voulez-vous vraiment, vraiment bloquer {domain} en entier? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans vos fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.",
"confirmations.edit.confirm": "Modifier",
"confirmations.edit.message": "Modifier maintenant écrasera votre message en cours de rédaction. Voulez-vous vraiment continuer ?",
@ -200,6 +209,27 @@
"dismissable_banner.explore_statuses": "Ces messages venant de tout le web social gagnent en popularité aujourdhui. Les nouveaux messages avec plus de boosts et de favoris sont classés plus haut.",
"dismissable_banner.explore_tags": "Ces hashtags sont actuellement en train de gagner de l'ampleur parmi les personnes sur les serveurs du réseau décentralisé dont celui-ci.",
"dismissable_banner.public_timeline": "Ce sont les posts publics les plus récents de personnes sur le web social que les gens sur {domain} suivent.",
"domain_block_modal.block": "Bloquer le serveur",
"domain_block_modal.block_account_instead": "Bloquer @{name} à la place",
"domain_block_modal.they_can_interact_with_old_posts": "Les personnes de ce serveur peuvent interagir avec vos anciennes publications.",
"domain_block_modal.they_cant_follow": "Personne de ce serveur ne peut vous suivre.",
"domain_block_modal.they_wont_know": "Il ne saura pas qu'il a été bloqué.",
"domain_block_modal.title": "Bloquer le domaine ?",
"domain_block_modal.you_will_lose_followers": "Tous vos abonnés de ce serveur seront supprimés.",
"domain_block_modal.you_wont_see_posts": "Vous ne verrez plus les publications ou les notifications des utilisateurs de ce serveur.",
"domain_pill.activitypub_lets_connect": "Cela vous permet de vous connecter et d'interagir avec les autres non seulement sur Mastodon, mais également sur d'autres applications de réseaux sociaux.",
"domain_pill.activitypub_like_language": "ActivityPub est comme une langue que Mastodon utilise pour communiquer avec les autres réseaux sociaux.",
"domain_pill.server": "Serveur",
"domain_pill.their_handle": "Son identifiant :",
"domain_pill.their_server": "Son foyer numérique, là où tous ses posts résident.",
"domain_pill.their_username": "Son identifiant unique sur leur serveur. Il est possible de rencontrer des utilisateurs avec le même nom sur différents serveurs.",
"domain_pill.username": "Nom dutilisateur",
"domain_pill.whats_in_a_handle": "Qu'est-ce qu'un identifiant ?",
"domain_pill.who_they_are": "Comme un identifiant contient le nom et le service hébergeant une personne, vous pouvez interagir sur <button>les plateformes sociales implémentant ActivityPub</button>.",
"domain_pill.who_you_are": "Comme un identifiant indique votre nom et le service vous hébergeant, vous pouvez interagir avec <button>les autres plateformes sociales implémentant ActivityPub</button>.",
"domain_pill.your_handle": "Votre identifiant :",
"domain_pill.your_server": "Votre foyer numérique, là où vos messages résident. Vous souhaitez changer ? Lancez un transfert vers un autre serveur quand vous le voulez et vos abonné·e·s suivront automatiquement.",
"domain_pill.your_username": "Votre identifiant unique sur ce serveur. Il est possible de trouver des utilisateurs ayant le même nom d'utilisateur sur différents serveurs.",
"embed.instructions": "Intégrez ce message à votre site en copiant le code ci-dessous.",
"embed.preview": "Il apparaîtra comme cela:",
"emoji_button.activity": "Activités",
@ -236,6 +266,7 @@
"empty_column.list": "Il ny a rien dans cette liste pour linstant. Quand des membres de cette liste publieront de nouveaux messages, ils apparaîtront ici.",
"empty_column.lists": "Vous navez pas encore de liste. Lorsque vous en créerez une, elle apparaîtra ici.",
"empty_column.mutes": "Vous navez masqué aucun compte pour le moment.",
"empty_column.notification_requests": "C'est fini ! Il n'y a plus rien ici. Lorsque vous recevez de nouvelles notifications, elles apparaitront ici conformément à vos préférences.",
"empty_column.notifications": "Vous 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 serveurs pour remplir le fil public",
"error.unexpected_crash.explanation": "En raison dun bug dans notre code ou dun problème de compatibilité avec votre navigateur, cette page na pas pu être affichée correctement.",
@ -396,6 +427,15 @@
"loading_indicator.label": "Chargement…",
"media_gallery.toggle_visible": "{number, plural, one {Cacher limage} other {Cacher les images}}",
"moved_to_account_banner.text": "Votre compte {disabledAccount} est actuellement désactivé parce que vous l'avez déplacé à {movedToAccount}.",
"mute_modal.hide_from_notifications": "Cacher des notifications",
"mute_modal.hide_options": "Masquer les options",
"mute_modal.indefinite": "Jusqu'à ce que je les réactive",
"mute_modal.show_options": "Afficher les options",
"mute_modal.they_can_mention_and_follow": "Ils peuvent vous mentionner et vous suivre, mais vous ne les verrez pas.",
"mute_modal.they_wont_know": "Ils ne sauront pas qu'ils ont été rendus silencieux.",
"mute_modal.title": "Rendre cet utilisateur silencieux ?",
"mute_modal.you_wont_see_mentions": "Vous ne verrez pas les publications qui le mentionne.",
"mute_modal.you_wont_see_posts": "Il peut toujours voir vos publications, mais vous ne verrez pas les siennes.",
"navigation_bar.about": "À propos",
"navigation_bar.advanced_interface": "Ouvrir dans linterface avancée",
"navigation_bar.blocks": "Comptes bloqués",
@ -431,8 +471,13 @@
"notification.own_poll": "Votre sondage est terminé",
"notification.poll": "Un sondage auquel vous avez participé vient de se terminer",
"notification.reblog": "{name} a partagé votre message",
"notification.severed_relationships": "Relation avec {name} rompues",
"notification.status": "{name} vient de publier",
"notification.update": "{name} a modifié un message",
"notification_requests.accept": "Accepter",
"notification_requests.dismiss": "Rejeter",
"notification_requests.notifications_from": "Notifications de {name}",
"notification_requests.title": "Notifications filtrées",
"notifications.clear": "Effacer les notifications",
"notifications.clear_confirmation": "Voulez-vous vraiment effacer toutes vos notifications?",
"notifications.column_settings.admin.report": "Nouveaux signalements :",
@ -464,6 +509,15 @@
"notifications.permission_denied": "Impossible dactiver les notifications de bureau car lautorisation a été refusée.",
"notifications.permission_denied_alert": "Les notifications de bureau ne peuvent pas être activées, car lautorisation du navigateur a été refusée avant",
"notifications.permission_required": "Les notifications de bureau ne sont pas disponibles car lautorisation requise na pas été accordée.",
"notifications.policy.filter_new_accounts.hint": "Créés au cours des derniers {days, plural, one {un jour} other {# jours}}",
"notifications.policy.filter_new_accounts_title": "Nouveaux comptes",
"notifications.policy.filter_not_followers_hint": "Incluant les personnes qui vous suivent depuis moins de {days, plural, one {un jour} other {# jours}}",
"notifications.policy.filter_not_followers_title": "Personnes qui ne vous suivent pas",
"notifications.policy.filter_not_following_hint": "Jusqu'à ce que vous les validiez manuellement",
"notifications.policy.filter_not_following_title": "Personnes que vous ne suivez pas",
"notifications.policy.filter_private_mentions_hint": "Filtré sauf si c'est en réponse à une mention de vous ou si vous suivez l'expéditeur",
"notifications.policy.filter_private_mentions_title": "Mentions privées non sollicitées",
"notifications.policy.title": "Filtrer les notifications de…",
"notifications_permission_banner.enable": "Activer les notifications de bureau",
"notifications_permission_banner.how_to_control": "Pour recevoir des notifications lorsque Mastodon nest pas ouvert, activez les notifications du bureau. Vous pouvez contrôler précisément quels types dinteractions génèrent des notifications de bureau via le bouton {icon} ci-dessus une fois quelles sont activées.",
"notifications_permission_banner.title": "Toujours au courant",
@ -534,6 +588,12 @@
"refresh": "Actualiser",
"regeneration_indicator.label": "Chargement…",
"regeneration_indicator.sublabel": "Votre fil principal est en cours de préparation!",
"relationship_severance_notification.purged_data": "supprimées par les administrateurs",
"relationship_severance_notification.relationships": "{count, plural, one {# relation} other {# relations}}",
"relationship_severance_notification.types.account_suspension": "Le compte a été suspendu",
"relationship_severance_notification.types.domain_block": "Le domaine a été suspendu",
"relationship_severance_notification.types.user_domain_block": "Vous avez bloqué ce domaine",
"relationship_severance_notification.view": "Afficher",
"relative_time.days": "{number} j",
"relative_time.full.days": "il y a {number, plural, one {# jour} other {# jours}}",
"relative_time.full.hours": "il y a {number, plural, one {# heure} other {# heures}}",
@ -640,9 +700,11 @@
"status.direct": "Mention privée @{name}",
"status.direct_indicator": "Mention privée",
"status.edit": "Modifier",
"status.edited": "Dernière modification le {date}",
"status.edited_x_times": "Modifié {count, plural, one {{count} fois} other {{count} fois}}",
"status.embed": "Intégrer",
"status.favourite": "Ajouter aux favoris",
"status.favourites": "{count, plural, one {favori} other {favoris}}",
"status.filter": "Filtrer ce message",
"status.filtered": "Filtré",
"status.hide": "Masquer le message",
@ -663,6 +725,7 @@
"status.reblog": "Partager",
"status.reblog_private": "Partager à laudience originale",
"status.reblogged_by": "{name} a partagé",
"status.reblogs": "{count, plural, one {boost} other {boosts}}",
"status.reblogs.empty": "Personne na encore partagé ce message. Lorsque quelquun le fera, il apparaîtra ici.",
"status.redraft": "Supprimer et réécrire",
"status.remove_bookmark": "Retirer des marque-pages",

@ -471,6 +471,7 @@
"notification.own_poll": "Thàinig an cunntas-bheachd agad gu crìoch",
"notification.poll": "Thàinig cunntas-bheachd sa bhòt thu gu crìoch",
"notification.reblog": "Bhrosnaich {name} am post agad",
"notification.severed_relationships": "Chaidh na dàimhean le {name} a dhealachadh",
"notification.status": "Phostaich {name} rud",
"notification.update": "Dheasaich {name} post",
"notification_requests.accept": "Gabh ris",
@ -508,13 +509,13 @@
"notifications.permission_denied": "Chan eil brathan deasga ri fhaighinn on a chaidh iarrtas ceadan a bhrabhsair a dhiùltadh cheana",
"notifications.permission_denied_alert": "Cha ghabh brathan deasga a chur an comas on a chaidh iarrtas ceadan a bhrabhsair a dhiùltadh cheana",
"notifications.permission_required": "Chan eil brathan deasga ri fhaighinn on nach deach an cead riatanach a thoirt seachad.",
"notifications.policy.filter_new_accounts.hint": "Chaidh a chruthachadh o chionn {count, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}",
"notifications.policy.filter_new_accounts.hint": "Chaidh a chruthachadh o chionn {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}",
"notifications.policy.filter_new_accounts_title": "Cunntasan ùra",
"notifications.policy.filter_not_followers_hint": "A gabhail a-staigh an fheadhainn a lean ort nas lugha na {count, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} seo chaidh",
"notifications.policy.filter_not_followers_hint": "A gabhail a-staigh an fheadhainn a lean ort nas lugha na {days, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} seo chaidh",
"notifications.policy.filter_not_followers_title": "Daoine nach eil gad leantainn",
"notifications.policy.filter_not_following_hint": "Gus an aontaich thu riutha a làimh",
"notifications.policy.filter_not_following_title": "Daoine nach eil thu a leantainn",
"notifications.policy.filter_private_mentions_hint": "Criathraichte ach ma tha e a freagairt do dhiomradh agad fhèin no ma tha thu a leantainn an seòladair",
"notifications.policy.filter_private_mentions_hint": "Criathraichte ach ma tha e a freagairt do dhiomradh agad fhèin no ma tha thu a leantainn an t-seòladair",
"notifications.policy.filter_private_mentions_title": "Iomraidhean prìobhaideach o choigrich",
"notifications.policy.title": "Falamhaich na brathan o…",
"notifications_permission_banner.enable": "Cuir brathan deasga an comas",
@ -587,6 +588,12 @@
"refresh": "Ath-nuadhaich",
"regeneration_indicator.label": "Ga luchdadh…",
"regeneration_indicator.sublabel": "Tha do dhachaigh ga ullachadh!",
"relationship_severance_notification.purged_data": "chaidh a phurgaideachadh leis na rianairean",
"relationship_severance_notification.relationships": "{count, plural, one {# dàimh} two {# dhàimh} few {# dàimhean} other {# dàimh}}",
"relationship_severance_notification.types.account_suspension": "Chaidh cunntas a chur à rèim",
"relationship_severance_notification.types.domain_block": "Chaidh àrainn a chur à rèim",
"relationship_severance_notification.types.user_domain_block": "Bhac thu an àrainn seo",
"relationship_severance_notification.view": "Seall",
"relative_time.days": "{number}l",
"relative_time.full.days": "{number, plural, one {# latha} two {# latha} few {# làithean} other {# latha}} air ais",
"relative_time.full.hours": "{number, plural, one {# uair a thìde} two {# uair a thìde} few {# uairean a thìde} other {# uair a thìde}} air ais",
@ -694,10 +701,10 @@
"status.direct_indicator": "Iomradh prìobhaideach",
"status.edit": "Deasaich",
"status.edited": "An deasachadh mu dheireadh {date}",
"status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{counter} turas} two {{counter} thuras} few {{counter} tursan} other {{counter} turas}}",
"status.edited_x_times": "Chaidh a dheasachadh {count, plural, one {{count} turas} two {{count} thuras} few {{count} tursan} other {{count} turas}}",
"status.embed": "Leabaich",
"status.favourite": "Cuir ris na h-annsachdan",
"status.favourites": "{count, plural, one {annsachd} two {annsachd} few {annsachdan} other {annsachd}",
"status.favourites": "{count, plural, one {annsachd} two {annsachd} few {annsachdan} other {annsachd}}",
"status.filter": "Criathraich am post seo",
"status.filtered": "Criathraichte",
"status.hide": "Falaich am post",
@ -718,7 +725,7 @@
"status.reblog": "Brosnaich",
"status.reblog_private": "Brosnaich leis an t-so-fhaicsinneachd tùsail",
"status.reblogged_by": "Ga bhrosnachadh le {name}",
"status.reblogs": "{count, plural, one {bhrosnachadh} two {bhrosnachadh} few {brosnachaidhean} other {brosnachadh}",
"status.reblogs": "{count, plural, one {bhrosnachadh} two {bhrosnachadh} few {brosnachaidhean} other {brosnachadh}}",
"status.reblogs.empty": "Chan deach am post seo a bhrosnachadh le duine sam bith fhathast. Nuair a bhrosnaicheas cuideigin e, nochdaidh iad an-seo.",
"status.redraft": "Sguab às ⁊ dèan dreachd ùr",
"status.remove_bookmark": "Thoir an comharra-lìn air falbh",

@ -471,6 +471,7 @@
"notification.own_poll": "A túa enquisa rematou",
"notification.poll": "Rematou a enquisa na que votaches",
"notification.reblog": "{name} compartiu a túa publicación",
"notification.severed_relationships": "Cortouse a relación con {name}",
"notification.status": "{name} publicou",
"notification.update": "{name} editou unha publicación",
"notification_requests.accept": "Aceptar",
@ -587,6 +588,12 @@
"refresh": "Actualizar",
"regeneration_indicator.label": "Estase a cargar…",
"regeneration_indicator.sublabel": "Estase a preparar a túa cronoloxía de inicio!",
"relationship_severance_notification.purged_data": "purgada pola administración",
"relationship_severance_notification.relationships": "{count, plural, one {# relación} other {# relacións}}",
"relationship_severance_notification.types.account_suspension": "A conta foi suspendida",
"relationship_severance_notification.types.domain_block": "O dominio foi suspendido",
"relationship_severance_notification.types.user_domain_block": "Bloqueaches este dominio",
"relationship_severance_notification.view": "Ver",
"relative_time.days": "{number}d",
"relative_time.full.days": "hai {number, plural, one {# día} other {# días}}",
"relative_time.full.hours": "hai {number, plural, one {# hora} other {# horas}}",

@ -248,7 +248,7 @@
"emoji_button.symbols": "סמלים",
"emoji_button.travel": "טיולים ואתרים",
"empty_column.account_hides_collections": "המשתמש.ת בחר.ה להסתיר מידע זה",
"empty_column.account_suspended": "חשבון מושהה",
"empty_column.account_suspended": "חשבון מושעה",
"empty_column.account_timeline": "אין עדיין אף הודעה!",
"empty_column.account_unavailable": "פרופיל לא זמין",
"empty_column.blocks": "עדיין לא חסמתם משתמשים אחרים.",
@ -471,6 +471,7 @@
"notification.own_poll": "הסקר שלך הסתיים",
"notification.poll": "סקר שהצבעת בו הסתיים",
"notification.reblog": "הודעתך הודהדה על ידי {name}",
"notification.severed_relationships": "חתכתם כל קשר עם {name}",
"notification.status": "{name} הרגע פרסמו",
"notification.update": "{name} ערכו הודעה",
"notification_requests.accept": "לקבל",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "הרשמות חדשות:",
"notifications.column_settings.alert": "התראות לשולחן העבודה",
"notifications.column_settings.favourite": "חיבובים:",
"notifications.column_settings.filter_bar.advanced": "להציג את כל הקטגוריות",
"notifications.column_settings.filter_bar.category": "שורת סינון מהיר",
"notifications.column_settings.follow": "עוקבים חדשים:",
"notifications.column_settings.follow_request": "בקשות מעקב חדשות:",
"notifications.column_settings.mention": "פניות:",
@ -587,6 +590,12 @@
"refresh": "רענון",
"regeneration_indicator.label": "טוען…",
"regeneration_indicator.sublabel": "פיד הבית שלך בהכנה!",
"relationship_severance_notification.purged_data": "המידע נמחק על ידי ההנהלה",
"relationship_severance_notification.relationships": "{count, plural, one {קשר אחד} other {# קשרים}}",
"relationship_severance_notification.types.account_suspension": "החשבון הושעה",
"relationship_severance_notification.types.domain_block": "השרת הושעה",
"relationship_severance_notification.types.user_domain_block": "חסמת שרת זה",
"relationship_severance_notification.view": "הצג",
"relative_time.days": "{number} ימים",
"relative_time.full.days": "לפני {number, plural, one {# יום} other {# ימים}}",
"relative_time.full.hours": "לפני {number, plural, one {# שעה} other {# שעות}}",

@ -471,6 +471,7 @@
"notification.own_poll": "A szavazásod véget ért",
"notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
"notification.reblog": "{name} megtolta a bejegyzésedet",
"notification.severed_relationships": "A kapcsolatok megszakítva ezzel: {name}",
"notification.status": "{name} bejegyzést tett közzé",
"notification.update": "{name} szerkesztett egy bejegyzést",
"notification_requests.accept": "Elfogadás",
@ -587,6 +588,12 @@
"refresh": "Frissítés",
"regeneration_indicator.label": "Betöltés…",
"regeneration_indicator.sublabel": "A saját idővonalad épp készül!",
"relationship_severance_notification.purged_data": "rendszergazdák által véglegesen törölve",
"relationship_severance_notification.relationships": "{count, plural, one {# kapcsolat} other {# kapcsolat}}",
"relationship_severance_notification.types.account_suspension": "A fiók fel van függesztve",
"relationship_severance_notification.types.domain_block": "A domain fel van függesztve",
"relationship_severance_notification.types.user_domain_block": "Blokkoltad ezt a domaint",
"relationship_severance_notification.view": "Megtekintés",
"relative_time.days": "{number}n",
"relative_time.full.days": "{number, plural, one {# napja} other {# napja}}",
"relative_time.full.hours": "{number, plural, one {# órája} other {# órája}}",

@ -483,6 +483,8 @@
"notifications.column_settings.admin.sign_up": "Nýjar skráningar:",
"notifications.column_settings.alert": "Tilkynningar á skjáborði",
"notifications.column_settings.favourite": "Eftirlæti:",
"notifications.column_settings.filter_bar.advanced": "Birta alla flokka",
"notifications.column_settings.filter_bar.category": "Skyndisíustika",
"notifications.column_settings.follow": "Nýir fylgjendur:",
"notifications.column_settings.follow_request": "Nýjar beiðnir um að fylgjast með:",
"notifications.column_settings.mention": "Tilvísanir:",
@ -587,6 +589,8 @@
"refresh": "Endurlesa",
"regeneration_indicator.label": "Hleð inn…",
"regeneration_indicator.sublabel": "Verið er að útbúa heimastreymið þitt!",
"relationship_severance_notification.relationships": "{count, plural, one {# tengsl} other {# tengsl}}",
"relationship_severance_notification.view": "Skoða",
"relative_time.days": "{number}d",
"relative_time.full.days": "Fyrir {number, plural, one {# degi} other {# dögum}} síðan",
"relative_time.full.hours": "Fyrir {number, plural, one {# klukkustund} other {# klukkustundum}} síðan",

@ -89,6 +89,14 @@
"announcement.announcement": "Annuncio",
"attachments_list.unprocessed": "(non elaborato)",
"audio.hide": "Nascondi audio",
"block_modal.remote_users_caveat": "Chiederemo al server {domain} di rispettare la tua decisione. Tuttavia, la conformità non è garantita poiché alcuni server potrebbero gestire i blocchi in modo diverso. I post pubblici potrebbero essere ancora visibili agli utenti che non hanno effettuato l'accesso.",
"block_modal.show_less": "Mostra meno",
"block_modal.show_more": "Mostra di più",
"block_modal.they_cant_mention": "Non possono menzionarti o seguirti.",
"block_modal.they_cant_see_posts": "Non possono vedere i tuoi post e tu non vedrai i loro.",
"block_modal.they_will_know": "Possono vedere che sono bloccati.",
"block_modal.title": "Bloccare l'utente?",
"block_modal.you_wont_see_mentions": "Non vedrai i post che li menzionano.",
"boost_modal.combo": "Puoi premere {combo} per saltare questo passaggio, la prossima volta",
"bundle_column_error.copy_stacktrace": "Copia rapporto sull'errore",
"bundle_column_error.error.body": "Impossibile rendedrizzare la pagina richiesta. Potrebbe dipendere da un bug nel nostro codice o da un problema di compatibilità di un browser.",
@ -169,6 +177,7 @@
"confirmations.delete_list.message": "Sei sicuro di voler eliminare permanentemente questa lista?",
"confirmations.discard_edit_media.confirm": "Scarta",
"confirmations.discard_edit_media.message": "Hai delle modifiche non salvate alla descrizione o anteprima del media, scartarle comunque?",
"confirmations.domain_block.confirm": "Blocca il server",
"confirmations.domain_block.message": "Sei davvero sicuro di voler bloccare l'intero {domain}? In gran parte dei casi, è sufficiente e preferibile bloccare o silenziare alcuni profili. Non visualizzerai i contenuti da quel dominio in alcuna cronologia pubblica o tra le tue notifiche. I tuoi seguaci da quel dominio saranno rimossi.",
"confirmations.edit.confirm": "Modifica",
"confirmations.edit.message": "Modificare ora sovrascriverà il messaggio che stai correntemente componendo. Sei sicuro di voler procedere?",
@ -200,6 +209,27 @@
"dismissable_banner.explore_statuses": "Questi sono post da tutto il social web che stanno guadagnando popolarità oggi. I post più recenti con più condivisioni e preferiti sono classificati più in alto.",
"dismissable_banner.explore_tags": "Questi hashtag stanno ottenendo popolarità tra le persone su questo e altri server della rete decentralizzata, al momento.",
"dismissable_banner.public_timeline": "Questi sono i post pubblici più recenti di persone sul social che le persone su {domain} seguono.",
"domain_block_modal.block": "Blocca il server",
"domain_block_modal.block_account_instead": "Blocca invece @{name}",
"domain_block_modal.they_can_interact_with_old_posts": "Le persone da questo server possono interagire con i tuoi vecchi post.",
"domain_block_modal.they_cant_follow": "Nessuno da questo server può seguirti.",
"domain_block_modal.they_wont_know": "Non sapranno di essere stati bloccati.",
"domain_block_modal.title": "Bloccare il dominio?",
"domain_block_modal.you_will_lose_followers": "Tutti i tuoi seguaci da questo server verranno rimossi.",
"domain_block_modal.you_wont_see_posts": "Non vedrai post o notifiche dagli utenti su questo server.",
"domain_pill.activitypub_lets_connect": "Ti consente di connetterti e interagire con le persone non solo su Mastodon, ma anche su diverse app social.",
"domain_pill.activitypub_like_language": "ActivityPub è come la lingua che Mastodon parla con altri social network.",
"domain_pill.server": "Server",
"domain_pill.their_handle": "Il loro nome univoco:",
"domain_pill.their_server": "La loro casa digitale, dove risiedono tutti i loro post.",
"domain_pill.their_username": "Il loro identificatore univoco sul loro server. È possibile trovare utenti con lo stesso nome utente su server diversi.",
"domain_pill.username": "Nome utente",
"domain_pill.whats_in_a_handle": "Cosa c'è in un nome univoco?",
"domain_pill.who_they_are": "Poiché i nomi univoci indicano chi sia qualcuno e dove si trovi, puoi interagire con le persone attraverso la rete sociale delle <button>piattaforme basate su ActivityPub</button>.",
"domain_pill.who_you_are": "Poiché il tuo nome univoco indica chi tu sia e dove ti trovi, le persone possono interagire con te sulla rete sociale delle <button>piattaforme basate su ActivityPub</button>.",
"domain_pill.your_handle": "Il tuo nome univoco:",
"domain_pill.your_server": "La tua casa digitale, dove vivono tutti i tuoi post. Non ti piace questa? Cambia server in qualsiasi momento e porta con te anche i tuoi seguaci.",
"domain_pill.your_username": "Il tuo identificatore univoco su questo server. È possibile trovare utenti con lo stesso nome utente su server diversi.",
"embed.instructions": "Incorpora questo post sul tuo sito web, copiando il seguente codice.",
"embed.preview": "Ecco come apparirà:",
"emoji_button.activity": "Attività",
@ -397,6 +427,15 @@
"loading_indicator.label": "Caricamento…",
"media_gallery.toggle_visible": "{number, plural, one {Nascondi immagine} other {Nascondi immagini}}",
"moved_to_account_banner.text": "Il tuo profilo {disabledAccount} è correntemente disabilitato perché ti sei spostato a {movedToAccount}.",
"mute_modal.hide_from_notifications": "Nascondi dalle notifiche",
"mute_modal.hide_options": "Nascondi le opzioni",
"mute_modal.indefinite": "Finché io non le riattivo",
"mute_modal.show_options": "Mostre le opzioni",
"mute_modal.they_can_mention_and_follow": "Possono menzionarti e seguirti, ma non li vedrai.",
"mute_modal.they_wont_know": "Non sapranno di essere stati silenziati.",
"mute_modal.title": "Silenziare l'utente?",
"mute_modal.you_wont_see_mentions": "Non vedrai i post che li menzionano.",
"mute_modal.you_wont_see_posts": "Possono ancora vedere i tuoi post, ma tu non vedrai i loro.",
"navigation_bar.about": "Info",
"navigation_bar.advanced_interface": "Apri nell'interfaccia web avanzata",
"navigation_bar.blocks": "Utenti bloccati",
@ -432,6 +471,7 @@
"notification.own_poll": "Il tuo sondaggio è terminato",
"notification.poll": "Un sondaggio in cui hai votato è terminato",
"notification.reblog": "{name} ha rebloggato il tuo post",
"notification.severed_relationships": "Relazioni interrotte con {name}",
"notification.status": "{name} ha appena pubblicato un post",
"notification.update": "{name} ha modificato un post",
"notification_requests.accept": "Accetta",
@ -444,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nuove iscrizioni:",
"notifications.column_settings.alert": "Notifiche desktop",
"notifications.column_settings.favourite": "Preferiti:",
"notifications.column_settings.filter_bar.advanced": "Mostra tutte le categorie",
"notifications.column_settings.filter_bar.category": "Barra del filtro veloce",
"notifications.column_settings.follow": "Nuovi seguaci:",
"notifications.column_settings.follow_request": "Nuove richieste di seguirti:",
"notifications.column_settings.mention": "Menzioni:",
@ -548,6 +590,12 @@
"refresh": "Ricarica",
"regeneration_indicator.label": "Caricamento…",
"regeneration_indicator.sublabel": "Il feed della tua home è in preparazione!",
"relationship_severance_notification.purged_data": "rimossi dagli amministratori",
"relationship_severance_notification.relationships": "{count, plural,one {# relazione} other {# relazioni}}",
"relationship_severance_notification.types.account_suspension": "L'account è stato sospeso",
"relationship_severance_notification.types.domain_block": "Il dominio è stato sospeso",
"relationship_severance_notification.types.user_domain_block": "Hai bloccato questo dominio",
"relationship_severance_notification.view": "Visualizza",
"relative_time.days": "{number}g",
"relative_time.full.days": "{number, plural, one {# giorno} other {# giorni}} fa",
"relative_time.full.hours": "{number, plural, one {# ora} other {# ore}} fa",

@ -89,6 +89,14 @@
"announcement.announcement": "お知らせ",
"attachments_list.unprocessed": "(未処理)",
"audio.hide": "音声を閉じる",
"block_modal.remote_users_caveat": "このサーバーはあなたのブロックの意思を尊重するように {domain} へ通知します。しかしながら、ブロックの扱い方はサーバーによってさまざまで、相手のサーバーは必ずしもこのブロックを適切に取り扱うものではないことに留意が必要です。また、あなたの公開投稿はサーバーからログアウトすれば誰からも見ることができます。",
"block_modal.show_less": "注意事項を閉じる",
"block_modal.show_more": "注意事項",
"block_modal.they_cant_mention": "相手はあなたへの返信やフォローができなくなります。",
"block_modal.they_cant_see_posts": "相手はあなたの投稿を閲覧できなくなり、あなたも相手の投稿を閲覧できなくなります。",
"block_modal.they_will_know": "ブロックは相手からわかります。",
"block_modal.title": "ユーザーをブロックしますか?",
"block_modal.you_wont_see_mentions": "宛先に相手が入っている投稿も閲覧できなくなります。",
"boost_modal.combo": "次からは{combo}を押せばスキップできます",
"bundle_column_error.copy_stacktrace": "エラーレポートをコピー",
"bundle_column_error.error.body": "要求されたページをレンダリングできませんでした。コードのバグ、またはブラウザの互換性の問題が原因である可能性があります。",
@ -200,6 +208,14 @@
"dismissable_banner.explore_statuses": "ネットワーク上で注目を集めている投稿です。ブーストやお気に入り登録の多い新しい投稿が上位に表示されます。",
"dismissable_banner.explore_tags": "ネットワーク上でトレンドになっているハッシュタグです。たくさんのユーザーに使われたタグほど上位に表示されます。",
"dismissable_banner.public_timeline": "{domain}のユーザーがリモートフォローしているアカウントからの公開投稿のタイムラインです。",
"domain_block_modal.block": "サーバーをブロック",
"domain_block_modal.block_account_instead": "@{name} さんのみをブロック",
"domain_block_modal.they_can_interact_with_old_posts": "あなたの今までの投稿は、引き続きこのサーバーのユーザーが閲覧できます。",
"domain_block_modal.they_cant_follow": "このサーバーのユーザーはあなたをフォローできなくなります。",
"domain_block_modal.they_wont_know": "ドメインブロックは相手からはわかりません。",
"domain_block_modal.title": "ドメインをブロックしますか?",
"domain_block_modal.you_will_lose_followers": "このサーバーのフォロワーはすべてフォロー解除されます。",
"domain_block_modal.you_wont_see_posts": "このサーバーのユーザーからの投稿や通知が閲覧できなくなります。",
"embed.instructions": "下記のコードをコピーしてウェブサイトに埋め込みます。",
"embed.preview": "表示例:",
"emoji_button.activity": "活動",
@ -397,6 +413,15 @@
"loading_indicator.label": "読み込み中…",
"media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}",
"moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。",
"mute_modal.hide_from_notifications": "通知をオフにする",
"mute_modal.hide_options": "オプションを閉じる",
"mute_modal.indefinite": "無期限",
"mute_modal.show_options": "オプションを表示",
"mute_modal.they_can_mention_and_follow": "相手はあなたへの返信やフォローができますが、あなたには見えません。",
"mute_modal.they_wont_know": "ミュートは相手からはわかりません。",
"mute_modal.title": "ユーザーをミュートしますか?",
"mute_modal.you_wont_see_mentions": "宛先に相手が入っている投稿も閲覧できなくなります。",
"mute_modal.you_wont_see_posts": "相手はあなたの投稿を今までどおり閲覧できますが、あなたは相手の投稿を閲覧できなくなります。",
"navigation_bar.about": "概要",
"navigation_bar.advanced_interface": "上級者向けUIに戻る",
"navigation_bar.blocks": "ブロックしたユーザー",

@ -220,7 +220,7 @@
"domain_pill.activitypub_lets_connect": "이것은 마스토돈 뿐만이 아니라 다른 소셜 앱들을 넘나들며 사람들을 연결하고 상호작용 할 수 있게 합니다.",
"domain_pill.activitypub_like_language": "액티비티펍은 마스토돈이 다른 소셜 네트워크와 대화할 때 쓰는 언어 같은 것입니다.",
"domain_pill.server": "서버",
"domain_pill.their_handle": "의 핸들:",
"domain_pill.their_handle": "이 사람의 핸들:",
"domain_pill.their_server": "그의 게시물이 살고 있는 디지털 거처입니다.",
"domain_pill.their_username": "그의 서버에서 유일한 식별자입니다. 다른 서버에서 같은 사용자명을 가진 사용자를 찾을 수도 있습니다.",
"domain_pill.username": "사용자명",
@ -471,6 +471,7 @@
"notification.own_poll": "설문을 마침",
"notification.poll": "참여한 설문이 종료됨",
"notification.reblog": "{name} 님이 부스트했습니다",
"notification.severed_relationships": "{name} 님과의 관계가 단절되었습니다",
"notification.status": "{name} 님이 방금 게시물을 올렸습니다",
"notification.update": "{name} 님이 게시물을 수정했습니다",
"notification_requests.accept": "수락",
@ -483,6 +484,7 @@
"notifications.column_settings.admin.sign_up": "새로운 가입:",
"notifications.column_settings.alert": "데스크탑 알림",
"notifications.column_settings.favourite": "좋아요:",
"notifications.column_settings.filter_bar.advanced": "모든 범주 표시",
"notifications.column_settings.follow": "새 팔로워:",
"notifications.column_settings.follow_request": "새 팔로우 요청:",
"notifications.column_settings.mention": "멘션:",
@ -587,6 +589,12 @@
"refresh": "새로고침",
"regeneration_indicator.label": "불러오는 중…",
"regeneration_indicator.sublabel": "홈 피드를 준비하고 있습니다!",
"relationship_severance_notification.purged_data": "관리자에 의해 제거되었습니다",
"relationship_severance_notification.relationships": "{count, plural, other {# 건의 관계}}",
"relationship_severance_notification.types.account_suspension": "계정이 정지되었습니다",
"relationship_severance_notification.types.domain_block": "도메인이 정지되었습니다",
"relationship_severance_notification.types.user_domain_block": "내가 이 도메인을 차단했습니다",
"relationship_severance_notification.view": "보기",
"relative_time.days": "{number}일 전",
"relative_time.full.days": "{number} 일 전",
"relative_time.full.hours": "{number} 시간 전",

@ -91,7 +91,10 @@
"audio.hide": "Eskonde audio",
"block_modal.show_less": "Amostra manko",
"block_modal.show_more": "Amostra mas",
"block_modal.they_cant_mention": "No te puede enmentar ni segir.",
"block_modal.they_will_know": "Puede ver ke esta blokado.",
"block_modal.title": "Bloka utilizador?",
"block_modal.you_wont_see_mentions": "No veras publikasyones ke lo enmentan.",
"boost_modal.combo": "Puedes klikar {combo} para ometer esto la proksima vez",
"bundle_column_error.copy_stacktrace": "Kopia el raporto de yerro",
"bundle_column_error.error.body": "La pajina solisitada no pudo ser renderada. Podria ser por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador.",
@ -205,9 +208,17 @@
"dismissable_banner.explore_tags": "Estas etiketas estan agora popularas en la red sosyala. Etiketas uzadas por mas djente aparesen primero.",
"dismissable_banner.public_timeline": "Estas son las publikasyones publikas mas resientes de personas en la red sosyala a las kualas la djente de {domain} sige.",
"domain_block_modal.block": "Bloka sirvidor",
"domain_block_modal.block_account_instead": "Bloka @{name} en su lugar",
"domain_block_modal.they_cant_follow": "Dingun de este sirvidor puede segirte.",
"domain_block_modal.they_wont_know": "No savra ke tiene sido blokado.",
"domain_block_modal.title": "Bloka el domeno?",
"domain_block_modal.you_will_lose_followers": "Se efasaran todos tus suivantes de este sirvidor.",
"domain_block_modal.you_wont_see_posts": "No veras publikasyones ni avizos de utilizadores en este sirvidor.",
"domain_pill.server": "Sirvidor",
"domain_pill.their_handle": "Su alias:",
"domain_pill.username": "Nombre de utilizador",
"domain_pill.whats_in_a_handle": "En ke konsiste el alias?",
"domain_pill.your_handle": "Tu alias:",
"embed.instructions": "Enkrusta esta publikasyon en tu sitio internetiko kopiando este kodiche.",
"embed.preview": "Paresera ansina:",
"emoji_button.activity": "Aktivita",
@ -404,6 +415,13 @@
"loading_indicator.label": "Eskargando…",
"media_gallery.toggle_visible": "{number, plural, one {Eskonde imaje} other {Eskonde imajes}}",
"moved_to_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado porke transferates a {movedToAccount}.",
"mute_modal.hide_from_notifications": "Eskonde de avizos",
"mute_modal.hide_options": "Eskonde opsyones",
"mute_modal.indefinite": "Asta ke desho de silensyarlo",
"mute_modal.show_options": "Amostra opsyones",
"mute_modal.they_wont_know": "No savra ke tiene sido silensyado.",
"mute_modal.title": "Silensiar utilizador?",
"mute_modal.you_wont_see_mentions": "No veras publikasyones ke lo enmentan.",
"navigation_bar.about": "Sovre mozotros",
"navigation_bar.advanced_interface": "Avre en la enterfaz avanzada",
"navigation_bar.blocks": "Utilizadores blokados",
@ -553,6 +571,8 @@
"refresh": "Arefreska",
"regeneration_indicator.label": "Eskargando…",
"regeneration_indicator.sublabel": "Tu linya de tiempo prinsipala esta preparando!",
"relationship_severance_notification.types.user_domain_block": "Blokates este domeno",
"relationship_severance_notification.view": "Mira",
"relative_time.days": "{number} d",
"relative_time.full.days": "antes {number, plural, one {# diya} other {# diyas}}",
"relative_time.full.hours": "antes {number, plural, one {# ora} other {# oras}}",

@ -555,6 +555,9 @@
"refresh": "Atnaujinti",
"regeneration_indicator.label": "Kraunama…",
"regeneration_indicator.sublabel": "Ruošiamas tavo pagrindinis srautas!",
"relationship_severance_notification.relationships": "{count, plural, one {# santykis} few {# santykiai} many {# santykio} other {# santykių}}",
"relationship_severance_notification.types.user_domain_block": "Užblokavai šį domeną",
"relationship_severance_notification.view": "Peržiūrėti",
"relative_time.days": "{number} d.",
"relative_time.full.days": "prieš {number, plural, one {# dieną} few {# dienas} many {# dienos} other {# dienų}}",
"relative_time.full.hours": "prieš {number, plural, one {# valandą} few {# valandas} many {# valandos} other {# valandų}}",

@ -236,7 +236,7 @@
"empty_column.lists": "Pašlaik Tev nav neviena saraksta. Kad tādu izveidosi, tas parādīsies šeit.",
"empty_column.mutes": "Neviens lietotājs vēl nav apklusināts.",
"empty_column.notifications": "Tev vēl nav paziņojumu. Kad citi cilvēki ar Tevi mijiedarbosies, Tu to redzēsi šeit.",
"empty_column.public": "Šeit nekā nav! Ieraksti kaut ko publiski vai seko lietotājiem no citiem serveriem, lai iegūtu saturu",
"empty_column.public": "Šeit nekā nav. Ieraksti kaut ko publiski vai seko lietotājiem no citiem serveriem, lai iegūtu saturu",
"error.unexpected_crash.explanation": "Koda kļūdas vai pārlūkprogrammas saderības problēmas dēļ šo lapu nevarēja parādīt pareizi.",
"error.unexpected_crash.explanation_addons": "Šo lapu nevarēja parādīt pareizi. Šo kļūdu, iespējams, izraisīja pārlūkprogrammas papildinājums vai automātiskās tulkošanas rīki.",
"error.unexpected_crash.next_steps": "Mēģini atsvaidzināt lapu. Ja tas nepalīdz, iespējams, varēsi lietot Mastodon, izmantojot citu pārlūkprogrammu vai lietotni.",
@ -265,6 +265,7 @@
"filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu",
"filter_modal.select_filter.title": "Filtrēt šo ziņu",
"filter_modal.title.status": "Filtrēt ziņu",
"filtered_notifications_banner.pending_requests": "Paziņojumi no {count, plural, =0 {neviena} one {viena cilvēka} other {# cilvēkiem}}, ko Tu varētu zināt",
"firehose.all": "Visi",
"firehose.local": "Šis serveris",
"firehose.remote": "Citi serveri",
@ -273,6 +274,7 @@
"follow_requests.unlocked_explanation": "Lai gan Tavs konts nav slēgts, {domain} darbinieki iedomājās, ka Tu varētu vēlēties pašrocīgi pārskatīt sekošanas pieprasījumus no šiem kontiem.",
"follow_suggestions.curated_suggestion": "Darbinieku izvēle",
"follow_suggestions.dismiss": "Vairs nerādīt",
"follow_suggestions.personalized_suggestion": "Pielāgots ieteikums",
"follow_suggestions.view_all": "Skatīt visu",
"follow_suggestions.who_to_follow": "Kam sekot",
"followed_tags": "Sekojamie tēmturi",
@ -413,7 +415,7 @@
"navigation_bar.security": "Drošība",
"not_signed_in_indicator.not_signed_in": "Ir jāpiesakās, lai piekļūtu šim resursam.",
"notification.admin.report": "{name} ziņoja par {target}",
"notification.admin.sign_up": "{name} ir pierakstījies",
"notification.admin.sign_up": "{name} pierakstījās",
"notification.favourite": "{name} pievienoja tavu ziņu izlasei",
"notification.follow": "{name} uzsāka Tev sekot",
"notification.follow_request": "{name} nosūtīja Tev sekošanas pieprasījumu",
@ -464,7 +466,7 @@
"onboarding.compose.template": "Sveiki, #Mastodon!",
"onboarding.follows.empty": "Diemžēl pašlaik nevar parādīt rezultātus. Vari mēģināt izmantot meklēšanu vai pārlūkot izpētes lapu, lai atrastu cilvēkus, kuriem sekot, vai vēlāk mēģināt vēlreiz.",
"onboarding.follows.lead": "Tava mājas plūsma ir galvenais veids, kā izbaudīt Mastodon. Jo vairāk cilvēku sekosi, jo aktīvāk un interesantāk tas būs. Lai sāktu, šeit ir daži ieteikumi:",
"onboarding.follows.title": "Populārs Mastodon",
"onboarding.follows.title": "Pielāgo savu mājas barotni",
"onboarding.profile.discoverable": "Padarīt manu profilu atklājamu",
"onboarding.profile.display_name": "Attēlojamais vārds",
"onboarding.profile.display_name_hint": "Tavs pilnais vārds vai Tavs joku vārds…",
@ -482,7 +484,7 @@
"onboarding.start.skip": "Nav nepieciešama palīdzība darba sākšanai?",
"onboarding.start.title": "Tev tas izdevās!",
"onboarding.steps.follow_people.body": "Tu pats veido savu plūsmu. Piepildīsim to ar interesantiem cilvēkiem.",
"onboarding.steps.follow_people.title": "Sekot {count, plural, one {one person} other {# cilvēkiem}}",
"onboarding.steps.follow_people.title": "Pielāgo savu mājas barotni",
"onboarding.steps.publish_status.body": "Sveicini pasauli ar tekstu, fotoattēliem, video, vai aptaujām {emoji}",
"onboarding.steps.publish_status.title": "Izveido savu pirmo ziņu",
"onboarding.steps.setup_profile.body": "Palielini mijiedarbību ar aptverošu profilu!",
@ -492,14 +494,14 @@
"onboarding.tips.2fa": "<strong>Vai zināji?</strong> Tu vari aizsargāt savu kontu, konta iestatījumos iestatot divpakāpju autentifikāciju. Tas darbojas ar jebkuru Tevis izvēlētu TOTP lietotni, nav nepieciešams tālruņa numurs!",
"onboarding.tips.accounts_from_other_servers": "<strong>Vai zināji?</strong> Tā kā Mastodon ir decentralizēts, daži profili, ar kuriem saskaraties, tiks mitināti citos, nevis tavos serveros. Un tomēr tu varat sazināties ar viņiem nevainojami! Viņu serveris atrodas viņu lietotājvārda otrajā pusē!",
"onboarding.tips.migration": "<strong>Vai zināji?</strong> Ja uzskati, ka {domain} nākotnē nav lieliska servera izvēle, vari pāriet uz citu Mastodon serveri, nezaudējot savus sekotājus. Tu pat vari mitināt savu serveri!",
"onboarding.tips.verification": "<strong>Vai zināji?</strong> Tu vari verificēt savu kontu, ievietojot saiti uz savu Mastodon profilu savā vietnē un pievienojot vietni savam profilam. Nav nepieciešami nekādi maksājumi vai dokumenti!",
"onboarding.tips.verification": "<strong>Vai zināji?</strong> Tu vari apliecināt savu kontu, ievietojot savā tīmekļvietnē saiti uz savu Mastodon profilu un pievienojot tīmekļvietni savam profilam. Nav nepieciešami nekādi maksājumi vai dokumenti.",
"password_confirmation.exceeds_maxlength": "Paroles apstiprināšana pārsniedz maksimālo paroles garumu",
"password_confirmation.mismatching": "Paroles apstiprinājums neatbilst",
"picture_in_picture.restore": "Novietot atpakaļ",
"poll.closed": "Pabeigta",
"poll.refresh": "Atsvaidzināt",
"poll.reveal": "Skatīt rezultātus",
"poll.total_people": "{count, plural, zero {# cilvēku} one {# persona} other {# cilvēki}}",
"poll.total_people": "{count, plural, zero {# cilvēku} one {# cilvēks} other {# cilvēki}}",
"poll.total_votes": "{count, plural, zero {# balsojumu} one {# balsojums} other {# balsojumi}}",
"poll.vote": "Balsot",
"poll.voted": "Tu balsoji par šo atbildi",

@ -205,10 +205,10 @@
"disabled_account_banner.text": "Jouw account {disabledAccount} is momenteel uitgeschakeld.",
"dismissable_banner.community_timeline": "Dit zijn de meest recente openbare berichten van accounts op {domain}. Je kunt onder 'instellingen > voorkeuren > overig' kiezen welke talen je wilt zien.",
"dismissable_banner.dismiss": "Sluiten",
"dismissable_banner.explore_links": "Dit zijn nieuwsberichten die vandaag het meest op het sociale web worden gedeeld. Nieuwere nieuwsberichten die door meer verschillende mensen zijn geplaatst staan hoger op de lijst.",
"dismissable_banner.explore_statuses": "Dit zijn berichten op het sociale web die vandaag aan populariteit winnen. Nieuwere berichten met meer boosts en favorieten staan hoger.",
"dismissable_banner.explore_tags": "Deze hashtags winnen aan populariteit op het sociale web. Hashtags die door meer verschillende mensen worden gebruikt staan hoger.",
"dismissable_banner.public_timeline": "Dit zijn de meest recente openbare berichten van accounts op het sociale web die door mensen op {domain} worden gevolgd.",
"dismissable_banner.explore_links": "Dit zijn nieuwsberichten die vandaag het meest op het sociale web (fediverse) worden gedeeld. Nieuwere nieuwsberichten die door meer verschillende mensen zijn geplaatst staan hoger op de lijst.",
"dismissable_banner.explore_statuses": "Dit zijn berichten op het sociale web (fediverse) die vandaag aan populariteit winnen. Nieuwere berichten met meer boosts en favorieten staan hoger.",
"dismissable_banner.explore_tags": "Deze hashtags winnen aan populariteit op het sociale web (fediverse). Hashtags die door meer verschillende mensen worden gebruikt staan hoger.",
"dismissable_banner.public_timeline": "Dit zijn de meest recente openbare berichten van accounts op het sociale web (fediverse) die door mensen op {domain} worden gevolgd.",
"domain_block_modal.block": "Server blokkeren",
"domain_block_modal.block_account_instead": "In plaats hiervan {name} blokkeren",
"domain_block_modal.they_can_interact_with_old_posts": "Mensen op deze server kunnen interactie hebben met jouw oude berichten.",
@ -220,14 +220,14 @@
"domain_pill.activitypub_lets_connect": "Het zorgt ervoor dat je niet alleen maar kunt verbinden en communiceren met mensen op Mastodon, maar ook met andere sociale apps.",
"domain_pill.activitypub_like_language": "ActivityPub is de taal die Mastodon met andere sociale netwerken spreekt.",
"domain_pill.server": "Server",
"domain_pill.their_handle": "Hun Mastodon-adres:",
"domain_pill.their_handle": "Hun fediverse-adres:",
"domain_pill.their_server": "Hun digitale thuis, waar al hun berichten zich bevinden.",
"domain_pill.their_username": "Hun unieke identificatie-adres op hun server. Het is mogelijk dat er gebruikers met dezelfde gebruikersnaam op verschillende servers te vinden zijn.",
"domain_pill.username": "Gebruikersnaam",
"domain_pill.whats_in_a_handle": "Wat is een Mastodon-adres?",
"domain_pill.who_they_are": "Omdat je aan een Mastodon-adres kunt zien wie iemand is en waar die zich bevindt, kun je met mensen op het door <button>ActivityPub aangedreven</button> sociale web communiceren.",
"domain_pill.who_you_are": "Omdat je aan jouw Mastodon-adres kunt zien wie jij bent is en waar je je bevindt, kunnen mensen op het door <button>ActivityPub aangedreven</button> sociale web met jou communiceren.",
"domain_pill.your_handle": "Jouw Mastodon-adres:",
"domain_pill.whats_in_a_handle": "Wat is een fediverse-adres?",
"domain_pill.who_they_are": "Omdat je aan een fediverse-adres kunt zien wie iemand is en waar die zich bevindt, kun je met mensen op het door <button>ActivityPub aangedreven</button> sociale web (fediverse) communiceren.",
"domain_pill.who_you_are": "Omdat je aan jouw fediverse-adres kunt zien wie jij bent is en waar je je bevindt, kunnen mensen op het door <button>ActivityPub aangedreven</button> sociale web (fediverse) met jou communiceren.",
"domain_pill.your_handle": "Jouw fediverse-adres:",
"domain_pill.your_server": "Jouw digitale thuis, waar al jouw berichten zich bevinden. Is deze server toch niet naar jouw wens? Dan kun je op elk moment naar een andere server verhuizen en ook jouw volgers overbrengen.",
"domain_pill.your_username": "Jouw unieke identificatie-adres op deze server. Het is mogelijk dat er gebruikers met dezelfde gebruikersnaam op verschillende servers te vinden zijn.",
"embed.instructions": "Embed dit bericht op jouw website door de onderstaande code te kopiëren.",
@ -471,6 +471,7 @@
"notification.own_poll": "Jouw peiling is beëindigd",
"notification.poll": "Een peiling waaraan jij hebt meegedaan is beëindigd",
"notification.reblog": "{name} boostte jouw bericht",
"notification.severed_relationships": "Volgrelaties met {name} verbroken",
"notification.status": "{name} heeft zojuist een bericht geplaatst",
"notification.update": "{name} heeft een bericht bewerkt",
"notification_requests.accept": "Accepteren",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nieuwe registraties:",
"notifications.column_settings.alert": "Desktopmeldingen",
"notifications.column_settings.favourite": "Favorieten:",
"notifications.column_settings.filter_bar.advanced": "Alle categorieën tonen",
"notifications.column_settings.filter_bar.category": "Snelle filterbalk",
"notifications.column_settings.follow": "Nieuwe volgers:",
"notifications.column_settings.follow_request": "Nieuw volgverzoek:",
"notifications.column_settings.mention": "Vermeldingen:",
@ -587,6 +590,12 @@
"refresh": "Vernieuwen",
"regeneration_indicator.label": "Aan het laden…",
"regeneration_indicator.sublabel": "Jouw starttijdlijn wordt aangemaakt!",
"relationship_severance_notification.purged_data": "verwijderd door beheerders",
"relationship_severance_notification.relationships": "{count, plural, one {# volgrelatie} other {# volgrelaties}}",
"relationship_severance_notification.types.account_suspension": "Account is opgeschort",
"relationship_severance_notification.types.domain_block": "Domein is opgeschort",
"relationship_severance_notification.types.user_domain_block": "Je hebt dit domein geblokkeerd",
"relationship_severance_notification.view": "Weergeven",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# dag} other {# dagen}} geleden",
"relative_time.full.hours": "{number, plural, one {# uur} other {# uur}} geleden",

@ -32,7 +32,7 @@
"account.featured_tags.last_status_never": "Ingen innlegg",
"account.featured_tags.title": "{name} sine framheva emneknaggar",
"account.follow": "Fylg",
"account.follow_back": "Følg tilbake",
"account.follow_back": "Fylg tilbake",
"account.followers": "Fylgjarar",
"account.followers.empty": "Ingen fylgjer denne brukaren enno.",
"account.followers_counter": "{count, plural, one {{counter} fylgjar} other {{counter} fylgjarar}}",
@ -49,7 +49,7 @@
"account.media": "Media",
"account.mention": "Nemn @{name}",
"account.moved_to": "{name} seier at deira nye konto no er:",
"account.mute": "Målbind @{name}",
"account.mute": "Demp @{name}",
"account.mute_notifications_short": "Demp varslingar",
"account.mute_short": "Demp",
"account.muted": "Målbunden",
@ -69,9 +69,9 @@
"account.unblock_short": "Stopp blokkering",
"account.unendorse": "Ikkje vis på profil",
"account.unfollow": "Slutt å fylgja",
"account.unmute": "Opphev målbinding av @{name}",
"account.unmute": "Opphev demping av @{name}",
"account.unmute_notifications_short": "Opphev demping av varslingar",
"account.unmute_short": "Opphev målbinding",
"account.unmute_short": "Opphev demping",
"account_note.placeholder": "Klikk for å leggja til merknad",
"admin.dashboard.daily_retention": "Mengda brukarar aktive ved dagar etter registrering",
"admin.dashboard.monthly_retention": "Mengda brukarar aktive ved månader etter registrering",
@ -79,8 +79,8 @@
"admin.dashboard.retention.cohort": "Registrert månad",
"admin.dashboard.retention.cohort_size": "Nye brukarar",
"admin.impact_report.instance_accounts": "Kontoprofilar dette vil sletta",
"admin.impact_report.instance_followers": "Følgjarar våre brukarar vil mista",
"admin.impact_report.instance_follows": "Følgjarar deira brukarar vil mista",
"admin.impact_report.instance_followers": "Fylgjarar som brukarane våre ville mista",
"admin.impact_report.instance_follows": "Fylgjarar som brukarane deira ville mista",
"admin.impact_report.title": "Samandrag av konsekvensane",
"alert.rate_limited.message": "Ver venleg å prøv på nytt etter {retry_time, time, medium}.",
"alert.rate_limited.title": "Redusert kapasitet",
@ -89,7 +89,7 @@
"announcement.announcement": "Kunngjering",
"attachments_list.unprocessed": "(ubehandla)",
"audio.hide": "Gøym lyd",
"block_modal.remote_users_caveat": "Vi vil be tenaren {domain} om å respektere di avgjerd. Det kan ikkje garanterast at det vert etterfølgd, sidan nokre tenarar kan handtere blokkering ulikt. Offentlege innlegg kan framleis vere synlege for ikkje-innlogga brukarar.",
"block_modal.remote_users_caveat": "Me vil be tenaren {domain} om å respektere di avgjerd. Me kan ikkje garantera at det vert gjort, sidan nokre tenarar kan handtera blokkering ulikt. Offentlege innlegg kan framleis vera synlege for ikkje-innlogga brukarar.",
"block_modal.show_less": "Vis mindre",
"block_modal.show_more": "Vis meir",
"block_modal.they_cant_mention": "Dei kan ikkje nemna eller fylgja deg.",
@ -178,12 +178,12 @@
"confirmations.discard_edit_media.confirm": "Forkast",
"confirmations.discard_edit_media.message": "Du har ulagra endringar i mediaskildringa eller førehandsvisinga. Vil du forkasta dei likevel?",
"confirmations.domain_block.confirm": "Blokker tenaren",
"confirmations.domain_block.message": "Er du heilt, heilt sikker på at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og føretrekt med nokre få målretta blokkeringar eller målbindingar. Du kjem ikkje til å sjå innhald frå domenet i fødererte tidsliner eller i varsla dine. Fylgjarane dine frå domenet vert fjerna.",
"confirmations.domain_block.message": "Er du heilt, heilt sikker på at du vil skjula heile {domain}? I dei fleste tilfelle er det godt nok og føretrekt med nokre få målretta blokkeringar eller dempingar. Du kjem ikkje til å sjå innhald frå domenet i fødererte tidsliner eller i varsla dine. Fylgjarane dine frå domenet vert fjerna.",
"confirmations.edit.confirm": "Rediger",
"confirmations.edit.message": "Å redigera no vil overskriva den meldinga du er i ferd med å skriva. Er du sikker på at du vil halda fram?",
"confirmations.logout.confirm": "Logg ut",
"confirmations.logout.message": "Er du sikker på at du vil logga ut?",
"confirmations.mute.confirm": "Målbind",
"confirmations.mute.confirm": "Demp",
"confirmations.redraft.confirm": "Slett & skriv på nytt",
"confirmations.redraft.message": "Er du sikker på at du vil sletta denne statusen og skriva han på nytt? Då misser du favorittar og framhevingar, og svar til det opprinnelege innlegget vert foreldrelause.",
"confirmations.reply.confirm": "Svar",
@ -208,7 +208,7 @@
"dismissable_banner.explore_links": "Desse nyhendesakene snakkast om av folk på denne og andre tenarar på det desentraliserte nettverket no.",
"dismissable_banner.explore_statuses": "Dette er innlegg frå det desentraliserte nettverket som er i støytet i dag. Nye statusar som er mykje framheva og merkte som favorittar er rangert høgare.",
"dismissable_banner.explore_tags": "Desse emneknaggane er populære blant folk på denne tenaren og andre tenarar i det desentraliserte nettverket nett no.",
"dismissable_banner.public_timeline": "Dette er dei nyaste offentlege innlegga frå menneske på det sosiale nettet som folk på {domain} følgjer.",
"dismissable_banner.public_timeline": "Dette er dei nyaste offentlege innlegga frå menneske på det sosiale nettet som folk på {domain} fylgjer.",
"domain_block_modal.block": "Blokker tenaren",
"domain_block_modal.block_account_instead": "Blokker @{name} i staden",
"domain_block_modal.they_can_interact_with_old_posts": "Folk på denne tenaren kan samhandla med dei gamle innlegga dine.",
@ -228,7 +228,7 @@
"domain_pill.who_they_are": "Sidan handtak seier kven nokon er og kvar dei er, kan du interagere med folk på tvers av det sosiale nettverket av <button>plattformar som støttar ActivityPub</button>.",
"domain_pill.who_you_are": "Sidan handtaket ditt seier kven du er og kvar du er, kan folk interagere med deg på tvers av det sosiale nettverket av <button>plattformar som støttar ActivityPub</button>.",
"domain_pill.your_handle": "Handtaket ditt:",
"domain_pill.your_server": "Din digitale heim, som alle postane dine bur i. Liker du ikkje dette? Overfør tenarar når som helst og ta med følgjarane dine òg.",
"domain_pill.your_server": "Din digitale heim, der alle innlegga dine bur i. Liker du ikkje dette? Byt til ein ny tenar når som helst og ta med fylgjarane dine òg.",
"domain_pill.your_username": "Din unike identifikator på denne tenaren. Det er mogleg å finne brukarar med same brukarnamn på forskjellige tenarar.",
"embed.instructions": "Bygg inn denne statusen på nettsida di ved å kopiera koden nedanfor.",
"embed.preview": "Slik kjem det til å sjå ut:",
@ -259,16 +259,16 @@
"empty_column.explore_statuses": "Ingenting er i støytet nett no. Prøv igjen seinare!",
"empty_column.favourited_statuses": "Du har ingen favoritt-statusar ennå. Når du merkjer ein som favoritt, dukkar han opp her.",
"empty_column.favourites": "Ingen har merkt denne statusen som favoritt enno. Når nokon gjer det, dukkar dei opp her.",
"empty_column.follow_requests": "Du har ingen følgjeførespurnadar ennå. Når du får ein, så vil den dukke opp her.",
"empty_column.follow_requests": "Ingen har spurt om å fylgja deg enno. Når nokon gjer det, vil det dukka opp her.",
"empty_column.followed_tags": "Du fylgjer ingen emneknaggar enno. Når du gjer det, vil dei syna her.",
"empty_column.hashtag": "Det er ingenting i denne emneknaggen enno.",
"empty_column.home": "Heime-tidslina di er tom! Følg fleire folk for å fylle ho med innhald. {suggestions}",
"empty_column.home": "Heime-tidslina di er tom! Fylg fleire folk for å fylla ho med innhald. {suggestions}.",
"empty_column.list": "Det er ingenting i denne lista enno. Når medlemer av denne lista legg ut nye statusar, så dukkar dei opp her.",
"empty_column.lists": "Du har ingen lister enno. Når du lagar ei, så dukkar ho opp her.",
"empty_column.mutes": "Du har ikkje målbunde nokon enno.",
"empty_column.notification_requests": "Ferdig! Her er det ingenting. Når du får nye varsel, kjem dei opp her slik du har valt.",
"empty_column.notifications": "Du har ingen varsel enno. Kommuniser med andre for å starte samtalen.",
"empty_column.public": "Det er ingenting her! Skriv noko offentleg, eller følg brukarar frå andre tenarar manuelt for å fylle det opp",
"empty_column.public": "Det er ingenting her! Skriv noko offentleg, eller fylg brukarar frå andre tenarar manuelt for å få meir her",
"error.unexpected_crash.explanation": "På grunn av eit nettlesarkompatibilitetsproblem eller ein feil i koden vår, kunne ikkje denne sida bli vist slik den skal.",
"error.unexpected_crash.explanation_addons": "Denne sida kunne ikkje visast som den skulle. Feilen kjem truleg frå ei nettleserutviding eller frå automatiske omsetjingsverktøy.",
"error.unexpected_crash.next_steps": "Prøv å lasta inn sida på nytt. Hjelper ikkje dette kan du framleis nytta Mastodon i ein annan nettlesar eller app.",
@ -315,7 +315,7 @@
"follow_suggestions.personalized_suggestion": "Personleg forslag",
"follow_suggestions.popular_suggestion": "Populært forslag",
"follow_suggestions.view_all": "Vis alle",
"follow_suggestions.who_to_follow": "Kven som skal følgjast",
"follow_suggestions.who_to_follow": "Kven du kan fylgja",
"followed_tags": "Fylgde emneknaggar",
"footer.about": "Om",
"footer.directory": "Profilmappe",
@ -471,6 +471,7 @@
"notification.own_poll": "Rundspørjinga di er ferdig",
"notification.poll": "Ei rundspørjing du har røysta i er ferdig",
"notification.reblog": "{name} framheva innlegget ditt",
"notification.severed_relationships": "Forholda med {name} er brotne",
"notification.status": "{name} la nettopp ut",
"notification.update": "{name} redigerte eit innlegg",
"notification_requests.accept": "Godkjenn",
@ -574,8 +575,8 @@
"privacy.change": "Endre personvernet på innlegg",
"privacy.direct.long": "Alle nemnde i innlegget",
"privacy.direct.short": "Spesifikke folk",
"privacy.private.long": "Berre dine følgjarar",
"privacy.private.short": "Følgjarar",
"privacy.private.long": "Berre dei som fylgjer deg",
"privacy.private.short": "Fylgjarar",
"privacy.public.long": "Kven som helst på og av Mastodon",
"privacy.public.short": "Offentleg",
"privacy.unlisted.additional": "Dette er akkurat som offentleg, bortsett frå at innlegga ikkje dukkar opp i direktestraumar eller merkelappar, i oppdagingar eller Mastodon-søk, sjølv om du har sagt ja til at kontoen skal vera synleg.",
@ -587,6 +588,12 @@
"refresh": "Oppdater",
"regeneration_indicator.label": "Lastar…",
"regeneration_indicator.sublabel": "Heimetidslina di vert førebudd!",
"relationship_severance_notification.purged_data": "sletta av administratorar",
"relationship_severance_notification.relationships": "{count, plural, one {# forhold} other {# forhold}}",
"relationship_severance_notification.types.account_suspension": "Kontoen er utvist",
"relationship_severance_notification.types.domain_block": "Domenet er utestengt",
"relationship_severance_notification.types.user_domain_block": "Du blokkerte dette domenet",
"relationship_severance_notification.view": "Sjå",
"relative_time.days": "{number}dg",
"relative_time.full.days": "{number, plural, one {# dag} other {# dagar}} sidan",
"relative_time.full.hours": "{number, plural, one {# time} other {# timar}} sidan",
@ -615,7 +622,7 @@
"report.comment.title": "Er det noko anna du meiner me bør vite?",
"report.forward": "Vidaresend til {target}",
"report.forward_hint": "Kontoen er frå ein annan tenar. Vil du senda ein anonymisert kopi av rapporten dit òg?",
"report.mute": "Målbind",
"report.mute": "Demp",
"report.mute_explanation": "Du vil ikkje lenger sjå innlegga deira. Dei kan framleis fylgje deg og sjå innlegga dine, men vil ikkje vite at du har valt å ikkje sjå innlegga deira.",
"report.next": "Neste",
"report.placeholder": "Tilleggskommentarar",
@ -686,7 +693,7 @@
"status.block": "Blokker @{name}",
"status.bookmark": "Set bokmerke",
"status.cancel_reblog_private": "Opphev framheving",
"status.cannot_reblog": "Denne posten kan ikkje framhevast",
"status.cannot_reblog": "Du kan ikkje framheva dette innlegget",
"status.copy": "Kopier lenke til status",
"status.delete": "Slett",
"status.detailed_status": "Detaljert samtalevisning",
@ -709,8 +716,8 @@
"status.media_hidden": "Mediet er gøymt",
"status.mention": "Nemn @{name}",
"status.more": "Meir",
"status.mute": "Målbind @{name}",
"status.mute_conversation": "Målbind samtale",
"status.mute": "Demp @{name}",
"status.mute_conversation": "Demp samtale",
"status.open": "Utvid denne statusen",
"status.pin": "Fest på profil",
"status.pinned": "Festa tut",
@ -734,11 +741,11 @@
"status.show_more": "Vis meir",
"status.show_more_all": "Vis meir for alle",
"status.show_original": "Vis original",
"status.title.with_attachments": "{user} postet {attachmentCount, plural, one {et vedlegg} other {{attachmentCount} vedlegg}}",
"status.title.with_attachments": "{user} la ut {attachmentCount, plural, one {eitt vedlegg} other {{attachmentCount} vedlegg}}",
"status.translate": "Omset",
"status.translated_from_with": "Omsett frå {lang} ved bruk av {provider}",
"status.uncached_media_warning": "Førehandsvisning er ikkje tilgjengeleg",
"status.unmute_conversation": "Opphev målbinding av samtalen",
"status.unmute_conversation": "Opphev demping av samtalen",
"status.unpin": "Løys frå profil",
"subscribed_languages.lead": "Kun innlegg på valde språk vil bli dukke opp i heimestraumen din og i listene dine etter denne endringa. For å motta innlegg på alle språk, la vere å velje nokon.",
"subscribed_languages.save": "Lagre endringar",

@ -471,6 +471,7 @@
"notification.own_poll": "Twoje głosowanie zakończyło się",
"notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyło się",
"notification.reblog": "Twój post został podbity przez {name}",
"notification.severed_relationships": "Zerwano związki z {name}",
"notification.status": "{name} opublikował(a) nowy wpis",
"notification.update": "{name} edytował(a) post",
"notification_requests.accept": "Akceptuj",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Nowe rejestracje:",
"notifications.column_settings.alert": "Powiadomienia na pulpicie",
"notifications.column_settings.favourite": "Ulubione:",
"notifications.column_settings.filter_bar.advanced": "Wyświetl wszystkie kategorie",
"notifications.column_settings.filter_bar.category": "Szybkie filtrowanie",
"notifications.column_settings.follow": "Nowi obserwujący:",
"notifications.column_settings.follow_request": "Nowe prośby o możliwość obserwacji:",
"notifications.column_settings.mention": "Wspomnienia:",
@ -587,6 +590,12 @@
"refresh": "Odśwież",
"regeneration_indicator.label": "Ładuję…",
"regeneration_indicator.sublabel": "Twoja oś czasu jest przygotowywana!",
"relationship_severance_notification.purged_data": "wyczyszczone przez administratorów",
"relationship_severance_notification.relationships": "{count, plural, one {# związek} few {# związki} other {# związków}}",
"relationship_severance_notification.types.account_suspension": "Konto zostało zawieszone",
"relationship_severance_notification.types.domain_block": "Domena została zawieszona",
"relationship_severance_notification.types.user_domain_block": "Domena przez ciebie blokowana",
"relationship_severance_notification.view": "Pokaż",
"relative_time.days": "{number} dni",
"relative_time.full.days": "{number, plural, one {# dzień} few {# dni} many {# dni} other {# dni}} temu",
"relative_time.full.hours": "{number, plural, one {# godzinę} few {# godziny} many {# godzin} other {# godzin}} temu",

@ -471,6 +471,7 @@
"notification.own_poll": "A sua votação terminou",
"notification.poll": "Uma votação em que participaste chegou ao fim",
"notification.reblog": "{name} reforçou a tua publicação",
"notification.severed_relationships": "Relações com {name} cessadas",
"notification.status": "{name} acabou de publicar",
"notification.update": "{name} editou uma publicação",
"notification_requests.accept": "Aceitar",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Novas inscrições:",
"notifications.column_settings.alert": "Notificações no ambiente de trabalho",
"notifications.column_settings.favourite": "Favoritos:",
"notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
"notifications.column_settings.filter_bar.category": "Barra de filtros rápidos",
"notifications.column_settings.follow": "Novos seguidores:",
"notifications.column_settings.follow_request": "Novos pedidos de seguidor:",
"notifications.column_settings.mention": "Menções:",
@ -587,6 +590,12 @@
"refresh": "Actualizar",
"regeneration_indicator.label": "A carregar…",
"regeneration_indicator.sublabel": "A tua página inicial está a ser preparada!",
"relationship_severance_notification.purged_data": "purgado pelos administradores",
"relationship_severance_notification.relationships": "{count, plural,one {# relação} other {# relações}}",
"relationship_severance_notification.types.account_suspension": "A conta foi suspensa",
"relationship_severance_notification.types.domain_block": "O domínio foi suspenso",
"relationship_severance_notification.types.user_domain_block": "Bloqueou este domínio",
"relationship_severance_notification.view": "Visualizar",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural,one {# dia} other {# dias}} atrás",
"relative_time.full.hours": "{number, plural,one {# hora}other {# horas}} atrás",

@ -35,11 +35,13 @@
"account.following": "Слідуєте",
"account.follows.empty": "Сись хосновач щи никого не слідує.",
"account.go_to_profile": "Перейти на профіл",
"account.hide_reblogs": "Спрятати друленя уд @{name}",
"account.joined_short": "Датум прикапчованя",
"account.languages": "Поміняти убрані языкы",
"account.link_verified_on": "Властность сього удкликованя было звірено {date}",
"account.media": "Медіа",
"account.moved_to": "Хосновач {name} указав, ож новый профіл йим є:",
"account.mute": "Стишити {name}",
"account.mute_notifications_short": "Стишити голошіня",
"account.mute_short": "Стишити",
"account.muted": "Стишено",
@ -52,8 +54,22 @@
"account.requested": "Чекат ся на пудтвердженя. Нажміт убы удмінити запрос на слідованя",
"account.requested_follow": "Хосновач {name} просит ся пудписати ся на вас",
"account.share": "Пошырити профіл хосновача {name}",
"account.show_reblogs": "Указати друленя уд {name}",
"account.unblock": "Розблоковати {name}",
"account.unblock_domain": "Розблоковати домен {domain}",
"account.unblock_short": "Розблоковати",
"account.unendorse": "Не указовати на профілови",
"account.unfollow": "Удписати ся",
"account.unmute_notifications_short": "Указовати голошіня",
"account.unmute_short": "Указовати",
"account_note.placeholder": "Клопкніт обы додати примітку",
"admin.dashboard.retention.cohort_size": "Нові хосновачі",
"admin.impact_report.instance_accounts": "Профілі из акаунтув, котрі ся удалят",
"admin.impact_report.instance_followers": "Пудписникы, котрых стратят наші хосновачі",
"admin.impact_report.instance_follows": "Пудписникы, котрых стратят їхні хосновачі",
"admin.impact_report.title": "Вплыв цілком",
"alert.rate_limited.message": "Попробуйте зась по {retry_time, time, medium}.",
"alert.rate_limited.title": "Частота обмежена",
"bundle_column_error.return": "Вернути ся на головну",
"bundle_column_error.routing.body": "Не можеме найти сяку сторунку. Бизувні сьте, ож URL у адресному шорикови є добрый?",
"bundle_column_error.routing.title": "404",

@ -205,8 +205,10 @@
"dismissable_banner.explore_tags": "Toto sú hashtagy zo sociálnej siete, ktoré sú dnes populárne. Novšie hashtagy používané viacerými ľuďmi sú radené vyššie.",
"dismissable_banner.public_timeline": "Toto sú najnovšie verejné príspevky od účtov na sociálnej sieti, ktoré sú sledované účtami z {domain}.",
"domain_block_modal.block": "Blokovať server",
"domain_block_modal.block_account_instead": "Namiesto toho zablokuj @{name}",
"domain_block_modal.title": "Blokovať doménu?",
"domain_pill.server": "Server",
"domain_pill.their_server": "Ich digitálny domov, kde žijú všetky ich príspevky.",
"domain_pill.username": "Používateľské meno",
"embed.instructions": "Tento príspevok môžete pridať na svoju webovú stránku použitím tohto kódu.",
"embed.preview": "Takto bude vyzerať:",
@ -404,6 +406,7 @@
"loading_indicator.label": "Načítavanie…",
"media_gallery.toggle_visible": "{number, plural, one {Skryť obrázok} other {Skryť obrázky}}",
"moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálne deaktivovaný, pretože ste sa presunuli na {movedToAccount}.",
"mute_modal.hide_from_notifications": "Ukryť z upozornení",
"mute_modal.hide_options": "Skryť možnosti",
"mute_modal.show_options": "Zobraziť možnosti",
"mute_modal.title": "Stíšiť užívateľa?",
@ -454,6 +457,7 @@
"notifications.column_settings.admin.sign_up": "Nové registrácie:",
"notifications.column_settings.alert": "Upozornenia na ploche",
"notifications.column_settings.favourite": "Ohviezdičkované:",
"notifications.column_settings.filter_bar.advanced": "Zobraziť všetky kategórie",
"notifications.column_settings.follow": "Nové sledovania od:",
"notifications.column_settings.follow_request": "Nové žiadosti o sledovanie od:",
"notifications.column_settings.mention": "Označenia:",
@ -553,6 +557,8 @@
"refresh": "Obnoviť",
"regeneration_indicator.label": "Načítavanie…",
"regeneration_indicator.sublabel": "Váš domovský kanál sa pripravuje.",
"relationship_severance_notification.types.user_domain_block": "Túto doménu si zablokoval/a",
"relationship_severance_notification.view": "Zobraziť",
"relative_time.days": "{number} dní",
"relative_time.full.days": "Pred {number, plural, one {# dňom} other {# dňami}}",
"relative_time.full.hours": "Pred {number, plural, one {# hodinou} other {# hodinami}}",

@ -471,6 +471,7 @@
"notification.own_poll": "Vaša anketa je zaključena",
"notification.poll": "Anketa, v kateri ste sodelovali, je zaključena",
"notification.reblog": "{name} je izpostavila/a vašo objavo",
"notification.severed_relationships": "Veze z {name} prekinjene",
"notification.status": "{name} je pravkar objavil/a",
"notification.update": "{name} je uredil(a) objavo",
"notification_requests.accept": "Sprejmi",
@ -516,7 +517,7 @@
"notifications.policy.filter_not_following_title": "Ljudje, ki jim ne sledite",
"notifications.policy.filter_private_mentions_hint": "Filtrirano, razen če je odgovor na vašo lastno omembo ali če sledite pošiljatelju",
"notifications.policy.filter_private_mentions_title": "Neželene zasebne omembe",
"notifications.policy.title": "Skrij obvestila od …",
"notifications.policy.title": "Filtriraj obvestila od …",
"notifications_permission_banner.enable": "Omogoči obvestila na namizju",
"notifications_permission_banner.how_to_control": "Če želite prejemati obvestila, ko Mastodon ni odprt, omogočite namizna obvestila. Natančno lahko nadzirate, katere vrste interakcij naj tvorijo namizna obvestila; ko so omogočena, za to uporabite gumb {icon} zgoraj.",
"notifications_permission_banner.title": "Nikoli ne zamudite ničesar",
@ -587,6 +588,12 @@
"refresh": "Osveži",
"regeneration_indicator.label": "Nalaganje …",
"regeneration_indicator.sublabel": "Vaš domači vir se pripravlja!",
"relationship_severance_notification.purged_data": "očistili skrbniki",
"relationship_severance_notification.relationships": "{count, plural, one {# veza} two {# vezi} few {# veze} other {# vez}}",
"relationship_severance_notification.types.account_suspension": "Račun je bil suspendiran",
"relationship_severance_notification.types.domain_block": "Domena je bila suspendirana",
"relationship_severance_notification.types.user_domain_block": "Domeno ste blokirali",
"relationship_severance_notification.view": "Pogled",
"relative_time.days": "{number} d",
"relative_time.full.days": "{number, plural, one {pred # dnem} two {pred # dnevoma} few {pred # dnevi} other {pred # dnevi}}",
"relative_time.full.hours": "{number, plural, one {pred # uro} two {pred # urama} few {pred # urami} other {pred # urami}}",

@ -470,6 +470,7 @@
"notification.own_poll": "Pyetësori juaj ka përfunduar",
"notification.poll": "Ka përfunduar një pyetësor ku keni votuar",
"notification.reblog": "{name} përforcoi mesazhin tuaj",
"notification.severed_relationships": "Marrëdhëniet me {name} u ndërprenë",
"notification.status": "{name} sapo postoi",
"notification.update": "{name} përpunoi një postim",
"notification_requests.accept": "Pranoje",
@ -482,6 +483,8 @@
"notifications.column_settings.admin.sign_up": "Regjistrime të reja:",
"notifications.column_settings.alert": "Njoftime desktopi",
"notifications.column_settings.favourite": "Të parapëlqyer:",
"notifications.column_settings.filter_bar.advanced": "Shfaq krejt kategoritë",
"notifications.column_settings.filter_bar.category": "Shtyllë filtrimesh të shpejta",
"notifications.column_settings.follow": "Ndjekës të rinj:",
"notifications.column_settings.follow_request": "Kërkesa të reja për ndjekje:",
"notifications.column_settings.mention": "Përmendje:",
@ -584,6 +587,12 @@
"refresh": "Rifreskoje",
"regeneration_indicator.label": "Po ngarkohet…",
"regeneration_indicator.sublabel": "Prurja juaj vetjake po përgatitet!",
"relationship_severance_notification.purged_data": "spastruar nga përgjegjës",
"relationship_severance_notification.relationships": "{count, plural, one {# marrëdhënie} other {# marrëdhënie}}",
"relationship_severance_notification.types.account_suspension": "Llogaria është pezulluar",
"relationship_severance_notification.types.domain_block": "Përkatësia është pezulluar",
"relationship_severance_notification.types.user_domain_block": "E bllokuat këtë përkatësi",
"relationship_severance_notification.view": "Shiheni",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# ditë} other {# ditë}} më parë",
"relative_time.full.hours": "{number, plural, one {# orë} other {# orë}} më parë",

@ -89,6 +89,7 @@
"announcement.announcement": "Meddelande",
"attachments_list.unprocessed": "(obehandlad)",
"audio.hide": "Dölj audio",
"block_modal.remote_users_caveat": "Vi kommer att be servern {domain} att respektera ditt beslut. Dock garanteras inte efterlevnad eftersom vissa servrar kan hantera blockeringar på olika sätt. Offentliga inlägg kan fortfarande vara synliga för icke-inloggade användare.",
"block_modal.show_less": "Visa mindre",
"block_modal.show_more": "Visa mer",
"block_modal.they_cant_mention": "De kan inte nämna eller följa dig.",
@ -212,8 +213,12 @@
"domain_block_modal.block_account_instead": "Blockera @{name} istället",
"domain_block_modal.they_can_interact_with_old_posts": "Personer från denna server kan interagera med dina gamla inlägg.",
"domain_block_modal.they_cant_follow": "Ingen från denna server kan följa dig.",
"domain_block_modal.they_wont_know": "De kommer inte veta att de har blockerats.",
"domain_block_modal.title": "Blockera domän?",
"domain_block_modal.you_will_lose_followers": "Alla dina följare från denna server kommer att tas bort.",
"domain_block_modal.you_wont_see_posts": "Du kommer inte att se inlägg eller meddelanden från användare på den här servern.",
"domain_pill.activitypub_lets_connect": "Det låter dig ansluta och interagera med människor inte bara på Mastodon, men även på andra sociala appar.",
"domain_pill.activitypub_like_language": "ActivityPub är som språket Mastodon talar med andra sociala nätverk.",
"domain_pill.server": "Server",
"domain_pill.their_username": "Deras unika identifierare på deras server. Det är möjligt att hitta användare med samma användarnamn på olika servrar.",
"domain_pill.username": "Användarnamn",
@ -415,6 +420,8 @@
"mute_modal.hide_options": "Dölj alternativ",
"mute_modal.show_options": "Visa alternativ",
"mute_modal.they_can_mention_and_follow": "De kan nämna och följa dig, men du ser dem inte.",
"mute_modal.they_wont_know": "De vet inte att de har blivit tysta.",
"mute_modal.title": "Tysta användare?",
"mute_modal.you_wont_see_mentions": "Du kommer inte att se inlägg som nämner dem.",
"mute_modal.you_wont_see_posts": "De kan fortfarande se dina inlägg, men du kan inte se deras.",
"navigation_bar.about": "Om",
@ -454,12 +461,17 @@
"notification.reblog": "{name} boostade ditt inlägg",
"notification.status": "{name} publicerade just ett inlägg",
"notification.update": "{name} redigerade ett inlägg",
"notification_requests.accept": "Godkänn",
"notification_requests.dismiss": "Avfärda",
"notification_requests.notifications_from": "Aviseringar från {name}",
"notification_requests.title": "Filtrerade meddelanden",
"notifications.clear": "Rensa aviseringar",
"notifications.clear_confirmation": "Är du säker på att du vill rensa alla dina aviseringar permanent?",
"notifications.column_settings.admin.report": "Nya rapporter:",
"notifications.column_settings.admin.sign_up": "Nya registreringar:",
"notifications.column_settings.alert": "Skrivbordsaviseringar",
"notifications.column_settings.favourite": "Favoriter:",
"notifications.column_settings.filter_bar.advanced": "Visa alla kategorier",
"notifications.column_settings.follow": "Nya följare:",
"notifications.column_settings.follow_request": "Ny följ-förfrågan:",
"notifications.column_settings.mention": "Omnämningar:",
@ -485,9 +497,12 @@
"notifications.permission_denied": "Skrivbordsaviseringar är otillgängliga på grund av tidigare nekade förfrågningar om behörighet i webbläsaren",
"notifications.permission_denied_alert": "Skrivbordsaviseringar kan inte aktiveras, eftersom att webbläsarens behörighet har nekats innan",
"notifications.permission_required": "Skrivbordsaviseringar är otillgängliga eftersom att rättigheten som krävs inte har godkänts.",
"notifications.policy.filter_new_accounts.hint": "Skapad inom de senaste {days, plural, one {dagen} other {# dagarna}}",
"notifications.policy.filter_new_accounts_title": "Nya konton",
"notifications.policy.filter_not_followers_title": "Personer som inte följer dig",
"notifications.policy.filter_not_following_title": "Personer du inte följer",
"notifications.policy.filter_private_mentions_title": "Oombedda privata omnämnanden",
"notifications.policy.title": "Filtrera ut aviseringar från…",
"notifications_permission_banner.enable": "Aktivera skrivbordsaviseringar",
"notifications_permission_banner.how_to_control": "För att ta emot aviseringar när Mastodon inte är öppet, aktivera skrivbordsaviseringar. När de är aktiverade kan du styra exakt vilka typer av interaktioner som aviseras via {icon} -knappen ovan.",
"notifications_permission_banner.title": "Missa aldrig något",
@ -558,6 +573,11 @@
"refresh": "Läs om",
"regeneration_indicator.label": "Laddar…",
"regeneration_indicator.sublabel": "Ditt hemmaflöde förbereds!",
"relationship_severance_notification.purged_data": "rensad av administratörer",
"relationship_severance_notification.types.account_suspension": "Ditt konto har blivit avstängt",
"relationship_severance_notification.types.domain_block": "Domänen har stängts av",
"relationship_severance_notification.types.user_domain_block": "Du blockerade denna domän",
"relationship_severance_notification.view": "Visa",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# dag} other {# dagar}} sedan",
"relative_time.full.hours": "{number, plural, one {# timme} other {# timmar}} sedan",

@ -471,6 +471,7 @@
"notification.own_poll": "การสำรวจความคิดเห็นของคุณได้สิ้นสุดแล้ว",
"notification.poll": "การสำรวจความคิดเห็นที่คุณได้ลงคะแนนได้สิ้นสุดแล้ว",
"notification.reblog": "{name} ได้ดันโพสต์ของคุณ",
"notification.severed_relationships": "ตัดขาดความสัมพันธ์กับ {name} แล้ว",
"notification.status": "{name} เพิ่งโพสต์",
"notification.update": "{name} ได้แก้ไขโพสต์",
"notification_requests.accept": "ยอมรับ",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "การลงทะเบียนใหม่:",
"notifications.column_settings.alert": "การแจ้งเตือนบนเดสก์ท็อป",
"notifications.column_settings.favourite": "รายการโปรด:",
"notifications.column_settings.filter_bar.advanced": "แสดงหมวดหมู่ทั้งหมด",
"notifications.column_settings.filter_bar.category": "แถบตัวกรองด่วน",
"notifications.column_settings.follow": "ผู้ติดตามใหม่:",
"notifications.column_settings.follow_request": "คำขอติดตามใหม่:",
"notifications.column_settings.mention": "การกล่าวถึง:",
@ -587,6 +590,12 @@
"refresh": "รีเฟรช",
"regeneration_indicator.label": "กำลังโหลด…",
"regeneration_indicator.sublabel": "กำลังเตรียมฟีดหน้าแรกของคุณ!",
"relationship_severance_notification.purged_data": "ล้างข้อมูลโดยผู้ดูแล",
"relationship_severance_notification.relationships": "{count, plural, other {# ความสัมพันธ์}}",
"relationship_severance_notification.types.account_suspension": "ระงับบัญชีแล้ว",
"relationship_severance_notification.types.domain_block": "ระงับโดเมนแล้ว",
"relationship_severance_notification.types.user_domain_block": "คุณได้ปิดกั้นโดเมนนี้",
"relationship_severance_notification.view": "ดู",
"relative_time.days": "{number} วัน",
"relative_time.full.days": "{number, plural, other {# วัน}}ที่แล้ว",
"relative_time.full.hours": "{number, plural, other {# ชั่วโมง}}ที่แล้ว",

@ -471,6 +471,7 @@
"notification.own_poll": "Anketiniz sona erdi",
"notification.poll": "Oy verdiğiniz bir anket sona erdi",
"notification.reblog": "{name} gönderini yeniden paylaştı",
"notification.severed_relationships": "{name} ile ilişkiler koptu",
"notification.status": "{name} az önce gönderdi",
"notification.update": "{name} bir gönderiyi düzenledi",
"notification_requests.accept": "Onayla",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "Yeni kayıtlar:",
"notifications.column_settings.alert": "Masaüstü bildirimleri",
"notifications.column_settings.favourite": "Favorilerin:",
"notifications.column_settings.filter_bar.advanced": "Tüm kategorileri görüntüle",
"notifications.column_settings.filter_bar.category": "Hızlı filtre çubuğu",
"notifications.column_settings.follow": "Yeni takipçiler:",
"notifications.column_settings.follow_request": "Yeni takip istekleri:",
"notifications.column_settings.mention": "Değinmeler:",
@ -587,6 +590,12 @@
"refresh": "Yenile",
"regeneration_indicator.label": "Yükleniyor…",
"regeneration_indicator.sublabel": "Ana akışın hazırlanıyor!",
"relationship_severance_notification.purged_data": "yöneticiler tarafından temizlendi",
"relationship_severance_notification.relationships": "{count, plural, one {# ilişki} other {# ilişki}}",
"relationship_severance_notification.types.account_suspension": "Hesap askıya alındı",
"relationship_severance_notification.types.domain_block": "Alan adı askıya alındı",
"relationship_severance_notification.types.user_domain_block": "Bu alan adını engellediniz",
"relationship_severance_notification.view": "Görüntüle",
"relative_time.days": "{number}d",
"relative_time.full.days": "{number, plural, one {# gün} other {# gün}} önce",
"relative_time.full.hours": "{number, plural, one {# saat} other {# saat}} önce",

@ -89,6 +89,14 @@
"announcement.announcement": "Оголошення",
"attachments_list.unprocessed": "(не оброблено)",
"audio.hide": "Сховати аудіо",
"block_modal.remote_users_caveat": "Ми попросимо сервер {domain} поважати ваше рішення. Однак дотримання вимог не гарантується, оскільки деякі сервери можуть обробляти блоки по-різному. Загальнодоступні дописи все ще можуть бути видимими для користувачів, які не увійшли в систему.",
"block_modal.show_less": "Згорнути",
"block_modal.show_more": "Розгорнути",
"block_modal.they_cant_mention": "Вони не можуть згадувати та стежити за вами.",
"block_modal.they_cant_see_posts": "Вони не можуть бачити ваших дописів, а ви бачитимете їхні.",
"block_modal.they_will_know": "Вони можуть бачити, що вони заблоковані.",
"block_modal.title": "Заблокувати користувача?",
"block_modal.you_wont_see_mentions": "Ви не бачитимете дописів, де їх згадано.",
"boost_modal.combo": "Ви можете натиснути {combo}, щоби пропустити це наступного разу",
"bundle_column_error.copy_stacktrace": "Копіювати звіт про помилку",
"bundle_column_error.error.body": "Неможливо показати запитану сторінку. Це може бути спричинено помилкою у нашому коді, або через проблему сумісності з браузером.",
@ -169,6 +177,7 @@
"confirmations.delete_list.message": "Ви впевнені, що хочете видалити цей список назавжди?",
"confirmations.discard_edit_media.confirm": "Відкинути",
"confirmations.discard_edit_media.message": "У вас є незбережені зміни в описі медіа або попереднього перегляду, все одно відкинути їх?",
"confirmations.domain_block.confirm": "Блокувати сервер",
"confirmations.domain_block.message": "Ви точно, точно впевнені, що хочете заблокувати весь домен {domain}? У більшості випадків для нормальної роботи краще заблокувати або приховати лише деяких користувачів. Ви не зможете бачити контент з цього домену у будь-яких стрічках або ваших сповіщеннях. Ваші підписники з цього домену будуть відписані від вас.",
"confirmations.edit.confirm": "Змінити",
"confirmations.edit.message": "Редагування перезапише повідомлення, яке ви зараз пишете. Ви впевнені, що хочете продовжити?",
@ -200,6 +209,16 @@
"dismissable_banner.explore_statuses": "Ці дописи з цього та інших серверів децентралізованої мережі зараз набирають популярності на цьому сервері. Новіші дописи з частішим поширенням та додаванням до вподобаного мають вищий рейтинг.",
"dismissable_banner.explore_tags": "Ці хештеги зараз набирають популярності серед людей на цьому та інших серверах децентралізованої мережі. Хештеги, які використовуються більшою кількістю людей, мають вищий рейтинг.",
"dismissable_banner.public_timeline": "Це найновіші загальнодоступні дописи від людей в соціальній мережі, на які підписані люди в {domain}.",
"domain_block_modal.block": "Блокувати сервер",
"domain_block_modal.block_account_instead": "Блокувати @{name} натомість",
"domain_block_modal.they_can_interact_with_old_posts": "Люди з цього сервера можуть взаємодіяти зі своїми старими дописами.",
"domain_block_modal.they_cant_follow": "Ніхто з цього сервера не може слідкувати за вами.",
"domain_block_modal.they_wont_know": "Вони не знають, що їх заблоковано.",
"domain_block_modal.title": "Заблокувати домен?",
"domain_block_modal.you_will_lose_followers": "Усіх ваших підписників з цього сервера буде вилучено.",
"domain_block_modal.you_wont_see_posts": "Ви не бачитимете дописів і сповіщень від користувачів на цьому сервері.",
"domain_pill.server": "Сервер",
"domain_pill.username": "Ім'я користувача",
"embed.instructions": "Вбудуйте цей допис до вашого вебсайту, скопіювавши код нижче.",
"embed.preview": "Ось який вигляд це матиме:",
"emoji_button.activity": "Діяльність",
@ -397,6 +416,15 @@
"loading_indicator.label": "Завантаження…",
"media_gallery.toggle_visible": "{number, plural, one {Приховати зображення} other {Приховати зображення}}",
"moved_to_account_banner.text": "Ваш обліковий запис {disabledAccount} наразі вимкнений, оскільки вас перенесено до {movedToAccount}.",
"mute_modal.hide_from_notifications": "Сховати зі сповіщень",
"mute_modal.hide_options": "Сховати опції",
"mute_modal.indefinite": "Доки я не перестану ігнорувати їх",
"mute_modal.show_options": "Показати опції",
"mute_modal.they_can_mention_and_follow": "Вони зможуть згадувати та стежити за вами, але ви їх не бачитимете.",
"mute_modal.they_wont_know": "Вони не знатимуть, що їх ігнорують.",
"mute_modal.title": "Ігнорувати користувача?",
"mute_modal.you_wont_see_mentions": "Ви не бачитимете дописів, де їх згадано.",
"mute_modal.you_wont_see_posts": "Вони все ще можуть бачити ваші дописи, але ви не бачитимете їхніх.",
"navigation_bar.about": "Про застосунок",
"navigation_bar.advanced_interface": "Відкрити в розширеному вебінтерфейсі",
"navigation_bar.blocks": "Заблоковані користувачі",
@ -432,6 +460,7 @@
"notification.own_poll": "Ваше опитування завершилося",
"notification.poll": "Опитування, у якому ви голосували, скінчилося",
"notification.reblog": "{name} поширює ваш допис",
"notification.severed_relationships": "Зв'язки з {name} розірвані",
"notification.status": "{name} щойно дописує",
"notification.update": "{name} змінює допис",
"notification_requests.accept": "Прийняти",
@ -444,6 +473,8 @@
"notifications.column_settings.admin.sign_up": "Нові реєстрації:",
"notifications.column_settings.alert": "Сповіщення стільниці",
"notifications.column_settings.favourite": "Уподобане:",
"notifications.column_settings.filter_bar.advanced": "Показати всі категорії",
"notifications.column_settings.filter_bar.category": "Панель швидкого фільтру",
"notifications.column_settings.follow": "Нові підписники:",
"notifications.column_settings.follow_request": "Нові запити на підписку:",
"notifications.column_settings.mention": "Згадки:",
@ -544,6 +575,12 @@
"refresh": "Оновити",
"regeneration_indicator.label": "Завантаження…",
"regeneration_indicator.sublabel": "Хвилинку, ми готуємо вашу стрічку!",
"relationship_severance_notification.purged_data": "очищено адміністраторами",
"relationship_severance_notification.relationships": "{count, plural, one {# зв'язок} few {# зв'язки} many {# зв'язків} other {# зв'язок}}",
"relationship_severance_notification.types.account_suspension": "Обліковий запис призупинено",
"relationship_severance_notification.types.domain_block": "Домен призупинено",
"relationship_severance_notification.types.user_domain_block": "Ви заблокували цей домен",
"relationship_severance_notification.view": "Вигляд",
"relative_time.days": "{number}д",
"relative_time.full.days": "{number, plural, one {# день} few {# дні} other {# днів}} тому",
"relative_time.full.hours": "{number, plural, one {# година} few {# години} other {# годин}} тому",

@ -471,6 +471,7 @@
"notification.own_poll": "Cuộc bình chọn của bạn đã kết thúc",
"notification.poll": "Cuộc bình chọn đã kết thúc",
"notification.reblog": "{name} đăng lại tút của bạn",
"notification.severed_relationships": "Mối quan hệ với {name} bị cắt đứt",
"notification.status": "{name} đăng tút mới",
"notification.update": "{name} đã sửa tút",
"notification_requests.accept": "Chấp nhận",
@ -587,6 +588,12 @@
"refresh": "Làm mới",
"regeneration_indicator.label": "Đang tải…",
"regeneration_indicator.sublabel": "Trang chủ của bạn đang được cập nhật!",
"relationship_severance_notification.purged_data": "bị quản trị viên xóa",
"relationship_severance_notification.relationships": "{count, plural, other {# mối quan hệ}}",
"relationship_severance_notification.types.account_suspension": "Người này đã bị vô hiệu hóa",
"relationship_severance_notification.types.domain_block": "Máy chủ này đã bị vô hiệu hóa",
"relationship_severance_notification.types.user_domain_block": "Bạn đã chặn máy chủ này",
"relationship_severance_notification.view": "Chi tiết",
"relative_time.days": "{number} ngày",
"relative_time.full.days": "{number, plural, other {# ngày}}",
"relative_time.full.hours": "{number, plural, other {# giờ}}",

@ -471,6 +471,7 @@
"notification.own_poll": "你的投票已经结束",
"notification.poll": "你参与的一个投票已经结束",
"notification.reblog": "{name} 转发了你的嘟文",
"notification.severed_relationships": "与 {name} 的关系已被切断",
"notification.status": "{name} 刚刚发布嘟文",
"notification.update": "{name} 编辑了嘟文",
"notification_requests.accept": "接受",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "新注册:",
"notifications.column_settings.alert": "桌面通知",
"notifications.column_settings.favourite": "喜欢:",
"notifications.column_settings.filter_bar.advanced": "显示所有类别",
"notifications.column_settings.filter_bar.category": "快速筛选栏",
"notifications.column_settings.follow": "新粉丝:",
"notifications.column_settings.follow_request": "新关注请求:",
"notifications.column_settings.mention": "提及:",
@ -587,6 +590,12 @@
"refresh": "刷新",
"regeneration_indicator.label": "加载中…",
"regeneration_indicator.sublabel": "你的主页动态正在准备中!",
"relationship_severance_notification.purged_data": "被管理员清除",
"relationship_severance_notification.relationships": "{count, plural, other {# 条关系}}",
"relationship_severance_notification.types.account_suspension": "账户已被封禁",
"relationship_severance_notification.types.domain_block": "域名已被封禁",
"relationship_severance_notification.types.user_domain_block": "你屏蔽了这个域名",
"relationship_severance_notification.view": "查看",
"relative_time.days": "{number} 天前",
"relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前",
"relative_time.full.hours": "{number, plural, one {# 小时} other {# 小时}}前",

@ -471,6 +471,7 @@
"notification.own_poll": "你的投票已結束",
"notification.poll": "你參與過的一個投票已經結束",
"notification.reblog": "{name} 轉推你的文章",
"notification.severed_relationships": "已斷絕與 {name} 的關係",
"notification.status": "{name} 剛發表了文章",
"notification.update": "{name} 編輯了帖文",
"notification_requests.accept": "接受",
@ -587,6 +588,12 @@
"refresh": "重新整理",
"regeneration_indicator.label": "載入中……",
"regeneration_indicator.sublabel": "你的主頁時間軸正在準備中!",
"relationship_severance_notification.purged_data": "已被管理員清除",
"relationship_severance_notification.relationships": "{count, plural, one {# 個關係} other {# 個關係}}",
"relationship_severance_notification.types.account_suspension": "帳號已被停權",
"relationship_severance_notification.types.domain_block": "網域已被停權",
"relationship_severance_notification.types.user_domain_block": "你封鎖了此網域",
"relationship_severance_notification.view": "查看",
"relative_time.days": "{number}日前",
"relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前",
"relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前",
@ -697,6 +704,7 @@
"status.edited_x_times": "Edited {count, plural, one {{count} 次} other {{count} 次}}",
"status.embed": "嵌入",
"status.favourite": "最愛",
"status.favourites": "{count, plural, one {則最愛} other {則最愛}}",
"status.filter": "篩選此帖文",
"status.filtered": "已過濾",
"status.hide": "隱藏帖文",
@ -717,6 +725,7 @@
"status.reblog": "轉推",
"status.reblog_private": "轉推到原讀者",
"status.reblogged_by": "{name} 轉推",
"status.reblogs": "{count, plural, one {則轉推} other {則轉推}}",
"status.reblogs.empty": "還未有人轉推。有的話會顯示在這裡。",
"status.redraft": "刪除並編輯",
"status.remove_bookmark": "移除書籤",

@ -471,6 +471,7 @@
"notification.own_poll": "您的投票已結束",
"notification.poll": "您曾投過的投票已經結束",
"notification.reblog": "{name} 已轉嘟您的嘟文",
"notification.severed_relationships": "已斷絕與 {name} 之服務關係",
"notification.status": "{name} 剛剛嘟文",
"notification.update": "{name} 已編輯嘟文",
"notification_requests.accept": "接受",
@ -483,6 +484,8 @@
"notifications.column_settings.admin.sign_up": "新註冊帳號:",
"notifications.column_settings.alert": "桌面通知",
"notifications.column_settings.favourite": "最愛:",
"notifications.column_settings.filter_bar.advanced": "顯示所有分類",
"notifications.column_settings.filter_bar.category": "快速過濾器",
"notifications.column_settings.follow": "新的跟隨者:",
"notifications.column_settings.follow_request": "新的跟隨請求:",
"notifications.column_settings.mention": "提及:",
@ -587,6 +590,12 @@
"refresh": "重新整理",
"regeneration_indicator.label": "載入中…",
"regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!",
"relationship_severance_notification.purged_data": "已被管理員清除",
"relationship_severance_notification.relationships": "{count, plural, other {# 個服務關係}}",
"relationship_severance_notification.types.account_suspension": "該帳號已被停權",
"relationship_severance_notification.types.domain_block": "該網域已被停權",
"relationship_severance_notification.types.user_domain_block": "您已封鎖此網域",
"relationship_severance_notification.view": "檢視",
"relative_time.days": "{number} 天",
"relative_time.full.days": "{number, plural, other {# 天}}前",
"relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前",

@ -45,6 +45,7 @@ import {
INIT_MEDIA_EDIT_MODAL,
COMPOSE_CHANGE_MEDIA_DESCRIPTION,
COMPOSE_CHANGE_MEDIA_FOCUS,
COMPOSE_CHANGE_MEDIA_ORDER,
COMPOSE_SET_STATUS,
COMPOSE_FOCUS,
} from '../actions/compose';
@ -536,6 +537,14 @@ export default function compose(state = initialState, action) {
return state.set('language', action.language);
case COMPOSE_FOCUS:
return state.set('focusDate', new Date()).update('text', text => text.length > 0 ? text : action.defaultText);
case COMPOSE_CHANGE_MEDIA_ORDER:
return state.update('media_attachments', list => {
const indexA = list.findIndex(x => x.get('id') === action.a);
const moveItem = list.get(indexA);
const indexB = list.findIndex(x => x.get('id') === action.b);
return list.splice(indexA, 1).splice(indexB, 0, moveItem);
});
default:
return state;
}

@ -55,6 +55,7 @@ export const notificationToMap = notification => ImmutableMap({
created_at: notification.created_at,
status: notification.status ? notification.status.id : null,
report: notification.report ? fromJS(notification.report) : null,
event: notification.event ? fromJS(notification.event) : null,
});
const normalizeNotification = (state, notification, usePendingItems) => {

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

Loading…
Cancel
Save