Merge remote-tracking branch 'upstream/main'
All checks were successful
continuous-integration/drone Build is passing
All checks were successful
continuous-integration/drone Build is passing
This commit is contained in:
commit
2c4f8b71cb
305 changed files with 5080 additions and 2949 deletions
|
@ -70,7 +70,7 @@ services:
|
||||||
hard: -1
|
hard: -1
|
||||||
|
|
||||||
libretranslate:
|
libretranslate:
|
||||||
image: libretranslate/libretranslate:v1.4.1
|
image: libretranslate/libretranslate:v1.5.2
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- lt-data:/home/libretranslate/.local
|
- lt-data:/home/libretranslate/.local
|
||||||
|
|
13
.github/codecov.yml
vendored
Normal file
13
.github/codecov.yml
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
# Github status check is not blocking
|
||||||
|
informational: true
|
||||||
|
patch:
|
||||||
|
default:
|
||||||
|
# Github status check is not blocking
|
||||||
|
informational: true
|
||||||
|
comment:
|
||||||
|
# Only write a comment in PR if there are changes
|
||||||
|
require_changes: true
|
12
.github/workflows/test-ruby.yml
vendored
12
.github/workflows/test-ruby.yml
vendored
|
@ -94,7 +94,7 @@ jobs:
|
||||||
DB_HOST: localhost
|
DB_HOST: localhost
|
||||||
DB_USER: postgres
|
DB_USER: postgres
|
||||||
DB_PASS: postgres
|
DB_PASS: postgres
|
||||||
DISABLE_SIMPLECOV: true
|
DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }}
|
||||||
RAILS_ENV: test
|
RAILS_ENV: test
|
||||||
ALLOW_NOPAM: true
|
ALLOW_NOPAM: true
|
||||||
PAM_ENABLED: true
|
PAM_ENABLED: true
|
||||||
|
@ -137,6 +137,12 @@ jobs:
|
||||||
|
|
||||||
- run: bin/rspec
|
- run: bin/rspec
|
||||||
|
|
||||||
|
- name: Upload coverage reports to Codecov
|
||||||
|
if: matrix.ruby-version == '.ruby-version'
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
files: coverage/lcov/mastodon.lcov
|
||||||
|
|
||||||
test-e2e:
|
test-e2e:
|
||||||
name: End to End testing
|
name: End to End testing
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -221,7 +227,7 @@ jobs:
|
||||||
path: tmp/screenshots/
|
path: tmp/screenshots/
|
||||||
|
|
||||||
test-search:
|
test-search:
|
||||||
name: Testing search
|
name: Elastic Search integration testing
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
needs:
|
needs:
|
||||||
|
@ -308,7 +314,7 @@ jobs:
|
||||||
- name: Load database schema
|
- name: Load database schema
|
||||||
run: './bin/rails db:create db:schema:load db:seed'
|
run: './bin/rails db:create db:schema:load db:seed'
|
||||||
|
|
||||||
- run: bundle exec rake spec:search
|
- run: bin/rspec --tag search
|
||||||
|
|
||||||
- name: Archive logs
|
- name: Archive logs
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
|
|
@ -41,23 +41,6 @@ Metrics/CyclomaticComplexity:
|
||||||
Metrics/PerceivedComplexity:
|
Metrics/PerceivedComplexity:
|
||||||
Max: 27
|
Max: 27
|
||||||
|
|
||||||
RSpec/AnyInstance:
|
|
||||||
Exclude:
|
|
||||||
- 'spec/controllers/activitypub/inboxes_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/accounts_controller_spec.rb'
|
|
||||||
- 'spec/controllers/admin/resets_controller_spec.rb'
|
|
||||||
- 'spec/controllers/auth/sessions_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/two_factor_authentication/confirmations_controller_spec.rb'
|
|
||||||
- 'spec/controllers/settings/two_factor_authentication/recovery_codes_controller_spec.rb'
|
|
||||||
- 'spec/lib/request_spec.rb'
|
|
||||||
- 'spec/lib/status_filter_spec.rb'
|
|
||||||
- 'spec/models/account_spec.rb'
|
|
||||||
- 'spec/models/setting_spec.rb'
|
|
||||||
- 'spec/services/activitypub/process_collection_service_spec.rb'
|
|
||||||
- 'spec/validators/follow_limit_validator_spec.rb'
|
|
||||||
- 'spec/workers/activitypub/delivery_worker_spec.rb'
|
|
||||||
- 'spec/workers/web/push_notification_worker_spec.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: CountAsOne.
|
# Configuration parameters: CountAsOne.
|
||||||
RSpec/ExampleLength:
|
RSpec/ExampleLength:
|
||||||
Max: 22
|
Max: 22
|
||||||
|
|
22
.simplecov
Normal file
22
.simplecov
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
if ENV['CI']
|
||||||
|
require 'simplecov-lcov'
|
||||||
|
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
|
||||||
|
SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
|
||||||
|
else
|
||||||
|
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
|
||||||
|
end
|
||||||
|
|
||||||
|
SimpleCov.start 'rails' do
|
||||||
|
enable_coverage :branch
|
||||||
|
|
||||||
|
add_filter 'lib/linter'
|
||||||
|
|
||||||
|
add_group 'Libraries', 'lib'
|
||||||
|
add_group 'Policies', 'app/policies'
|
||||||
|
add_group 'Presenters', 'app/presenters'
|
||||||
|
add_group 'Serializers', 'app/serializers'
|
||||||
|
add_group 'Services', 'app/services'
|
||||||
|
add_group 'Validators', 'app/validators'
|
||||||
|
end
|
3
.watchmanconfig
Normal file
3
.watchmanconfig
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"ignore_dirs": ["node_modules/", "public/"]
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ RUN apt-get update && \
|
||||||
corepack enable
|
corepack enable
|
||||||
|
|
||||||
COPY Gemfile* package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
COPY Gemfile* package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||||
|
COPY streaming/package.json /opt/mastodon/streaming/
|
||||||
COPY .yarn /opt/mastodon/.yarn
|
COPY .yarn /opt/mastodon/.yarn
|
||||||
|
|
||||||
RUN bundle install -j"$(nproc)"
|
RUN bundle install -j"$(nproc)"
|
||||||
|
|
4
Gemfile
4
Gemfile
|
@ -109,6 +109,9 @@ group :test do
|
||||||
# RSpec progress bar formatter
|
# RSpec progress bar formatter
|
||||||
gem 'fuubar', '~> 2.5'
|
gem 'fuubar', '~> 2.5'
|
||||||
|
|
||||||
|
# RSpec helpers for email specs
|
||||||
|
gem 'email_spec'
|
||||||
|
|
||||||
# Extra RSpec extenion methods and helpers for sidekiq
|
# Extra RSpec extenion methods and helpers for sidekiq
|
||||||
gem 'rspec-sidekiq', '~> 4.0'
|
gem 'rspec-sidekiq', '~> 4.0'
|
||||||
|
|
||||||
|
@ -139,6 +142,7 @@ group :test do
|
||||||
|
|
||||||
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
||||||
gem 'simplecov', '~> 0.22', require: false
|
gem 'simplecov', '~> 0.22', require: false
|
||||||
|
gem 'simplecov-lcov', '~> 0.8', require: false
|
||||||
|
|
||||||
# Stub web requests for specs
|
# Stub web requests for specs
|
||||||
gem 'webmock', '~> 3.18'
|
gem 'webmock', '~> 3.18'
|
||||||
|
|
128
Gemfile.lock
128
Gemfile.lock
|
@ -39,50 +39,51 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (7.1.1)
|
actioncable (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
zeitwerk (~> 2.6)
|
zeitwerk (~> 2.6)
|
||||||
actionmailbox (7.1.1)
|
actionmailbox (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
activejob (= 7.1.1)
|
activejob (= 7.1.2)
|
||||||
activerecord (= 7.1.1)
|
activerecord (= 7.1.2)
|
||||||
activestorage (= 7.1.1)
|
activestorage (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
actionmailer (7.1.1)
|
actionmailer (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
actionview (= 7.1.1)
|
actionview (= 7.1.2)
|
||||||
activejob (= 7.1.1)
|
activejob (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
net-imap
|
net-imap
|
||||||
net-pop
|
net-pop
|
||||||
net-smtp
|
net-smtp
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
actionpack (7.1.1)
|
actionpack (7.1.2)
|
||||||
actionview (= 7.1.1)
|
actionview (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
|
racc
|
||||||
rack (>= 2.2.4)
|
rack (>= 2.2.4)
|
||||||
rack-session (>= 1.0.1)
|
rack-session (>= 1.0.1)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
rails-html-sanitizer (~> 1.6)
|
rails-html-sanitizer (~> 1.6)
|
||||||
actiontext (7.1.1)
|
actiontext (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
activerecord (= 7.1.1)
|
activerecord (= 7.1.2)
|
||||||
activestorage (= 7.1.1)
|
activestorage (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
globalid (>= 0.6.0)
|
globalid (>= 0.6.0)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (7.1.1)
|
actionview (7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.11)
|
erubi (~> 1.11)
|
||||||
rails-dom-testing (~> 2.2)
|
rails-dom-testing (~> 2.2)
|
||||||
|
@ -92,22 +93,22 @@ GEM
|
||||||
activemodel (>= 4.1)
|
activemodel (>= 4.1)
|
||||||
case_transform (>= 0.2)
|
case_transform (>= 0.2)
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||||
activejob (7.1.1)
|
activejob (7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (7.1.1)
|
activemodel (7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
activerecord (7.1.1)
|
activerecord (7.1.2)
|
||||||
activemodel (= 7.1.1)
|
activemodel (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
timeout (>= 0.4.0)
|
timeout (>= 0.4.0)
|
||||||
activestorage (7.1.1)
|
activestorage (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
activejob (= 7.1.1)
|
activejob (= 7.1.2)
|
||||||
activerecord (= 7.1.1)
|
activerecord (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
activesupport (7.1.1)
|
activesupport (7.1.2)
|
||||||
base64
|
base64
|
||||||
bigdecimal
|
bigdecimal
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
|
@ -218,7 +219,7 @@ GEM
|
||||||
activerecord (>= 5.a)
|
activerecord (>= 5.a)
|
||||||
database_cleaner-core (~> 2.0.0)
|
database_cleaner-core (~> 2.0.0)
|
||||||
database_cleaner-core (2.0.1)
|
database_cleaner-core (2.0.1)
|
||||||
date (3.3.3)
|
date (3.3.4)
|
||||||
debug_inspector (1.1.0)
|
debug_inspector (1.1.0)
|
||||||
devise (4.9.3)
|
devise (4.9.3)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
|
@ -259,6 +260,10 @@ GEM
|
||||||
elasticsearch-transport (7.13.3)
|
elasticsearch-transport (7.13.3)
|
||||||
faraday (~> 1)
|
faraday (~> 1)
|
||||||
multi_json
|
multi_json
|
||||||
|
email_spec (2.2.2)
|
||||||
|
htmlentities (~> 4.3.3)
|
||||||
|
launchy (~> 2.1)
|
||||||
|
mail (~> 2.7)
|
||||||
encryptor (3.0.0)
|
encryptor (3.0.0)
|
||||||
erubi (1.12.0)
|
erubi (1.12.0)
|
||||||
et-orbi (1.2.7)
|
et-orbi (1.2.7)
|
||||||
|
@ -369,7 +374,7 @@ GEM
|
||||||
terminal-table (>= 1.5.1)
|
terminal-table (>= 1.5.1)
|
||||||
idn-ruby (0.1.5)
|
idn-ruby (0.1.5)
|
||||||
io-console (0.6.0)
|
io-console (0.6.0)
|
||||||
irb (1.8.1)
|
irb (1.8.3)
|
||||||
rdoc
|
rdoc
|
||||||
reline (>= 0.3.8)
|
reline (>= 0.3.8)
|
||||||
jmespath (1.6.2)
|
jmespath (1.6.2)
|
||||||
|
@ -462,13 +467,13 @@ GEM
|
||||||
uri
|
uri
|
||||||
net-http-persistent (4.0.2)
|
net-http-persistent (4.0.2)
|
||||||
connection_pool (~> 2.2)
|
connection_pool (~> 2.2)
|
||||||
net-imap (0.4.1)
|
net-imap (0.4.4)
|
||||||
date
|
date
|
||||||
net-protocol
|
net-protocol
|
||||||
net-ldap (0.18.0)
|
net-ldap (0.18.0)
|
||||||
net-pop (0.1.2)
|
net-pop (0.1.2)
|
||||||
net-protocol
|
net-protocol
|
||||||
net-protocol (0.2.1)
|
net-protocol (0.2.2)
|
||||||
timeout
|
timeout
|
||||||
net-smtp (0.4.0)
|
net-smtp (0.4.0)
|
||||||
net-protocol
|
net-protocol
|
||||||
|
@ -526,7 +531,7 @@ GEM
|
||||||
net-smtp
|
net-smtp
|
||||||
premailer (~> 1.7, >= 1.7.9)
|
premailer (~> 1.7, >= 1.7.9)
|
||||||
private_address_check (0.5.0)
|
private_address_check (0.5.0)
|
||||||
psych (5.1.1)
|
psych (5.1.1.1)
|
||||||
stringio
|
stringio
|
||||||
public_suffix (5.0.3)
|
public_suffix (5.0.3)
|
||||||
puma (6.4.0)
|
puma (6.4.0)
|
||||||
|
@ -557,20 +562,20 @@ GEM
|
||||||
rackup (1.0.0)
|
rackup (1.0.0)
|
||||||
rack (< 3)
|
rack (< 3)
|
||||||
webrick
|
webrick
|
||||||
rails (7.1.1)
|
rails (7.1.2)
|
||||||
actioncable (= 7.1.1)
|
actioncable (= 7.1.2)
|
||||||
actionmailbox (= 7.1.1)
|
actionmailbox (= 7.1.2)
|
||||||
actionmailer (= 7.1.1)
|
actionmailer (= 7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
actiontext (= 7.1.1)
|
actiontext (= 7.1.2)
|
||||||
actionview (= 7.1.1)
|
actionview (= 7.1.2)
|
||||||
activejob (= 7.1.1)
|
activejob (= 7.1.2)
|
||||||
activemodel (= 7.1.1)
|
activemodel (= 7.1.2)
|
||||||
activerecord (= 7.1.1)
|
activerecord (= 7.1.2)
|
||||||
activestorage (= 7.1.1)
|
activestorage (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 7.1.1)
|
railties (= 7.1.2)
|
||||||
rails-controller-testing (1.0.5)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.rc1)
|
actionpack (>= 5.0.1.rc1)
|
||||||
actionview (>= 5.0.1.rc1)
|
actionview (>= 5.0.1.rc1)
|
||||||
|
@ -585,9 +590,9 @@ GEM
|
||||||
rails-i18n (7.0.8)
|
rails-i18n (7.0.8)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 8)
|
railties (>= 6.0.0, < 8)
|
||||||
railties (7.1.1)
|
railties (7.1.2)
|
||||||
actionpack (= 7.1.1)
|
actionpack (= 7.1.2)
|
||||||
activesupport (= 7.1.1)
|
activesupport (= 7.1.2)
|
||||||
irb
|
irb
|
||||||
rackup (>= 1.0.0)
|
rackup (>= 1.0.0)
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
|
@ -724,6 +729,7 @@ GEM
|
||||||
simplecov-html (~> 0.11)
|
simplecov-html (~> 0.11)
|
||||||
simplecov_json_formatter (~> 0.1)
|
simplecov_json_formatter (~> 0.1)
|
||||||
simplecov-html (0.12.3)
|
simplecov-html (0.12.3)
|
||||||
|
simplecov-lcov (0.8.0)
|
||||||
simplecov_json_formatter (0.1.4)
|
simplecov_json_formatter (0.1.4)
|
||||||
smart_properties (1.17.0)
|
smart_properties (1.17.0)
|
||||||
sprockets (3.7.2)
|
sprockets (3.7.2)
|
||||||
|
@ -737,7 +743,7 @@ GEM
|
||||||
statsd-ruby (1.5.0)
|
statsd-ruby (1.5.0)
|
||||||
stoplight (3.0.2)
|
stoplight (3.0.2)
|
||||||
redlock (~> 1.0)
|
redlock (~> 1.0)
|
||||||
stringio (3.0.8)
|
stringio (3.0.9)
|
||||||
strong_migrations (1.6.4)
|
strong_migrations (1.6.4)
|
||||||
activerecord (>= 5.2)
|
activerecord (>= 5.2)
|
||||||
swd (1.3.0)
|
swd (1.3.0)
|
||||||
|
@ -753,7 +759,7 @@ GEM
|
||||||
test-prof (1.2.3)
|
test-prof (1.2.3)
|
||||||
thor (1.3.0)
|
thor (1.3.0)
|
||||||
tilt (2.3.0)
|
tilt (2.3.0)
|
||||||
timeout (0.4.0)
|
timeout (0.4.1)
|
||||||
tpm-key_attestation (0.12.0)
|
tpm-key_attestation (0.12.0)
|
||||||
bindata (~> 2.4)
|
bindata (~> 2.4)
|
||||||
openssl (> 2.0)
|
openssl (> 2.0)
|
||||||
|
@ -851,6 +857,7 @@ DEPENDENCIES
|
||||||
doorkeeper (~> 5.6)
|
doorkeeper (~> 5.6)
|
||||||
dotenv-rails (~> 2.8)
|
dotenv-rails (~> 2.8)
|
||||||
ed25519 (~> 1.3)
|
ed25519 (~> 1.3)
|
||||||
|
email_spec
|
||||||
fabrication (~> 2.30)
|
fabrication (~> 2.30)
|
||||||
faker (~> 3.2)
|
faker (~> 3.2)
|
||||||
fast_blank (~> 1.0)
|
fast_blank (~> 1.0)
|
||||||
|
@ -935,6 +942,7 @@ DEPENDENCIES
|
||||||
simple-navigation (~> 4.4)
|
simple-navigation (~> 4.4)
|
||||||
simple_form (~> 5.2)
|
simple_form (~> 5.2)
|
||||||
simplecov (~> 0.22)
|
simplecov (~> 0.22)
|
||||||
|
simplecov-lcov (~> 0.8)
|
||||||
sprockets (~> 3.7.2)
|
sprockets (~> 3.7.2)
|
||||||
sprockets-rails (~> 3.4)
|
sprockets-rails (~> 3.4)
|
||||||
stackprof
|
stackprof
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
|
web: env PORT=3000 RAILS_ENV=development bundle exec puma -C config/puma.rb
|
||||||
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
|
sidekiq: env PORT=3000 RAILS_ENV=development bundle exec sidekiq
|
||||||
stream: env PORT=4000 yarn run start
|
stream: env PORT=4000 yarn workspace @mastodon/streaming start
|
||||||
webpack: bin/webpack-dev-server
|
webpack: bin/webpack-dev-server
|
||||||
|
|
|
@ -53,7 +53,7 @@ class PublicStatusesIndex < Chewy::Index
|
||||||
index_scope ::Status.unscoped
|
index_scope ::Status.unscoped
|
||||||
.kept
|
.kept
|
||||||
.indexable
|
.indexable
|
||||||
.includes(:media_attachments, :preloadable_poll, :preview_cards, :tags)
|
.includes(:media_attachments, :preloadable_poll, :tags, preview_cards_status: :preview_card)
|
||||||
|
|
||||||
root date_detection: false do
|
root date_detection: false do
|
||||||
field(:id, type: 'long')
|
field(:id, type: 'long')
|
||||||
|
|
|
@ -50,7 +50,7 @@ class StatusesIndex < Chewy::Index
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :preview_cards, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
|
index_scope ::Status.unscoped.kept.without_reblogs.includes(:media_attachments, :local_mentioned, :local_favorited, :local_reblogged, :local_bookmarked, :tags, preview_cards_status: :preview_card, preloadable_poll: :local_voters), delete_if: ->(status) { status.searchable_by.empty? }
|
||||||
|
|
||||||
root date_detection: false do
|
root date_detection: false do
|
||||||
field(:id, type: 'long')
|
field(:id, type: 'long')
|
||||||
|
|
|
@ -7,6 +7,7 @@ class Api::BaseController < ApplicationController
|
||||||
include RateLimitHeaders
|
include RateLimitHeaders
|
||||||
include AccessTokenTrackingConcern
|
include AccessTokenTrackingConcern
|
||||||
include ApiCachingConcern
|
include ApiCachingConcern
|
||||||
|
include Api::ContentSecurityPolicy
|
||||||
|
|
||||||
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
skip_before_action :require_functional!, unless: :limited_federation_mode?
|
||||||
|
|
||||||
|
@ -17,26 +18,6 @@ class Api::BaseController < ApplicationController
|
||||||
|
|
||||||
protect_from_forgery with: :null_session
|
protect_from_forgery with: :null_session
|
||||||
|
|
||||||
content_security_policy do |p|
|
|
||||||
# Set every directive that does not have a fallback
|
|
||||||
p.default_src :none
|
|
||||||
p.frame_ancestors :none
|
|
||||||
p.form_action :none
|
|
||||||
|
|
||||||
# Disable every directive with a fallback to cut on response size
|
|
||||||
p.base_uri false
|
|
||||||
p.font_src false
|
|
||||||
p.img_src false
|
|
||||||
p.style_src false
|
|
||||||
p.media_src false
|
|
||||||
p.frame_src false
|
|
||||||
p.manifest_src false
|
|
||||||
p.connect_src false
|
|
||||||
p.script_src false
|
|
||||||
p.child_src false
|
|
||||||
p.worker_src false
|
|
||||||
end
|
|
||||||
|
|
||||||
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
||||||
render json: { error: e.to_s }, status: 422
|
render json: { error: e.to_s }, status: 422
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,8 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
||||||
current_user.update(user_params) if user_params
|
current_user.update(user_params) if user_params
|
||||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||||
|
rescue ActiveRecord::RecordInvalid => e
|
||||||
|
render json: ValidationErrorFormatter.new(e).as_json, status: 422
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::AccountsController < Api::BaseController
|
class Api::V1::AccountsController < Api::BaseController
|
||||||
|
include RegistrationHelper
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute]
|
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute]
|
||||||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
|
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
|
||||||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:mutes' }, only: [:mute, :unmute]
|
before_action -> { doorkeeper_authorize! :follow, :write, :'write:mutes' }, only: [:mute, :unmute]
|
||||||
|
@ -90,18 +92,14 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_params
|
def account_params
|
||||||
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone)
|
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code)
|
||||||
|
end
|
||||||
|
|
||||||
|
def invite
|
||||||
|
Invite.find_by(code: params[:invite_code]) if params[:invite_code].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_enabled_registrations
|
def check_enabled_registrations
|
||||||
forbidden if single_user_mode? || omniauth_only? || !allowed_registrations?
|
forbidden unless allowed_registration?(request.remote_ip, invite)
|
||||||
end
|
|
||||||
|
|
||||||
def allowed_registrations?
|
|
||||||
Setting.registrations_mode != 'none'
|
|
||||||
end
|
|
||||||
|
|
||||||
def omniauth_only?
|
|
||||||
ENV['OMNIAUTH_ONLY'] == 'true'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -41,10 +41,10 @@ class Api::V1::ConversationsController < Api::BaseController
|
||||||
account: :account_stat,
|
account: :account_stat,
|
||||||
last_status: [
|
last_status: [
|
||||||
:media_attachments,
|
:media_attachments,
|
||||||
:preview_cards,
|
|
||||||
:status_stat,
|
:status_stat,
|
||||||
:tags,
|
:tags,
|
||||||
{
|
{
|
||||||
|
preview_cards_status: :preview_card,
|
||||||
active_mentions: [account: :account_stat],
|
active_mentions: [account: :account_stat],
|
||||||
account: :account_stat,
|
account: :account_stat,
|
||||||
},
|
},
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr
|
||||||
cache_if_unauthenticated!
|
cache_if_unauthenticated!
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: @domain_blocks, each_serializer: REST::DomainBlockSerializer, with_comment: (Setting.show_domain_blocks_rationale == 'all' || (Setting.show_domain_blocks_rationale == 'users' && user_signed_in?))
|
render json: @domain_blocks, each_serializer: REST::DomainBlockSerializer, with_comment: show_rationale_in_response?
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -25,4 +25,16 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr
|
||||||
def set_domain_blocks
|
def set_domain_blocks
|
||||||
@domain_blocks = DomainBlock.with_user_facing_limitations.by_severity
|
@domain_blocks = DomainBlock.with_user_facing_limitations.by_severity
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_rationale_in_response?
|
||||||
|
always_show_rationale? || show_rationale_for_user?
|
||||||
|
end
|
||||||
|
|
||||||
|
def always_show_rationale?
|
||||||
|
Setting.show_domain_blocks_rationale == 'all'
|
||||||
|
end
|
||||||
|
|
||||||
|
def show_rationale_for_user?
|
||||||
|
Setting.show_domain_blocks_rationale == 'users' && user_signed_in?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
30
app/controllers/api/v1/invites_controller.rb
Normal file
30
app/controllers/api/v1/invites_controller.rb
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Api::V1::InvitesController < Api::BaseController
|
||||||
|
include RegistrationHelper
|
||||||
|
|
||||||
|
skip_before_action :require_authenticated_user!
|
||||||
|
skip_around_action :set_locale
|
||||||
|
|
||||||
|
before_action :set_invite
|
||||||
|
before_action :check_enabled_registrations!
|
||||||
|
|
||||||
|
# Override `current_user` to avoid reading session cookies
|
||||||
|
def current_user; end
|
||||||
|
|
||||||
|
def show
|
||||||
|
render json: { invite_code: params[:invite_code], instance_api_url: api_v2_instance_url }, status: 200
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_invite
|
||||||
|
@invite = Invite.find_by!(code: params[:invite_code])
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_enabled_registrations!
|
||||||
|
return render json: { error: I18n.t('invites.invalid') }, status: 401 unless @invite.valid_for_use?
|
||||||
|
|
||||||
|
raise Mastodon::NotPermittedError unless allowed_registration?(request.remote_ip, @invite)
|
||||||
|
end
|
||||||
|
end
|
16
app/controllers/api/v1/statuses/base_controller.rb
Normal file
16
app/controllers/api/v1/statuses/base_controller.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Api::V1::Statuses::BaseController < Api::BaseController
|
||||||
|
include Authorization
|
||||||
|
|
||||||
|
before_action :set_status
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_status
|
||||||
|
@status = Status.find(params[:status_id])
|
||||||
|
authorize @status, :show?
|
||||||
|
rescue Mastodon::NotPermittedError
|
||||||
|
not_found
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::BookmarksController < Api::BaseController
|
class Api::V1::Statuses::BookmarksController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:bookmarks' }
|
before_action -> { doorkeeper_authorize! :write, :'write:bookmarks' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_status, only: [:create]
|
skip_before_action :set_status, only: [:destroy]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
current_account.bookmarks.find_or_create_by!(account: current_account, status: @status)
|
current_account.bookmarks.find_or_create_by!(account: current_account, status: @status)
|
||||||
|
@ -28,13 +26,4 @@ class Api::V1::Statuses::BookmarksController < Api::BaseController
|
||||||
rescue Mastodon::NotPermittedError
|
rescue Mastodon::NotPermittedError
|
||||||
not_found
|
not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
class Api::V1::Statuses::FavouritedByAccountsController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
||||||
before_action :set_status
|
|
||||||
after_action :insert_pagination_headers
|
after_action :insert_pagination_headers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -61,13 +58,6 @@ class Api::V1::Statuses::FavouritedByAccountsController < Api::BaseController
|
||||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit).permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::FavouritesController < Api::BaseController
|
class Api::V1::Statuses::FavouritesController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:favourites' }
|
before_action -> { doorkeeper_authorize! :write, :'write:favourites' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_status, only: [:create]
|
skip_before_action :set_status, only: [:destroy]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
FavouriteService.new.call(current_account, @status)
|
FavouriteService.new.call(current_account, @status)
|
||||||
|
@ -30,13 +28,4 @@ class Api::V1::Statuses::FavouritesController < Api::BaseController
|
||||||
rescue Mastodon::NotPermittedError
|
rescue Mastodon::NotPermittedError
|
||||||
not_found
|
not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::HistoriesController < Api::BaseController
|
class Api::V1::Statuses::HistoriesController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :read, :'read:statuses' }
|
before_action -> { authorize_if_got_token! :read, :'read:statuses' }
|
||||||
before_action :set_status
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
cache_if_unauthenticated!
|
cache_if_unauthenticated!
|
||||||
|
@ -16,11 +13,4 @@ class Api::V1::Statuses::HistoriesController < Api::BaseController
|
||||||
def status_edits
|
def status_edits
|
||||||
@status.edits.includes(:account, status: [:account]).to_a.presence || [@status.build_snapshot(at_time: @status.edited_at || @status.created_at)]
|
@status.edits.includes(:account, status: [:account]).to_a.presence || [@status.build_snapshot(at_time: @status.edited_at || @status.created_at)]
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::MutesController < Api::BaseController
|
class Api::V1::Statuses::MutesController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:mutes' }
|
before_action -> { doorkeeper_authorize! :write, :'write:mutes' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_status
|
|
||||||
before_action :set_conversation
|
before_action :set_conversation
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
@ -24,13 +21,6 @@ class Api::V1::Statuses::MutesController < Api::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_conversation
|
def set_conversation
|
||||||
@conversation = @status.conversation
|
@conversation = @status.conversation
|
||||||
raise Mastodon::ValidationError if @conversation.nil?
|
raise Mastodon::ValidationError if @conversation.nil?
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::PinsController < Api::BaseController
|
class Api::V1::Statuses::PinsController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
|
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_status
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
StatusPin.create!(account: current_account, status: @status)
|
StatusPin.create!(account: current_account, status: @status)
|
||||||
|
@ -26,10 +23,6 @@ class Api::V1::Statuses::PinsController < Api::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
end
|
|
||||||
|
|
||||||
def distribute_add_activity!
|
def distribute_add_activity!
|
||||||
json = ActiveModelSerializers::SerializableResource.new(
|
json = ActiveModelSerializers::SerializableResource.new(
|
||||||
@status,
|
@status,
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
class Api::V1::Statuses::RebloggedByAccountsController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
before_action -> { authorize_if_got_token! :read, :'read:accounts' }
|
||||||
before_action :set_status
|
|
||||||
after_action :insert_pagination_headers
|
after_action :insert_pagination_headers
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -57,13 +54,6 @@ class Api::V1::Statuses::RebloggedByAccountsController < Api::BaseController
|
||||||
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
@accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
def pagination_params(core_params)
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
params.slice(:limit).permit(:limit).merge(core_params)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::ReblogsController < Api::BaseController
|
class Api::V1::Statuses::ReblogsController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
include Redisable
|
include Redisable
|
||||||
include Lockable
|
include Lockable
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
|
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_reblog, only: [:create]
|
before_action :set_reblog, only: [:create]
|
||||||
|
skip_before_action :set_status
|
||||||
|
|
||||||
override_rate_limit_headers :create, family: :statuses
|
override_rate_limit_headers :create, family: :statuses
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::SourcesController < Api::BaseController
|
class Api::V1::Statuses::SourcesController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
|
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
|
||||||
before_action :set_status
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render json: @status, serializer: REST::StatusSourceSerializer
|
render json: @status, serializer: REST::StatusSourceSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Statuses::TranslationsController < Api::BaseController
|
class Api::V1::Statuses::TranslationsController < Api::V1::Statuses::BaseController
|
||||||
include Authorization
|
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
|
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }
|
||||||
before_action :set_status
|
|
||||||
before_action :set_translation
|
before_action :set_translation
|
||||||
|
|
||||||
rescue_from TranslationService::NotConfiguredError, with: :not_found
|
rescue_from TranslationService::NotConfiguredError, with: :not_found
|
||||||
|
@ -24,13 +21,6 @@ class Api::V1::Statuses::TranslationsController < Api::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_status
|
|
||||||
@status = Status.find(params[:status_id])
|
|
||||||
authorize @status, :show?
|
|
||||||
rescue Mastodon::NotPermittedError
|
|
||||||
not_found
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_translation
|
def set_translation
|
||||||
@translation = TranslateStatusService.new.call(@status, content_locale)
|
@translation = TranslateStatusService.new.call(@status, content_locale)
|
||||||
end
|
end
|
||||||
|
|
33
app/controllers/api/v1/timelines/base_controller.rb
Normal file
33
app/controllers/api/v1/timelines/base_controller.rb
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Api::V1::Timelines::BaseController < Api::BaseController
|
||||||
|
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def insert_pagination_headers
|
||||||
|
set_pagination_headers(next_path, prev_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_max_id
|
||||||
|
@statuses.last.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def pagination_since_id
|
||||||
|
@statuses.first.id
|
||||||
|
end
|
||||||
|
|
||||||
|
def next_path_params
|
||||||
|
permitted_params.merge(max_id: pagination_max_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def prev_path_params
|
||||||
|
permitted_params.merge(min_id: pagination_since_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitted_params
|
||||||
|
params
|
||||||
|
.slice(*self.class::PERMITTED_PARAMS)
|
||||||
|
.permit(*self.class::PERMITTED_PARAMS)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Timelines::HomeController < Api::BaseController
|
class Api::V1::Timelines::HomeController < Api::V1::Timelines::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
|
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:show]
|
||||||
before_action :require_user!, only: [:show]
|
before_action :require_user!, only: [:show]
|
||||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
|
||||||
|
PERMITTED_PARAMS = %i(local limit).freeze
|
||||||
|
|
||||||
def show
|
def show
|
||||||
with_read_replica do
|
with_read_replica do
|
||||||
|
@ -40,27 +41,11 @@ class Api::V1::Timelines::HomeController < Api::BaseController
|
||||||
HomeFeed.new(current_account)
|
HomeFeed.new(current_account)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:local, :limit).permit(:local, :limit).merge(core_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
api_v1_timelines_home_url pagination_params(max_id: pagination_max_id)
|
api_v1_timelines_home_url next_path_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_home_url pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_home_url prev_path_params
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
@statuses.last.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
@statuses.first.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Timelines::ListController < Api::BaseController
|
class Api::V1::Timelines::ListController < Api::V1::Timelines::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:lists' }
|
before_action -> { doorkeeper_authorize! :read, :'read:lists' }
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_list
|
before_action :set_list
|
||||||
before_action :set_statuses
|
before_action :set_statuses
|
||||||
|
|
||||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
PERMITTED_PARAMS = %i(limit).freeze
|
||||||
|
|
||||||
def show
|
def show
|
||||||
render json: @statuses,
|
render json: @statuses,
|
||||||
|
@ -41,27 +41,11 @@ class Api::V1::Timelines::ListController < Api::BaseController
|
||||||
ListFeed.new(@list)
|
ListFeed.new(@list)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:limit).permit(:limit).merge(core_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
api_v1_timelines_list_url params[:id], pagination_params(max_id: pagination_max_id)
|
api_v1_timelines_list_url params[:id], next_path_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_list_url params[:id], pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_list_url params[:id], prev_path_params
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
@statuses.last.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
@statuses.first.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Timelines::PublicController < Api::BaseController
|
class Api::V1::Timelines::PublicController < Api::V1::Timelines::BaseController
|
||||||
before_action :require_user!, only: [:show], if: :require_auth?
|
before_action :require_user!, only: [:show], if: :require_auth?
|
||||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
|
||||||
|
PERMITTED_PARAMS = %i(local remote limit only_media).freeze
|
||||||
|
|
||||||
def show
|
def show
|
||||||
cache_if_unauthenticated!
|
cache_if_unauthenticated!
|
||||||
|
@ -42,27 +43,11 @@ class Api::V1::Timelines::PublicController < Api::BaseController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:local, :remote, :limit, :only_media).permit(:local, :remote, :limit, :only_media).merge(core_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
api_v1_timelines_public_url pagination_params(max_id: pagination_max_id)
|
api_v1_timelines_public_url next_path_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_public_url pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_public_url prev_path_params
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
@statuses.last.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
@statuses.first.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Api::V1::Timelines::TagController < Api::BaseController
|
class Api::V1::Timelines::TagController < Api::V1::Timelines::BaseController
|
||||||
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth?
|
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: :show, if: :require_auth?
|
||||||
before_action :load_tag
|
before_action :load_tag
|
||||||
after_action :insert_pagination_headers, unless: -> { @statuses.empty? }
|
|
||||||
|
PERMITTED_PARAMS = %i(local limit only_media).freeze
|
||||||
|
|
||||||
def show
|
def show
|
||||||
cache_if_unauthenticated!
|
cache_if_unauthenticated!
|
||||||
|
@ -51,27 +52,11 @@ class Api::V1::Timelines::TagController < Api::BaseController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def insert_pagination_headers
|
|
||||||
set_pagination_headers(next_path, prev_path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_params(core_params)
|
|
||||||
params.slice(:local, :limit, :only_media).permit(:local, :limit, :only_media).merge(core_params)
|
|
||||||
end
|
|
||||||
|
|
||||||
def next_path
|
def next_path
|
||||||
api_v1_timelines_tag_url params[:id], pagination_params(max_id: pagination_max_id)
|
api_v1_timelines_tag_url params[:id], next_path_params
|
||||||
end
|
end
|
||||||
|
|
||||||
def prev_path
|
def prev_path
|
||||||
api_v1_timelines_tag_url params[:id], pagination_params(min_id: pagination_since_id)
|
api_v1_timelines_tag_url params[:id], prev_path_params
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_max_id
|
|
||||||
@statuses.last.id
|
|
||||||
end
|
|
||||||
|
|
||||||
def pagination_since_id
|
|
||||||
@statuses.first.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,37 +3,13 @@
|
||||||
class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_push_subscription, only: :update
|
before_action :set_push_subscription, only: :update
|
||||||
|
before_action :destroy_previous_subscriptions, only: :create, if: :prior_subscriptions?
|
||||||
|
after_action :update_session_with_subscription, only: :create
|
||||||
|
|
||||||
def create
|
def create
|
||||||
active_session = current_session
|
@push_subscription = ::Web::PushSubscription.create!(web_push_subscription_params)
|
||||||
|
|
||||||
unless active_session.web_push_subscription.nil?
|
render json: @push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
||||||
active_session.web_push_subscription.destroy!
|
|
||||||
active_session.update!(web_push_subscription: nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Mobile devices do not support regular notifications, so we enable push notifications by default
|
|
||||||
alerts_enabled = active_session.detection.device.mobile? || active_session.detection.device.tablet?
|
|
||||||
|
|
||||||
data = {
|
|
||||||
policy: 'all',
|
|
||||||
alerts: Notification::TYPES.index_with { alerts_enabled },
|
|
||||||
}
|
|
||||||
|
|
||||||
data.deep_merge!(data_params) if params[:data]
|
|
||||||
|
|
||||||
push_subscription = ::Web::PushSubscription.create!(
|
|
||||||
endpoint: subscription_params[:endpoint],
|
|
||||||
key_p256dh: subscription_params[:keys][:p256dh],
|
|
||||||
key_auth: subscription_params[:keys][:auth],
|
|
||||||
data: data,
|
|
||||||
user_id: active_session.user_id,
|
|
||||||
access_token_id: active_session.access_token_id
|
|
||||||
)
|
|
||||||
|
|
||||||
active_session.update!(web_push_subscription: push_subscription)
|
|
||||||
|
|
||||||
render json: push_subscription, serializer: REST::WebPushSubscriptionSerializer
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
@ -43,6 +19,41 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def active_session
|
||||||
|
@active_session ||= current_session
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_previous_subscriptions
|
||||||
|
active_session.web_push_subscription.destroy!
|
||||||
|
active_session.update!(web_push_subscription: nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
def prior_subscriptions?
|
||||||
|
active_session.web_push_subscription.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
def subscription_data
|
||||||
|
default_subscription_data.tap do |data|
|
||||||
|
data.deep_merge!(data_params) if params[:data]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_subscription_data
|
||||||
|
{
|
||||||
|
policy: 'all',
|
||||||
|
alerts: Notification::TYPES.index_with { alerts_enabled },
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def alerts_enabled
|
||||||
|
# Mobile devices do not support regular notifications, so we enable push notifications by default
|
||||||
|
active_session.detection.device.mobile? || active_session.detection.device.tablet?
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_session_with_subscription
|
||||||
|
active_session.update!(web_push_subscription: @push_subscription)
|
||||||
|
end
|
||||||
|
|
||||||
def set_push_subscription
|
def set_push_subscription
|
||||||
@push_subscription = ::Web::PushSubscription.find(params[:id])
|
@push_subscription = ::Web::PushSubscription.find(params[:id])
|
||||||
end
|
end
|
||||||
|
@ -51,6 +62,17 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController
|
||||||
@subscription_params ||= params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
|
@subscription_params ||= params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def web_push_subscription_params
|
||||||
|
{
|
||||||
|
access_token_id: active_session.access_token_id,
|
||||||
|
data: subscription_data,
|
||||||
|
endpoint: subscription_params[:endpoint],
|
||||||
|
key_auth: subscription_params[:keys][:auth],
|
||||||
|
key_p256dh: subscription_params[:keys][:p256dh],
|
||||||
|
user_id: active_session.user_id,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def data_params
|
def data_params
|
||||||
@data_params ||= params.require(:data).permit(:policy, alerts: Notification::TYPES)
|
@data_params ||= params.require(:data).permit(:policy, alerts: Notification::TYPES)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Auth::RegistrationsController < Devise::RegistrationsController
|
class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
|
include RegistrationHelper
|
||||||
include RegistrationSpamConcern
|
include RegistrationSpamConcern
|
||||||
|
|
||||||
layout :determine_layout
|
layout :determine_layout
|
||||||
|
@ -82,19 +83,7 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_enabled_registrations
|
def check_enabled_registrations
|
||||||
redirect_to root_path if single_user_mode? || omniauth_only? || !allowed_registrations? || ip_blocked?
|
redirect_to root_path unless allowed_registration?(request.remote_ip, @invite)
|
||||||
end
|
|
||||||
|
|
||||||
def allowed_registrations?
|
|
||||||
Setting.registrations_mode != 'none' || @invite&.valid_for_use?
|
|
||||||
end
|
|
||||||
|
|
||||||
def omniauth_only?
|
|
||||||
ENV['OMNIAUTH_ONLY'] == 'true'
|
|
||||||
end
|
|
||||||
|
|
||||||
def ip_blocked?
|
|
||||||
IpBlock.where(severity: :sign_up_block).where('ip >>= ?', request.remote_ip.to_s).exists?
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def invite_code
|
def invite_code
|
||||||
|
|
27
app/controllers/concerns/api/content_security_policy.rb
Normal file
27
app/controllers/concerns/api/content_security_policy.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api::ContentSecurityPolicy
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
content_security_policy do |policy|
|
||||||
|
# Set every directive that does not have a fallback
|
||||||
|
policy.default_src :none
|
||||||
|
policy.frame_ancestors :none
|
||||||
|
policy.form_action :none
|
||||||
|
|
||||||
|
# Disable every directive with a fallback to cut on response size
|
||||||
|
policy.base_uri false
|
||||||
|
policy.font_src false
|
||||||
|
policy.img_src false
|
||||||
|
policy.style_src false
|
||||||
|
policy.media_src false
|
||||||
|
policy.frame_src false
|
||||||
|
policy.manifest_src false
|
||||||
|
policy.connect_src false
|
||||||
|
policy.script_src false
|
||||||
|
policy.child_src false
|
||||||
|
policy.worker_src false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
app/helpers/registration_helper.rb
Normal file
21
app/helpers/registration_helper.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module RegistrationHelper
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def allowed_registration?(remote_ip, invite)
|
||||||
|
!Rails.configuration.x.single_user_mode && !omniauth_only? && (registrations_open? || invite&.valid_for_use?) && !ip_blocked?(remote_ip)
|
||||||
|
end
|
||||||
|
|
||||||
|
def registrations_open?
|
||||||
|
Setting.registrations_mode != 'none'
|
||||||
|
end
|
||||||
|
|
||||||
|
def omniauth_only?
|
||||||
|
ENV['OMNIAUTH_ONLY'] == 'true'
|
||||||
|
end
|
||||||
|
|
||||||
|
def ip_blocked?(remote_ip)
|
||||||
|
IpBlock.where(severity: :sign_up_block).exists?(['ip >>= ?', remote_ip.to_s])
|
||||||
|
end
|
||||||
|
end
|
|
@ -661,3 +661,18 @@ export function unpinAccountFail(error) {
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const updateAccount = ({ displayName, note, avatar, header, discoverable, indexable }) => (dispatch, getState) => {
|
||||||
|
const data = new FormData();
|
||||||
|
|
||||||
|
data.append('display_name', displayName);
|
||||||
|
data.append('note', note);
|
||||||
|
if (avatar) data.append('avatar', avatar);
|
||||||
|
if (header) data.append('header', header);
|
||||||
|
data.append('discoverable', discoverable);
|
||||||
|
data.append('indexable', indexable);
|
||||||
|
|
||||||
|
return api(getState).patch('/api/v1/accounts/update_credentials', data).then(response => {
|
||||||
|
dispatch(importFetchedAccount(response.data));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@ export interface ApiAccountJSON {
|
||||||
bot: boolean;
|
bot: boolean;
|
||||||
created_at: string;
|
created_at: string;
|
||||||
discoverable: boolean;
|
discoverable: boolean;
|
||||||
|
indexable: boolean;
|
||||||
display_name: string;
|
display_name: string;
|
||||||
emojis: ApiCustomEmojiJSON[];
|
emojis: ApiCustomEmojiJSON[];
|
||||||
fields: ApiAccountFieldJSON[];
|
fields: ApiAccountFieldJSON[];
|
||||||
|
|
|
@ -51,7 +51,7 @@ export default class Retention extends PureComponent {
|
||||||
let content;
|
let content;
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
content = <FormattedMessage id='loading_indicator.label' defaultMessage='Loading...' />;
|
content = <FormattedMessage id='loading_indicator.label' defaultMessage='Loading…' />;
|
||||||
} else {
|
} else {
|
||||||
content = (
|
content = (
|
||||||
<table className='retention__table'>
|
<table className='retention__table'>
|
||||||
|
|
44
app/javascript/mastodon/components/copy_icon_button.jsx
Normal file
44
app/javascript/mastodon/components/copy_icon_button.jsx
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useState, useCallback } from 'react';
|
||||||
|
|
||||||
|
import { defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg';
|
||||||
|
|
||||||
|
import { showAlert } from 'mastodon/actions/alerts';
|
||||||
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
copied: { id: 'copy_icon_button.copied', defaultMessage: 'Copied to clipboard' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CopyIconButton = ({ title, value, className }) => {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {
|
||||||
|
navigator.clipboard.writeText(value);
|
||||||
|
setCopied(true);
|
||||||
|
dispatch(showAlert({ message: messages.copied }));
|
||||||
|
setTimeout(() => setCopied(false), 700);
|
||||||
|
}, [setCopied, value, dispatch]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
className={classNames(className, copied ? 'copied' : 'copyable')}
|
||||||
|
title={title}
|
||||||
|
onClick={handleClick}
|
||||||
|
iconComponent={ContentCopyIcon}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
CopyIconButton.propTypes = {
|
||||||
|
title: PropTypes.string,
|
||||||
|
value: PropTypes.string,
|
||||||
|
className: PropTypes.string,
|
||||||
|
};
|
|
@ -1,7 +1,23 @@
|
||||||
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { CircularProgress } from './circular_progress';
|
import { CircularProgress } from './circular_progress';
|
||||||
|
|
||||||
export const LoadingIndicator: React.FC = () => (
|
const messages = defineMessages({
|
||||||
<div className='loading-indicator'>
|
loading: { id: 'loading_indicator.label', defaultMessage: 'Loading…' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const LoadingIndicator: React.FC = () => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className='loading-indicator'
|
||||||
|
role='progressbar'
|
||||||
|
aria-busy
|
||||||
|
aria-live='polite'
|
||||||
|
aria-label={intl.formatMessage(messages.loading)}
|
||||||
|
>
|
||||||
<CircularProgress size={50} strokeWidth={6} />
|
<CircularProgress size={50} strokeWidth={6} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
|
@ -19,6 +19,8 @@ import { ReactComponent as StarIcon } from '@material-symbols/svg-600/outlined/s
|
||||||
import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outlined/star.svg';
|
import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outlined/star.svg';
|
||||||
import { ReactComponent as VisibilityIcon } from '@material-symbols/svg-600/outlined/visibility.svg';
|
import { ReactComponent as VisibilityIcon } from '@material-symbols/svg-600/outlined/visibility.svg';
|
||||||
|
|
||||||
|
import { ReactComponent as RepeatDisabledIcon } from 'mastodon/../svg-icons/repeat_disabled.svg';
|
||||||
|
import { ReactComponent as RepeatPrivateIcon } from 'mastodon/../svg-icons/repeat_private.svg';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
|
@ -348,6 +350,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
let replyIcon;
|
let replyIcon;
|
||||||
let replyIconComponent;
|
let replyIconComponent;
|
||||||
let replyTitle;
|
let replyTitle;
|
||||||
|
|
||||||
if (status.get('in_reply_to_id', null) === null) {
|
if (status.get('in_reply_to_id', null) === null) {
|
||||||
replyIcon = 'reply';
|
replyIcon = 'reply';
|
||||||
replyIconComponent = ReplyIcon;
|
replyIconComponent = ReplyIcon;
|
||||||
|
@ -360,15 +363,20 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
|
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
|
||||||
|
|
||||||
let reblogTitle = '';
|
let reblogTitle, reblogIconComponent;
|
||||||
|
|
||||||
if (status.get('reblogged')) {
|
if (status.get('reblogged')) {
|
||||||
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
||||||
|
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon;
|
||||||
} else if (publicStatus) {
|
} else if (publicStatus) {
|
||||||
reblogTitle = intl.formatMessage(messages.reblog);
|
reblogTitle = intl.formatMessage(messages.reblog);
|
||||||
|
reblogIconComponent = RepeatIcon;
|
||||||
} else if (reblogPrivate) {
|
} else if (reblogPrivate) {
|
||||||
reblogTitle = intl.formatMessage(messages.reblog_private);
|
reblogTitle = intl.formatMessage(messages.reblog_private);
|
||||||
|
reblogIconComponent = RepeatPrivateIcon;
|
||||||
} else {
|
} else {
|
||||||
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
||||||
|
reblogIconComponent = RepeatDisabledIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterButton = this.props.onFilter && (
|
const filterButton = this.props.onFilter && (
|
||||||
|
@ -380,7 +388,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='status__action-bar'>
|
<div className='status__action-bar'>
|
||||||
<IconButton className='status__action-bar__button' title={replyTitle} icon={isReply ? 'reply' : replyIcon} iconComponent={isReply ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
|
<IconButton className='status__action-bar__button' title={replyTitle} icon={isReply ? 'reply' : replyIcon} iconComponent={isReply ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
|
||||||
<IconButton className={classNames('status__action-bar__button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} counter={withCounters ? status.get('reblogs_count') : undefined} />
|
<IconButton className={classNames('status__action-bar__button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={reblogIconComponent} onClick={this.handleReblogClick} counter={withCounters ? status.get('reblogs_count') : undefined} />
|
||||||
<IconButton className='status__action-bar__button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
<IconButton className='status__action-bar__button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
||||||
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,12 @@ import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/l
|
||||||
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
|
import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg';
|
||||||
import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications.svg';
|
import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications.svg';
|
||||||
import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active-fill.svg';
|
import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active-fill.svg';
|
||||||
|
import { ReactComponent as ShareIcon } from '@material-symbols/svg-600/outlined/share.svg';
|
||||||
|
|
||||||
import { Avatar } from 'mastodon/components/avatar';
|
import { Avatar } from 'mastodon/components/avatar';
|
||||||
import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge';
|
import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge';
|
||||||
import { Button } from 'mastodon/components/button';
|
import { Button } from 'mastodon/components/button';
|
||||||
|
import { CopyIconButton } from 'mastodon/components/copy_icon_button';
|
||||||
import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters';
|
import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters';
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { IconButton } from 'mastodon/components/icon_button';
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
|
@ -46,6 +48,7 @@ const messages = defineMessages({
|
||||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||||
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
|
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
|
||||||
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
|
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
|
||||||
|
copy: { id: 'account.copy', defaultMessage: 'Copy link to profile' },
|
||||||
media: { id: 'account.media', defaultMessage: 'Media' },
|
media: { id: 'account.media', defaultMessage: 'Media' },
|
||||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||||
|
@ -245,10 +248,9 @@ class Header extends ImmutablePureComponent {
|
||||||
const isRemote = account.get('acct') !== account.get('username');
|
const isRemote = account.get('acct') !== account.get('username');
|
||||||
const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null;
|
const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null;
|
||||||
|
|
||||||
|
let actionBtn, bellBtn, lockedIcon, shareBtn;
|
||||||
|
|
||||||
let info = [];
|
let info = [];
|
||||||
let actionBtn = '';
|
|
||||||
let bellBtn = '';
|
|
||||||
let lockedIcon = '';
|
|
||||||
let menu = [];
|
let menu = [];
|
||||||
|
|
||||||
if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) {
|
if (me !== account.get('id') && account.getIn(['relationship', 'followed_by'])) {
|
||||||
|
@ -267,6 +269,12 @@ class Header extends ImmutablePureComponent {
|
||||||
bellBtn = <IconButton icon={account.getIn(['relationship', 'notifying']) ? 'bell' : 'bell-o'} iconComponent={account.getIn(['relationship', 'notifying']) ? NotificationsActiveIcon : NotificationsIcon} active={account.getIn(['relationship', 'notifying'])} title={intl.formatMessage(account.getIn(['relationship', 'notifying']) ? messages.disableNotifications : messages.enableNotifications, { name: account.get('username') })} onClick={this.props.onNotifyToggle} />;
|
bellBtn = <IconButton icon={account.getIn(['relationship', 'notifying']) ? 'bell' : 'bell-o'} iconComponent={account.getIn(['relationship', 'notifying']) ? NotificationsActiveIcon : NotificationsIcon} active={account.getIn(['relationship', 'notifying'])} title={intl.formatMessage(account.getIn(['relationship', 'notifying']) ? messages.disableNotifications : messages.enableNotifications, { name: account.get('username') })} onClick={this.props.onNotifyToggle} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('share' in navigator) {
|
||||||
|
shareBtn = <IconButton className='optional' iconComponent={ShareIcon} title={intl.formatMessage(messages.share, { name: account.get('username') })} onClick={this.handleShare} />;
|
||||||
|
} else {
|
||||||
|
shareBtn = <CopyIconButton className='optional' title={intl.formatMessage(messages.copy)} value={account.get('url')} />;
|
||||||
|
}
|
||||||
|
|
||||||
if (me !== account.get('id')) {
|
if (me !== account.get('id')) {
|
||||||
if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded
|
if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded
|
||||||
actionBtn = '';
|
actionBtn = '';
|
||||||
|
@ -297,10 +305,6 @@ class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
if (isRemote) {
|
if (isRemote) {
|
||||||
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: account.get('url') });
|
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: account.get('url') });
|
||||||
}
|
|
||||||
|
|
||||||
if ('share' in navigator && !account.get('suspended')) {
|
|
||||||
menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare });
|
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,6 +418,7 @@ class Header extends ImmutablePureComponent {
|
||||||
<>
|
<>
|
||||||
{actionBtn}
|
{actionBtn}
|
||||||
{bellBtn}
|
{bellBtn}
|
||||||
|
{shareBtn}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -204,7 +204,7 @@ class ListTimeline extends PureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='setting-toggle'>
|
<div className='setting-toggle'>
|
||||||
<Toggle id={`list-${id}-exclusive`} defaultChecked={isExclusive} onChange={this.onExclusiveToggle} />
|
<Toggle id={`list-${id}-exclusive`} checked={isExclusive} onChange={this.onExclusiveToggle} />
|
||||||
<label htmlFor={`list-${id}-exclusive`} className='setting-toggle__label'>
|
<label htmlFor={`list-${id}-exclusive`} className='setting-toggle__label'>
|
||||||
<FormattedMessage id='lists.exclusive' defaultMessage='Hide these posts from home' />
|
<FormattedMessage id='lists.exclusive' defaultMessage='Hide these posts from home' />
|
||||||
</label>
|
</label>
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Fragment } from 'react';
|
|
||||||
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/done.svg';
|
|
||||||
|
|
||||||
import { Icon } from 'mastodon/components/icon';
|
|
||||||
|
|
||||||
const ProgressIndicator = ({ steps, completed }) => (
|
|
||||||
<div className='onboarding__progress-indicator'>
|
|
||||||
{(new Array(steps)).fill().map((_, i) => (
|
|
||||||
<Fragment key={i}>
|
|
||||||
{i > 0 && <div className={classNames('onboarding__progress-indicator__line', { active: completed > i })} />}
|
|
||||||
|
|
||||||
<div className={classNames('onboarding__progress-indicator__step', { active: completed > i })}>
|
|
||||||
{completed > i && <Icon icon={CheckIcon} />}
|
|
||||||
</div>
|
|
||||||
</Fragment>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
ProgressIndicator.propTypes = {
|
|
||||||
steps: PropTypes.number.isRequired,
|
|
||||||
completed: PropTypes.number,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ProgressIndicator;
|
|
|
@ -1,11 +1,13 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
||||||
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/done.svg';
|
import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/done.svg';
|
||||||
|
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
|
||||||
const Step = ({ label, description, icon, iconComponent, completed, onClick, href }) => {
|
export const Step = ({ label, description, icon, iconComponent, completed, onClick, href, to }) => {
|
||||||
const content = (
|
const content = (
|
||||||
<>
|
<>
|
||||||
<div className='onboarding__steps__item__icon'>
|
<div className='onboarding__steps__item__icon'>
|
||||||
|
@ -29,6 +31,12 @@ const Step = ({ label, description, icon, iconComponent, completed, onClick, hre
|
||||||
{content}
|
{content}
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
} else if (to) {
|
||||||
|
return (
|
||||||
|
<Link to={to} className='onboarding__steps__item'>
|
||||||
|
{content}
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -45,7 +53,6 @@ Step.propTypes = {
|
||||||
iconComponent: PropTypes.func,
|
iconComponent: PropTypes.func,
|
||||||
completed: PropTypes.bool,
|
completed: PropTypes.bool,
|
||||||
href: PropTypes.string,
|
href: PropTypes.string,
|
||||||
|
to: PropTypes.string,
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Step;
|
|
||||||
|
|
|
@ -1,44 +1,31 @@
|
||||||
import PropTypes from 'prop-types';
|
import { useEffect } from 'react';
|
||||||
import { PureComponent } from 'react';
|
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import { Link } from 'react-router-dom';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
|
||||||
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
||||||
import { markAsPartial } from 'mastodon/actions/timelines';
|
import { markAsPartial } from 'mastodon/actions/timelines';
|
||||||
import Column from 'mastodon/components/column';
|
|
||||||
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
||||||
import { EmptyAccount } from 'mastodon/components/empty_account';
|
import { EmptyAccount } from 'mastodon/components/empty_account';
|
||||||
import Account from 'mastodon/containers/account_container';
|
import Account from 'mastodon/containers/account_container';
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
export const Follows = () => {
|
||||||
suggestions: state.getIn(['suggestions', 'items']),
|
const dispatch = useDispatch();
|
||||||
isLoading: state.getIn(['suggestions', 'isLoading']),
|
const isLoading = useAppSelector(state => state.getIn(['suggestions', 'isLoading']));
|
||||||
});
|
const suggestions = useAppSelector(state => state.getIn(['suggestions', 'items']));
|
||||||
|
|
||||||
class Follows extends PureComponent {
|
useEffect(() => {
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
onBack: PropTypes.func,
|
|
||||||
dispatch: PropTypes.func.isRequired,
|
|
||||||
suggestions: ImmutablePropTypes.list,
|
|
||||||
isLoading: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch(fetchSuggestions(true));
|
dispatch(fetchSuggestions(true));
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
return () => {
|
||||||
const { dispatch } = this.props;
|
|
||||||
dispatch(markAsPartial('home'));
|
dispatch(markAsPartial('home'));
|
||||||
}
|
};
|
||||||
|
}, [dispatch]);
|
||||||
render () {
|
|
||||||
const { onBack, isLoading, suggestions } = this.props;
|
|
||||||
|
|
||||||
let loadedContent;
|
let loadedContent;
|
||||||
|
|
||||||
|
@ -51,8 +38,8 @@ class Follows extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column>
|
<>
|
||||||
<ColumnBackButton onClick={onBack} />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<div className='scrollable privacy-policy'>
|
<div className='scrollable privacy-policy'>
|
||||||
<div className='column-title'>
|
<div className='column-title'>
|
||||||
|
@ -67,13 +54,9 @@ class Follows extends PureComponent {
|
||||||
<p className='onboarding__lead'><FormattedMessage id='onboarding.tips.accounts_from_other_servers' defaultMessage='<strong>Did you know?</strong> Since Mastodon is decentralized, some profiles you come across will be hosted on servers other than yours. And yet you can interact with them seamlessly! Their server is in the second half of their username!' values={{ strong: chunks => <strong>{chunks}</strong> }} /></p>
|
<p className='onboarding__lead'><FormattedMessage id='onboarding.tips.accounts_from_other_servers' defaultMessage='<strong>Did you know?</strong> Since Mastodon is decentralized, some profiles you come across will be hosted on servers other than yours. And yet you can interact with them seamlessly! Their server is in the second half of their username!' values={{ strong: chunks => <strong>{chunks}</strong> }} /></p>
|
||||||
|
|
||||||
<div className='onboarding__footer'>
|
<div className='onboarding__footer'>
|
||||||
<button className='link-button' onClick={onBack}><FormattedMessage id='onboarding.actions.back' defaultMessage='Take me back' /></button>
|
<Link className='link-button' to='/start'><FormattedMessage id='onboarding.actions.back' defaultMessage='Take me back' /></Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Column>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(Follows);
|
|
||||||
|
|
|
@ -1,116 +1,50 @@
|
||||||
import PropTypes from 'prop-types';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
|
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { Link, withRouter } from 'react-router-dom';
|
import { Link, Switch, Route, useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { ReactComponent as AccountCircleIcon } from '@material-symbols/svg-600/outlined/account_circle.svg';
|
import { ReactComponent as AccountCircleIcon } from '@material-symbols/svg-600/outlined/account_circle.svg';
|
||||||
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
||||||
import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg';
|
import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg';
|
||||||
import { ReactComponent as EditNoteIcon } from '@material-symbols/svg-600/outlined/edit_note.svg';
|
import { ReactComponent as EditNoteIcon } from '@material-symbols/svg-600/outlined/edit_note.svg';
|
||||||
import { ReactComponent as PersonAddIcon } from '@material-symbols/svg-600/outlined/person_add.svg';
|
import { ReactComponent as PersonAddIcon } from '@material-symbols/svg-600/outlined/person_add.svg';
|
||||||
import { debounce } from 'lodash';
|
|
||||||
|
|
||||||
import illustration from 'mastodon/../images/elephant_ui_conversation.svg';
|
import illustration from 'mastodon/../images/elephant_ui_conversation.svg';
|
||||||
import { fetchAccount } from 'mastodon/actions/accounts';
|
|
||||||
import { focusCompose } from 'mastodon/actions/compose';
|
import { focusCompose } from 'mastodon/actions/compose';
|
||||||
import { closeOnboarding } from 'mastodon/actions/onboarding';
|
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import Column from 'mastodon/features/ui/components/column';
|
import Column from 'mastodon/features/ui/components/column';
|
||||||
import { me } from 'mastodon/initial_state';
|
import { me } from 'mastodon/initial_state';
|
||||||
import { makeGetAccount } from 'mastodon/selectors';
|
import { useAppSelector } from 'mastodon/store';
|
||||||
import { assetHost } from 'mastodon/utils/config';
|
import { assetHost } from 'mastodon/utils/config';
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
|
||||||
|
|
||||||
import Step from './components/step';
|
import { Step } from './components/step';
|
||||||
import Follows from './follows';
|
import { Follows } from './follows';
|
||||||
import Share from './share';
|
import { Profile } from './profile';
|
||||||
|
import { Share } from './share';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
template: { id: 'onboarding.compose.template', defaultMessage: 'Hello #Mastodon!' },
|
template: { id: 'onboarding.compose.template', defaultMessage: 'Hello #Mastodon!' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = () => {
|
const Onboarding = () => {
|
||||||
const getAccount = makeGetAccount();
|
const account = useAppSelector(state => state.getIn(['accounts', me]));
|
||||||
|
const dispatch = useDispatch();
|
||||||
return state => ({
|
const intl = useIntl();
|
||||||
account: getAccount(state, me),
|
const history = useHistory();
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
class Onboarding extends ImmutablePureComponent {
|
|
||||||
static propTypes = {
|
|
||||||
dispatch: PropTypes.func.isRequired,
|
|
||||||
account: ImmutablePropTypes.record,
|
|
||||||
...WithRouterPropTypes,
|
|
||||||
};
|
|
||||||
|
|
||||||
state = {
|
|
||||||
step: null,
|
|
||||||
profileClicked: false,
|
|
||||||
shareClicked: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleClose = () => {
|
|
||||||
const { dispatch, history } = this.props;
|
|
||||||
|
|
||||||
dispatch(closeOnboarding());
|
|
||||||
history.push('/home');
|
|
||||||
};
|
|
||||||
|
|
||||||
handleProfileClick = () => {
|
|
||||||
this.setState({ profileClicked: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleFollowClick = () => {
|
|
||||||
this.setState({ step: 'follows' });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleComposeClick = () => {
|
|
||||||
const { dispatch, intl, history } = this.props;
|
|
||||||
|
|
||||||
|
const handleComposeClick = useCallback(() => {
|
||||||
dispatch(focusCompose(history, intl.formatMessage(messages.template)));
|
dispatch(focusCompose(history, intl.formatMessage(messages.template)));
|
||||||
};
|
}, [dispatch, intl, history]);
|
||||||
|
|
||||||
handleShareClick = () => {
|
|
||||||
this.setState({ step: 'share', shareClicked: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleBackClick = () => {
|
|
||||||
this.setState({ step: null });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleWindowFocus = debounce(() => {
|
|
||||||
const { dispatch, account } = this.props;
|
|
||||||
dispatch(fetchAccount(account.get('id')));
|
|
||||||
}, 1000, { trailing: true });
|
|
||||||
|
|
||||||
componentDidMount () {
|
|
||||||
window.addEventListener('focus', this.handleWindowFocus, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount () {
|
|
||||||
window.removeEventListener('focus', this.handleWindowFocus);
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { account } = this.props;
|
|
||||||
const { step, shareClicked } = this.state;
|
|
||||||
|
|
||||||
switch(step) {
|
|
||||||
case 'follows':
|
|
||||||
return <Follows onBack={this.handleBackClick} />;
|
|
||||||
case 'share':
|
|
||||||
return <Share onBack={this.handleBackClick} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column>
|
<Column>
|
||||||
|
<Switch>
|
||||||
|
<Route path='/start' exact>
|
||||||
<div className='scrollable privacy-policy'>
|
<div className='scrollable privacy-policy'>
|
||||||
<div className='column-title'>
|
<div className='column-title'>
|
||||||
<img src={illustration} alt='' className='onboarding__illustration' />
|
<img src={illustration} alt='' className='onboarding__illustration' />
|
||||||
|
@ -119,10 +53,10 @@ class Onboarding extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='onboarding__steps'>
|
<div className='onboarding__steps'>
|
||||||
<Step onClick={this.handleProfileClick} href='/settings/profile' completed={(!account.get('avatar').endsWith('missing.png')) || (account.get('display_name').length > 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={<FormattedMessage id='onboarding.steps.setup_profile.title' defaultMessage='Customize your profile' />} description={<FormattedMessage id='onboarding.steps.setup_profile.body' defaultMessage='Others are more likely to interact with you with a filled out profile.' />} />
|
<Step to='/start/profile' completed={(!account.get('avatar').endsWith('missing.png')) || (account.get('display_name').length > 0 && account.get('note').length > 0)} icon='address-book-o' iconComponent={AccountCircleIcon} label={<FormattedMessage id='onboarding.steps.setup_profile.title' defaultMessage='Customize your profile' />} description={<FormattedMessage id='onboarding.steps.setup_profile.body' defaultMessage='Others are more likely to interact with you with a filled out profile.' />} />
|
||||||
<Step onClick={this.handleFollowClick} completed={(account.get('following_count') * 1) >= 7} icon='user-plus' iconComponent={PersonAddIcon} label={<FormattedMessage id='onboarding.steps.follow_people.title' defaultMessage='Find at least {count, plural, one {one person} other {# people}} to follow' values={{ count: 7 }} />} description={<FormattedMessage id='onboarding.steps.follow_people.body' defaultMessage="You curate your own home feed. Let's fill it with interesting people." />} />
|
<Step to='/start/follows' completed={(account.get('following_count') * 1) >= 1} icon='user-plus' iconComponent={PersonAddIcon} label={<FormattedMessage id='onboarding.steps.follow_people.title' defaultMessage='Find at least {count, plural, one {one person} other {# people}} to follow' values={{ count: 7 }} />} description={<FormattedMessage id='onboarding.steps.follow_people.body' defaultMessage="You curate your own home feed. Let's fill it with interesting people." />} />
|
||||||
<Step onClick={this.handleComposeClick} completed={(account.get('statuses_count') * 1) >= 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={<FormattedMessage id='onboarding.steps.publish_status.title' defaultMessage='Make your first post' />} description={<FormattedMessage id='onboarding.steps.publish_status.body' defaultMessage='Say hello to the world.' values={{ emoji: <img className='emojione' alt='🐘' src={`${assetHost}/emoji/1f418.svg`} /> }} />} />
|
<Step onClick={handleComposeClick} completed={(account.get('statuses_count') * 1) >= 1} icon='pencil-square-o' iconComponent={EditNoteIcon} label={<FormattedMessage id='onboarding.steps.publish_status.title' defaultMessage='Make your first post' />} description={<FormattedMessage id='onboarding.steps.publish_status.body' defaultMessage='Say hello to the world.' values={{ emoji: <img className='emojione' alt='🐘' src={`${assetHost}/emoji/1f418.svg`} /> }} />} />
|
||||||
<Step onClick={this.handleShareClick} completed={shareClicked} icon='copy' iconComponent={ContentCopyIcon} label={<FormattedMessage id='onboarding.steps.share_profile.title' defaultMessage='Share your profile' />} description={<FormattedMessage id='onboarding.steps.share_profile.body' defaultMessage='Let your friends know how to find you on Mastodon!' />} />
|
<Step to='/start/share' icon='copy' iconComponent={ContentCopyIcon} label={<FormattedMessage id='onboarding.steps.share_profile.title' defaultMessage='Share your profile' />} description={<FormattedMessage id='onboarding.steps.share_profile.body' defaultMessage='Let your friends know how to find you on Mastodon!' />} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className='onboarding__lead'><FormattedMessage id='onboarding.start.skip' defaultMessage="Don't need help getting started?" /></p>
|
<p className='onboarding__lead'><FormattedMessage id='onboarding.start.skip' defaultMessage="Don't need help getting started?" /></p>
|
||||||
|
@ -139,14 +73,18 @@ class Onboarding extends ImmutablePureComponent {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path='/start/profile' component={Profile} />
|
||||||
|
<Route path='/start/follows' component={Follows} />
|
||||||
|
<Route path='/start/share' component={Share} />
|
||||||
|
</Switch>
|
||||||
|
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<meta name='robots' content='noindex' />
|
<meta name='robots' content='noindex' />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
</Column>
|
</Column>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
export default Onboarding;
|
||||||
|
|
||||||
export default withRouter(connect(mapStateToProps)(injectIntl(Onboarding)));
|
|
||||||
|
|
160
app/javascript/mastodon/features/onboarding/profile.jsx
Normal file
160
app/javascript/mastodon/features/onboarding/profile.jsx
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
import { useState, useMemo, useCallback, createRef } from 'react';
|
||||||
|
|
||||||
|
import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
|
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
|
|
||||||
|
import { ReactComponent as AddPhotoAlternateIcon } from '@material-symbols/svg-600/outlined/add_photo_alternate.svg';
|
||||||
|
import { ReactComponent as EditIcon } from '@material-symbols/svg-600/outlined/edit.svg';
|
||||||
|
import Toggle from 'react-toggle';
|
||||||
|
|
||||||
|
import { updateAccount } from 'mastodon/actions/accounts';
|
||||||
|
import { Button } from 'mastodon/components/button';
|
||||||
|
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||||
|
import { me } from 'mastodon/initial_state';
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
import { unescapeHTML } from 'mastodon/utils/html';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
uploadHeader: { id: 'onboarding.profile.upload_header', defaultMessage: 'Upload profile header' },
|
||||||
|
uploadAvatar: { id: 'onboarding.profile.upload_avatar', defaultMessage: 'Upload profile picture' },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Profile = () => {
|
||||||
|
const account = useAppSelector(state => state.getIn(['accounts', me]));
|
||||||
|
const [displayName, setDisplayName] = useState(account.get('display_name'));
|
||||||
|
const [note, setNote] = useState(unescapeHTML(account.get('note')));
|
||||||
|
const [avatar, setAvatar] = useState(null);
|
||||||
|
const [header, setHeader] = useState(null);
|
||||||
|
const [discoverable, setDiscoverable] = useState(account.get('discoverable'));
|
||||||
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
const [errors, setErrors] = useState();
|
||||||
|
const avatarFileRef = createRef();
|
||||||
|
const headerFileRef = createRef();
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const intl = useIntl();
|
||||||
|
const history = useHistory();
|
||||||
|
|
||||||
|
const handleDisplayNameChange = useCallback(e => {
|
||||||
|
setDisplayName(e.target.value);
|
||||||
|
}, [setDisplayName]);
|
||||||
|
|
||||||
|
const handleNoteChange = useCallback(e => {
|
||||||
|
setNote(e.target.value);
|
||||||
|
}, [setNote]);
|
||||||
|
|
||||||
|
const handleDiscoverableChange = useCallback(e => {
|
||||||
|
setDiscoverable(e.target.checked);
|
||||||
|
}, [setDiscoverable]);
|
||||||
|
|
||||||
|
const handleAvatarChange = useCallback(e => {
|
||||||
|
setAvatar(e.target?.files?.[0]);
|
||||||
|
}, [setAvatar]);
|
||||||
|
|
||||||
|
const handleHeaderChange = useCallback(e => {
|
||||||
|
setHeader(e.target?.files?.[0]);
|
||||||
|
}, [setHeader]);
|
||||||
|
|
||||||
|
const avatarPreview = useMemo(() => avatar ? URL.createObjectURL(avatar) : account.get('avatar'), [avatar, account]);
|
||||||
|
const headerPreview = useMemo(() => header ? URL.createObjectURL(header) : account.get('header'), [header, account]);
|
||||||
|
|
||||||
|
const handleSubmit = useCallback(() => {
|
||||||
|
setIsSaving(true);
|
||||||
|
|
||||||
|
dispatch(updateAccount({
|
||||||
|
displayName,
|
||||||
|
note,
|
||||||
|
avatar,
|
||||||
|
header,
|
||||||
|
discoverable,
|
||||||
|
indexable: discoverable,
|
||||||
|
})).then(() => history.push('/start/follows')).catch(err => {
|
||||||
|
setIsSaving(false);
|
||||||
|
setErrors(err.response.data.details);
|
||||||
|
});
|
||||||
|
}, [dispatch, displayName, note, avatar, header, discoverable, history]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ColumnBackButton />
|
||||||
|
|
||||||
|
<div className='scrollable privacy-policy'>
|
||||||
|
<div className='column-title'>
|
||||||
|
<h3><FormattedMessage id='onboarding.profile.title' defaultMessage='Profile setup' /></h3>
|
||||||
|
<p><FormattedMessage id='onboarding.profile.lead' defaultMessage='You can always complete this later in the settings, where even more customization options are available.' /></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='simple_form'>
|
||||||
|
<div className='onboarding__profile'>
|
||||||
|
<label className={classNames('app-form__header-input', { selected: !!headerPreview, invalid: !!errors?.header })} title={intl.formatMessage(messages.uploadHeader)}>
|
||||||
|
<input
|
||||||
|
type='file'
|
||||||
|
hidden
|
||||||
|
ref={headerFileRef}
|
||||||
|
accept='image/*'
|
||||||
|
onChange={handleHeaderChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{headerPreview && <img src={headerPreview} alt='' />}
|
||||||
|
|
||||||
|
<Icon icon={headerPreview ? EditIcon : AddPhotoAlternateIcon} />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className={classNames('app-form__avatar-input', { selected: !!avatarPreview, invalid: !!errors?.avatar })} title={intl.formatMessage(messages.uploadAvatar)}>
|
||||||
|
<input
|
||||||
|
type='file'
|
||||||
|
hidden
|
||||||
|
ref={avatarFileRef}
|
||||||
|
accept='image/*'
|
||||||
|
onChange={handleAvatarChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{avatarPreview && <img src={avatarPreview} alt='' />}
|
||||||
|
|
||||||
|
<Icon icon={avatarPreview ? EditIcon : AddPhotoAlternateIcon} />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={classNames('input with_block_label', { field_with_errors: !!errors?.display_name })}>
|
||||||
|
<label htmlFor='display_name'><FormattedMessage id='onboarding.profile.display_name' defaultMessage='Display name' /></label>
|
||||||
|
<span className='hint'><FormattedMessage id='onboarding.profile.display_name_hint' defaultMessage='Your full name or your fun name…' /></span>
|
||||||
|
<div className='label_input'>
|
||||||
|
<input id='display_name' type='text' value={displayName} onChange={handleDisplayNameChange} maxLength={30} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={classNames('input with_block_label', { field_with_errors: !!errors?.note })}>
|
||||||
|
<label htmlFor='note'><FormattedMessage id='onboarding.profile.note' defaultMessage='Bio' /></label>
|
||||||
|
<span className='hint'><FormattedMessage id='onboarding.profile.note_hint' defaultMessage='You can @mention other people or #hashtags…' /></span>
|
||||||
|
<div className='label_input'>
|
||||||
|
<textarea id='note' value={note} onChange={handleNoteChange} maxLength={500} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label className='app-form__toggle'>
|
||||||
|
<div className='app-form__toggle__label'>
|
||||||
|
<strong><FormattedMessage id='onboarding.profile.discoverable' defaultMessage='Make my profile discoverable' /></strong> <span className='recommended'><FormattedMessage id='recommended' defaultMessage='Recommended' /></span>
|
||||||
|
<span className='hint'><FormattedMessage id='onboarding.profile.discoverable_hint' defaultMessage='When you opt in to discoverability on Mastodon, your posts may appear in search results and trending, and your profile may be suggested to people with similar interests to you.' /></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='app-form__toggle__toggle'>
|
||||||
|
<div>
|
||||||
|
<Toggle checked={discoverable} onChange={handleDiscoverableChange} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='onboarding__footer'>
|
||||||
|
<Button block onClick={handleSubmit} disabled={isSaving}>{isSaving ? <LoadingIndicator /> : <FormattedMessage id='onboarding.profile.save_and_continue' defaultMessage='Save and continue' />}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -1,31 +1,25 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { PureComponent } from 'react';
|
import { PureComponent } from 'react';
|
||||||
|
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
import { ReactComponent as ArrowRightAltIcon } from '@material-symbols/svg-600/outlined/arrow_right_alt.svg';
|
||||||
import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg';
|
import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/outlined/content_copy.svg';
|
||||||
import SwipeableViews from 'react-swipeable-views';
|
import SwipeableViews from 'react-swipeable-views';
|
||||||
|
|
||||||
import Column from 'mastodon/components/column';
|
|
||||||
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
import { ColumnBackButton } from 'mastodon/components/column_back_button';
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { me, domain } from 'mastodon/initial_state';
|
import { me, domain } from 'mastodon/initial_state';
|
||||||
|
import { useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
shareableMessage: { id: 'onboarding.share.message', defaultMessage: 'I\'m {username} on #Mastodon! Come follow me at {url}' },
|
shareableMessage: { id: 'onboarding.share.message', defaultMessage: 'I\'m {username} on #Mastodon! Come follow me at {url}' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
account: state.getIn(['accounts', me]),
|
|
||||||
});
|
|
||||||
|
|
||||||
class CopyPasteText extends PureComponent {
|
class CopyPasteText extends PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -141,22 +135,14 @@ class TipCarousel extends PureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Share extends PureComponent {
|
export const Share = () => {
|
||||||
|
const account = useAppSelector(state => state.getIn(['accounts', me]));
|
||||||
static propTypes = {
|
const intl = useIntl();
|
||||||
onBack: PropTypes.func,
|
|
||||||
account: ImmutablePropTypes.record,
|
|
||||||
intl: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { onBack, account, intl } = this.props;
|
|
||||||
|
|
||||||
const url = (new URL(`/@${account.get('username')}`, document.baseURI)).href;
|
const url = (new URL(`/@${account.get('username')}`, document.baseURI)).href;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Column>
|
<>
|
||||||
<ColumnBackButton onClick={onBack} />
|
<ColumnBackButton />
|
||||||
|
|
||||||
<div className='scrollable privacy-policy'>
|
<div className='scrollable privacy-policy'>
|
||||||
<div className='column-title'>
|
<div className='column-title'>
|
||||||
|
@ -187,13 +173,9 @@ class Share extends PureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='onboarding__footer'>
|
<div className='onboarding__footer'>
|
||||||
<button className='link-button' onClick={onBack}><FormattedMessage id='onboarding.action.back' defaultMessage='Take me back' /></button>
|
<Link className='link-button' to='/start'><FormattedMessage id='onboarding.action.back' defaultMessage='Take me back' /></Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Column>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export default connect(mapStateToProps)(injectIntl(Share));
|
|
||||||
|
|
|
@ -166,7 +166,7 @@ class Footer extends ImmutablePureComponent {
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
this.props.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|
|
@ -18,6 +18,8 @@ import { ReactComponent as ReplyAllIcon } from '@material-symbols/svg-600/outlin
|
||||||
import { ReactComponent as StarIcon } from '@material-symbols/svg-600/outlined/star-fill.svg';
|
import { ReactComponent as StarIcon } from '@material-symbols/svg-600/outlined/star-fill.svg';
|
||||||
import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outlined/star.svg';
|
import { ReactComponent as StarBorderIcon } from '@material-symbols/svg-600/outlined/star.svg';
|
||||||
|
|
||||||
|
import { ReactComponent as RepeatDisabledIcon } from 'mastodon/../svg-icons/repeat_disabled.svg';
|
||||||
|
import { ReactComponent as RepeatPrivateIcon } from 'mastodon/../svg-icons/repeat_private.svg';
|
||||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
|
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
|
@ -280,6 +282,7 @@ class ActionBar extends PureComponent {
|
||||||
|
|
||||||
let replyIcon;
|
let replyIcon;
|
||||||
let replyIconComponent;
|
let replyIconComponent;
|
||||||
|
|
||||||
if (status.get('in_reply_to_id', null) === null) {
|
if (status.get('in_reply_to_id', null) === null) {
|
||||||
replyIcon = 'reply';
|
replyIcon = 'reply';
|
||||||
replyIconComponent = ReplyIcon;
|
replyIconComponent = ReplyIcon;
|
||||||
|
@ -290,21 +293,26 @@ class ActionBar extends PureComponent {
|
||||||
|
|
||||||
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
|
const reblogPrivate = status.getIn(['account', 'id']) === me && status.get('visibility') === 'private';
|
||||||
|
|
||||||
let reblogTitle;
|
let reblogTitle, reblogIconComponent;
|
||||||
|
|
||||||
if (status.get('reblogged')) {
|
if (status.get('reblogged')) {
|
||||||
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
reblogTitle = intl.formatMessage(messages.cancel_reblog_private);
|
||||||
|
reblogIconComponent = publicStatus ? RepeatIcon : RepeatPrivateIcon;
|
||||||
} else if (publicStatus) {
|
} else if (publicStatus) {
|
||||||
reblogTitle = intl.formatMessage(messages.reblog);
|
reblogTitle = intl.formatMessage(messages.reblog);
|
||||||
|
reblogIconComponent = RepeatIcon;
|
||||||
} else if (reblogPrivate) {
|
} else if (reblogPrivate) {
|
||||||
reblogTitle = intl.formatMessage(messages.reblog_private);
|
reblogTitle = intl.formatMessage(messages.reblog_private);
|
||||||
|
reblogIconComponent = RepeatPrivateIcon;
|
||||||
} else {
|
} else {
|
||||||
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
reblogTitle = intl.formatMessage(messages.cannot_reblog);
|
||||||
|
reblogIconComponent = RepeatDisabledIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='detailed-status__action-bar'>
|
<div className='detailed-status__action-bar'>
|
||||||
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} iconComponent={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} /></div>
|
<div className='detailed-status__button'><IconButton title={intl.formatMessage(messages.reply)} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} iconComponent={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} /></div>
|
||||||
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={RepeatIcon} onClick={this.handleReblogClick} /></div>
|
<div className='detailed-status__button'><IconButton className={classNames({ reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' iconComponent={reblogIconComponent} onClick={this.handleReblogClick} /></div>
|
||||||
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} /></div>
|
<div className='detailed-status__button'><IconButton className='star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} /></div>
|
||||||
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} /></div>
|
<div className='detailed-status__button'><IconButton className='bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} /></div>
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ class SwitchingColumnsArea extends PureComponent {
|
||||||
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
<WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
|
||||||
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
<WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
|
||||||
|
|
||||||
<WrappedRoute path='/start' exact component={Onboarding} content={children} />
|
<WrappedRoute path='/start' component={Onboarding} content={children} />
|
||||||
<WrappedRoute path='/directory' component={Directory} content={children} />
|
<WrappedRoute path='/directory' component={Directory} content={children} />
|
||||||
<WrappedRoute path={['/explore', '/search']} component={Explore} content={children} />
|
<WrappedRoute path={['/explore', '/search']} component={Explore} content={children} />
|
||||||
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
<WrappedRoute path={['/publish', '/statuses/new']} component={Compose} content={children} />
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"account.badges.group": "Groep",
|
"account.badges.group": "Groep",
|
||||||
"account.block": "Blokkeer @{name}",
|
"account.block": "Blokkeer @{name}",
|
||||||
"account.block_domain": "Blokkeer domein {domain}",
|
"account.block_domain": "Blokkeer domein {domain}",
|
||||||
|
"account.block_short": "Blokkeer",
|
||||||
"account.blocked": "Geblokkeer",
|
"account.blocked": "Geblokkeer",
|
||||||
"account.browse_more_on_origin_server": "Verken die oorspronklike profiel",
|
"account.browse_more_on_origin_server": "Verken die oorspronklike profiel",
|
||||||
"account.cancel_follow_request": "Herroep volgversoek",
|
"account.cancel_follow_request": "Herroep volgversoek",
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
"account.posts_with_replies": "Plasings en antwoorde",
|
"account.posts_with_replies": "Plasings en antwoorde",
|
||||||
"account.report": "Rapporteer @{name}",
|
"account.report": "Rapporteer @{name}",
|
||||||
"account.requested": "Wag op goedkeuring. Klik om volgversoek te kanselleer",
|
"account.requested": "Wag op goedkeuring. Klik om volgversoek te kanselleer",
|
||||||
|
"account.requested_follow": "{name} het versoek om jou te volg",
|
||||||
"account.share": "Deel @{name} se profiel",
|
"account.share": "Deel @{name} se profiel",
|
||||||
"account.show_reblogs": "Wys aangestuurde plasings van @{name}",
|
"account.show_reblogs": "Wys aangestuurde plasings van @{name}",
|
||||||
"account.statuses_counter": "{count, plural, one {{counter} Plaas} other {{counter} Plasings}}",
|
"account.statuses_counter": "{count, plural, one {{counter} Plaas} other {{counter} Plasings}}",
|
||||||
|
@ -82,6 +84,7 @@
|
||||||
"column.community": "Plaaslike tydlyn",
|
"column.community": "Plaaslike tydlyn",
|
||||||
"column.directory": "Blaai deur profiele",
|
"column.directory": "Blaai deur profiele",
|
||||||
"column.domain_blocks": "Geblokkeerde domeine",
|
"column.domain_blocks": "Geblokkeerde domeine",
|
||||||
|
"column.favourites": "Gunstelinge",
|
||||||
"column.follow_requests": "Volgversoeke",
|
"column.follow_requests": "Volgversoeke",
|
||||||
"column.home": "Tuis",
|
"column.home": "Tuis",
|
||||||
"column.lists": "Lyste",
|
"column.lists": "Lyste",
|
||||||
|
@ -271,6 +274,7 @@
|
||||||
"privacy.unlisted.short": "Ongelys",
|
"privacy.unlisted.short": "Ongelys",
|
||||||
"privacy_policy.last_updated": "Laaste bywerking op {date}",
|
"privacy_policy.last_updated": "Laaste bywerking op {date}",
|
||||||
"privacy_policy.title": "Privaatheidsbeleid",
|
"privacy_policy.title": "Privaatheidsbeleid",
|
||||||
|
"regeneration_indicator.sublabel": "Jou tuis-voer word voorberei!",
|
||||||
"reply_indicator.cancel": "Kanselleer",
|
"reply_indicator.cancel": "Kanselleer",
|
||||||
"report.placeholder": "Type or paste additional comments",
|
"report.placeholder": "Type or paste additional comments",
|
||||||
"report.submit": "Submit report",
|
"report.submit": "Submit report",
|
||||||
|
|
|
@ -334,7 +334,6 @@
|
||||||
"lists.search": "Buscar entre la chent a la quala sigues",
|
"lists.search": "Buscar entre la chent a la quala sigues",
|
||||||
"lists.subheading": "Las tuyas listas",
|
"lists.subheading": "Las tuyas listas",
|
||||||
"load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}",
|
"load_pending": "{count, plural, one {# nuevo elemento} other {# nuevos elementos}}",
|
||||||
"loading_indicator.label": "Cargando...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Amaga la imachen} other {Amaga las imáchens}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Amaga la imachen} other {Amaga las imáchens}}",
|
||||||
"moved_to_account_banner.text": "La tuya cuenta {disabledAccount} ye actualment deshabilitada perque t'has mudau a {movedToAccount}.",
|
"moved_to_account_banner.text": "La tuya cuenta {disabledAccount} ye actualment deshabilitada perque t'has mudau a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Duración",
|
"mute_modal.duration": "Duración",
|
||||||
|
|
|
@ -389,7 +389,6 @@
|
||||||
"lists.search": "إبحث في قائمة الحسابات التي تُتابِعها",
|
"lists.search": "إبحث في قائمة الحسابات التي تُتابِعها",
|
||||||
"lists.subheading": "قوائمك",
|
"lists.subheading": "قوائمك",
|
||||||
"load_pending": "{count, plural, one {# عنصر جديد} other {# عناصر جديدة}}",
|
"load_pending": "{count, plural, one {# عنصر جديد} other {# عناصر جديدة}}",
|
||||||
"loading_indicator.label": "جارٍ التحميل…",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, zero {} one {اخف الصورة} two {اخف الصورتين} few {اخف الصور} many {اخف الصور} other {اخف الصور}}",
|
"media_gallery.toggle_visible": "{number, plural, zero {} one {اخف الصورة} two {اخف الصورتين} few {اخف الصور} many {اخف الصور} other {اخف الصور}}",
|
||||||
"moved_to_account_banner.text": "حسابك {disabledAccount} معطل حاليًا لأنك انتقلت إلى {movedToAccount}.",
|
"moved_to_account_banner.text": "حسابك {disabledAccount} معطل حاليًا لأنك انتقلت إلى {movedToAccount}.",
|
||||||
"mute_modal.duration": "المدة",
|
"mute_modal.duration": "المدة",
|
||||||
|
|
|
@ -272,7 +272,6 @@
|
||||||
"lists.search": "Buscar ente los perfiles que sigues",
|
"lists.search": "Buscar ente los perfiles que sigues",
|
||||||
"lists.subheading": "Les tos llistes",
|
"lists.subheading": "Les tos llistes",
|
||||||
"load_pending": "{count, plural, one {# elementu nuevu} other {# elementos nuevos}}",
|
"load_pending": "{count, plural, one {# elementu nuevu} other {# elementos nuevos}}",
|
||||||
"loading_indicator.label": "Cargando…",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Anubrir la imaxe} other {Anubrir les imáxenes}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Anubrir la imaxe} other {Anubrir les imáxenes}}",
|
||||||
"mute_modal.duration": "Duración",
|
"mute_modal.duration": "Duración",
|
||||||
"mute_modal.hide_notifications": "¿Quies anubrir los avisos d'esti perfil?",
|
"mute_modal.hide_notifications": "¿Quies anubrir los avisos d'esti perfil?",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Заблакіраваны",
|
"account.blocked": "Заблакіраваны",
|
||||||
"account.browse_more_on_origin_server": "Глядзіце больш у арыгінальным профілі",
|
"account.browse_more_on_origin_server": "Глядзіце больш у арыгінальным профілі",
|
||||||
"account.cancel_follow_request": "Скасаваць запыт на падпіску",
|
"account.cancel_follow_request": "Скасаваць запыт на падпіску",
|
||||||
|
"account.copy": "Скапіраваць спасылку на профіль",
|
||||||
"account.direct": "Згадаць асабіста @{name}",
|
"account.direct": "Згадаць асабіста @{name}",
|
||||||
"account.disable_notifications": "Не паведамляць мне пра публікацыі @{name}",
|
"account.disable_notifications": "Не паведамляць мне пра публікацыі @{name}",
|
||||||
"account.domain_blocked": "Дамен заблакаваны",
|
"account.domain_blocked": "Дамен заблакаваны",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Адзначыць прачытаным",
|
"conversation.mark_as_read": "Адзначыць прачытаным",
|
||||||
"conversation.open": "Прагледзець размову",
|
"conversation.open": "Прагледзець размову",
|
||||||
"conversation.with": "З {names}",
|
"conversation.with": "З {names}",
|
||||||
|
"copy_icon_button.copied": "Скапіявана ў буфер абмену",
|
||||||
"copypaste.copied": "Скапіравана",
|
"copypaste.copied": "Скапіравана",
|
||||||
"copypaste.copy_to_clipboard": "Капіраваць у буфер абмену",
|
"copypaste.copy_to_clipboard": "Капіраваць у буфер абмену",
|
||||||
"directory.federated": "З вядомага федэсвету",
|
"directory.federated": "З вядомага федэсвету",
|
||||||
|
@ -201,7 +203,7 @@
|
||||||
"disabled_account_banner.text": "Ваш уліковы запіс {disabledAccount} часова адключаны.",
|
"disabled_account_banner.text": "Ваш уліковы запіс {disabledAccount} часова адключаны.",
|
||||||
"dismissable_banner.community_timeline": "Гэта самыя апошнія допісы ад людзей, уліковыя запісы якіх размяшчаюцца на {domain}.",
|
"dismissable_banner.community_timeline": "Гэта самыя апошнія допісы ад людзей, уліковыя запісы якіх размяшчаюцца на {domain}.",
|
||||||
"dismissable_banner.dismiss": "Адхіліць",
|
"dismissable_banner.dismiss": "Адхіліць",
|
||||||
"dismissable_banner.explore_links": "Гэтыя навіны абмяркоўваюцца прама зараз на гэтым і іншых серверах дэцэнтралізаванай сеткі.",
|
"dismissable_banner.explore_links": "Гэтыя навіны абмяркоўваюцца цяпер на гэтым і іншых серверах дэцэнтралізаванай сеткі.",
|
||||||
"dismissable_banner.explore_statuses": "Допісы з гэтага і іншых сервераў дэцэнтралізаванай сеткі, якія набіраюць папулярнасць прама зараз.",
|
"dismissable_banner.explore_statuses": "Допісы з гэтага і іншых сервераў дэцэнтралізаванай сеткі, якія набіраюць папулярнасць прама зараз.",
|
||||||
"dismissable_banner.explore_tags": "Гэтыя хэштэгі зараз набіраюць папулярнасць сярод людзей на гэтым і іншых серверах дэцэнтралізаванай сеткі",
|
"dismissable_banner.explore_tags": "Гэтыя хэштэгі зараз набіраюць папулярнасць сярод людзей на гэтым і іншых серверах дэцэнтралізаванай сеткі",
|
||||||
"dismissable_banner.public_timeline": "Гэта апошнія публічныя допісы людзей з усей сеткі, за якімі сочаць карыстальнікі {domain}.",
|
"dismissable_banner.public_timeline": "Гэта апошнія публічныя допісы людзей з усей сеткі, за якімі сочаць карыстальнікі {domain}.",
|
||||||
|
@ -222,6 +224,7 @@
|
||||||
"emoji_button.search_results": "Вынікі пошуку",
|
"emoji_button.search_results": "Вынікі пошуку",
|
||||||
"emoji_button.symbols": "Сімвалы",
|
"emoji_button.symbols": "Сімвалы",
|
||||||
"emoji_button.travel": "Падарожжы і месцы",
|
"emoji_button.travel": "Падарожжы і месцы",
|
||||||
|
"empty_column.account_hides_collections": "Гэты карыстальнік вырашыў схаваць гэтую інфармацыю",
|
||||||
"empty_column.account_suspended": "Уліковы запіс прыпынены",
|
"empty_column.account_suspended": "Уліковы запіс прыпынены",
|
||||||
"empty_column.account_timeline": "Тут няма допісаў!",
|
"empty_column.account_timeline": "Тут няма допісаў!",
|
||||||
"empty_column.account_unavailable": "Профіль недаступны",
|
"empty_column.account_unavailable": "Профіль недаступны",
|
||||||
|
@ -389,7 +392,7 @@
|
||||||
"lists.search": "Шукайце сярод людзей, на якіх Вы падпісаны",
|
"lists.search": "Шукайце сярод людзей, на якіх Вы падпісаны",
|
||||||
"lists.subheading": "Вашыя спісы",
|
"lists.subheading": "Вашыя спісы",
|
||||||
"load_pending": "{count, plural, one {# новы элемент} few {# новыя элементы} many {# новых элементаў} other {# новых элементаў}}",
|
"load_pending": "{count, plural, one {# новы элемент} few {# новыя элементы} many {# новых элементаў} other {# новых элементаў}}",
|
||||||
"loading_indicator.label": "Загрузка...",
|
"loading_indicator.label": "Загрузка…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Схаваць відарыс} other {Схаваць відарысы}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Схаваць відарыс} other {Схаваць відарысы}}",
|
||||||
"moved_to_account_banner.text": "Ваш уліковы запіс {disabledAccount} зараз адключаны таму што вы перанесены на {movedToAccount}.",
|
"moved_to_account_banner.text": "Ваш уліковы запіс {disabledAccount} зараз адключаны таму што вы перанесены на {movedToAccount}.",
|
||||||
"mute_modal.duration": "Працягласць",
|
"mute_modal.duration": "Працягласць",
|
||||||
|
@ -478,10 +481,21 @@
|
||||||
"onboarding.follows.empty": "На жаль, зараз немагчыма паказаць вынікі. Вы можаце паспрабаваць выкарыстоўваць пошук і праглядзець старонку агляду, каб знайсці людзей, на якіх можна падпісацца, або паўтарыце спробу пазней.",
|
"onboarding.follows.empty": "На жаль, зараз немагчыма паказаць вынікі. Вы можаце паспрабаваць выкарыстоўваць пошук і праглядзець старонку агляду, каб знайсці людзей, на якіх можна падпісацца, або паўтарыце спробу пазней.",
|
||||||
"onboarding.follows.lead": "Вы самі ствараеце свой хатні канал. Чым больш людзей вы падпішаце, тым больш актыўна і цікавей гэта будзе. Гэтыя профілі могуць стаць добрай адпраўной кропкай — вы заўсёды можаце адмяніць падпіску на іх пазней!",
|
"onboarding.follows.lead": "Вы самі ствараеце свой хатні канал. Чым больш людзей вы падпішаце, тым больш актыўна і цікавей гэта будзе. Гэтыя профілі могуць стаць добрай адпраўной кропкай — вы заўсёды можаце адмяніць падпіску на іх пазней!",
|
||||||
"onboarding.follows.title": "Папулярна на Mastodon",
|
"onboarding.follows.title": "Папулярна на Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Уключыць профіль і допісы ў алгарытмы рэкамендацый",
|
||||||
|
"onboarding.profile.display_name": "Бачнае імя",
|
||||||
|
"onboarding.profile.display_name_hint": "Ваша поўнае імя або ваш псеўданім…",
|
||||||
|
"onboarding.profile.indexable": "Індэксаваць публічныя допісы ў пошукавых сістэмах",
|
||||||
|
"onboarding.profile.lead": "Вы заўсёды можаце выканаць гэта пазней у Наладах, дзе даступна яшчэ больш параметраў.",
|
||||||
|
"onboarding.profile.note": "Біяграфія",
|
||||||
|
"onboarding.profile.note_hint": "Вы можаце @згадаць іншых людзей або выкарыстоўваць #хэштэгі…",
|
||||||
|
"onboarding.profile.save_and_continue": "Захаваць і працягнуць",
|
||||||
|
"onboarding.profile.title": "Налады профілю",
|
||||||
|
"onboarding.profile.upload_avatar": "Загрузіць фота профілю",
|
||||||
|
"onboarding.profile.upload_header": "Загрузіць шапку профілю",
|
||||||
"onboarding.share.lead": "Дайце людзям ведаць, як яны могуць знайсці вас на Mastodon!",
|
"onboarding.share.lead": "Дайце людзям ведаць, як яны могуць знайсці вас на Mastodon!",
|
||||||
"onboarding.share.message": "Я {username} на #Mastodon! Сачыце за мной на {url}",
|
"onboarding.share.message": "Я {username} на #Mastodon! Сачыце за мной на {url}",
|
||||||
"onboarding.share.next_steps": "Магчымыя наступныя крокі:",
|
"onboarding.share.next_steps": "Магчымыя наступныя крокі:",
|
||||||
"onboarding.share.title": "Падзяліцеся сваім профілем",
|
"onboarding.share.title": "Абагульце свой профіль",
|
||||||
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
|
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
|
||||||
"onboarding.start.skip": "Want to skip right ahead?",
|
"onboarding.start.skip": "Want to skip right ahead?",
|
||||||
"onboarding.start.title": "Вы зрабілі гэта!",
|
"onboarding.start.title": "Вы зрабілі гэта!",
|
||||||
|
@ -492,7 +506,7 @@
|
||||||
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
|
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
|
||||||
"onboarding.steps.setup_profile.title": "Customize your profile",
|
"onboarding.steps.setup_profile.title": "Customize your profile",
|
||||||
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
|
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
|
||||||
"onboarding.steps.share_profile.title": "Share your profile",
|
"onboarding.steps.share_profile.title": "Абагульць ваш профіль у Mastodon",
|
||||||
"onboarding.tips.2fa": "<strong>Ці вы ведаеце?</strong> Вы можаце абараніць свой уліковы запіс, усталяваўшы двухфактарную аўтэнтыфікацыю ў наладах уліковага запісу. Яна працуе з любой праграмай TOTP на ваш выбар, нумар тэлефона не патрэбны!",
|
"onboarding.tips.2fa": "<strong>Ці вы ведаеце?</strong> Вы можаце абараніць свой уліковы запіс, усталяваўшы двухфактарную аўтэнтыфікацыю ў наладах уліковага запісу. Яна працуе з любой праграмай TOTP на ваш выбар, нумар тэлефона не патрэбны!",
|
||||||
"onboarding.tips.accounts_from_other_servers": "<strong>Ці вы ведаеце?</strong> Паколькі Mastodon дэцэнтралізаваны, некаторыя профілі, якія вам трапляюцца, будуць размяшчацца на іншых серверах, адрозных ад вашага. І ўсё ж вы можаце бесперашкодна ўзаемадзейнічаць з імі! Іх сервер пазначаны ў другой палове імя карыстальніка!",
|
"onboarding.tips.accounts_from_other_servers": "<strong>Ці вы ведаеце?</strong> Паколькі Mastodon дэцэнтралізаваны, некаторыя профілі, якія вам трапляюцца, будуць размяшчацца на іншых серверах, адрозных ад вашага. І ўсё ж вы можаце бесперашкодна ўзаемадзейнічаць з імі! Іх сервер пазначаны ў другой палове імя карыстальніка!",
|
||||||
"onboarding.tips.migration": "<strong>Ці вы ведаеце?</strong> Калі вы адчуваеце, што {domain} не з'яўляецца для вас лепшым выбарам у будучыні, вы можаце перайсці на іншы сервер Mastodon, не губляючы сваіх падпісчыкаў. Вы нават можаце стварыць свой уласны сервер!",
|
"onboarding.tips.migration": "<strong>Ці вы ведаеце?</strong> Калі вы адчуваеце, што {domain} не з'яўляецца для вас лепшым выбарам у будучыні, вы можаце перайсці на іншы сервер Mastodon, не губляючы сваіх падпісчыкаў. Вы нават можаце стварыць свой уласны сервер!",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "Резултати от търсене",
|
"emoji_button.search_results": "Резултати от търсене",
|
||||||
"emoji_button.symbols": "Символи",
|
"emoji_button.symbols": "Символи",
|
||||||
"emoji_button.travel": "Пътуване и места",
|
"emoji_button.travel": "Пътуване и места",
|
||||||
|
"empty_column.account_hides_collections": "Този потребител е избрал да не прави това сведение достъпно",
|
||||||
"empty_column.account_suspended": "Спрян акаунт",
|
"empty_column.account_suspended": "Спрян акаунт",
|
||||||
"empty_column.account_timeline": "Тук няма публикации!",
|
"empty_column.account_timeline": "Тук няма публикации!",
|
||||||
"empty_column.account_unavailable": "Профилът не е наличен",
|
"empty_column.account_unavailable": "Профилът не е наличен",
|
||||||
|
@ -389,7 +390,7 @@
|
||||||
"lists.search": "Търсене измежду последваните",
|
"lists.search": "Търсене измежду последваните",
|
||||||
"lists.subheading": "Вашите списъци",
|
"lists.subheading": "Вашите списъци",
|
||||||
"load_pending": "{count, plural, one {# нов елемент} other {# нови елемента}}",
|
"load_pending": "{count, plural, one {# нов елемент} other {# нови елемента}}",
|
||||||
"loading_indicator.label": "Зареждане...",
|
"loading_indicator.label": "Зареждане…",
|
||||||
"media_gallery.toggle_visible": "Скриване на {number, plural, one {изображение} other {изображения}}",
|
"media_gallery.toggle_visible": "Скриване на {number, plural, one {изображение} other {изображения}}",
|
||||||
"moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
|
"moved_to_account_banner.text": "Вашият акаунт {disabledAccount} сега е изключен, защото се преместихте в {movedToAccount}.",
|
||||||
"mute_modal.duration": "Времетраене",
|
"mute_modal.duration": "Времетраене",
|
||||||
|
@ -478,6 +479,17 @@
|
||||||
"onboarding.follows.empty": "За съжаление, в момента не могат да се показват резултати. Може да опитате да употребявате търсене или да прегледате страницата за изследване, за да намерите страница за последване, или да опитате пак по-късно.",
|
"onboarding.follows.empty": "За съжаление, в момента не могат да се показват резултати. Може да опитате да употребявате търсене или да прегледате страницата за изследване, за да намерите страница за последване, или да опитате пак по-късно.",
|
||||||
"onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!",
|
"onboarding.follows.lead": "Може да бъдете куратор на началния си инфоканал. Последвайки повече хора, по-деен и по-интересен ще става. Тези профили може да са добра начална точка, от която винаги по-късно да спрете да следвате!",
|
||||||
"onboarding.follows.title": "Популярно в Mastodon",
|
"onboarding.follows.title": "Популярно в Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Включване на профила и публикации в алгоритмите за откриване",
|
||||||
|
"onboarding.profile.display_name": "Името на показ",
|
||||||
|
"onboarding.profile.display_name_hint": "Вашето пълно име или псевдоним…",
|
||||||
|
"onboarding.profile.indexable": "Включване на обществени публикации в резултатите от търсене",
|
||||||
|
"onboarding.profile.lead": "Винаги може да завършите това по-късно в настройките, където дори има повече възможности за настройване.",
|
||||||
|
"onboarding.profile.note": "Биогр.",
|
||||||
|
"onboarding.profile.note_hint": "Може да @споменавате други хора или #хаштагове…",
|
||||||
|
"onboarding.profile.save_and_continue": "Запазване и продължаване",
|
||||||
|
"onboarding.profile.title": "Настройване на профила",
|
||||||
|
"onboarding.profile.upload_avatar": "Качване на снимка на профила",
|
||||||
|
"onboarding.profile.upload_header": "Качване на заглавка на профила",
|
||||||
"onboarding.share.lead": "Позволете на хората да знаят, че могат да ви намерят в Mastodon!",
|
"onboarding.share.lead": "Позволете на хората да знаят, че могат да ви намерят в Mastodon!",
|
||||||
"onboarding.share.message": "Аз съм {username} в #Mastodon! Елате да ме последвате при {url}",
|
"onboarding.share.message": "Аз съм {username} в #Mastodon! Елате да ме последвате при {url}",
|
||||||
"onboarding.share.next_steps": "Възможни следващи стъпки:",
|
"onboarding.share.next_steps": "Възможни следващи стъпки:",
|
||||||
|
|
|
@ -314,7 +314,6 @@
|
||||||
"lists.search": "যাদের অনুসরণ করেন তাদের ভেতরে খুঁজুন",
|
"lists.search": "যাদের অনুসরণ করেন তাদের ভেতরে খুঁজুন",
|
||||||
"lists.subheading": "আপনার তালিকা",
|
"lists.subheading": "আপনার তালিকা",
|
||||||
"load_pending": "{count, plural, one {# নতুন জিনিস} other {# নতুন জিনিস}}",
|
"load_pending": "{count, plural, one {# নতুন জিনিস} other {# নতুন জিনিস}}",
|
||||||
"loading_indicator.label": "আসছে...",
|
|
||||||
"media_gallery.toggle_visible": "দৃশ্যতার অবস্থা বদলান",
|
"media_gallery.toggle_visible": "দৃশ্যতার অবস্থা বদলান",
|
||||||
"mute_modal.duration": "সময়কাল",
|
"mute_modal.duration": "সময়কাল",
|
||||||
"mute_modal.hide_notifications": "এই ব্যবহারকারীর প্রজ্ঞাপন বন্ধ করবেন ?",
|
"mute_modal.hide_notifications": "এই ব্যবহারকারীর প্রজ্ঞাপন বন্ধ করবেন ?",
|
||||||
|
|
|
@ -329,7 +329,6 @@
|
||||||
"lists.search": "Klask e-touez tud heuliet ganeoc'h",
|
"lists.search": "Klask e-touez tud heuliet ganeoc'h",
|
||||||
"lists.subheading": "Ho listennoù",
|
"lists.subheading": "Ho listennoù",
|
||||||
"load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}",
|
"load_pending": "{count, plural, one {# dra nevez} other {# dra nevez}}",
|
||||||
"loading_indicator.label": "O kargañ...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Kuzhat ar skeudenn} other {Kuzhat ar skeudenn}}",
|
||||||
"mute_modal.duration": "Padelezh",
|
"mute_modal.duration": "Padelezh",
|
||||||
"mute_modal.hide_notifications": "Kuzhat kemenadennoù eus an implijer-se ?",
|
"mute_modal.hide_notifications": "Kuzhat kemenadennoù eus an implijer-se ?",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "Resultats de la cerca",
|
"emoji_button.search_results": "Resultats de la cerca",
|
||||||
"emoji_button.symbols": "Símbols",
|
"emoji_button.symbols": "Símbols",
|
||||||
"emoji_button.travel": "Viatges i llocs",
|
"emoji_button.travel": "Viatges i llocs",
|
||||||
|
"empty_column.account_hides_collections": "Aquest usuari ha elegit no mostrar aquesta informació",
|
||||||
"empty_column.account_suspended": "Compte suspès",
|
"empty_column.account_suspended": "Compte suspès",
|
||||||
"empty_column.account_timeline": "No hi ha tuts aquí!",
|
"empty_column.account_timeline": "No hi ha tuts aquí!",
|
||||||
"empty_column.account_unavailable": "Perfil no disponible",
|
"empty_column.account_unavailable": "Perfil no disponible",
|
||||||
|
@ -389,7 +390,6 @@
|
||||||
"lists.search": "Cerca entre les persones que segueixes",
|
"lists.search": "Cerca entre les persones que segueixes",
|
||||||
"lists.subheading": "Les teves llistes",
|
"lists.subheading": "Les teves llistes",
|
||||||
"load_pending": "{count, plural, one {# element nou} other {# elements nous}}",
|
"load_pending": "{count, plural, one {# element nou} other {# elements nous}}",
|
||||||
"loading_indicator.label": "Es carrega...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Amaga la imatge} other {Amaga les imatges}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Amaga la imatge} other {Amaga les imatges}}",
|
||||||
"moved_to_account_banner.text": "El teu compte {disabledAccount} està desactivat perquè l'has mogut a {movedToAccount}.",
|
"moved_to_account_banner.text": "El teu compte {disabledAccount} està desactivat perquè l'has mogut a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Durada",
|
"mute_modal.duration": "Durada",
|
||||||
|
|
|
@ -342,7 +342,6 @@
|
||||||
"lists.search": "بگەڕێ لەناو ئەو کەسانەی کە شوێنیان کەوتویت",
|
"lists.search": "بگەڕێ لەناو ئەو کەسانەی کە شوێنیان کەوتویت",
|
||||||
"lists.subheading": "لیستەکانت",
|
"lists.subheading": "لیستەکانت",
|
||||||
"load_pending": "{count, plural, one {# بەڕگەی نوێ} other {# بەڕگەی نوێ}}",
|
"load_pending": "{count, plural, one {# بەڕگەی نوێ} other {# بەڕگەی نوێ}}",
|
||||||
"loading_indicator.label": "بارکردن...",
|
|
||||||
"media_gallery.toggle_visible": "شاردنەوەی {number, plural, one {image} other {images}}",
|
"media_gallery.toggle_visible": "شاردنەوەی {number, plural, one {image} other {images}}",
|
||||||
"moved_to_account_banner.text": "ئەکاونتەکەت {disabledAccount} لە ئێستادا لەکارخراوە چونکە تۆ چوویتە {movedToAccount}.",
|
"moved_to_account_banner.text": "ئەکاونتەکەت {disabledAccount} لە ئێستادا لەکارخراوە چونکە تۆ چوویتە {movedToAccount}.",
|
||||||
"mute_modal.duration": "ماوە",
|
"mute_modal.duration": "ماوە",
|
||||||
|
|
|
@ -236,7 +236,6 @@
|
||||||
"lists.search": "Circà indè i vostr'abbunamenti",
|
"lists.search": "Circà indè i vostr'abbunamenti",
|
||||||
"lists.subheading": "E vo liste",
|
"lists.subheading": "E vo liste",
|
||||||
"load_pending": "{count, plural, one {# entrata nova} other {# entrate nove}}",
|
"load_pending": "{count, plural, one {# entrata nova} other {# entrate nove}}",
|
||||||
"loading_indicator.label": "Caricamentu...",
|
|
||||||
"media_gallery.toggle_visible": "Piattà {number, plural, one {ritrattu} other {ritratti}}",
|
"media_gallery.toggle_visible": "Piattà {number, plural, one {ritrattu} other {ritratti}}",
|
||||||
"mute_modal.duration": "Durata",
|
"mute_modal.duration": "Durata",
|
||||||
"mute_modal.hide_notifications": "Piattà nutificazione da st'utilizatore?",
|
"mute_modal.hide_notifications": "Piattà nutificazione da st'utilizatore?",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Blokovaný",
|
"account.blocked": "Blokovaný",
|
||||||
"account.browse_more_on_origin_server": "Více na původním profilu",
|
"account.browse_more_on_origin_server": "Více na původním profilu",
|
||||||
"account.cancel_follow_request": "Zrušit žádost o sledování",
|
"account.cancel_follow_request": "Zrušit žádost o sledování",
|
||||||
|
"account.copy": "Kopírovat odkaz na profil",
|
||||||
"account.direct": "Soukromě zmínit @{name}",
|
"account.direct": "Soukromě zmínit @{name}",
|
||||||
"account.disable_notifications": "Přestat mě upozorňovat, když @{name} zveřejní příspěvek",
|
"account.disable_notifications": "Přestat mě upozorňovat, když @{name} zveřejní příspěvek",
|
||||||
"account.domain_blocked": "Doména blokována",
|
"account.domain_blocked": "Doména blokována",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Označit jako přečtené",
|
"conversation.mark_as_read": "Označit jako přečtené",
|
||||||
"conversation.open": "Zobrazit konverzaci",
|
"conversation.open": "Zobrazit konverzaci",
|
||||||
"conversation.with": "S {names}",
|
"conversation.with": "S {names}",
|
||||||
|
"copy_icon_button.copied": "Zkopírováno do schránky",
|
||||||
"copypaste.copied": "Zkopírováno",
|
"copypaste.copied": "Zkopírováno",
|
||||||
"copypaste.copy_to_clipboard": "Zkopírovat do schránky",
|
"copypaste.copy_to_clipboard": "Zkopírovat do schránky",
|
||||||
"directory.federated": "Ze známého fedivesmíru",
|
"directory.federated": "Ze známého fedivesmíru",
|
||||||
|
@ -222,6 +224,7 @@
|
||||||
"emoji_button.search_results": "Výsledky hledání",
|
"emoji_button.search_results": "Výsledky hledání",
|
||||||
"emoji_button.symbols": "Symboly",
|
"emoji_button.symbols": "Symboly",
|
||||||
"emoji_button.travel": "Cestování a místa",
|
"emoji_button.travel": "Cestování a místa",
|
||||||
|
"empty_column.account_hides_collections": "Tento uživatel se rozhodl nezveřejňovat tuto informaci",
|
||||||
"empty_column.account_suspended": "Účet je pozastaven",
|
"empty_column.account_suspended": "Účet je pozastaven",
|
||||||
"empty_column.account_timeline": "Nejsou tu žádné příspěvky!",
|
"empty_column.account_timeline": "Nejsou tu žádné příspěvky!",
|
||||||
"empty_column.account_unavailable": "Profil není dostupný",
|
"empty_column.account_unavailable": "Profil není dostupný",
|
||||||
|
@ -385,7 +388,6 @@
|
||||||
"lists.search": "Hledejte mezi lidmi, které sledujete",
|
"lists.search": "Hledejte mezi lidmi, které sledujete",
|
||||||
"lists.subheading": "Vaše seznamy",
|
"lists.subheading": "Vaše seznamy",
|
||||||
"load_pending": "{count, plural, one {# nová položka} few {# nové položky} many {# nových položek} other {# nových položek}}",
|
"load_pending": "{count, plural, one {# nová položka} few {# nové položky} many {# nových položek} other {# nových položek}}",
|
||||||
"loading_indicator.label": "Načítání...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Skrýt obrázek} few {Skrýt obrázky} many {Skrýt obrázky} other {Skrýt obrázky}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Skrýt obrázek} few {Skrýt obrázky} many {Skrýt obrázky} other {Skrýt obrázky}}",
|
||||||
"moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálně deaktivován, protože jste se přesunul/a na {movedToAccount}.",
|
"moved_to_account_banner.text": "Váš účet {disabledAccount} je momentálně deaktivován, protože jste se přesunul/a na {movedToAccount}.",
|
||||||
"mute_modal.duration": "Trvání",
|
"mute_modal.duration": "Trvání",
|
||||||
|
|
|
@ -191,6 +191,7 @@
|
||||||
"conversation.mark_as_read": "Nodi fel wedi'i ddarllen",
|
"conversation.mark_as_read": "Nodi fel wedi'i ddarllen",
|
||||||
"conversation.open": "Gweld sgwrs",
|
"conversation.open": "Gweld sgwrs",
|
||||||
"conversation.with": "Gyda {names}",
|
"conversation.with": "Gyda {names}",
|
||||||
|
"copy_icon_button.copied": "Copïwyd i'r clipfwrdd",
|
||||||
"copypaste.copied": "Wedi ei gopïo",
|
"copypaste.copied": "Wedi ei gopïo",
|
||||||
"copypaste.copy_to_clipboard": "Copïo i'r clipfwrdd",
|
"copypaste.copy_to_clipboard": "Copïo i'r clipfwrdd",
|
||||||
"directory.federated": "O'r ffedysawd cyfan",
|
"directory.federated": "O'r ffedysawd cyfan",
|
||||||
|
@ -390,7 +391,7 @@
|
||||||
"lists.search": "Chwilio ymysg pobl rydych yn eu dilyn",
|
"lists.search": "Chwilio ymysg pobl rydych yn eu dilyn",
|
||||||
"lists.subheading": "Eich rhestrau",
|
"lists.subheading": "Eich rhestrau",
|
||||||
"load_pending": "{count, plural, one {# eitem newydd} other {# eitem newydd}}",
|
"load_pending": "{count, plural, one {# eitem newydd} other {# eitem newydd}}",
|
||||||
"loading_indicator.label": "Llwytho...",
|
"loading_indicator.label": "Yn llwytho…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}",
|
||||||
"moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.",
|
"moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.",
|
||||||
"mute_modal.duration": "Hyd",
|
"mute_modal.duration": "Hyd",
|
||||||
|
@ -479,6 +480,11 @@
|
||||||
"onboarding.follows.empty": "Yn anffodus, nid oes modd dangos unrhyw ganlyniadau ar hyn o bryd. Gallwch geisio defnyddio chwilio neu bori'r dudalen archwilio i ddod o hyd i bobl i'w dilyn, neu ceisio eto yn nes ymlaen.",
|
"onboarding.follows.empty": "Yn anffodus, nid oes modd dangos unrhyw ganlyniadau ar hyn o bryd. Gallwch geisio defnyddio chwilio neu bori'r dudalen archwilio i ddod o hyd i bobl i'w dilyn, neu ceisio eto yn nes ymlaen.",
|
||||||
"onboarding.follows.lead": "Rydych chi'n curadu eich ffrwd gartref eich hun. Po fwyaf o bobl y byddwch chi'n eu dilyn, y mwyaf egnïol a diddorol fydd hi. Gall y proffiliau hyn fod yn fan cychwyn da - gallwch chi bob amser eu dad-ddilyn yn nes ymlaen:",
|
"onboarding.follows.lead": "Rydych chi'n curadu eich ffrwd gartref eich hun. Po fwyaf o bobl y byddwch chi'n eu dilyn, y mwyaf egnïol a diddorol fydd hi. Gall y proffiliau hyn fod yn fan cychwyn da - gallwch chi bob amser eu dad-ddilyn yn nes ymlaen:",
|
||||||
"onboarding.follows.title": "Yn boblogaidd ar Mastodon",
|
"onboarding.follows.title": "Yn boblogaidd ar Mastodon",
|
||||||
|
"onboarding.profile.display_name_hint": "Eich enw llawn neu'ch enw hwyl…",
|
||||||
|
"onboarding.profile.note": "Bywgraffiad",
|
||||||
|
"onboarding.profile.note_hint": "Gallwch @grybwyll pobl eraill neu #hashnodau…",
|
||||||
|
"onboarding.profile.save_and_continue": "Cadw a pharhau",
|
||||||
|
"onboarding.profile.title": "Gosodiad proffil",
|
||||||
"onboarding.share.lead": "Cofiwch ddweud wrth bobl sut y gallan nhw ddod o hyd i chi ar Mastodon!",
|
"onboarding.share.lead": "Cofiwch ddweud wrth bobl sut y gallan nhw ddod o hyd i chi ar Mastodon!",
|
||||||
"onboarding.share.message": "Fi yw {username} ar #Mastodon! Dewch i'm dilyn i yn {url}",
|
"onboarding.share.message": "Fi yw {username} ar #Mastodon! Dewch i'm dilyn i yn {url}",
|
||||||
"onboarding.share.next_steps": "Camau nesaf posib:",
|
"onboarding.share.next_steps": "Camau nesaf posib:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Blokeret",
|
"account.blocked": "Blokeret",
|
||||||
"account.browse_more_on_origin_server": "Se mere på den oprindelige profil",
|
"account.browse_more_on_origin_server": "Se mere på den oprindelige profil",
|
||||||
"account.cancel_follow_request": "Annullér anmodning om at følge",
|
"account.cancel_follow_request": "Annullér anmodning om at følge",
|
||||||
|
"account.copy": "Kopiér link til profil",
|
||||||
"account.direct": "Privat omtale @{name}",
|
"account.direct": "Privat omtale @{name}",
|
||||||
"account.disable_notifications": "Advisér mig ikke længere, når @{name} poster",
|
"account.disable_notifications": "Advisér mig ikke længere, når @{name} poster",
|
||||||
"account.domain_blocked": "Domæne blokeret",
|
"account.domain_blocked": "Domæne blokeret",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Markér som læst",
|
"conversation.mark_as_read": "Markér som læst",
|
||||||
"conversation.open": "Vis samtale",
|
"conversation.open": "Vis samtale",
|
||||||
"conversation.with": "Med {names}",
|
"conversation.with": "Med {names}",
|
||||||
|
"copy_icon_button.copied": "Kopieret til udklipsholderen",
|
||||||
"copypaste.copied": "Kopieret",
|
"copypaste.copied": "Kopieret",
|
||||||
"copypaste.copy_to_clipboard": "Kopiér til udklipsholder",
|
"copypaste.copy_to_clipboard": "Kopiér til udklipsholder",
|
||||||
"directory.federated": "Fra kendt fedivers",
|
"directory.federated": "Fra kendt fedivers",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Søg blandt personer, som følges",
|
"lists.search": "Søg blandt personer, som følges",
|
||||||
"lists.subheading": "Dine lister",
|
"lists.subheading": "Dine lister",
|
||||||
"load_pending": "{count, plural, one {# nyt emne} other {# nye emner}}",
|
"load_pending": "{count, plural, one {# nyt emne} other {# nye emner}}",
|
||||||
"loading_indicator.label": "Indlæser...",
|
"loading_indicator.label": "Indlæser…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Skjul billede} other {Skjul billeder}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Skjul billede} other {Skjul billeder}}",
|
||||||
"moved_to_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret, da du flyttede til {movedToAccount}.",
|
"moved_to_account_banner.text": "Din konto {disabledAccount} er pt. deaktiveret, da du flyttede til {movedToAccount}.",
|
||||||
"mute_modal.duration": "Varighed",
|
"mute_modal.duration": "Varighed",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Ingen resultater tilgængelige pt. Prøv at bruge søgning eller gennemse siden for at finde personer at følge, eller forsøg igen senere.",
|
"onboarding.follows.empty": "Ingen resultater tilgængelige pt. Prøv at bruge søgning eller gennemse siden for at finde personer at følge, eller forsøg igen senere.",
|
||||||
"onboarding.follows.lead": "Man kurerer sin eget hjemme-feed. Jo flere personer man følger, des mere aktiv og interessant vil det være. Disse profiler kan være et godt udgangspunkt – de kan altid fjernes senere!",
|
"onboarding.follows.lead": "Man kurerer sin eget hjemme-feed. Jo flere personer man følger, des mere aktiv og interessant vil det være. Disse profiler kan være et godt udgangspunkt – de kan altid fjernes senere!",
|
||||||
"onboarding.follows.title": "Populært på Mastodon",
|
"onboarding.follows.title": "Populært på Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Fremhæv profil og indlæg i detekteringsalgoritmer",
|
||||||
|
"onboarding.profile.display_name": "Visningsnavn",
|
||||||
|
"onboarding.profile.display_name_hint": "Fulde navn eller dit sjove navn…",
|
||||||
|
"onboarding.profile.indexable": "Medtag offentlige indlæg i søgeresultater",
|
||||||
|
"onboarding.profile.lead": "Dette kan altid færdiggøres senere i indstillingerne, hvor endnu flere tilpasningsmuligheder forefindes.",
|
||||||
|
"onboarding.profile.note": "Bio",
|
||||||
|
"onboarding.profile.note_hint": "Man kan @omtale andre personer eller #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Gem og fortsæt",
|
||||||
|
"onboarding.profile.title": "Profilopsætning",
|
||||||
|
"onboarding.profile.upload_avatar": "Upload profilbillede",
|
||||||
|
"onboarding.profile.upload_header": "Upload profiloverskrift",
|
||||||
"onboarding.share.lead": "Lad folk vide, hvordan de kan finde dig på Mastodon!",
|
"onboarding.share.lead": "Lad folk vide, hvordan de kan finde dig på Mastodon!",
|
||||||
"onboarding.share.message": "Jeg er {username} på #Mastodon! Følg mig på {url}",
|
"onboarding.share.message": "Jeg er {username} på #Mastodon! Følg mig på {url}",
|
||||||
"onboarding.share.next_steps": "Mulige næste trin:",
|
"onboarding.share.next_steps": "Mulige næste trin:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Blockiert",
|
"account.blocked": "Blockiert",
|
||||||
"account.browse_more_on_origin_server": "Mehr auf dem Originalprofil durchsuchen",
|
"account.browse_more_on_origin_server": "Mehr auf dem Originalprofil durchsuchen",
|
||||||
"account.cancel_follow_request": "Folgeanfrage zurückziehen",
|
"account.cancel_follow_request": "Folgeanfrage zurückziehen",
|
||||||
|
"account.copy": "Link zum Profil kopieren",
|
||||||
"account.direct": "@{name} privat erwähnen",
|
"account.direct": "@{name} privat erwähnen",
|
||||||
"account.disable_notifications": "Höre auf mich zu benachrichtigen wenn @{name} etwas postet",
|
"account.disable_notifications": "Höre auf mich zu benachrichtigen wenn @{name} etwas postet",
|
||||||
"account.domain_blocked": "Domain versteckt",
|
"account.domain_blocked": "Domain versteckt",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Als gelesen markieren",
|
"conversation.mark_as_read": "Als gelesen markieren",
|
||||||
"conversation.open": "Unterhaltung anzeigen",
|
"conversation.open": "Unterhaltung anzeigen",
|
||||||
"conversation.with": "Mit {names}",
|
"conversation.with": "Mit {names}",
|
||||||
|
"copy_icon_button.copied": "In die Zwischenablage kopiert",
|
||||||
"copypaste.copied": "Kopiert",
|
"copypaste.copied": "Kopiert",
|
||||||
"copypaste.copy_to_clipboard": "In die Zwischenablage kopieren",
|
"copypaste.copy_to_clipboard": "In die Zwischenablage kopieren",
|
||||||
"directory.federated": "Aus bekanntem Fediverse",
|
"directory.federated": "Aus bekanntem Fediverse",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Suche nach Leuten, denen du folgst",
|
"lists.search": "Suche nach Leuten, denen du folgst",
|
||||||
"lists.subheading": "Deine Listen",
|
"lists.subheading": "Deine Listen",
|
||||||
"load_pending": "{count, plural, one {# neuer Beitrag} other {# neue Beiträge}}",
|
"load_pending": "{count, plural, one {# neuer Beitrag} other {# neue Beiträge}}",
|
||||||
"loading_indicator.label": "Wird geladen …",
|
"loading_indicator.label": "Wird geladen …",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Medium ausblenden} other {Medien ausblenden}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Medium ausblenden} other {Medien ausblenden}}",
|
||||||
"moved_to_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert, weil du zu {movedToAccount} umgezogen bist.",
|
"moved_to_account_banner.text": "Dein Konto {disabledAccount} ist derzeit deaktiviert, weil du zu {movedToAccount} umgezogen bist.",
|
||||||
"mute_modal.duration": "Dauer",
|
"mute_modal.duration": "Dauer",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.",
|
"onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.",
|
||||||
"onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:",
|
"onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:",
|
||||||
"onboarding.follows.title": "Personalisiere deine Startseite",
|
"onboarding.follows.title": "Personalisiere deine Startseite",
|
||||||
|
"onboarding.profile.discoverable": "Profil und Beiträge in Suchalgorithmen berücksichtigen",
|
||||||
|
"onboarding.profile.display_name": "Anzeigename",
|
||||||
|
"onboarding.profile.display_name_hint": "Dein richtiger Name oder dein Fantasiename …",
|
||||||
|
"onboarding.profile.indexable": "Öffentliche Beiträge in die Suchergebnisse einbeziehen",
|
||||||
|
"onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.",
|
||||||
|
"onboarding.profile.note": "Über mich",
|
||||||
|
"onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …",
|
||||||
|
"onboarding.profile.save_and_continue": "Speichern und fortsetzen",
|
||||||
|
"onboarding.profile.title": "Profil einrichten",
|
||||||
|
"onboarding.profile.upload_avatar": "Profilbild hochladen",
|
||||||
|
"onboarding.profile.upload_header": "Titelbild hochladen",
|
||||||
"onboarding.share.lead": "Lass die Leute wissen, wie sie dich auf Mastodon finden können!",
|
"onboarding.share.lead": "Lass die Leute wissen, wie sie dich auf Mastodon finden können!",
|
||||||
"onboarding.share.message": "Ich bin {username} auf #Mastodon! Folge mir auf {url}",
|
"onboarding.share.message": "Ich bin {username} auf #Mastodon! Folge mir auf {url}",
|
||||||
"onboarding.share.next_steps": "Mögliche nächste Schritte:",
|
"onboarding.share.next_steps": "Mögliche nächste Schritte:",
|
||||||
|
|
|
@ -345,7 +345,6 @@
|
||||||
"lists.search": "Αναζήτησε μεταξύ των ανθρώπων που ακουλουθείς",
|
"lists.search": "Αναζήτησε μεταξύ των ανθρώπων που ακουλουθείς",
|
||||||
"lists.subheading": "Οι λίστες σου",
|
"lists.subheading": "Οι λίστες σου",
|
||||||
"load_pending": "{count, plural, one {# νέο στοιχείο} other {# νέα στοιχεία}}",
|
"load_pending": "{count, plural, one {# νέο στοιχείο} other {# νέα στοιχεία}}",
|
||||||
"loading_indicator.label": "Φορτώνει...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Απόκρυψη εικόνας} other {Απόκρυψη εικόνων}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Απόκρυψη εικόνας} other {Απόκρυψη εικόνων}}",
|
||||||
"moved_to_account_banner.text": "Ο λογαριασμός σου {disabledAccount} είναι προσωρινά απενεργοποιημένος επειδή μεταφέρθηκες στον {movedToAccount}.",
|
"moved_to_account_banner.text": "Ο λογαριασμός σου {disabledAccount} είναι προσωρινά απενεργοποιημένος επειδή μεταφέρθηκες στον {movedToAccount}.",
|
||||||
"mute_modal.duration": "Διάρκεια",
|
"mute_modal.duration": "Διάρκεια",
|
||||||
|
|
|
@ -389,7 +389,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"load_pending": "{count, plural, one {# new item} other {# new items}}",
|
"load_pending": "{count, plural, one {# new item} other {# new items}}",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
|
||||||
"moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
|
"moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
|
||||||
"mute_modal.duration": "Duration",
|
"mute_modal.duration": "Duration",
|
||||||
|
@ -478,6 +478,17 @@
|
||||||
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
|
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
|
||||||
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
||||||
"onboarding.follows.title": "Personalize your home feed",
|
"onboarding.follows.title": "Personalize your home feed",
|
||||||
|
"onboarding.profile.discoverable": "Feature profile and posts in discovery algorithms",
|
||||||
|
"onboarding.profile.display_name": "Display name",
|
||||||
|
"onboarding.profile.display_name_hint": "Your full name or your fun name…",
|
||||||
|
"onboarding.profile.indexable": "Include public posts in search results",
|
||||||
|
"onboarding.profile.lead": "You can always complete this later in the settings, where even more customisation options are available.",
|
||||||
|
"onboarding.profile.note": "Bio",
|
||||||
|
"onboarding.profile.note_hint": "You can @mention other people or #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Save and continue",
|
||||||
|
"onboarding.profile.title": "Profile setup",
|
||||||
|
"onboarding.profile.upload_avatar": "Upload profile picture",
|
||||||
|
"onboarding.profile.upload_header": "Upload profile header",
|
||||||
"onboarding.share.lead": "Let people know how they can find you on Mastodon!",
|
"onboarding.share.lead": "Let people know how they can find you on Mastodon!",
|
||||||
"onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}",
|
"onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}",
|
||||||
"onboarding.share.next_steps": "Possible next steps:",
|
"onboarding.share.next_steps": "Possible next steps:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Blocked",
|
"account.blocked": "Blocked",
|
||||||
"account.browse_more_on_origin_server": "Browse more on the original profile",
|
"account.browse_more_on_origin_server": "Browse more on the original profile",
|
||||||
"account.cancel_follow_request": "Cancel follow",
|
"account.cancel_follow_request": "Cancel follow",
|
||||||
|
"account.copy": "Copy link to profile",
|
||||||
"account.direct": "Privately mention @{name}",
|
"account.direct": "Privately mention @{name}",
|
||||||
"account.disable_notifications": "Stop notifying me when @{name} posts",
|
"account.disable_notifications": "Stop notifying me when @{name} posts",
|
||||||
"account.domain_blocked": "Domain blocked",
|
"account.domain_blocked": "Domain blocked",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Mark as read",
|
"conversation.mark_as_read": "Mark as read",
|
||||||
"conversation.open": "View conversation",
|
"conversation.open": "View conversation",
|
||||||
"conversation.with": "With {names}",
|
"conversation.with": "With {names}",
|
||||||
|
"copy_icon_button.copied": "Copied to clipboard",
|
||||||
"copypaste.copied": "Copied",
|
"copypaste.copied": "Copied",
|
||||||
"copypaste.copy_to_clipboard": "Copy to clipboard",
|
"copypaste.copy_to_clipboard": "Copy to clipboard",
|
||||||
"directory.federated": "From known fediverse",
|
"directory.federated": "From known fediverse",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Search among people you follow",
|
"lists.search": "Search among people you follow",
|
||||||
"lists.subheading": "Your lists",
|
"lists.subheading": "Your lists",
|
||||||
"load_pending": "{count, plural, one {# new item} other {# new items}}",
|
"load_pending": "{count, plural, one {# new item} other {# new items}}",
|
||||||
"loading_indicator.label": "Loading...",
|
"loading_indicator.label": "Loading…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
|
||||||
"moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
|
"moved_to_account_banner.text": "Your account {disabledAccount} is currently disabled because you moved to {movedToAccount}.",
|
||||||
"mute_modal.duration": "Duration",
|
"mute_modal.duration": "Duration",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
|
"onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.",
|
||||||
"onboarding.follows.lead": "Your home feed is the primary way to experience Mastodon. The more people you follow, the more active and interesting it will be. To get you started, here are some suggestions:",
|
"onboarding.follows.lead": "Your home feed is the primary way to experience Mastodon. The more people you follow, the more active and interesting it will be. To get you started, here are some suggestions:",
|
||||||
"onboarding.follows.title": "Personalize your home feed",
|
"onboarding.follows.title": "Personalize your home feed",
|
||||||
|
"onboarding.profile.discoverable": "Make my profile discoverable",
|
||||||
|
"onboarding.profile.discoverable_hint": "When you opt in to discoverability on Mastodon, your posts may appear in search results and trending, and your profile may be suggested to people with similar interests to you.",
|
||||||
|
"onboarding.profile.display_name": "Display name",
|
||||||
|
"onboarding.profile.display_name_hint": "Your full name or your fun name…",
|
||||||
|
"onboarding.profile.lead": "You can always complete this later in the settings, where even more customization options are available.",
|
||||||
|
"onboarding.profile.note": "Bio",
|
||||||
|
"onboarding.profile.note_hint": "You can @mention other people or #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Save and continue",
|
||||||
|
"onboarding.profile.title": "Profile setup",
|
||||||
|
"onboarding.profile.upload_avatar": "Upload profile picture",
|
||||||
|
"onboarding.profile.upload_header": "Upload profile header",
|
||||||
"onboarding.share.lead": "Let people know how they can find you on Mastodon!",
|
"onboarding.share.lead": "Let people know how they can find you on Mastodon!",
|
||||||
"onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}",
|
"onboarding.share.message": "I'm {username} on #Mastodon! Come follow me at {url}",
|
||||||
"onboarding.share.next_steps": "Possible next steps:",
|
"onboarding.share.next_steps": "Possible next steps:",
|
||||||
|
@ -522,6 +535,7 @@
|
||||||
"privacy.unlisted.short": "Unlisted",
|
"privacy.unlisted.short": "Unlisted",
|
||||||
"privacy_policy.last_updated": "Last updated {date}",
|
"privacy_policy.last_updated": "Last updated {date}",
|
||||||
"privacy_policy.title": "Privacy Policy",
|
"privacy_policy.title": "Privacy Policy",
|
||||||
|
"recommended": "Recommended",
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
"regeneration_indicator.label": "Loading…",
|
"regeneration_indicator.label": "Loading…",
|
||||||
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
|
||||||
|
|
|
@ -365,7 +365,6 @@
|
||||||
"lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
|
"lists.search": "Serĉi inter la homoj, kiujn vi sekvas",
|
||||||
"lists.subheading": "Viaj listoj",
|
"lists.subheading": "Viaj listoj",
|
||||||
"load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}",
|
"load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}",
|
||||||
"loading_indicator.label": "Ŝargado…",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Kaŝi la bildon} other {Kaŝi la bildojn}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Kaŝi la bildon} other {Kaŝi la bildojn}}",
|
||||||
"moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.",
|
"moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.",
|
||||||
"mute_modal.duration": "Daŭro",
|
"mute_modal.duration": "Daŭro",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Bloqueado",
|
"account.blocked": "Bloqueado",
|
||||||
"account.browse_more_on_origin_server": "Explorar más en el perfil original",
|
"account.browse_more_on_origin_server": "Explorar más en el perfil original",
|
||||||
"account.cancel_follow_request": "Dejar de seguir",
|
"account.cancel_follow_request": "Dejar de seguir",
|
||||||
|
"account.copy": "Copiar enlace al perfil",
|
||||||
"account.direct": "Mención privada a @{name}",
|
"account.direct": "Mención privada a @{name}",
|
||||||
"account.disable_notifications": "Dejar de notificarme cuando @{name} envíe mensajes",
|
"account.disable_notifications": "Dejar de notificarme cuando @{name} envíe mensajes",
|
||||||
"account.domain_blocked": "Dominio bloqueado",
|
"account.domain_blocked": "Dominio bloqueado",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Marcar como leída",
|
"conversation.mark_as_read": "Marcar como leída",
|
||||||
"conversation.open": "Ver conversación",
|
"conversation.open": "Ver conversación",
|
||||||
"conversation.with": "Con {names}",
|
"conversation.with": "Con {names}",
|
||||||
|
"copy_icon_button.copied": "Copiado en el portapapeles",
|
||||||
"copypaste.copied": "Copiado",
|
"copypaste.copied": "Copiado",
|
||||||
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
||||||
"directory.federated": "Desde fediverso conocido",
|
"directory.federated": "Desde fediverso conocido",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Buscar entre la gente que seguís",
|
"lists.search": "Buscar entre la gente que seguís",
|
||||||
"lists.subheading": "Tus listas",
|
"lists.subheading": "Tus listas",
|
||||||
"load_pending": "{count, plural, one {# elemento nuevo} other {# elementos nuevos}}",
|
"load_pending": "{count, plural, one {# elemento nuevo} other {# elementos nuevos}}",
|
||||||
"loading_indicator.label": "Cargando...",
|
"loading_indicator.label": "Cargando…",
|
||||||
"media_gallery.toggle_visible": "Ocultar {number, plural, one {imagen} other {imágenes}}",
|
"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}.",
|
"moved_to_account_banner.text": "Tu cuenta {disabledAccount} está actualmente deshabilitada porque te mudaste a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Duración",
|
"mute_modal.duration": "Duración",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Podés intentar usar la búsqueda o navegar por la página de exploración para encontrar cuentas a las que seguir, o intentarlo de nuevo más tarde.",
|
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Podés intentar usar la búsqueda o navegar por la página de exploración para encontrar cuentas a las que seguir, o intentarlo de nuevo más tarde.",
|
||||||
"onboarding.follows.lead": "Tu línea temporal de inicio es la forma principal de experimentar Mastodon. Cuanta más cuentas sigás, más activa e interesante será. Para empezar, acá tenés algunas sugerencias:",
|
"onboarding.follows.lead": "Tu línea temporal de inicio es la forma principal de experimentar Mastodon. Cuanta más cuentas sigás, más activa e interesante será. Para empezar, acá tenés algunas sugerencias:",
|
||||||
"onboarding.follows.title": "Personalizá tu línea de tiempo principal",
|
"onboarding.follows.title": "Personalizá tu línea de tiempo principal",
|
||||||
|
"onboarding.profile.discoverable": "Destacar perfil y mensajes en algoritmos de descubrimiento",
|
||||||
|
"onboarding.profile.display_name": "Nombre para mostrar",
|
||||||
|
"onboarding.profile.display_name_hint": "Tu nombre completo o tu pseudónimo…",
|
||||||
|
"onboarding.profile.indexable": "Incluir mensajes públicos en resultados de búsqueda",
|
||||||
|
"onboarding.profile.lead": "Siempre podés completar esto más tarde en la configuración, donde hay disponibles más opciones de personalización.",
|
||||||
|
"onboarding.profile.note": "Biografía",
|
||||||
|
"onboarding.profile.note_hint": "Podés @mencionar otras cuentas o usar #etiquetas…",
|
||||||
|
"onboarding.profile.save_and_continue": "Guardar y continuar",
|
||||||
|
"onboarding.profile.title": "Configuración del perfil",
|
||||||
|
"onboarding.profile.upload_avatar": "Subir avatar",
|
||||||
|
"onboarding.profile.upload_header": "Subir cabecera",
|
||||||
"onboarding.share.lead": "¡Decile a la gente cómo te pueden encontrar en Mastodon!",
|
"onboarding.share.lead": "¡Decile a la gente cómo te pueden encontrar en Mastodon!",
|
||||||
"onboarding.share.message": "¡En #Mastodon soy «{username}»! Podés seguirme desde {url}",
|
"onboarding.share.message": "¡En #Mastodon soy «{username}»! Podés seguirme desde {url}",
|
||||||
"onboarding.share.next_steps": "Posibles próximos pasos:",
|
"onboarding.share.next_steps": "Posibles próximos pasos:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Bloqueado",
|
"account.blocked": "Bloqueado",
|
||||||
"account.browse_more_on_origin_server": "Ver más en el perfil original",
|
"account.browse_more_on_origin_server": "Ver más en el perfil original",
|
||||||
"account.cancel_follow_request": "Retirar solicitud de seguimiento",
|
"account.cancel_follow_request": "Retirar solicitud de seguimiento",
|
||||||
|
"account.copy": "Copiar enlace al perfil",
|
||||||
"account.direct": "Mención privada @{name}",
|
"account.direct": "Mención privada @{name}",
|
||||||
"account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo",
|
"account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo",
|
||||||
"account.domain_blocked": "Dominio oculto",
|
"account.domain_blocked": "Dominio oculto",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Marcar como leído",
|
"conversation.mark_as_read": "Marcar como leído",
|
||||||
"conversation.open": "Ver conversación",
|
"conversation.open": "Ver conversación",
|
||||||
"conversation.with": "Con {names}",
|
"conversation.with": "Con {names}",
|
||||||
|
"copy_icon_button.copied": "Copiado al portapapeles",
|
||||||
"copypaste.copied": "Copiado",
|
"copypaste.copied": "Copiado",
|
||||||
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
||||||
"directory.federated": "Desde el fediverso conocido",
|
"directory.federated": "Desde el fediverso conocido",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar gente a la que seguir, o inténtalo de nuevo más tarde.",
|
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar gente a la que seguir, o inténtalo de nuevo más tarde.",
|
||||||
"onboarding.follows.lead": "Tienes que personalizar tu inicio. Cuantas más personas sigas, más activo e interesante será. Estos perfiles pueden ser un buen punto de partida, ¡pero siempre puedes dejar de seguirlos más adelante!",
|
"onboarding.follows.lead": "Tienes que personalizar tu inicio. Cuantas más personas sigas, más activo e interesante será. Estos perfiles pueden ser un buen punto de partida, ¡pero siempre puedes dejar de seguirlos más adelante!",
|
||||||
"onboarding.follows.title": "Popular en Mastodon",
|
"onboarding.follows.title": "Popular en Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Destacar el perfil y las publicaciones en el algoritmo de descubrimiento",
|
||||||
|
"onboarding.profile.display_name": "Nombre a mostrar",
|
||||||
|
"onboarding.profile.display_name_hint": "Tu nombre completo o tu apodo…",
|
||||||
|
"onboarding.profile.indexable": "Incluir publicaciones públicas en los resultados de búsqueda",
|
||||||
|
"onboarding.profile.lead": "Siempre puedes completar esto más tarde en los ajustes, donde hay aún más opciones de personalización disponibles.",
|
||||||
|
"onboarding.profile.note": "Biografía",
|
||||||
|
"onboarding.profile.note_hint": "Puedes @mencionar a otras personas o #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Guardar y continuar",
|
||||||
|
"onboarding.profile.title": "Configuración del perfil",
|
||||||
|
"onboarding.profile.upload_avatar": "Subir foto de perfil",
|
||||||
|
"onboarding.profile.upload_header": "Subir foto de cabecera",
|
||||||
"onboarding.share.lead": "¡Dile a la gente cómo te pueden encontrar en Mastodon!",
|
"onboarding.share.lead": "¡Dile a la gente cómo te pueden encontrar en Mastodon!",
|
||||||
"onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}",
|
"onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}",
|
||||||
"onboarding.share.next_steps": "Posibles siguientes pasos:",
|
"onboarding.share.next_steps": "Posibles siguientes pasos:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Bloqueado",
|
"account.blocked": "Bloqueado",
|
||||||
"account.browse_more_on_origin_server": "Ver más en el perfil original",
|
"account.browse_more_on_origin_server": "Ver más en el perfil original",
|
||||||
"account.cancel_follow_request": "Retirar solicitud de seguimiento",
|
"account.cancel_follow_request": "Retirar solicitud de seguimiento",
|
||||||
|
"account.copy": "Copiar enlace al perfil",
|
||||||
"account.direct": "Mención privada a @{name}",
|
"account.direct": "Mención privada a @{name}",
|
||||||
"account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo",
|
"account.disable_notifications": "Dejar de notificarme cuando @{name} publique algo",
|
||||||
"account.domain_blocked": "Dominio bloqueado",
|
"account.domain_blocked": "Dominio bloqueado",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Marcar como leído",
|
"conversation.mark_as_read": "Marcar como leído",
|
||||||
"conversation.open": "Ver conversación",
|
"conversation.open": "Ver conversación",
|
||||||
"conversation.with": "Con {names}",
|
"conversation.with": "Con {names}",
|
||||||
|
"copy_icon_button.copied": "Copiado al portapapeles",
|
||||||
"copypaste.copied": "Copiado",
|
"copypaste.copied": "Copiado",
|
||||||
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
"copypaste.copy_to_clipboard": "Copiar al portapapeles",
|
||||||
"directory.federated": "Desde el fediverso conocido",
|
"directory.federated": "Desde el fediverso conocido",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar personas a las que seguir, o inténtalo de nuevo más tarde.",
|
"onboarding.follows.empty": "Desafortunadamente, no se pueden mostrar resultados en este momento. Puedes intentar usar la búsqueda o navegar por la página de exploración para encontrar personas a las que seguir, o inténtalo de nuevo más tarde.",
|
||||||
"onboarding.follows.lead": "Tu línea de inicio es la forma principal de experimentar Mastodon. Cuanta más personas sigas, más activa e interesante será. Para empezar, aquí hay algunas sugerencias:",
|
"onboarding.follows.lead": "Tu línea de inicio es la forma principal de experimentar Mastodon. Cuanta más personas sigas, más activa e interesante será. Para empezar, aquí hay algunas sugerencias:",
|
||||||
"onboarding.follows.title": "Personaliza tu línea de inicio",
|
"onboarding.follows.title": "Personaliza tu línea de inicio",
|
||||||
|
"onboarding.profile.discoverable": "Destacar perfil y publicaciones en algoritmos de descubrimiento",
|
||||||
|
"onboarding.profile.display_name": "Nombre para mostrar",
|
||||||
|
"onboarding.profile.display_name_hint": "Tu nombre completo o tu apodo…",
|
||||||
|
"onboarding.profile.indexable": "Incluir publicaciones públicas en los resultados de búsqueda",
|
||||||
|
"onboarding.profile.lead": "Siempre puedes completar esto más tarde en los ajustes, donde hay aún más opciones de personalización disponibles.",
|
||||||
|
"onboarding.profile.note": "Biografía",
|
||||||
|
"onboarding.profile.note_hint": "Puedes @mencionar a otras personas o #etiquetas…",
|
||||||
|
"onboarding.profile.save_and_continue": "Guardar y continuar",
|
||||||
|
"onboarding.profile.title": "Configuración del perfil",
|
||||||
|
"onboarding.profile.upload_avatar": "Subir foto de perfil",
|
||||||
|
"onboarding.profile.upload_header": "Subir encabezado de perfil",
|
||||||
"onboarding.share.lead": "¡Cuéntale a otras personas cómo te pueden encontrar en Mastodon!",
|
"onboarding.share.lead": "¡Cuéntale a otras personas cómo te pueden encontrar en Mastodon!",
|
||||||
"onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}",
|
"onboarding.share.message": "¡Soy {username} en #Mastodon! Ven a seguirme en {url}",
|
||||||
"onboarding.share.next_steps": "Posibles siguientes pasos:",
|
"onboarding.share.next_steps": "Posibles siguientes pasos:",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "Otsitulemused",
|
"emoji_button.search_results": "Otsitulemused",
|
||||||
"emoji_button.symbols": "Sümbolid",
|
"emoji_button.symbols": "Sümbolid",
|
||||||
"emoji_button.travel": "Reisimine & kohad",
|
"emoji_button.travel": "Reisimine & kohad",
|
||||||
|
"empty_column.account_hides_collections": "See kasutaja otsustas mitte teha seda infot saadavaks",
|
||||||
"empty_column.account_suspended": "Konto kustutatud",
|
"empty_column.account_suspended": "Konto kustutatud",
|
||||||
"empty_column.account_timeline": "Siin postitusi ei ole!",
|
"empty_column.account_timeline": "Siin postitusi ei ole!",
|
||||||
"empty_column.account_unavailable": "Profiil pole saadaval",
|
"empty_column.account_unavailable": "Profiil pole saadaval",
|
||||||
|
@ -389,7 +390,6 @@
|
||||||
"lists.search": "Otsi enda jälgitavate inimeste hulgast",
|
"lists.search": "Otsi enda jälgitavate inimeste hulgast",
|
||||||
"lists.subheading": "Sinu nimekirjad",
|
"lists.subheading": "Sinu nimekirjad",
|
||||||
"load_pending": "{count, plural, one {# uus kirje} other {# uut kirjet}}",
|
"load_pending": "{count, plural, one {# uus kirje} other {# uut kirjet}}",
|
||||||
"loading_indicator.label": "Laeb..",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Varja pilt} other {Varja pildid}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Varja pilt} other {Varja pildid}}",
|
||||||
"moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.",
|
"moved_to_account_banner.text": "Kontot {disabledAccount} ei ole praegu võimalik kasutada, sest kolisid kontole {movedToAccount}.",
|
||||||
"mute_modal.duration": "Kestus",
|
"mute_modal.duration": "Kestus",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Blokeatuta",
|
"account.blocked": "Blokeatuta",
|
||||||
"account.browse_more_on_origin_server": "Arakatu gehiago jatorrizko profilean",
|
"account.browse_more_on_origin_server": "Arakatu gehiago jatorrizko profilean",
|
||||||
"account.cancel_follow_request": "Baztertu jarraitzeko eskaera",
|
"account.cancel_follow_request": "Baztertu jarraitzeko eskaera",
|
||||||
|
"account.copy": "Kopiatu profilerako esteka",
|
||||||
"account.direct": "Aipatu pribatuki @{name}",
|
"account.direct": "Aipatu pribatuki @{name}",
|
||||||
"account.disable_notifications": "Utzi jakinarazteari @{name} erabiltzailearen bidalketetan",
|
"account.disable_notifications": "Utzi jakinarazteari @{name} erabiltzailearen bidalketetan",
|
||||||
"account.domain_blocked": "Ezkutatutako domeinua",
|
"account.domain_blocked": "Ezkutatutako domeinua",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Markatu irakurrita bezala",
|
"conversation.mark_as_read": "Markatu irakurrita bezala",
|
||||||
"conversation.open": "Ikusi elkarrizketa",
|
"conversation.open": "Ikusi elkarrizketa",
|
||||||
"conversation.with": "Hauekin: {names}",
|
"conversation.with": "Hauekin: {names}",
|
||||||
|
"copy_icon_button.copied": "Arbelera kopiatu da",
|
||||||
"copypaste.copied": "Kopiatuta",
|
"copypaste.copied": "Kopiatuta",
|
||||||
"copypaste.copy_to_clipboard": "Kopiatu arbelera",
|
"copypaste.copy_to_clipboard": "Kopiatu arbelera",
|
||||||
"directory.federated": "Fedibertso ezagunekoak",
|
"directory.federated": "Fedibertso ezagunekoak",
|
||||||
|
@ -389,8 +391,8 @@
|
||||||
"lists.replies_policy.title": "Erakutsi erantzunak:",
|
"lists.replies_policy.title": "Erakutsi erantzunak:",
|
||||||
"lists.search": "Bilatu jarraitzen dituzun pertsonen artean",
|
"lists.search": "Bilatu jarraitzen dituzun pertsonen artean",
|
||||||
"lists.subheading": "Zure zerrendak",
|
"lists.subheading": "Zure zerrendak",
|
||||||
"load_pending": "{count, plural, one {eleentuberri #} other {# elementu berri}}",
|
"load_pending": "{count, plural, one {elementu berri #} other {# elementu berri}}",
|
||||||
"loading_indicator.label": "Kargatzen...",
|
"loading_indicator.label": "Kargatzen…",
|
||||||
"media_gallery.toggle_visible": "Txandakatu ikusgaitasuna",
|
"media_gallery.toggle_visible": "Txandakatu ikusgaitasuna",
|
||||||
"moved_to_account_banner.text": "Zure {disabledAccount} kontua desgaituta dago une honetan, {movedToAccount} kontura aldatu zinelako.",
|
"moved_to_account_banner.text": "Zure {disabledAccount} kontua desgaituta dago une honetan, {movedToAccount} kontura aldatu zinelako.",
|
||||||
"mute_modal.duration": "Iraupena",
|
"mute_modal.duration": "Iraupena",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Zoritxarrez, ezin da emaitzik erakutsi orain. Bilaketa erabil dezakezu edo Arakatu orrian jendea bilatu jarraitzeko, edo saiatu geroago.",
|
"onboarding.follows.empty": "Zoritxarrez, ezin da emaitzik erakutsi orain. Bilaketa erabil dezakezu edo Arakatu orrian jendea bilatu jarraitzeko, edo saiatu geroago.",
|
||||||
"onboarding.follows.lead": "Hasierako orria zuk pertsonalizatzen duzu. Gero eta jende gehiagori jarraitu, orduan eta aktibo eta interesgarriago izango da. Profil hauek egokiak izan daitezke hasteko, beti ere, geroago jarraitzeari utz diezazkiekezu!",
|
"onboarding.follows.lead": "Hasierako orria zuk pertsonalizatzen duzu. Gero eta jende gehiagori jarraitu, orduan eta aktibo eta interesgarriago izango da. Profil hauek egokiak izan daitezke hasteko, beti ere, geroago jarraitzeari utz diezazkiekezu!",
|
||||||
"onboarding.follows.title": "Mastodonen pil-pilean",
|
"onboarding.follows.title": "Mastodonen pil-pilean",
|
||||||
|
"onboarding.profile.discoverable": "Ezagutarazi profila eta bidalketak bilaketa algoritmoetan",
|
||||||
|
"onboarding.profile.display_name": "Bistaratzeko izena",
|
||||||
|
"onboarding.profile.display_name_hint": "Zure izena edo ezizena…",
|
||||||
|
"onboarding.profile.indexable": "Gehitu argitalpen publikoak bilaketa-emaitzetan",
|
||||||
|
"onboarding.profile.lead": "Geroagoago bete daiteke konfigurazioan, non pertsonalizatzeko aukera gehiago dauden.",
|
||||||
|
"onboarding.profile.note": "Biografia",
|
||||||
|
"onboarding.profile.note_hint": "Beste pertsona batzuk @aipa ditzakezu edo #traolak erabili…",
|
||||||
|
"onboarding.profile.save_and_continue": "Gorde eta jarraitu",
|
||||||
|
"onboarding.profile.title": "Profilaren konfigurazioa",
|
||||||
|
"onboarding.profile.upload_avatar": "Igo profilaren irudia",
|
||||||
|
"onboarding.profile.upload_header": "Igo profilaren goiburua",
|
||||||
"onboarding.share.lead": "Esan jendeari nola aurki zaitzaketen Mastodonen!",
|
"onboarding.share.lead": "Esan jendeari nola aurki zaitzaketen Mastodonen!",
|
||||||
"onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}",
|
"onboarding.share.message": "{username} naiz #Mastodon-en! Jarrai nazazu hemen: {url}",
|
||||||
"onboarding.share.next_steps": "Hurrengo urrats posibleak:",
|
"onboarding.share.next_steps": "Hurrengo urrats posibleak:",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "نتایج جستوجو",
|
"emoji_button.search_results": "نتایج جستوجو",
|
||||||
"emoji_button.symbols": "نمادها",
|
"emoji_button.symbols": "نمادها",
|
||||||
"emoji_button.travel": "سفر و مکان",
|
"emoji_button.travel": "سفر و مکان",
|
||||||
|
"empty_column.account_hides_collections": "کاربر خواسته که این اطّلاعات در دسترس نباشند",
|
||||||
"empty_column.account_suspended": "حساب معلق شد",
|
"empty_column.account_suspended": "حساب معلق شد",
|
||||||
"empty_column.account_timeline": "هیچ فرستهای اینجا نیست!",
|
"empty_column.account_timeline": "هیچ فرستهای اینجا نیست!",
|
||||||
"empty_column.account_unavailable": "نمایهٔ موجود نیست",
|
"empty_column.account_unavailable": "نمایهٔ موجود نیست",
|
||||||
|
@ -358,13 +359,13 @@
|
||||||
"keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده",
|
"keyboard_shortcuts.profile": "گشودن نمایهٔ نویسنده",
|
||||||
"keyboard_shortcuts.reply": "پاسخ به فرسته",
|
"keyboard_shortcuts.reply": "پاسخ به فرسته",
|
||||||
"keyboard_shortcuts.requests": "گشودن سیاههٔ درخواستهای پیگیری",
|
"keyboard_shortcuts.requests": "گشودن سیاههٔ درخواستهای پیگیری",
|
||||||
"keyboard_shortcuts.search": "تمرکز روی جستوجو",
|
"keyboard_shortcuts.search": "تمرکز روی نوار جستوجو",
|
||||||
"keyboard_shortcuts.spoilers": "نمایش/نهفتن زمینهٔ هشدار محتوا",
|
"keyboard_shortcuts.spoilers": "نمایش/نهفتن زمینهٔ هشدار محتوا",
|
||||||
"keyboard_shortcuts.start": "گشودن ستون «آغاز کنید»",
|
"keyboard_shortcuts.start": "گشودن ستون «آغاز کنید»",
|
||||||
"keyboard_shortcuts.toggle_hidden": "نمایش/نهفتن نوشتهٔ پشت هشدار محتوا",
|
"keyboard_shortcuts.toggle_hidden": "نمایش/نهفتن نوشتهٔ پشت هشدار محتوا",
|
||||||
"keyboard_shortcuts.toggle_sensitivity": "نمایش/نهفتن رسانه",
|
"keyboard_shortcuts.toggle_sensitivity": "نمایش/نهفتن رسانه",
|
||||||
"keyboard_shortcuts.toot": "شروع یک فرستهٔ جدید",
|
"keyboard_shortcuts.toot": "شروع یک فرستهٔ جدید",
|
||||||
"keyboard_shortcuts.unfocus": "برداشتن تمرکز از نوشتن/جستوجو",
|
"keyboard_shortcuts.unfocus": "برداشتن تمرکز از ناحیهٔ نوشتن یا جستوجو",
|
||||||
"keyboard_shortcuts.up": "بالا بردن در سیاهه",
|
"keyboard_shortcuts.up": "بالا بردن در سیاهه",
|
||||||
"lightbox.close": "بستن",
|
"lightbox.close": "بستن",
|
||||||
"lightbox.compress": "فشردهسازی جعبهٔ نمایش تصویر",
|
"lightbox.compress": "فشردهسازی جعبهٔ نمایش تصویر",
|
||||||
|
@ -389,7 +390,7 @@
|
||||||
"lists.search": "جستوجو بین کسانی که پیگرفتهاید",
|
"lists.search": "جستوجو بین کسانی که پیگرفتهاید",
|
||||||
"lists.subheading": "سیاهههایتان",
|
"lists.subheading": "سیاهههایتان",
|
||||||
"load_pending": "{count, plural, one {# مورد جدید} other {# مورد جدید}}",
|
"load_pending": "{count, plural, one {# مورد جدید} other {# مورد جدید}}",
|
||||||
"loading_indicator.label": "بار کردن…",
|
"loading_indicator.label": "در حال بارگذاری…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {نهفتن تصویر} other {نهفتن تصاویر}}",
|
"media_gallery.toggle_visible": "{number, plural, one {نهفتن تصویر} other {نهفتن تصاویر}}",
|
||||||
"moved_to_account_banner.text": "حسابتان {disabledAccount} اکنون از کار افتاده؛ چرا که به {movedToAccount} منتقل شدید.",
|
"moved_to_account_banner.text": "حسابتان {disabledAccount} اکنون از کار افتاده؛ چرا که به {movedToAccount} منتقل شدید.",
|
||||||
"mute_modal.duration": "مدت زمان",
|
"mute_modal.duration": "مدت زمان",
|
||||||
|
@ -478,6 +479,13 @@
|
||||||
"onboarding.follows.empty": "متأسفانه هماکنون نتیجهای قابل نمایش نیست. میتوانید استفاده از جستوجو یا مرور صفحهٔ کاوش را برای یافتن افرادی برای پیگیری آزموده یا دوباره تلاش کنید.",
|
"onboarding.follows.empty": "متأسفانه هماکنون نتیجهای قابل نمایش نیست. میتوانید استفاده از جستوجو یا مرور صفحهٔ کاوش را برای یافتن افرادی برای پیگیری آزموده یا دوباره تلاش کنید.",
|
||||||
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
||||||
"onboarding.follows.title": "Popular on Mastodon",
|
"onboarding.follows.title": "Popular on Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "معرفی نمایه و فرستهها در الگوریتمهای کشف",
|
||||||
|
"onboarding.profile.display_name": "نام نمایشی",
|
||||||
|
"onboarding.profile.display_name_hint": "نام کامل یا نام باحالتان…",
|
||||||
|
"onboarding.profile.note": "درباره شما",
|
||||||
|
"onboarding.profile.note_hint": "میتوانید افراد دیگر را @نامبردن یا #برچسب بزنید…",
|
||||||
|
"onboarding.profile.save_and_continue": "ذخیره کن و ادامه بده",
|
||||||
|
"onboarding.profile.title": "تنظیم نمایه",
|
||||||
"onboarding.share.lead": "بگذارید افراد بدانند چگونه میتوانند در ماستادون بیابندتان!",
|
"onboarding.share.lead": "بگذارید افراد بدانند چگونه میتوانند در ماستادون بیابندتان!",
|
||||||
"onboarding.share.message": "من {username} روی #ماستودون هستم! مرا در {url} پیبگیرید",
|
"onboarding.share.message": "من {username} روی #ماستودون هستم! مرا در {url} پیبگیرید",
|
||||||
"onboarding.share.next_steps": "گامهای ممکن بعدی:",
|
"onboarding.share.next_steps": "گامهای ممکن بعدی:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Estetty",
|
"account.blocked": "Estetty",
|
||||||
"account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella",
|
"account.browse_more_on_origin_server": "Selaile lisää alkuperäisellä palvelimella",
|
||||||
"account.cancel_follow_request": "Peruuta seurantapyyntö",
|
"account.cancel_follow_request": "Peruuta seurantapyyntö",
|
||||||
|
"account.copy": "Kopioi profiilin linkki",
|
||||||
"account.direct": "Mainitse @{name} yksityisesti",
|
"account.direct": "Mainitse @{name} yksityisesti",
|
||||||
"account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} julkaisee",
|
"account.disable_notifications": "Lopeta ilmoittamasta minulle, kun @{name} julkaisee",
|
||||||
"account.domain_blocked": "Verkkotunnus estetty",
|
"account.domain_blocked": "Verkkotunnus estetty",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Merkitse luetuksi",
|
"conversation.mark_as_read": "Merkitse luetuksi",
|
||||||
"conversation.open": "Näytä keskustelu",
|
"conversation.open": "Näytä keskustelu",
|
||||||
"conversation.with": "{names} kanssa",
|
"conversation.with": "{names} kanssa",
|
||||||
|
"copy_icon_button.copied": "Kopioitu leikepöydälle",
|
||||||
"copypaste.copied": "Kopioitu",
|
"copypaste.copied": "Kopioitu",
|
||||||
"copypaste.copy_to_clipboard": "Kopioi leikepöydälle",
|
"copypaste.copy_to_clipboard": "Kopioi leikepöydälle",
|
||||||
"directory.federated": "Koko tunnettu fediversumi",
|
"directory.federated": "Koko tunnettu fediversumi",
|
||||||
|
@ -222,6 +224,7 @@
|
||||||
"emoji_button.search_results": "Hakutulokset",
|
"emoji_button.search_results": "Hakutulokset",
|
||||||
"emoji_button.symbols": "Symbolit",
|
"emoji_button.symbols": "Symbolit",
|
||||||
"emoji_button.travel": "Matkailu ja paikat",
|
"emoji_button.travel": "Matkailu ja paikat",
|
||||||
|
"empty_column.account_hides_collections": "Käyttäjä on päättänyt olla julkaisematta näitä tietoja",
|
||||||
"empty_column.account_suspended": "Tili jäädytetty",
|
"empty_column.account_suspended": "Tili jäädytetty",
|
||||||
"empty_column.account_timeline": "Ei viestejä täällä.",
|
"empty_column.account_timeline": "Ei viestejä täällä.",
|
||||||
"empty_column.account_unavailable": "Profiilia ei löydy",
|
"empty_column.account_unavailable": "Profiilia ei löydy",
|
||||||
|
@ -389,7 +392,7 @@
|
||||||
"lists.search": "Etsi seuraamistasi henkilöistä",
|
"lists.search": "Etsi seuraamistasi henkilöistä",
|
||||||
"lists.subheading": "Omat listasi",
|
"lists.subheading": "Omat listasi",
|
||||||
"load_pending": "{count, plural, one {# uusi kohde} other {# uutta kohdetta}}",
|
"load_pending": "{count, plural, one {# uusi kohde} other {# uutta kohdetta}}",
|
||||||
"loading_indicator.label": "Ladataan...",
|
"loading_indicator.label": "Ladataan…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Piilota kuva} other {Piilota kuvat}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Piilota kuva} other {Piilota kuvat}}",
|
||||||
"moved_to_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä, koska teit siirron tiliin {movedToAccount}.",
|
"moved_to_account_banner.text": "Tilisi {disabledAccount} on tällä hetkellä poissa käytöstä, koska teit siirron tiliin {movedToAccount}.",
|
||||||
"mute_modal.duration": "Kesto",
|
"mute_modal.duration": "Kesto",
|
||||||
|
@ -478,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Valitettavasti tuloksia ei voida näyttää juuri nyt. Voit kokeilla hakua tai selata tutustumissivua löytääksesi seurattavaa tai yrittää myöhemmin uudelleen.",
|
"onboarding.follows.empty": "Valitettavasti tuloksia ei voida näyttää juuri nyt. Voit kokeilla hakua tai selata tutustumissivua löytääksesi seurattavaa tai yrittää myöhemmin uudelleen.",
|
||||||
"onboarding.follows.lead": "Kokoat oman kotisyötteesi itse. Mitä enemmän ihmisiä seuraat, sitä aktiivisempi ja kiinnostavampi syöte on. Nämä profiilit voivat olla alkuun hyvä lähtökohta — voit aina lopettaa niiden seuraamisen myöhemmin!",
|
"onboarding.follows.lead": "Kokoat oman kotisyötteesi itse. Mitä enemmän ihmisiä seuraat, sitä aktiivisempi ja kiinnostavampi syöte on. Nämä profiilit voivat olla alkuun hyvä lähtökohta — voit aina lopettaa niiden seuraamisen myöhemmin!",
|
||||||
"onboarding.follows.title": "Mukauta kotisyötettäsi",
|
"onboarding.follows.title": "Mukauta kotisyötettäsi",
|
||||||
|
"onboarding.profile.discoverable": "Pidä profiilia ja julkaisuja esillä löytämisalgoritmeissa",
|
||||||
|
"onboarding.profile.display_name": "Näyttönimi",
|
||||||
|
"onboarding.profile.display_name_hint": "Koko nimesi tai lempinimesi…",
|
||||||
|
"onboarding.profile.indexable": "Sisällytä julkiset julkaisut hakutuloksiin",
|
||||||
|
"onboarding.profile.lead": "Voit viimeistellä tämän milloin tahansa asetuksissa, jossa on saatavilla vielä enemmän mukautusvalintoja.",
|
||||||
|
"onboarding.profile.note": "Elämäkerta",
|
||||||
|
"onboarding.profile.note_hint": "Voit @mainita muita käyttäjiä tai #aihetunnisteita…",
|
||||||
|
"onboarding.profile.save_and_continue": "Tallenna ja jatka",
|
||||||
|
"onboarding.profile.title": "Profiilin määritys",
|
||||||
|
"onboarding.profile.upload_avatar": "Lataa profiilikuva",
|
||||||
|
"onboarding.profile.upload_header": "Lataa profiilin otsakekuva",
|
||||||
"onboarding.share.lead": "Kerro ihmisille, kuinka he voivat löytää sinut Mastodonista!",
|
"onboarding.share.lead": "Kerro ihmisille, kuinka he voivat löytää sinut Mastodonista!",
|
||||||
"onboarding.share.message": "Olen {username} #Mastodonissa! Seuraa minua osoitteessa {url}",
|
"onboarding.share.message": "Olen {username} #Mastodonissa! Seuraa minua osoitteessa {url}",
|
||||||
"onboarding.share.next_steps": "Mahdolliset seuraavat vaiheet:",
|
"onboarding.share.next_steps": "Mahdolliset seuraavat vaiheet:",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "Leitiúrslit",
|
"emoji_button.search_results": "Leitiúrslit",
|
||||||
"emoji_button.symbols": "Ímyndir",
|
"emoji_button.symbols": "Ímyndir",
|
||||||
"emoji_button.travel": "Ferðing og støð",
|
"emoji_button.travel": "Ferðing og støð",
|
||||||
|
"empty_column.account_hides_collections": "Hesin brúkarin hevur valt, at hesar upplýsingarnar ikki skulu vera tøkar",
|
||||||
"empty_column.account_suspended": "Kontan gjørd óvirkin",
|
"empty_column.account_suspended": "Kontan gjørd óvirkin",
|
||||||
"empty_column.account_timeline": "Einki uppslag her!",
|
"empty_column.account_timeline": "Einki uppslag her!",
|
||||||
"empty_column.account_unavailable": "Vangin er ikki tøkur",
|
"empty_column.account_unavailable": "Vangin er ikki tøkur",
|
||||||
|
@ -389,7 +390,6 @@
|
||||||
"lists.search": "Leita millum fólk, sum tú fylgir",
|
"lists.search": "Leita millum fólk, sum tú fylgir",
|
||||||
"lists.subheading": "Tínir listar",
|
"lists.subheading": "Tínir listar",
|
||||||
"load_pending": "{count, plural, one {# nýtt evni} other {# nýggj evni}}",
|
"load_pending": "{count, plural, one {# nýtt evni} other {# nýggj evni}}",
|
||||||
"loading_indicator.label": "Innlesi...",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Fjal mynd} other {Fjal myndir}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Fjal mynd} other {Fjal myndir}}",
|
||||||
"moved_to_account_banner.text": "Konta tín {disabledAccount} er í løtuni óvirkin, tí tú flutti til {movedToAccount}.",
|
"moved_to_account_banner.text": "Konta tín {disabledAccount} er í løtuni óvirkin, tí tú flutti til {movedToAccount}.",
|
||||||
"mute_modal.duration": "Tíðarbil",
|
"mute_modal.duration": "Tíðarbil",
|
||||||
|
|
|
@ -479,6 +479,9 @@
|
||||||
"onboarding.follows.empty": "Malheureusement, aucun résultat ne peut être affiché pour le moment. Vous pouvez essayer de rechercher ou de parcourir la page \"Explorer\" pour trouver des personnes à suivre, ou réessayer plus tard.",
|
"onboarding.follows.empty": "Malheureusement, aucun résultat ne peut être affiché pour le moment. Vous pouvez essayer de rechercher ou de parcourir la page \"Explorer\" pour trouver des personnes à suivre, ou réessayer plus tard.",
|
||||||
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
||||||
"onboarding.follows.title": "Popular on Mastodon",
|
"onboarding.follows.title": "Popular on Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Autoriser des algorithmes de découverte à mettre en avant votre profil et vos messages",
|
||||||
|
"onboarding.profile.save_and_continue": "Enregistrer et continuer",
|
||||||
|
"onboarding.profile.upload_avatar": "Importer une photo de profil",
|
||||||
"onboarding.share.lead": "Faites savoir aux gens comment vous trouver sur Mastodon!",
|
"onboarding.share.lead": "Faites savoir aux gens comment vous trouver sur Mastodon!",
|
||||||
"onboarding.share.message": "Je suis {username} sur #Mastodon! Suivez-moi sur {url}",
|
"onboarding.share.message": "Je suis {username} sur #Mastodon! Suivez-moi sur {url}",
|
||||||
"onboarding.share.next_steps": "Étapes suivantes possibles:",
|
"onboarding.share.next_steps": "Étapes suivantes possibles:",
|
||||||
|
|
|
@ -107,7 +107,7 @@
|
||||||
"closed_registrations_modal.preamble": "Mastodon est décentralisé : peu importe où vous créez votre compte, vous serez en mesure de suivre et d'interagir avec quiconque sur ce serveur. Vous pouvez même l'héberger !",
|
"closed_registrations_modal.preamble": "Mastodon est décentralisé : peu importe où vous créez votre compte, vous serez en mesure de suivre et d'interagir avec quiconque sur ce serveur. Vous pouvez même l'héberger !",
|
||||||
"closed_registrations_modal.title": "Inscription sur Mastodon",
|
"closed_registrations_modal.title": "Inscription sur Mastodon",
|
||||||
"column.about": "À propos",
|
"column.about": "À propos",
|
||||||
"column.blocks": "Comptes bloqués",
|
"column.blocks": "Utilisateurs bloqués",
|
||||||
"column.bookmarks": "Marque-pages",
|
"column.bookmarks": "Marque-pages",
|
||||||
"column.community": "Fil public local",
|
"column.community": "Fil public local",
|
||||||
"column.direct": "Mentions privées",
|
"column.direct": "Mentions privées",
|
||||||
|
@ -479,6 +479,9 @@
|
||||||
"onboarding.follows.empty": "Malheureusement, aucun résultat ne peut être affiché pour le moment. Vous pouvez essayer d'utiliser la recherche ou parcourir la page de découverte pour trouver des personnes à suivre, ou réessayez plus tard.",
|
"onboarding.follows.empty": "Malheureusement, aucun résultat ne peut être affiché pour le moment. Vous pouvez essayer d'utiliser la recherche ou parcourir la page de découverte pour trouver des personnes à suivre, ou réessayez plus tard.",
|
||||||
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
||||||
"onboarding.follows.title": "Personnaliser votre flux principal",
|
"onboarding.follows.title": "Personnaliser votre flux principal",
|
||||||
|
"onboarding.profile.discoverable": "Autoriser des algorithmes de découverte à mettre en avant votre profil et vos messages",
|
||||||
|
"onboarding.profile.save_and_continue": "Enregistrer et continuer",
|
||||||
|
"onboarding.profile.upload_avatar": "Importer une photo de profil",
|
||||||
"onboarding.share.lead": "Faites savoir aux gens comment ils peuvent vous trouver sur Mastodon!",
|
"onboarding.share.lead": "Faites savoir aux gens comment ils peuvent vous trouver sur Mastodon!",
|
||||||
"onboarding.share.message": "Je suis {username} sur #Mastodon ! Suivez-moi sur {url}",
|
"onboarding.share.message": "Je suis {username} sur #Mastodon ! Suivez-moi sur {url}",
|
||||||
"onboarding.share.next_steps": "Étapes suivantes possibles :",
|
"onboarding.share.next_steps": "Étapes suivantes possibles :",
|
||||||
|
|
|
@ -222,6 +222,7 @@
|
||||||
"emoji_button.search_results": "Sykresultaten",
|
"emoji_button.search_results": "Sykresultaten",
|
||||||
"emoji_button.symbols": "Symboalen",
|
"emoji_button.symbols": "Symboalen",
|
||||||
"emoji_button.travel": "Reizgje en lokaasjes",
|
"emoji_button.travel": "Reizgje en lokaasjes",
|
||||||
|
"empty_column.account_hides_collections": "Dizze brûker hat derfoar keazen dizze ynformaasje net beskikber te meitsjen",
|
||||||
"empty_column.account_suspended": "Account beskoattele",
|
"empty_column.account_suspended": "Account beskoattele",
|
||||||
"empty_column.account_timeline": "Hjir binne gjin berjochten!",
|
"empty_column.account_timeline": "Hjir binne gjin berjochten!",
|
||||||
"empty_column.account_unavailable": "Profyl net beskikber",
|
"empty_column.account_unavailable": "Profyl net beskikber",
|
||||||
|
@ -389,7 +390,6 @@
|
||||||
"lists.search": "Sykje nei minsken dy’t jo folgje",
|
"lists.search": "Sykje nei minsken dy’t jo folgje",
|
||||||
"lists.subheading": "Jo listen",
|
"lists.subheading": "Jo listen",
|
||||||
"load_pending": "{count, plural, one {# nij item} other {# nije items}}",
|
"load_pending": "{count, plural, one {# nij item} other {# nije items}}",
|
||||||
"loading_indicator.label": "Lade…",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {ôfbylding ferstopje} other {ôfbyldingen ferstopje}}",
|
"media_gallery.toggle_visible": "{number, plural, one {ôfbylding ferstopje} other {ôfbyldingen ferstopje}}",
|
||||||
"moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.",
|
"moved_to_account_banner.text": "Omdat jo nei {movedToAccount} ferhuze binne is jo account {disabledAccount} op dit stuit útskeakele.",
|
||||||
"mute_modal.duration": "Doer",
|
"mute_modal.duration": "Doer",
|
||||||
|
|
|
@ -316,7 +316,6 @@
|
||||||
"lists.replies_policy.title": "Taispeáin freagraí:",
|
"lists.replies_policy.title": "Taispeáin freagraí:",
|
||||||
"lists.search": "Cuardaigh i measc daoine atá á leanúint agat",
|
"lists.search": "Cuardaigh i measc daoine atá á leanúint agat",
|
||||||
"lists.subheading": "Do liostaí",
|
"lists.subheading": "Do liostaí",
|
||||||
"loading_indicator.label": "Ag lódáil...",
|
|
||||||
"mute_modal.duration": "Tréimhse",
|
"mute_modal.duration": "Tréimhse",
|
||||||
"mute_modal.hide_notifications": "Cuir póstalacha ón t-úsáideoir seo i bhfolach?",
|
"mute_modal.hide_notifications": "Cuir póstalacha ón t-úsáideoir seo i bhfolach?",
|
||||||
"mute_modal.indefinite": "Gan téarma",
|
"mute_modal.indefinite": "Gan téarma",
|
||||||
|
|
|
@ -389,7 +389,6 @@
|
||||||
"lists.search": "Lorg am measg nan daoine a leanas tu",
|
"lists.search": "Lorg am measg nan daoine a leanas tu",
|
||||||
"lists.subheading": "Na liostaichean agad",
|
"lists.subheading": "Na liostaichean agad",
|
||||||
"load_pending": "{count, plural, one {# nì ùr} two {# nì ùr} few {# nithean ùra} other {# nì ùr}}",
|
"load_pending": "{count, plural, one {# nì ùr} two {# nì ùr} few {# nithean ùra} other {# nì ùr}}",
|
||||||
"loading_indicator.label": "’Ga luchdadh…",
|
|
||||||
"media_gallery.toggle_visible": "{number, plural, 1 {Falaich an dealbh} one {Falaich na dealbhan} two {Falaich na dealbhan} few {Falaich na dealbhan} other {Falaich na dealbhan}}",
|
"media_gallery.toggle_visible": "{number, plural, 1 {Falaich an dealbh} one {Falaich na dealbhan} two {Falaich na dealbhan} few {Falaich na dealbhan} other {Falaich na dealbhan}}",
|
||||||
"moved_to_account_banner.text": "Tha an cunntas {disabledAccount} agad à comas on a rinn thu imrich gu {movedToAccount}.",
|
"moved_to_account_banner.text": "Tha an cunntas {disabledAccount} agad à comas on a rinn thu imrich gu {movedToAccount}.",
|
||||||
"mute_modal.duration": "Faide",
|
"mute_modal.duration": "Faide",
|
||||||
|
|
|
@ -390,7 +390,7 @@
|
||||||
"lists.search": "Procurar entre as persoas que segues",
|
"lists.search": "Procurar entre as persoas que segues",
|
||||||
"lists.subheading": "As túas listaxes",
|
"lists.subheading": "As túas listaxes",
|
||||||
"load_pending": "{count, plural, one {# novo elemento} other {# novos elementos}}",
|
"load_pending": "{count, plural, one {# novo elemento} other {# novos elementos}}",
|
||||||
"loading_indicator.label": "Estase a cargar...",
|
"loading_indicator.label": "Estase a cargar…",
|
||||||
"media_gallery.toggle_visible": "Agochar {number, plural, one {imaxe} other {imaxes}}",
|
"media_gallery.toggle_visible": "Agochar {number, plural, one {imaxe} other {imaxes}}",
|
||||||
"moved_to_account_banner.text": "A túa conta {disabledAccount} está actualmente desactivada porque movéchela a {movedToAccount}.",
|
"moved_to_account_banner.text": "A túa conta {disabledAccount} está actualmente desactivada porque movéchela a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Duración",
|
"mute_modal.duration": "Duración",
|
||||||
|
@ -479,6 +479,17 @@
|
||||||
"onboarding.follows.empty": "Desgraciadamente agora mesmo non hai nada que mostrar. Podes intentalo coa busca ou na páxina descubrir para atopar persoas ás que seguir, ou intentalo máis tarde.",
|
"onboarding.follows.empty": "Desgraciadamente agora mesmo non hai nada que mostrar. Podes intentalo coa busca ou na páxina descubrir para atopar persoas ás que seguir, ou intentalo máis tarde.",
|
||||||
"onboarding.follows.lead": "Podes facer que a túa cronoloxía de inicio sexa como ti a queres. Canta máis xente sigas máis interesante será. Estes perfís poderían axudarche a comezar —sempre poderás deixar de seguilos despois!",
|
"onboarding.follows.lead": "Podes facer que a túa cronoloxía de inicio sexa como ti a queres. Canta máis xente sigas máis interesante será. Estes perfís poderían axudarche a comezar —sempre poderás deixar de seguilos despois!",
|
||||||
"onboarding.follows.title": "Popular en Mastodon",
|
"onboarding.follows.title": "Popular en Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Perfil destacado e publicacións nos algoritmos de descubrimento",
|
||||||
|
"onboarding.profile.display_name": "Nome público",
|
||||||
|
"onboarding.profile.display_name_hint": "O teu nome completo ou un nome divertido…",
|
||||||
|
"onboarding.profile.indexable": "Incluír publicacións públicas nos resultados das buscas",
|
||||||
|
"onboarding.profile.lead": "Sempre poderás incluír esta información mais tarde nos axustes, onde terás máis opcións dispoñibles.",
|
||||||
|
"onboarding.profile.note": "Acerca de ti",
|
||||||
|
"onboarding.profile.note_hint": "Podes @mencionar a outras persoas ou usar #cancelos…",
|
||||||
|
"onboarding.profile.save_and_continue": "Gardar e continuar",
|
||||||
|
"onboarding.profile.title": "Configuración do perfil",
|
||||||
|
"onboarding.profile.upload_avatar": "Subir imaxe do perfil",
|
||||||
|
"onboarding.profile.upload_header": "Subir cabeceira para o perfil",
|
||||||
"onboarding.share.lead": "Fai que as persoas saiban como atoparte en Mastodon!",
|
"onboarding.share.lead": "Fai que as persoas saiban como atoparte en Mastodon!",
|
||||||
"onboarding.share.message": "Son {username} en #Mastodon! Ségueme en {url}",
|
"onboarding.share.message": "Son {username} en #Mastodon! Ségueme en {url}",
|
||||||
"onboarding.share.next_steps": "Seguintes pasos:",
|
"onboarding.share.next_steps": "Seguintes pasos:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "לחסום",
|
"account.blocked": "לחסום",
|
||||||
"account.browse_more_on_origin_server": "ראה יותר בפרופיל המקורי",
|
"account.browse_more_on_origin_server": "ראה יותר בפרופיל המקורי",
|
||||||
"account.cancel_follow_request": "משיכת בקשת מעקב",
|
"account.cancel_follow_request": "משיכת בקשת מעקב",
|
||||||
|
"account.copy": "להעתיק קישור לפרופיל",
|
||||||
"account.direct": "הודעה פרטית אל @{name}",
|
"account.direct": "הודעה פרטית אל @{name}",
|
||||||
"account.disable_notifications": "הפסק לשלוח לי התראות כש@{name} מפרסמים",
|
"account.disable_notifications": "הפסק לשלוח לי התראות כש@{name} מפרסמים",
|
||||||
"account.domain_blocked": "הדומיין חסום",
|
"account.domain_blocked": "הדומיין חסום",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "סמן כנקרא",
|
"conversation.mark_as_read": "סמן כנקרא",
|
||||||
"conversation.open": "צפו בשיחה",
|
"conversation.open": "צפו בשיחה",
|
||||||
"conversation.with": "עם {names}",
|
"conversation.with": "עם {names}",
|
||||||
|
"copy_icon_button.copied": "הועתק ללוח",
|
||||||
"copypaste.copied": "הועתק",
|
"copypaste.copied": "הועתק",
|
||||||
"copypaste.copy_to_clipboard": "העתקה ללוח הגזירים",
|
"copypaste.copy_to_clipboard": "העתקה ללוח הגזירים",
|
||||||
"directory.federated": "מהפדרציה הידועה",
|
"directory.federated": "מהפדרציה הידועה",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "חיפוש בין אנשים שאני עוקב\\ת אחריהם",
|
"lists.search": "חיפוש בין אנשים שאני עוקב\\ת אחריהם",
|
||||||
"lists.subheading": "הרשימות שלך",
|
"lists.subheading": "הרשימות שלך",
|
||||||
"load_pending": "{count, plural, one {# פריט חדש} other {# פריטים חדשים}}",
|
"load_pending": "{count, plural, one {# פריט חדש} other {# פריטים חדשים}}",
|
||||||
"loading_indicator.label": "טוען...",
|
"loading_indicator.label": "בטעינה…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {להסתיר תמונה} two {להסתיר תמונותיים} many {להסתיר תמונות} other {להסתיר תמונות}}",
|
"media_gallery.toggle_visible": "{number, plural, one {להסתיר תמונה} two {להסתיר תמונותיים} many {להסתיר תמונות} other {להסתיר תמונות}}",
|
||||||
"moved_to_account_banner.text": "חשבונך {disabledAccount} אינו פעיל כרגע עקב מעבר ל{movedToAccount}.",
|
"moved_to_account_banner.text": "חשבונך {disabledAccount} אינו פעיל כרגע עקב מעבר ל{movedToAccount}.",
|
||||||
"mute_modal.duration": "משך הזמן",
|
"mute_modal.duration": "משך הזמן",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "למצער, תוצאות לחיפושך אינן בנמצא. ניתן להשתמש בחיפוש או בדף החקירות לשם מציאת אנשים ולעקבם. אפשר גם לנסות שוב אחר כך.",
|
"onboarding.follows.empty": "למצער, תוצאות לחיפושך אינן בנמצא. ניתן להשתמש בחיפוש או בדף החקירות לשם מציאת אנשים ולעקבם. אפשר גם לנסות שוב אחר כך.",
|
||||||
"onboarding.follows.lead": "אתם אוצרים את הזרם הבייתי שלכם. ככל שתעקבו אחרי יותר אנשים, הוא יהיה עשיר ופעיל יותר. הנה כמה פרופילים להתחיל בהם - תמיד ניתן להפסיק מעקב אחריהם בהמשך!",
|
"onboarding.follows.lead": "אתם אוצרים את הזרם הבייתי שלכם. ככל שתעקבו אחרי יותר אנשים, הוא יהיה עשיר ופעיל יותר. הנה כמה פרופילים להתחיל בהם - תמיד ניתן להפסיק מעקב אחריהם בהמשך!",
|
||||||
"onboarding.follows.title": "פופולארי על מסטודון",
|
"onboarding.follows.title": "פופולארי על מסטודון",
|
||||||
|
"onboarding.profile.discoverable": "הצגת פרופיל והודעות במסך התגליות",
|
||||||
|
"onboarding.profile.display_name": "שם להצגה",
|
||||||
|
"onboarding.profile.display_name_hint": "שמך המלא או כינוי הכיף שלך…",
|
||||||
|
"onboarding.profile.indexable": "הכללת הודעות ציבוריות בתוצאות החיפוש",
|
||||||
|
"onboarding.profile.lead": "תמיד ניתן להשלים זאת אחר כך בהגדרות, שם יש אפילו עוד אפשרויות להתאמה אישית.",
|
||||||
|
"onboarding.profile.note": "אודות",
|
||||||
|
"onboarding.profile.note_hint": "ניתן @לאזכר משתמשים אחרים או #תגיות…",
|
||||||
|
"onboarding.profile.save_and_continue": "לשמור ולהמשיך",
|
||||||
|
"onboarding.profile.title": "הגדרת פרופיל",
|
||||||
|
"onboarding.profile.upload_avatar": "העלאת תמונת פרופיל",
|
||||||
|
"onboarding.profile.upload_header": "העלאת כותרת פרופיל",
|
||||||
"onboarding.share.lead": "כדאי להודיע לחברים היכן למצוא אותך במסטודון!",
|
"onboarding.share.lead": "כדאי להודיע לחברים היכן למצוא אותך במסטודון!",
|
||||||
"onboarding.share.message": "אני {username} ברשת #מסטודון! בואו לעקוב אחרי בכתובת {url}",
|
"onboarding.share.message": "אני {username} ברשת #מסטודון! בואו לעקוב אחרי בכתובת {url}",
|
||||||
"onboarding.share.next_steps": "לאיפה להמשיך מכאן:",
|
"onboarding.share.next_steps": "לאיפה להמשיך מכאן:",
|
||||||
|
@ -518,7 +531,7 @@
|
||||||
"privacy.private.short": "לעוקבים בלבד",
|
"privacy.private.short": "לעוקבים בלבד",
|
||||||
"privacy.public.long": "גלוי לכל",
|
"privacy.public.long": "גלוי לכל",
|
||||||
"privacy.public.short": "פומבי",
|
"privacy.public.short": "פומבי",
|
||||||
"privacy.unlisted.long": "גלוי לכל, אבל מוסתר מאמצעי גילוי",
|
"privacy.unlisted.long": "גלוי לכל, אבל מוסתר מאמצעי תגלית",
|
||||||
"privacy.unlisted.short": "לא רשום (לא לפיד הכללי)",
|
"privacy.unlisted.short": "לא רשום (לא לפיד הכללי)",
|
||||||
"privacy_policy.last_updated": "עודכן לאחרונה {date}",
|
"privacy_policy.last_updated": "עודכן לאחרונה {date}",
|
||||||
"privacy_policy.title": "מדיניות פרטיות",
|
"privacy_policy.title": "מדיניות פרטיות",
|
||||||
|
|
|
@ -360,7 +360,6 @@
|
||||||
"lists.replies_policy.none": "कोई नहीं",
|
"lists.replies_policy.none": "कोई नहीं",
|
||||||
"lists.replies_policy.title": "इसके जवाब दिखाएं:",
|
"lists.replies_policy.title": "इसके जवाब दिखाएं:",
|
||||||
"lists.subheading": "आपकी सूचियाँ",
|
"lists.subheading": "आपकी सूचियाँ",
|
||||||
"loading_indicator.label": "लोड हो रहा है...",
|
|
||||||
"mute_modal.duration": "अवधि",
|
"mute_modal.duration": "अवधि",
|
||||||
"mute_modal.hide_notifications": "इस सभ्य की ओरसे आनेवाली सूचनाए शांत करे",
|
"mute_modal.hide_notifications": "इस सभ्य की ओरसे आनेवाली सूचनाए शांत करे",
|
||||||
"mute_modal.indefinite": "अनिश्चितकालीन",
|
"mute_modal.indefinite": "अनिश्चितकालीन",
|
||||||
|
|
|
@ -306,7 +306,6 @@
|
||||||
"lists.replies_policy.none": "Nitko",
|
"lists.replies_policy.none": "Nitko",
|
||||||
"lists.search": "Traži među praćenim ljudima",
|
"lists.search": "Traži među praćenim ljudima",
|
||||||
"lists.subheading": "Vaše liste",
|
"lists.subheading": "Vaše liste",
|
||||||
"loading_indicator.label": "Učitavanje...",
|
|
||||||
"media_gallery.toggle_visible": "Sakrij {number, plural, one {sliku} other {slike}}",
|
"media_gallery.toggle_visible": "Sakrij {number, plural, one {sliku} other {slike}}",
|
||||||
"mute_modal.duration": "Trajanje",
|
"mute_modal.duration": "Trajanje",
|
||||||
"mute_modal.hide_notifications": "Sakrij obavijesti ovog korisnika?",
|
"mute_modal.hide_notifications": "Sakrij obavijesti ovog korisnika?",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Letiltva",
|
"account.blocked": "Letiltva",
|
||||||
"account.browse_more_on_origin_server": "További böngészés az eredeti profilon",
|
"account.browse_more_on_origin_server": "További böngészés az eredeti profilon",
|
||||||
"account.cancel_follow_request": "Követési kérés visszavonása",
|
"account.cancel_follow_request": "Követési kérés visszavonása",
|
||||||
|
"account.copy": "Hivatkozás másolása a profilba",
|
||||||
"account.direct": "@{name} személyes említése",
|
"account.direct": "@{name} személyes említése",
|
||||||
"account.disable_notifications": "Ne figyelmeztessen, ha @{name} bejegyzést tesz közzé",
|
"account.disable_notifications": "Ne figyelmeztessen, ha @{name} bejegyzést tesz közzé",
|
||||||
"account.domain_blocked": "Letiltott domain",
|
"account.domain_blocked": "Letiltott domain",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Megjelölés olvasottként",
|
"conversation.mark_as_read": "Megjelölés olvasottként",
|
||||||
"conversation.open": "Beszélgetés megtekintése",
|
"conversation.open": "Beszélgetés megtekintése",
|
||||||
"conversation.with": "Velük: {names}",
|
"conversation.with": "Velük: {names}",
|
||||||
|
"copy_icon_button.copied": "A szöveg a vágólapra másolva",
|
||||||
"copypaste.copied": "Másolva",
|
"copypaste.copied": "Másolva",
|
||||||
"copypaste.copy_to_clipboard": "Másolás vágólapra",
|
"copypaste.copy_to_clipboard": "Másolás vágólapra",
|
||||||
"directory.federated": "Az ismert fediverzumból",
|
"directory.federated": "Az ismert fediverzumból",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Keresés a követett személyek között",
|
"lists.search": "Keresés a követett személyek között",
|
||||||
"lists.subheading": "Saját listák",
|
"lists.subheading": "Saját listák",
|
||||||
"load_pending": "{count, plural, one {# új elem} other {# új elem}}",
|
"load_pending": "{count, plural, one {# új elem} other {# új elem}}",
|
||||||
"loading_indicator.label": "Betöltés...",
|
"loading_indicator.label": "Betöltés…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Kép elrejtése} other {Képek elrejtése}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Kép elrejtése} other {Képek elrejtése}}",
|
||||||
"moved_to_account_banner.text": "A(z) {disabledAccount} fiókod jelenleg le van tiltva, mert átköltöztél ide: {movedToAccount}.",
|
"moved_to_account_banner.text": "A(z) {disabledAccount} fiókod jelenleg le van tiltva, mert átköltöztél ide: {movedToAccount}.",
|
||||||
"mute_modal.duration": "Időtartam",
|
"mute_modal.duration": "Időtartam",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Sajnos jelenleg nem jeleníthető meg eredmény. Kipróbálhatod a keresést vagy böngészheted a felfedező oldalon a követni kívánt személyeket, vagy próbáld meg később.",
|
"onboarding.follows.empty": "Sajnos jelenleg nem jeleníthető meg eredmény. Kipróbálhatod a keresést vagy böngészheted a felfedező oldalon a követni kívánt személyeket, vagy próbáld meg később.",
|
||||||
"onboarding.follows.lead": "A saját hírfolyamod az elsődleges tapasztalás a Mastodonon. Minél több embert követsz, annál aktívabb és érdekesebb a dolog. Az induláshoz itt van néhány javaslat:",
|
"onboarding.follows.lead": "A saját hírfolyamod az elsődleges tapasztalás a Mastodonon. Minél több embert követsz, annál aktívabb és érdekesebb a dolog. Az induláshoz itt van néhány javaslat:",
|
||||||
"onboarding.follows.title": "Népszerű a Mastodonon",
|
"onboarding.follows.title": "Népszerű a Mastodonon",
|
||||||
|
"onboarding.profile.discoverable": "Profil és bejegyzések szerepeltetése a felfedezési algoritmusokban",
|
||||||
|
"onboarding.profile.display_name": "Megjelenített név",
|
||||||
|
"onboarding.profile.display_name_hint": "Teljes neved vagy vicces neved…",
|
||||||
|
"onboarding.profile.indexable": "Nyilvános bejegyzések szerepeltetése a keresési eredményekben",
|
||||||
|
"onboarding.profile.lead": "Ezt később bármikor befejezheted a beállításokban, ahol még több testreszabási lehetőség áll rendelkezésre.",
|
||||||
|
"onboarding.profile.note": "Bemutatkozás",
|
||||||
|
"onboarding.profile.note_hint": "Megemlíthetsz @másokat vagy #hashtag-eket…",
|
||||||
|
"onboarding.profile.save_and_continue": "Mentés és folytatás",
|
||||||
|
"onboarding.profile.title": "Profilbeállítás",
|
||||||
|
"onboarding.profile.upload_avatar": "Profilkép feltöltése",
|
||||||
|
"onboarding.profile.upload_header": "Profil fejléc feltöltése",
|
||||||
"onboarding.share.lead": "Tudassuk az emberekkel, hogyan találhatnak meg a Mastodonon!",
|
"onboarding.share.lead": "Tudassuk az emberekkel, hogyan találhatnak meg a Mastodonon!",
|
||||||
"onboarding.share.message": "{username} vagyok a #Mastodon hálózaton! Kövess itt: {url}.",
|
"onboarding.share.message": "{username} vagyok a #Mastodon hálózaton! Kövess itt: {url}.",
|
||||||
"onboarding.share.next_steps": "Lehetséges következő lépések:",
|
"onboarding.share.next_steps": "Lehetséges következő lépések:",
|
||||||
|
|
|
@ -314,7 +314,6 @@
|
||||||
"lists.search": "Փնտրել քո հետեւած մարդկանց մէջ",
|
"lists.search": "Փնտրել քո հետեւած մարդկանց մէջ",
|
||||||
"lists.subheading": "Քո ցանկերը",
|
"lists.subheading": "Քո ցանկերը",
|
||||||
"load_pending": "{count, plural, one {# նոր նիւթ} other {# նոր նիւթ}}",
|
"load_pending": "{count, plural, one {# նոր նիւթ} other {# նոր նիւթ}}",
|
||||||
"loading_indicator.label": "Բեռնւում է…",
|
|
||||||
"media_gallery.toggle_visible": "Ցուցադրել/թաքցնել",
|
"media_gallery.toggle_visible": "Ցուցադրել/թաքցնել",
|
||||||
"mute_modal.duration": "Տեւողութիւն",
|
"mute_modal.duration": "Տեւողութիւն",
|
||||||
"mute_modal.hide_notifications": "Թաքցնե՞լ ծանուցումներն այս օգտատիրոջից։",
|
"mute_modal.hide_notifications": "Թաքցնե՞լ ծանուցումներն այս օգտատիրոջից։",
|
||||||
|
|
|
@ -353,7 +353,6 @@
|
||||||
"lists.search": "Cari di antara orang yang Anda ikuti",
|
"lists.search": "Cari di antara orang yang Anda ikuti",
|
||||||
"lists.subheading": "Daftar Anda",
|
"lists.subheading": "Daftar Anda",
|
||||||
"load_pending": "{count, plural, other {# item baru}}",
|
"load_pending": "{count, plural, other {# item baru}}",
|
||||||
"loading_indicator.label": "Tunggu sebentar...",
|
|
||||||
"media_gallery.toggle_visible": "Tampil/Sembunyikan",
|
"media_gallery.toggle_visible": "Tampil/Sembunyikan",
|
||||||
"moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.",
|
"moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.",
|
||||||
"mute_modal.duration": "Durasi",
|
"mute_modal.duration": "Durasi",
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
{
|
{
|
||||||
"account.add_or_remove_from_list": "Tinye ma ọ bụ Wepu na ndepụta",
|
"account.add_or_remove_from_list": "Tinye ma ọ bụ Wepu na ndepụta",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
|
"account.badges.group": "Otù",
|
||||||
"account.cancel_follow_request": "Withdraw follow request",
|
"account.cancel_follow_request": "Withdraw follow request",
|
||||||
"account.follow": "Soro",
|
"account.follow": "Soro",
|
||||||
|
"account.followers": "Ndị na-eso",
|
||||||
|
"account.following": "Na-eso",
|
||||||
"account.follows_you": "Na-eso gị",
|
"account.follows_you": "Na-eso gị",
|
||||||
"account.mute": "Mee ogbi @{name}",
|
"account.mute": "Mee ogbi @{name}",
|
||||||
"account.unfollow": "Kwụsị iso",
|
"account.unfollow": "Kwụsị iso",
|
||||||
|
@ -11,16 +14,20 @@
|
||||||
"audio.hide": "Zoo ụda",
|
"audio.hide": "Zoo ụda",
|
||||||
"bundle_column_error.retry": "Nwaa ọzọ",
|
"bundle_column_error.retry": "Nwaa ọzọ",
|
||||||
"bundle_column_error.routing.title": "404",
|
"bundle_column_error.routing.title": "404",
|
||||||
|
"bundle_modal_error.close": "Mechie",
|
||||||
"bundle_modal_error.retry": "Nwaa ọzọ",
|
"bundle_modal_error.retry": "Nwaa ọzọ",
|
||||||
"column.about": "Maka",
|
"column.about": "Maka",
|
||||||
"column.blocks": "Ojiarụ egbochiri",
|
"column.blocks": "Ojiarụ egbochiri",
|
||||||
"column.bookmarks": "Ebenrụtụakā",
|
"column.bookmarks": "Ebenrụtụakā",
|
||||||
"column.home": "Be",
|
"column.home": "Be",
|
||||||
|
"column.lists": "Ndepụta",
|
||||||
"column.pins": "Pinned post",
|
"column.pins": "Pinned post",
|
||||||
|
"column_header.pin": "Gbado na profaịlụ gị",
|
||||||
"column_subheading.settings": "Mwube",
|
"column_subheading.settings": "Mwube",
|
||||||
"community.column_settings.media_only": "Media only",
|
"community.column_settings.media_only": "Media only",
|
||||||
"compose.language.change": "Gbanwee asụsụ",
|
"compose.language.change": "Gbanwee asụsụ",
|
||||||
"compose.language.search": "Chọọ asụsụ...",
|
"compose.language.search": "Chọọ asụsụ...",
|
||||||
|
"compose.published.open": "Mepe",
|
||||||
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
|
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
|
||||||
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
|
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
|
||||||
"compose_form.placeholder": "What is on your mind?",
|
"compose_form.placeholder": "What is on your mind?",
|
||||||
|
@ -32,7 +39,10 @@
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||||
"confirmations.delete_list.confirm": "Hichapụ",
|
"confirmations.delete_list.confirm": "Hichapụ",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "Hide entire domain",
|
||||||
|
"confirmations.edit.confirm": "Dezie",
|
||||||
|
"confirmations.mute.confirm": "Mee ogbi",
|
||||||
"confirmations.reply.confirm": "Zaa",
|
"confirmations.reply.confirm": "Zaa",
|
||||||
|
"confirmations.unfollow.confirm": "Kwụsị iso",
|
||||||
"conversation.delete": "Hichapụ nkata",
|
"conversation.delete": "Hichapụ nkata",
|
||||||
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
|
"dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.",
|
||||||
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
|
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
|
||||||
|
@ -76,8 +86,8 @@
|
||||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||||
"keyboard_shortcuts.up": "to move up in the list",
|
"keyboard_shortcuts.up": "to move up in the list",
|
||||||
"lists.delete": "Hichapụ ndepụta",
|
"lists.delete": "Hichapụ ndepụta",
|
||||||
|
"lists.edit": "Dezie ndepụta",
|
||||||
"lists.subheading": "Ndepụta gị",
|
"lists.subheading": "Ndepụta gị",
|
||||||
"loading_indicator.label": "Na-adọnye...",
|
|
||||||
"navigation_bar.about": "Maka",
|
"navigation_bar.about": "Maka",
|
||||||
"navigation_bar.bookmarks": "Ebenrụtụakā",
|
"navigation_bar.bookmarks": "Ebenrụtụakā",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "Hidden domains",
|
||||||
|
@ -100,20 +110,27 @@
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "Adjust status privacy",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "Direct",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "Followers-only",
|
||||||
|
"relative_time.full.just_now": "kịta",
|
||||||
"relative_time.just_now": "kịta",
|
"relative_time.just_now": "kịta",
|
||||||
"relative_time.today": "taa",
|
"relative_time.today": "taa",
|
||||||
"reply_indicator.cancel": "Kagbuo",
|
"reply_indicator.cancel": "Kagbuo",
|
||||||
"report.categories.other": "Ọzọ",
|
"report.categories.other": "Ọzọ",
|
||||||
|
"report.categories.spam": "Nzipụ Ozièlètrọniìk Nkeāchọghị",
|
||||||
|
"report.mute": "Mee ogbi",
|
||||||
"report.placeholder": "Type or paste additional comments",
|
"report.placeholder": "Type or paste additional comments",
|
||||||
"report.submit": "Submit report",
|
"report.submit": "Submit report",
|
||||||
"report.target": "Report {target}",
|
"report.target": "Report {target}",
|
||||||
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
|
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
|
||||||
|
"report_notification.categories.other": "Ọzọ",
|
||||||
|
"search.placeholder": "Chọọ",
|
||||||
"server_banner.active_users": "ojiarụ dị ìrè",
|
"server_banner.active_users": "ojiarụ dị ìrè",
|
||||||
|
"server_banner.learn_more": "Mụtakwuo",
|
||||||
"sign_in_banner.sign_in": "Sign in",
|
"sign_in_banner.sign_in": "Sign in",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.bookmark": "Kee ebenrụtụakā",
|
"status.bookmark": "Kee ebenrụtụakā",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Hichapụ",
|
"status.delete": "Hichapụ",
|
||||||
|
"status.edit": "Dezie",
|
||||||
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
|
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
|
||||||
"status.open": "Expand this status",
|
"status.open": "Expand this status",
|
||||||
"status.remove_bookmark": "Wepu ebenrụtụakā",
|
"status.remove_bookmark": "Wepu ebenrụtụakā",
|
||||||
|
|
|
@ -383,7 +383,6 @@
|
||||||
"lists.search": "Trovez inter personi quon vu sequas",
|
"lists.search": "Trovez inter personi quon vu sequas",
|
||||||
"lists.subheading": "Vua listi",
|
"lists.subheading": "Vua listi",
|
||||||
"load_pending": "{count, plural, one {# nova kozo} other {# nova kozi}}",
|
"load_pending": "{count, plural, one {# nova kozo} other {# nova kozi}}",
|
||||||
"loading_indicator.label": "Kargante...",
|
|
||||||
"media_gallery.toggle_visible": "Chanjar videbleso",
|
"media_gallery.toggle_visible": "Chanjar videbleso",
|
||||||
"moved_to_account_banner.text": "Vua konto {disabledAccount} es nune desaktiva pro ke vu movis a {movedToAccount}.",
|
"moved_to_account_banner.text": "Vua konto {disabledAccount} es nune desaktiva pro ke vu movis a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Durado",
|
"mute_modal.duration": "Durado",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Útilokaður",
|
"account.blocked": "Útilokaður",
|
||||||
"account.browse_more_on_origin_server": "Skoða nánari upplýsingar á notandasniðinu",
|
"account.browse_more_on_origin_server": "Skoða nánari upplýsingar á notandasniðinu",
|
||||||
"account.cancel_follow_request": "Taka fylgjendabeiðni til baka",
|
"account.cancel_follow_request": "Taka fylgjendabeiðni til baka",
|
||||||
|
"account.copy": "Afrita tengil í notandasnið",
|
||||||
"account.direct": "Einkaspjall við @{name}",
|
"account.direct": "Einkaspjall við @{name}",
|
||||||
"account.disable_notifications": "Hætta að láta mig vita þegar @{name} sendir inn",
|
"account.disable_notifications": "Hætta að láta mig vita þegar @{name} sendir inn",
|
||||||
"account.domain_blocked": "Lén útilokað",
|
"account.domain_blocked": "Lén útilokað",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Merkja sem lesið",
|
"conversation.mark_as_read": "Merkja sem lesið",
|
||||||
"conversation.open": "Skoða samtal",
|
"conversation.open": "Skoða samtal",
|
||||||
"conversation.with": "Við {names}",
|
"conversation.with": "Við {names}",
|
||||||
|
"copy_icon_button.copied": "Afritað á klippispjald",
|
||||||
"copypaste.copied": "Afritað",
|
"copypaste.copied": "Afritað",
|
||||||
"copypaste.copy_to_clipboard": "Afrita á klippispjald",
|
"copypaste.copy_to_clipboard": "Afrita á klippispjald",
|
||||||
"directory.federated": "Frá samtengdum vefþjónum",
|
"directory.federated": "Frá samtengdum vefþjónum",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Leita meðal þeirra sem þú fylgist með",
|
"lists.search": "Leita meðal þeirra sem þú fylgist með",
|
||||||
"lists.subheading": "Listarnir þínir",
|
"lists.subheading": "Listarnir þínir",
|
||||||
"load_pending": "{count, plural, one {# nýtt atriði} other {# ný atriði}}",
|
"load_pending": "{count, plural, one {# nýtt atriði} other {# ný atriði}}",
|
||||||
"loading_indicator.label": "Hleð inn...",
|
"loading_indicator.label": "Hleð inn…",
|
||||||
"media_gallery.toggle_visible": "Víxla sýnileika",
|
"media_gallery.toggle_visible": "Víxla sýnileika",
|
||||||
"moved_to_account_banner.text": "Aðgangurinn þinn {disabledAccount} er óvirkur í augnablikinu vegna þess að þú fluttir þig yfir á {movedToAccount}.",
|
"moved_to_account_banner.text": "Aðgangurinn þinn {disabledAccount} er óvirkur í augnablikinu vegna þess að þú fluttir þig yfir á {movedToAccount}.",
|
||||||
"mute_modal.duration": "Lengd",
|
"mute_modal.duration": "Lengd",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Því miður er ekki hægt að birta neinar niðurstöður í augnablikinu. Þú getur reynt að nota leitina eða skoðað könnunarsíðuna til að finna fólk til að fylgjast með, nú eða prófað aftur síðar.",
|
"onboarding.follows.empty": "Því miður er ekki hægt að birta neinar niðurstöður í augnablikinu. Þú getur reynt að nota leitina eða skoðað könnunarsíðuna til að finna fólk til að fylgjast með, nú eða prófað aftur síðar.",
|
||||||
"onboarding.follows.lead": "Þú ræktar heimastreymið þitt. Því fleira fólki sem þú fylgist með, því virkara og áhugaverðara verður það. Að fylgjast með þessum notendum gæti verið ágætt til að byrja með - þú getur alltaf hætt að fylgjast með þeim síðar!",
|
"onboarding.follows.lead": "Þú ræktar heimastreymið þitt. Því fleira fólki sem þú fylgist með, því virkara og áhugaverðara verður það. Að fylgjast með þessum notendum gæti verið ágætt til að byrja með - þú getur alltaf hætt að fylgjast með þeim síðar!",
|
||||||
"onboarding.follows.title": "Vinsælt á Mastodon",
|
"onboarding.follows.title": "Vinsælt á Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Hafa notandasnið og færslur með í reikniritum leitar",
|
||||||
|
"onboarding.profile.display_name": "Birtingarnafn",
|
||||||
|
"onboarding.profile.display_name_hint": "Fullt nafn þitt eða eitthvað til gamans…",
|
||||||
|
"onboarding.profile.indexable": "Hafa opinberar færslur með í leitarniðurstöðum",
|
||||||
|
"onboarding.profile.lead": "Þú getur alltaf klárað þetta seinna í stillingunum, þar sem enn fleiri möguleikar bjóðast á sérsníðingum.",
|
||||||
|
"onboarding.profile.note": "Æviágrip",
|
||||||
|
"onboarding.profile.note_hint": "Þú getur @minnst á annað fólk eða #myllumerki…",
|
||||||
|
"onboarding.profile.save_and_continue": "Vista og halda áfram",
|
||||||
|
"onboarding.profile.title": "Uppsetning notandasniðs",
|
||||||
|
"onboarding.profile.upload_avatar": "Sendu inn auðkennismynd",
|
||||||
|
"onboarding.profile.upload_header": "Sendu inn bakgrunnsmynd í haus notandasniðs",
|
||||||
"onboarding.share.lead": "Láttu fólk vita hvernig það getur fundið þig á Mastodon!",
|
"onboarding.share.lead": "Láttu fólk vita hvernig það getur fundið þig á Mastodon!",
|
||||||
"onboarding.share.message": "Ég heiti {username} á #Mastodon! Þú getur fylgst með mér á {url}",
|
"onboarding.share.message": "Ég heiti {username} á #Mastodon! Þú getur fylgst með mér á {url}",
|
||||||
"onboarding.share.next_steps": "Möguleg næstu skref:",
|
"onboarding.share.next_steps": "Möguleg næstu skref:",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
"account.blocked": "Bloccato",
|
"account.blocked": "Bloccato",
|
||||||
"account.browse_more_on_origin_server": "Sfoglia di più sul profilo originale",
|
"account.browse_more_on_origin_server": "Sfoglia di più sul profilo originale",
|
||||||
"account.cancel_follow_request": "Annulla la richiesta di seguire",
|
"account.cancel_follow_request": "Annulla la richiesta di seguire",
|
||||||
|
"account.copy": "Copia link del profilo",
|
||||||
"account.direct": "Menziona privatamente @{name}",
|
"account.direct": "Menziona privatamente @{name}",
|
||||||
"account.disable_notifications": "Smetti di avvisarmi quando @{name} pubblica un post",
|
"account.disable_notifications": "Smetti di avvisarmi quando @{name} pubblica un post",
|
||||||
"account.domain_blocked": "Dominio bloccato",
|
"account.domain_blocked": "Dominio bloccato",
|
||||||
|
@ -191,6 +192,7 @@
|
||||||
"conversation.mark_as_read": "Segna come letto",
|
"conversation.mark_as_read": "Segna come letto",
|
||||||
"conversation.open": "Visualizza conversazione",
|
"conversation.open": "Visualizza conversazione",
|
||||||
"conversation.with": "Con {names}",
|
"conversation.with": "Con {names}",
|
||||||
|
"copy_icon_button.copied": "Copiato negli appunti",
|
||||||
"copypaste.copied": "Copiato",
|
"copypaste.copied": "Copiato",
|
||||||
"copypaste.copy_to_clipboard": "Copia negli Appunti",
|
"copypaste.copy_to_clipboard": "Copia negli Appunti",
|
||||||
"directory.federated": "Da un fediverse noto",
|
"directory.federated": "Da un fediverse noto",
|
||||||
|
@ -252,7 +254,7 @@
|
||||||
"explore.search_results": "Risultati della ricerca",
|
"explore.search_results": "Risultati della ricerca",
|
||||||
"explore.suggested_follows": "Persone",
|
"explore.suggested_follows": "Persone",
|
||||||
"explore.title": "Esplora",
|
"explore.title": "Esplora",
|
||||||
"explore.trending_links": "Novità",
|
"explore.trending_links": "Notizie",
|
||||||
"explore.trending_statuses": "Post",
|
"explore.trending_statuses": "Post",
|
||||||
"explore.trending_tags": "Hashtag",
|
"explore.trending_tags": "Hashtag",
|
||||||
"filter_modal.added.context_mismatch_explanation": "La categoria di questo filtro non si applica al contesto in cui hai acceduto a questo post. Se desideri che il post sia filtrato anche in questo contesto, dovrai modificare il filtro.",
|
"filter_modal.added.context_mismatch_explanation": "La categoria di questo filtro non si applica al contesto in cui hai acceduto a questo post. Se desideri che il post sia filtrato anche in questo contesto, dovrai modificare il filtro.",
|
||||||
|
@ -390,7 +392,7 @@
|
||||||
"lists.search": "Cerca tra le persone che segui",
|
"lists.search": "Cerca tra le persone che segui",
|
||||||
"lists.subheading": "Le tue liste",
|
"lists.subheading": "Le tue liste",
|
||||||
"load_pending": "{count, plural, one {# nuovo oggetto} other {# nuovi oggetti}}",
|
"load_pending": "{count, plural, one {# nuovo oggetto} other {# nuovi oggetti}}",
|
||||||
"loading_indicator.label": "Caricamento...",
|
"loading_indicator.label": "Caricamento…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Nascondi immagine} other {Nascondi immagini}}",
|
"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}.",
|
"moved_to_account_banner.text": "Il tuo profilo {disabledAccount} è correntemente disabilitato perché ti sei spostato a {movedToAccount}.",
|
||||||
"mute_modal.duration": "Durata",
|
"mute_modal.duration": "Durata",
|
||||||
|
@ -479,6 +481,17 @@
|
||||||
"onboarding.follows.empty": "Sfortunatamente, nessun risultato può essere mostrato in questo momento. Puoi provare a utilizzare la ricerca o sfogliare la pagina di esplorazione per trovare persone da seguire, oppure riprova più tardi.",
|
"onboarding.follows.empty": "Sfortunatamente, nessun risultato può essere mostrato in questo momento. Puoi provare a utilizzare la ricerca o sfogliare la pagina di esplorazione per trovare persone da seguire, oppure riprova più tardi.",
|
||||||
"onboarding.follows.lead": "La cronologia della tua home è gestita da te. Più persone segui, più attiva e interessante sarà. Questi profili possono essere un buon punto di partenza; puoi sempre smettere di seguirli in seguito!",
|
"onboarding.follows.lead": "La cronologia della tua home è gestita da te. Più persone segui, più attiva e interessante sarà. Questi profili possono essere un buon punto di partenza; puoi sempre smettere di seguirli in seguito!",
|
||||||
"onboarding.follows.title": "Popolare su Mastodon",
|
"onboarding.follows.title": "Popolare su Mastodon",
|
||||||
|
"onboarding.profile.discoverable": "Include il profilo e i post negli algoritmi di scoperta",
|
||||||
|
"onboarding.profile.display_name": "Nome da visualizzare",
|
||||||
|
"onboarding.profile.display_name_hint": "Il tuo nome completo o il tuo nome divertente…",
|
||||||
|
"onboarding.profile.indexable": "Includi i post pubblici nei risultati di ricerca",
|
||||||
|
"onboarding.profile.lead": "Puoi sempre completarlo in un secondo momento nelle impostazioni, dove sono disponibili ancora più opzioni di personalizzazione.",
|
||||||
|
"onboarding.profile.note": "Biografia",
|
||||||
|
"onboarding.profile.note_hint": "Puoi @menzionare altre persone o #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Salva e continua",
|
||||||
|
"onboarding.profile.title": "Configurazione del profilo",
|
||||||
|
"onboarding.profile.upload_avatar": "Carica l'immagine del profilo",
|
||||||
|
"onboarding.profile.upload_header": "Carica l'intestazione del profilo",
|
||||||
"onboarding.share.lead": "Fai sapere alle persone come possono trovarti su Mastodon!",
|
"onboarding.share.lead": "Fai sapere alle persone come possono trovarti su Mastodon!",
|
||||||
"onboarding.share.message": "Sono {username} su #Mastodon! Vieni a seguirmi su {url}",
|
"onboarding.share.message": "Sono {username} su #Mastodon! Vieni a seguirmi su {url}",
|
||||||
"onboarding.share.next_steps": "Possibili passaggi successivi:",
|
"onboarding.share.next_steps": "Possibili passaggi successivi:",
|
||||||
|
|
|
@ -390,7 +390,7 @@
|
||||||
"lists.search": "フォローしている人の中から検索",
|
"lists.search": "フォローしている人の中から検索",
|
||||||
"lists.subheading": "あなたのリスト",
|
"lists.subheading": "あなたのリスト",
|
||||||
"load_pending": "{count}件の新着",
|
"load_pending": "{count}件の新着",
|
||||||
"loading_indicator.label": "読み込み中...",
|
"loading_indicator.label": "",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}",
|
"media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}",
|
||||||
"moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。",
|
"moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。",
|
||||||
"mute_modal.duration": "ミュートする期間",
|
"mute_modal.duration": "ミュートする期間",
|
||||||
|
@ -586,8 +586,8 @@
|
||||||
"search.no_recent_searches": "検索履歴はありません",
|
"search.no_recent_searches": "検索履歴はありません",
|
||||||
"search.placeholder": "検索",
|
"search.placeholder": "検索",
|
||||||
"search.quick_action.account_search": "{x}に該当するプロフィール",
|
"search.quick_action.account_search": "{x}に該当するプロフィール",
|
||||||
"search.quick_action.go_to_account": "{x}のプロフィールを見る",
|
"search.quick_action.go_to_account": "プロフィール {x} を見る",
|
||||||
"search.quick_action.go_to_hashtag": "{x}に該当するハッシュタグ",
|
"search.quick_action.go_to_hashtag": "ハッシュタグ {x} を見る",
|
||||||
"search.quick_action.open_url": "MastodonでURLを開く",
|
"search.quick_action.open_url": "MastodonでURLを開く",
|
||||||
"search.quick_action.status_search": "{x}に該当する投稿",
|
"search.quick_action.status_search": "{x}に該当する投稿",
|
||||||
"search.search_or_paste": "検索またはURLを入力",
|
"search.search_or_paste": "検索またはURLを入力",
|
||||||
|
|
|
@ -165,7 +165,6 @@
|
||||||
"lists.new.title_placeholder": "ახალი სიის სათაური",
|
"lists.new.title_placeholder": "ახალი სიის სათაური",
|
||||||
"lists.search": "ძებნა ადამიანებს შორის რომელთაც მიჰყვებით",
|
"lists.search": "ძებნა ადამიანებს შორის რომელთაც მიჰყვებით",
|
||||||
"lists.subheading": "თქვენი სიები",
|
"lists.subheading": "თქვენი სიები",
|
||||||
"loading_indicator.label": "იტვირთება...",
|
|
||||||
"media_gallery.toggle_visible": "ხილვადობის ჩართვა",
|
"media_gallery.toggle_visible": "ხილვადობის ჩართვა",
|
||||||
"mute_modal.hide_notifications": "დავმალოთ შეტყობინებები ამ მომხმარებლისგან?",
|
"mute_modal.hide_notifications": "დავმალოთ შეტყობინებები ამ მომხმარებლისგან?",
|
||||||
"navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
|
"navigation_bar.blocks": "დაბლოკილი მომხმარებლები",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue