Merge branch 'main' into bark-prod
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
130ae637e7
158 changed files with 6410 additions and 1783 deletions
10
.github/renovate.json5
vendored
10
.github/renovate.json5
vendored
|
@ -99,6 +99,16 @@
|
||||||
matchUpdateTypes: ['patch', 'minor'],
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
groupName: 'eslint (non-major)',
|
groupName: 'eslint (non-major)',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
// Group actions/*-artifact in the same PR
|
||||||
|
matchManagers: ['github-actions'],
|
||||||
|
matchPackageNames: [
|
||||||
|
'actions/download-artifact',
|
||||||
|
'actions/upload-artifact',
|
||||||
|
],
|
||||||
|
matchUpdateTypes: ['major'],
|
||||||
|
groupName: 'artifact actions (major)',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Update @types/* packages every week, with one grouped PR
|
// Update @types/* packages every week, with one grouped PR
|
||||||
matchPackagePrefixes: '@types/',
|
matchPackagePrefixes: '@types/',
|
||||||
|
|
|
@ -1,33 +1,21 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `haml-lint --auto-gen-config`
|
# `haml-lint --auto-gen-config`
|
||||||
# on 2023-10-26 09:32:34 -0400 using Haml-Lint version 0.51.0.
|
# on 2023-12-15 11:02:19 -0500 using Haml-Lint version 0.52.0.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the lints are removed from the code base.
|
# one by one as the lints are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
# versions of Haml-Lint, may require this file to be generated again.
|
# versions of Haml-Lint, may require this file to be generated again.
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
# Offense count: 16
|
# Offense count: 11
|
||||||
LineLength:
|
LineLength:
|
||||||
exclude:
|
exclude:
|
||||||
- 'app/views/admin/account_actions/new.html.haml'
|
|
||||||
- 'app/views/admin/accounts/index.html.haml'
|
|
||||||
- 'app/views/admin/ip_blocks/new.html.haml'
|
|
||||||
- 'app/views/admin/roles/_form.html.haml'
|
- 'app/views/admin/roles/_form.html.haml'
|
||||||
- 'app/views/admin/settings/discovery/show.html.haml'
|
|
||||||
- 'app/views/auth/registrations/edit.html.haml'
|
- 'app/views/auth/registrations/edit.html.haml'
|
||||||
- 'app/views/auth/registrations/new.html.haml'
|
- 'app/views/auth/registrations/new.html.haml'
|
||||||
- 'app/views/filters/_filter_fields.html.haml'
|
|
||||||
- 'app/views/media/player.html.haml'
|
- 'app/views/media/player.html.haml'
|
||||||
- 'app/views/settings/applications/_fields.html.haml'
|
- 'app/views/settings/applications/_fields.html.haml'
|
||||||
- 'app/views/settings/imports/index.html.haml'
|
- 'app/views/settings/imports/index.html.haml'
|
||||||
- 'app/views/settings/preferences/appearance/show.html.haml'
|
- 'app/views/settings/preferences/appearance/show.html.haml'
|
||||||
- 'app/views/settings/preferences/notifications/show.html.haml'
|
- 'app/views/settings/preferences/notifications/show.html.haml'
|
||||||
- 'app/views/settings/preferences/other/show.html.haml'
|
- 'app/views/settings/preferences/other/show.html.haml'
|
||||||
|
|
||||||
# Offense count: 9
|
|
||||||
RuboCop:
|
|
||||||
exclude:
|
|
||||||
- 'app/views/admin/accounts/_buttons.html.haml'
|
|
||||||
- 'app/views/admin/accounts/_local_account.html.haml'
|
|
||||||
- 'app/views/admin/roles/_form.html.haml'
|
|
||||||
|
|
15
.rubocop.yml
15
.rubocop.yml
|
@ -105,6 +105,21 @@ Rails/Exit:
|
||||||
- 'config/boot.rb'
|
- 'config/boot.rb'
|
||||||
- 'lib/mastodon/cli/*.rb'
|
- 'lib/mastodon/cli/*.rb'
|
||||||
|
|
||||||
|
Rails/SkipsModelValidations:
|
||||||
|
Exclude:
|
||||||
|
- 'db/*migrate/**/*'
|
||||||
|
|
||||||
|
# Reason: We want to preserve the ability to migrate from arbitrary old versions,
|
||||||
|
# and cannot guarantee that every installation has run every migration as they upgrade.
|
||||||
|
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsunusedignoredcolumns
|
||||||
|
Rails/UnusedIgnoredColumns:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
# Reason: Prevailing style choice
|
||||||
|
# https://docs.rubocop.org/rubocop-rails/cops_rails.html#railsnegateinclude
|
||||||
|
Rails/NegateInclude:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Some single letter camel case files shouldn't be split
|
# Reason: Some single letter camel case files shouldn't be split
|
||||||
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
|
# https://docs.rubocop.org/rubocop-rspec/cops_rspec.html#rspecfilepath
|
||||||
RSpec/FilePath:
|
RSpec/FilePath:
|
||||||
|
|
|
@ -26,7 +26,7 @@ Lint/NonLocalExitFromIterator:
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 125
|
Max: 100
|
||||||
|
|
||||||
# Configuration parameters: CountBlocks, Max.
|
# Configuration parameters: CountBlocks, Max.
|
||||||
Metrics/BlockNesting:
|
Metrics/BlockNesting:
|
||||||
|
@ -119,23 +119,6 @@ Rails/LexicallyScopedActionFilter:
|
||||||
- 'app/controllers/auth/passwords_controller.rb'
|
- 'app/controllers/auth/passwords_controller.rb'
|
||||||
- 'app/controllers/auth/registrations_controller.rb'
|
- 'app/controllers/auth/registrations_controller.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Rails/NegateInclude:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/concerns/signature_verification.rb'
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
|
||||||
- 'app/lib/activitypub/activity/create.rb'
|
|
||||||
- 'app/lib/activitypub/activity/move.rb'
|
|
||||||
- 'app/lib/feed_manager.rb'
|
|
||||||
- 'app/lib/link_details_extractor.rb'
|
|
||||||
- 'app/models/concerns/attachmentable.rb'
|
|
||||||
- 'app/models/concerns/remotable.rb'
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/services/activitypub/process_status_update_service.rb'
|
|
||||||
- 'app/services/fetch_link_card_service.rb'
|
|
||||||
- 'app/workers/web/push_notification_worker.rb'
|
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
|
||||||
|
|
||||||
Rails/OutputSafety:
|
Rails/OutputSafety:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'config/initializers/simple_form.rb'
|
- 'config/initializers/simple_form.rb'
|
||||||
|
@ -181,22 +164,6 @@ Rails/SkipsModelValidations:
|
||||||
- 'app/workers/move_worker.rb'
|
- 'app/workers/move_worker.rb'
|
||||||
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
|
- 'app/workers/scheduler/ip_cleanup_scheduler.rb'
|
||||||
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
|
- 'app/workers/scheduler/scheduled_statuses_scheduler.rb'
|
||||||
- 'db/migrate/20161203164520_add_from_account_id_to_notifications.rb'
|
|
||||||
- 'db/migrate/20170105224407_add_shortcode_to_media_attachments.rb'
|
|
||||||
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
|
|
||||||
- 'db/migrate/20170304202101_add_type_to_media_attachments.rb'
|
|
||||||
- 'db/migrate/20180528141303_fix_accounts_unique_index.rb'
|
|
||||||
- 'db/migrate/20180609104432_migrate_web_push_subscriptions2.rb'
|
|
||||||
- 'db/migrate/20181207011115_downcase_custom_emoji_domains.rb'
|
|
||||||
- 'db/migrate/20190511134027_add_silenced_at_suspended_at_to_accounts.rb'
|
|
||||||
- 'db/migrate/20191007013357_update_pt_locales.rb'
|
|
||||||
- 'db/migrate/20220316233212_update_kurdish_locales.rb'
|
|
||||||
- 'db/post_migrate/20190511152737_remove_suspended_silenced_account_fields.rb'
|
|
||||||
- 'db/post_migrate/20200917193528_migrate_notifications_type.rb'
|
|
||||||
- 'db/post_migrate/20201017234926_fill_account_suspension_origin.rb'
|
|
||||||
- 'db/post_migrate/20220617202502_migrate_roles.rb'
|
|
||||||
- 'db/post_migrate/20221101190723_backfill_admin_action_logs.rb'
|
|
||||||
- 'db/post_migrate/20221206114142_backfill_admin_action_logs_again.rb'
|
|
||||||
- 'lib/mastodon/cli/accounts.rb'
|
- 'lib/mastodon/cli/accounts.rb'
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
- 'lib/mastodon/cli/maintenance.rb'
|
||||||
- 'spec/lib/activitypub/activity/follow_spec.rb'
|
- 'spec/lib/activitypub/activity/follow_spec.rb'
|
||||||
|
@ -212,19 +179,6 @@ Rails/UniqueValidationWithoutIndex:
|
||||||
- 'app/models/identity.rb'
|
- 'app/models/identity.rb'
|
||||||
- 'app/models/webauthn_credential.rb'
|
- 'app/models/webauthn_credential.rb'
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/UnusedIgnoredColumns:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/account.rb'
|
|
||||||
- 'app/models/account_stat.rb'
|
|
||||||
- 'app/models/admin/action_log.rb'
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/models/email_domain_block.rb'
|
|
||||||
- 'app/models/report.rb'
|
|
||||||
- 'app/models/status_edit.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
# Configuration parameters: EnforcedStyle.
|
# Configuration parameters: EnforcedStyle.
|
||||||
# SupportedStyles: exists, where
|
# SupportedStyles: exists, where
|
||||||
|
@ -378,22 +332,6 @@ Style/IfUnlessModifier:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'config/initializers/ffmpeg.rb'
|
- 'config/initializers/ffmpeg.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: InverseMethods, InverseBlocks.
|
|
||||||
Style/InverseMethods:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/custom_filter.rb'
|
|
||||||
- 'app/services/update_account_service.rb'
|
|
||||||
- 'spec/controllers/activitypub/replies_controller_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: line_count_dependent, lambda, literal
|
|
||||||
Style/Lambda:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/simple_form.rb'
|
|
||||||
- 'config/routes.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/MapToHash:
|
Style/MapToHash:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
@ -458,15 +396,6 @@ Style/RedundantFetchBlock:
|
||||||
- 'config/initializers/paperclip.rb'
|
- 'config/initializers/paperclip.rb'
|
||||||
- 'config/puma.rb'
|
- 'config/puma.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: AllowMultipleReturnValues.
|
|
||||||
Style/RedundantReturn:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/api/v1/directories_controller.rb'
|
|
||||||
- 'app/controllers/auth/confirmations_controller.rb'
|
|
||||||
- 'app/lib/ostatus/tag_manager.rb'
|
|
||||||
- 'app/models/form/import.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
||||||
# AllowedMethods: present?, blank?, presence, try, try!
|
# AllowedMethods: present?, blank?, presence, try, try!
|
||||||
|
@ -487,11 +416,6 @@ Style/SingleArgumentDig:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'lib/webpacker/manifest_extensions.rb'
|
- 'lib/webpacker/manifest_extensions.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/StderrPuts:
|
|
||||||
Exclude:
|
|
||||||
- 'config/boot.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
# Configuration parameters: Mode.
|
# Configuration parameters: Mode.
|
||||||
Style/StringConcatenation:
|
Style/StringConcatenation:
|
||||||
|
@ -510,13 +434,6 @@ Style/StringLiterals:
|
||||||
- 'config/initializers/webauthn.rb'
|
- 'config/initializers/webauthn.rb'
|
||||||
- 'config/routes.rb'
|
- 'config/routes.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: AllowMethodsWithArguments, AllowedMethods, AllowedPatterns, AllowComments.
|
|
||||||
# AllowedMethods: define_method, mail, respond_to
|
|
||||||
Style/SymbolProc:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/3_omniauth.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
|
# Configuration parameters: EnforcedStyle, AllowSafeAssignment.
|
||||||
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
# SupportedStyles: require_parentheses, require_no_parentheses, require_parentheses_when_complex
|
||||||
|
|
30
Gemfile.lock
30
Gemfile.lock
|
@ -168,7 +168,7 @@ GEM
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
parser (>= 2.4)
|
parser (>= 2.4)
|
||||||
smart_properties
|
smart_properties
|
||||||
bigdecimal (3.1.4)
|
bigdecimal (3.1.5)
|
||||||
bindata (2.4.15)
|
bindata (2.4.15)
|
||||||
binding_of_caller (1.0.0)
|
binding_of_caller (1.0.0)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
|
@ -197,7 +197,7 @@ GEM
|
||||||
activesupport
|
activesupport
|
||||||
cbor (0.5.9.6)
|
cbor (0.5.9.6)
|
||||||
charlock_holmes (0.7.7)
|
charlock_holmes (0.7.7)
|
||||||
chewy (7.3.5)
|
chewy (7.4.0)
|
||||||
activesupport (>= 5.2)
|
activesupport (>= 5.2)
|
||||||
elasticsearch (>= 7.12.0, < 7.14.0)
|
elasticsearch (>= 7.12.0, < 7.14.0)
|
||||||
elasticsearch-dsl
|
elasticsearch-dsl
|
||||||
|
@ -326,7 +326,7 @@ GEM
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
globalid (1.2.1)
|
globalid (1.2.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
haml (6.2.0)
|
haml (6.3.0)
|
||||||
temple (>= 0.8.2)
|
temple (>= 0.8.2)
|
||||||
thor
|
thor
|
||||||
tilt
|
tilt
|
||||||
|
@ -335,7 +335,7 @@ GEM
|
||||||
activesupport (>= 5.1)
|
activesupport (>= 5.1)
|
||||||
haml (>= 4.0.6)
|
haml (>= 4.0.6)
|
||||||
railties (>= 5.1)
|
railties (>= 5.1)
|
||||||
haml_lint (0.51.0)
|
haml_lint (0.52.0)
|
||||||
haml (>= 4.0)
|
haml (>= 4.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
rainbow
|
rainbow
|
||||||
|
@ -381,7 +381,7 @@ GEM
|
||||||
rdoc
|
rdoc
|
||||||
reline (>= 0.3.8)
|
reline (>= 0.3.8)
|
||||||
jmespath (1.6.2)
|
jmespath (1.6.2)
|
||||||
json (2.7.0)
|
json (2.7.1)
|
||||||
json-canonicalization (1.0.0)
|
json-canonicalization (1.0.0)
|
||||||
json-jwt (1.15.3)
|
json-jwt (1.15.3)
|
||||||
activesupport (>= 4.2)
|
activesupport (>= 4.2)
|
||||||
|
@ -484,8 +484,8 @@ GEM
|
||||||
nokogiri (1.15.5)
|
nokogiri (1.15.5)
|
||||||
mini_portile2 (~> 2.8.2)
|
mini_portile2 (~> 2.8.2)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
oj (3.16.2)
|
oj (3.16.3)
|
||||||
bigdecimal (~> 3.1)
|
bigdecimal (>= 3.0)
|
||||||
omniauth (2.1.1)
|
omniauth (2.1.1)
|
||||||
hashie (>= 3.4.6)
|
hashie (>= 3.4.6)
|
||||||
rack (>= 2.2.3)
|
rack (>= 2.2.3)
|
||||||
|
@ -515,7 +515,7 @@ GEM
|
||||||
openssl (> 2.0)
|
openssl (> 2.0)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ox (2.14.17)
|
ox (2.14.17)
|
||||||
parallel (1.23.0)
|
parallel (1.24.0)
|
||||||
parser (3.2.2.4)
|
parser (3.2.2.4)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
racc
|
racc
|
||||||
|
@ -622,7 +622,7 @@ GEM
|
||||||
redis (>= 4)
|
redis (>= 4)
|
||||||
redlock (1.3.2)
|
redlock (1.3.2)
|
||||||
redis (>= 3.0.0, < 6.0)
|
redis (>= 3.0.0, < 6.0)
|
||||||
regexp_parser (2.8.2)
|
regexp_parser (2.8.3)
|
||||||
reline (0.4.1)
|
reline (0.4.1)
|
||||||
io-console (~> 0.5)
|
io-console (~> 0.5)
|
||||||
request_store (1.5.1)
|
request_store (1.5.1)
|
||||||
|
@ -662,7 +662,7 @@ GEM
|
||||||
rspec-mocks (~> 3.0)
|
rspec-mocks (~> 3.0)
|
||||||
sidekiq (>= 5, < 8)
|
sidekiq (>= 5, < 8)
|
||||||
rspec-support (3.12.1)
|
rspec-support (3.12.1)
|
||||||
rubocop (1.58.0)
|
rubocop (1.59.0)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (>= 3.17.0)
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
|
@ -679,10 +679,10 @@ GEM
|
||||||
rubocop (~> 1.41)
|
rubocop (~> 1.41)
|
||||||
rubocop-factory_bot (2.24.0)
|
rubocop-factory_bot (2.24.0)
|
||||||
rubocop (~> 1.33)
|
rubocop (~> 1.33)
|
||||||
rubocop-performance (1.19.1)
|
rubocop-performance (1.20.0)
|
||||||
rubocop (>= 1.7.0, < 2.0)
|
rubocop (>= 1.48.1, < 2.0)
|
||||||
rubocop-ast (>= 0.4.0)
|
rubocop-ast (>= 1.30.0, < 2.0)
|
||||||
rubocop-rails (2.22.2)
|
rubocop-rails (2.23.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 1.33.0, < 2.0)
|
rubocop (>= 1.33.0, < 2.0)
|
||||||
|
@ -759,7 +759,7 @@ GEM
|
||||||
unicode-display_width (>= 1.1.1, < 3)
|
unicode-display_width (>= 1.1.1, < 3)
|
||||||
terrapin (0.6.0)
|
terrapin (0.6.0)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
test-prof (1.3.0)
|
test-prof (1.3.1)
|
||||||
thor (1.3.0)
|
thor (1.3.0)
|
||||||
tilt (2.3.0)
|
tilt (2.3.0)
|
||||||
timeout (0.4.1)
|
timeout (0.4.1)
|
||||||
|
|
|
@ -8,7 +8,7 @@ module Admin
|
||||||
authorize :follow_recommendation, :show?
|
authorize :follow_recommendation, :show?
|
||||||
|
|
||||||
@form = Form::AccountBatch.new
|
@form = Form::AccountBatch.new
|
||||||
@accounts = filtered_follow_recommendations
|
@accounts = filtered_follow_recommendations.page(params[:page])
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
|
|
|
@ -108,6 +108,10 @@ class Api::BaseController < ApplicationController
|
||||||
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
|
render json: { error: 'Your login is currently disabled' }, status: 403 if current_user&.account&.unavailable?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def require_valid_pagination_options!
|
||||||
|
render json: { error: 'Pagination values for `offset` and `limit` must be positive' }, status: 400 if pagination_options_invalid?
|
||||||
|
end
|
||||||
|
|
||||||
def require_user!
|
def require_user!
|
||||||
if !current_user
|
if !current_user
|
||||||
render json: { error: 'This method requires an authenticated user' }, status: 422
|
render json: { error: 'This method requires an authenticated user' }, status: 422
|
||||||
|
@ -136,6 +140,10 @@ class Api::BaseController < ApplicationController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def pagination_options_invalid?
|
||||||
|
params.slice(:limit, :offset).values.map(&:to_i).any?(&:negative?)
|
||||||
|
end
|
||||||
|
|
||||||
def respond_with_error(code)
|
def respond_with_error(code)
|
||||||
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
|
render json: { error: Rack::Utils::HTTP_STATUS_CODES[code] }, status: code
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,6 @@ class Api::V1::Accounts::NotesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships_presenter
|
def relationships_presenter
|
||||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
|
AccountRelationshipsPresenter.new([@account], current_user.account_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,6 +25,6 @@ class Api::V1::Accounts::PinsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships_presenter
|
def relationships_presenter
|
||||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id)
|
AccountRelationshipsPresenter.new([@account], current_user.account_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Api::V1::Accounts::RelationshipsController < Api::BaseController
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@accounts = Account.where(id: account_ids).select('id')
|
@accounts = Account.where(id: account_ids).select(:id, :domain)
|
||||||
@accounts.merge!(Account.without_suspended) unless truthy_param?(:with_suspended)
|
@accounts.merge!(Account.without_suspended) unless truthy_param?(:with_suspended)
|
||||||
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
|
render json: @accounts, each_serializer: REST::RelationshipSerializer, relationships: relationships
|
||||||
end
|
end
|
||||||
|
|
|
@ -88,7 +88,7 @@ class Api::V1::AccountsController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships(**options)
|
def relationships(**options)
|
||||||
AccountRelationshipsPresenter.new([@account.id], current_user.account_id, **options)
|
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_params
|
def account_params
|
||||||
|
|
|
@ -12,7 +12,7 @@ class Api::V1::DirectoriesController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def require_enabled!
|
def require_enabled!
|
||||||
return not_found unless Setting.profile_directory
|
not_found unless Setting.profile_directory
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_accounts
|
def set_accounts
|
||||||
|
|
|
@ -25,11 +25,11 @@ class Api::V1::FollowRequestsController < Api::BaseController
|
||||||
private
|
private
|
||||||
|
|
||||||
def account
|
def account
|
||||||
Account.find(params[:id])
|
@account ||= Account.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def relationships(**options)
|
def relationships(**options)
|
||||||
AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, **options)
|
AccountRelationshipsPresenter.new([account], current_user.account_id, **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_accounts
|
def load_accounts
|
||||||
|
|
|
@ -3,22 +3,23 @@
|
||||||
class Api::V1::SuggestionsController < Api::BaseController
|
class Api::V1::SuggestionsController < Api::BaseController
|
||||||
include Authorization
|
include Authorization
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read }
|
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
|
||||||
|
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
|
before_action :set_suggestions
|
||||||
|
|
||||||
def index
|
def index
|
||||||
suggestions = suggestions_source.get(current_account, limit: limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i).map(&:account), each_serializer: REST::AccountSerializer
|
||||||
render json: suggestions.map(&:account), each_serializer: REST::AccountSerializer
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
suggestions_source.remove(current_account, params[:id])
|
@suggestions.remove(params[:id])
|
||||||
render_empty
|
render_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def suggestions_source
|
def set_suggestions
|
||||||
AccountSuggestions::PastInteractionsSource.new
|
@suggestions = AccountSuggestions.new(current_account)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,6 +12,7 @@ class Api::V2::SearchController < Api::BaseController
|
||||||
before_action :query_pagination_error, if: :pagination_requested?
|
before_action :query_pagination_error, if: :pagination_requested?
|
||||||
before_action :remote_resolve_error, if: :remote_resolve_requested?
|
before_action :remote_resolve_error, if: :remote_resolve_requested?
|
||||||
end
|
end
|
||||||
|
before_action :require_valid_pagination_options!
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@search = Search.new(search_results)
|
@search = Search.new(search_results)
|
||||||
|
|
|
@ -3,17 +3,23 @@
|
||||||
class Api::V2::SuggestionsController < Api::BaseController
|
class Api::V2::SuggestionsController < Api::BaseController
|
||||||
include Authorization
|
include Authorization
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :read }
|
before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index
|
||||||
|
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
before_action :set_suggestions
|
before_action :set_suggestions
|
||||||
|
|
||||||
def index
|
def index
|
||||||
render json: @suggestions, each_serializer: REST::SuggestionSerializer
|
render json: @suggestions.get(limit_param(DEFAULT_ACCOUNTS_LIMIT), params[:offset].to_i), each_serializer: REST::SuggestionSerializer
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@suggestions.remove(params[:id])
|
||||||
|
render_empty
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_suggestions
|
def set_suggestions
|
||||||
@suggestions = AccountSuggestions.get(current_account, limit_param(DEFAULT_ACCOUNTS_LIMIT))
|
@suggestions = AccountSuggestions.new(current_account)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||||
end
|
end
|
||||||
|
|
||||||
def captcha_user_bypass?
|
def captcha_user_bypass?
|
||||||
return true if @confirmation_user.nil? || @confirmation_user.confirmed?
|
@confirmation_user.nil? || @confirmation_user.confirmed?
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_unconfirmed!
|
def require_unconfirmed!
|
||||||
|
|
|
@ -33,7 +33,7 @@ class RelationshipsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_relationships
|
def set_relationships
|
||||||
@relationships = AccountRelationshipsPresenter.new(@accounts.pluck(:id), current_user.account_id)
|
@relationships = AccountRelationshipsPresenter.new(@accounts, current_user.account_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def form_account_batch_params
|
def form_account_batch_params
|
||||||
|
|
|
@ -110,11 +110,11 @@ module ApplicationHelper
|
||||||
def can?(action, record)
|
def can?(action, record)
|
||||||
return false if record.nil?
|
return false if record.nil?
|
||||||
|
|
||||||
policy(record).public_send("#{action}?")
|
policy(record).public_send(:"#{action}?")
|
||||||
end
|
end
|
||||||
|
|
||||||
def fa_icon(icon, attributes = {})
|
def fa_icon(icon, attributes = {})
|
||||||
class_names = attributes[:class]&.split(' ') || []
|
class_names = attributes[:class]&.split || []
|
||||||
class_names << 'fa'
|
class_names << 'fa'
|
||||||
class_names += icon.split.map { |cl| "fa-#{cl}" }
|
class_names += icon.split.map { |cl| "fa-#{cl}" }
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ function actionWithSkipLoadingTrue<Args extends object>(args: Args) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const followAccountSuccess = createAction(
|
export const followAccountSuccess = createAction(
|
||||||
'accounts/followAccountSuccess',
|
'accounts/followAccount/SUCCESS',
|
||||||
actionWithSkipLoadingTrue<{
|
actionWithSkipLoadingTrue<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
alreadyFollowing: boolean;
|
alreadyFollowing: boolean;
|
||||||
|
@ -29,7 +29,7 @@ export const followAccountSuccess = createAction(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const unfollowAccountSuccess = createAction(
|
export const unfollowAccountSuccess = createAction(
|
||||||
'accounts/unfollowAccountSuccess',
|
'accounts/unfollowAccount/SUCCESS',
|
||||||
actionWithSkipLoadingTrue<{
|
actionWithSkipLoadingTrue<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
statuses: unknown;
|
statuses: unknown;
|
||||||
|
@ -38,60 +38,60 @@ export const unfollowAccountSuccess = createAction(
|
||||||
);
|
);
|
||||||
|
|
||||||
export const authorizeFollowRequestSuccess = createAction<{ id: string }>(
|
export const authorizeFollowRequestSuccess = createAction<{ id: string }>(
|
||||||
'accounts/followRequestAuthorizeSuccess',
|
'accounts/followRequestAuthorize/SUCCESS',
|
||||||
);
|
);
|
||||||
|
|
||||||
export const rejectFollowRequestSuccess = createAction<{ id: string }>(
|
export const rejectFollowRequestSuccess = createAction<{ id: string }>(
|
||||||
'accounts/followRequestRejectSuccess',
|
'accounts/followRequestReject/SUCCESS',
|
||||||
);
|
);
|
||||||
|
|
||||||
export const followAccountRequest = createAction(
|
export const followAccountRequest = createAction(
|
||||||
'accounts/followRequest',
|
'accounts/follow/REQUEST',
|
||||||
actionWithSkipLoadingTrue<{ id: string; locked: boolean }>,
|
actionWithSkipLoadingTrue<{ id: string; locked: boolean }>,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const followAccountFail = createAction(
|
export const followAccountFail = createAction(
|
||||||
'accounts/followFail',
|
'accounts/follow/FAIL',
|
||||||
actionWithSkipLoadingTrue<{ id: string; error: string; locked: boolean }>,
|
actionWithSkipLoadingTrue<{ id: string; error: string; locked: boolean }>,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const unfollowAccountRequest = createAction(
|
export const unfollowAccountRequest = createAction(
|
||||||
'accounts/unfollowRequest',
|
'accounts/unfollow/REQUEST',
|
||||||
actionWithSkipLoadingTrue<{ id: string }>,
|
actionWithSkipLoadingTrue<{ id: string }>,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const unfollowAccountFail = createAction(
|
export const unfollowAccountFail = createAction(
|
||||||
'accounts/unfollowFail',
|
'accounts/unfollow/FAIL',
|
||||||
actionWithSkipLoadingTrue<{ id: string; error: string }>,
|
actionWithSkipLoadingTrue<{ id: string; error: string }>,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const blockAccountSuccess = createAction<{
|
export const blockAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
statuses: unknown;
|
statuses: unknown;
|
||||||
}>('accounts/blockSuccess');
|
}>('accounts/block/SUCCESS');
|
||||||
|
|
||||||
export const unblockAccountSuccess = createAction<{
|
export const unblockAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
}>('accounts/unblockSuccess');
|
}>('accounts/unblock/SUCCESS');
|
||||||
|
|
||||||
export const muteAccountSuccess = createAction<{
|
export const muteAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
statuses: unknown;
|
statuses: unknown;
|
||||||
}>('accounts/muteSuccess');
|
}>('accounts/mute/SUCCESS');
|
||||||
|
|
||||||
export const unmuteAccountSuccess = createAction<{
|
export const unmuteAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
}>('accounts/unmuteSuccess');
|
}>('accounts/unmute/SUCCESS');
|
||||||
|
|
||||||
export const pinAccountSuccess = createAction<{
|
export const pinAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
}>('accounts/pinSuccess');
|
}>('accounts/pin/SUCCESS');
|
||||||
|
|
||||||
export const unpinAccountSuccess = createAction<{
|
export const unpinAccountSuccess = createAction<{
|
||||||
relationship: ApiRelationshipJSON;
|
relationship: ApiRelationshipJSON;
|
||||||
}>('accounts/unpinSuccess');
|
}>('accounts/unpin/SUCCESS');
|
||||||
|
|
||||||
export const fetchRelationshipsSuccess = createAction(
|
export const fetchRelationshipsSuccess = createAction(
|
||||||
'relationships/fetchSuccess',
|
'relationships/fetch/SUCCESS',
|
||||||
actionWithSkipLoadingTrue<{ relationships: ApiRelationshipJSON[] }>,
|
actionWithSkipLoadingTrue<{ relationships: ApiRelationshipJSON[] }>,
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,9 +5,9 @@ import type { Account } from 'mastodon/models/account';
|
||||||
export const blockDomainSuccess = createAction<{
|
export const blockDomainSuccess = createAction<{
|
||||||
domain: string;
|
domain: string;
|
||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
}>('domain_blocks/blockSuccess');
|
}>('domain_blocks/block/SUCCESS');
|
||||||
|
|
||||||
export const unblockDomainSuccess = createAction<{
|
export const unblockDomainSuccess = createAction<{
|
||||||
domain: string;
|
domain: string;
|
||||||
accounts: Account[];
|
accounts: Account[];
|
||||||
}>('domain_blocks/unblockSuccess');
|
}>('domain_blocks/unblock/SUCCESS');
|
||||||
|
|
|
@ -257,7 +257,7 @@ class Dropdown extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.target?.buttonRef?.current;
|
return this.target?.buttonRef?.current ?? this.target;
|
||||||
};
|
};
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
componentWillUnmount = () => {
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import { render, fireEvent } from '@testing-library/react';
|
|
||||||
|
|
||||||
class Media extends Component {
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
paused: props.paused || false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
handleMediaClick = () => {
|
|
||||||
const { onClick } = this.props;
|
|
||||||
|
|
||||||
this.setState(prevState => ({
|
|
||||||
paused: !prevState.paused,
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (typeof onClick === 'function') {
|
|
||||||
onClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
const { title } = this.props;
|
|
||||||
const mediaElements = document.querySelectorAll(`div[title="${title}"]`);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
mediaElements.forEach(element => {
|
|
||||||
if (element !== this && !element.classList.contains('paused')) {
|
|
||||||
element.click();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { title } = this.props;
|
|
||||||
const { paused } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button title={title} onClick={this.handleMediaClick}>
|
|
||||||
Media Component - {paused ? 'Paused' : 'Playing'}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Media.propTypes = {
|
|
||||||
title: PropTypes.string.isRequired,
|
|
||||||
onClick: PropTypes.func,
|
|
||||||
paused: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
describe('Media attachments test', () => {
|
|
||||||
let currentMedia = null;
|
|
||||||
const togglePlayMock = jest.fn();
|
|
||||||
|
|
||||||
it('plays a new media file and pauses others that were playing', () => {
|
|
||||||
const container = render(
|
|
||||||
<div>
|
|
||||||
<Media title='firstMedia' paused onClick={togglePlayMock} />
|
|
||||||
<Media title='secondMedia' paused onClick={togglePlayMock} />
|
|
||||||
</div>,
|
|
||||||
);
|
|
||||||
|
|
||||||
fireEvent.click(container.getByTitle('firstMedia'));
|
|
||||||
expect(togglePlayMock).toHaveBeenCalledTimes(1);
|
|
||||||
currentMedia = container.getByTitle('firstMedia');
|
|
||||||
expect(currentMedia.textContent).toMatch(/Playing/);
|
|
||||||
|
|
||||||
fireEvent.click(container.getByTitle('secondMedia'));
|
|
||||||
expect(togglePlayMock).toHaveBeenCalledTimes(2);
|
|
||||||
currentMedia = container.getByTitle('secondMedia');
|
|
||||||
expect(currentMedia.textContent).toMatch(/Playing/);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -20,7 +20,6 @@ import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/featur
|
||||||
|
|
||||||
import { Blurhash } from '../../components/blurhash';
|
import { Blurhash } from '../../components/blurhash';
|
||||||
import { displayMedia, useBlurhash } from '../../initial_state';
|
import { displayMedia, useBlurhash } from '../../initial_state';
|
||||||
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
|
|
||||||
|
|
||||||
import Visualizer from './visualizer';
|
import Visualizer from './visualizer';
|
||||||
|
|
||||||
|
@ -166,32 +165,15 @@ class Audio extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
togglePlay = () => {
|
togglePlay = () => {
|
||||||
const audios = document.querySelectorAll('audio');
|
if (!this.audioContext) {
|
||||||
|
this._initAudioContext();
|
||||||
audios.forEach((audio) => {
|
|
||||||
const button = audio.previousElementSibling;
|
|
||||||
button.addEventListener('click', () => {
|
|
||||||
if(audio.paused) {
|
|
||||||
audios.forEach((e) => {
|
|
||||||
if (e !== audio) {
|
|
||||||
e.pause();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
audio.play();
|
|
||||||
this.setState({ paused: false });
|
|
||||||
} else {
|
|
||||||
audio.pause();
|
|
||||||
this.setState({ paused: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (currentMedia !== null) {
|
|
||||||
currentMedia.pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.audio.play();
|
if (this.state.paused) {
|
||||||
setCurrentMedia(this.audio);
|
this.setState({ paused: false }, () => this.audio.play());
|
||||||
|
} else {
|
||||||
|
this.setState({ paused: true }, () => this.audio.pause());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
handleResize = debounce(() => {
|
||||||
|
@ -213,7 +195,6 @@ class Audio extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePause = () => {
|
handlePause = () => {
|
||||||
this.audio.pause();
|
|
||||||
this.setState({ paused: true });
|
this.setState({ paused: true });
|
||||||
|
|
||||||
if (this.audioContext) {
|
if (this.audioContext) {
|
||||||
|
|
|
@ -22,7 +22,6 @@ import { Icon } from 'mastodon/components/icon';
|
||||||
import { playerSettings } from 'mastodon/settings';
|
import { playerSettings } from 'mastodon/settings';
|
||||||
|
|
||||||
import { displayMedia, useBlurhash } from '../../initial_state';
|
import { displayMedia, useBlurhash } from '../../initial_state';
|
||||||
import { currentMedia, setCurrentMedia } from '../../reducers/media_attachments';
|
|
||||||
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
|
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -182,7 +181,6 @@ class Video extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
handlePause = () => {
|
handlePause = () => {
|
||||||
this.video.pause();
|
|
||||||
this.setState({ paused: true });
|
this.setState({ paused: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -346,32 +344,11 @@ class Video extends PureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
togglePlay = () => {
|
togglePlay = () => {
|
||||||
const videos = document.querySelectorAll('video');
|
if (this.state.paused) {
|
||||||
|
this.setState({ paused: false }, () => this.video.play());
|
||||||
videos.forEach((video) => {
|
} else {
|
||||||
const button = video.nextElementSibling;
|
this.setState({ paused: true }, () => this.video.pause());
|
||||||
button.addEventListener('click', () => {
|
|
||||||
if (video.paused) {
|
|
||||||
videos.forEach((e) => {
|
|
||||||
if (e !== video) {
|
|
||||||
e.pause();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
video.play();
|
|
||||||
this.setState({ paused: false });
|
|
||||||
} else {
|
|
||||||
video.pause();
|
|
||||||
this.setState({ paused: true });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (currentMedia !== null) {
|
|
||||||
currentMedia.pause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.video.play();
|
|
||||||
setCurrentMedia(this.video);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleFullscreen = () => {
|
toggleFullscreen = () => {
|
||||||
|
|
|
@ -606,6 +606,7 @@
|
||||||
"search.quick_action.status_search": "Sobivad postitused {x}",
|
"search.quick_action.status_search": "Sobivad postitused {x}",
|
||||||
"search.search_or_paste": "Otsi või kleebi URL",
|
"search.search_or_paste": "Otsi või kleebi URL",
|
||||||
"search_popout.full_text_search_disabled_message": "Pole saadaval kohas {domain}.",
|
"search_popout.full_text_search_disabled_message": "Pole saadaval kohas {domain}.",
|
||||||
|
"search_popout.full_text_search_logged_out_message": "Saadaval vaid kui sisse logitud.",
|
||||||
"search_popout.language_code": "Keele ISO-kood",
|
"search_popout.language_code": "Keele ISO-kood",
|
||||||
"search_popout.options": "Otsimisvalikud",
|
"search_popout.options": "Otsimisvalikud",
|
||||||
"search_popout.quick_actions": "Kiirtegevused",
|
"search_popout.quick_actions": "Kiirtegevused",
|
||||||
|
|
|
@ -1 +1,145 @@
|
||||||
{}
|
{
|
||||||
|
"about.blocks": "Mga pinatimping server",
|
||||||
|
"about.contact": "Kontak:",
|
||||||
|
"about.disclaimer": "Ang Mastodon ay software na malaya at bukas-na-pinagmulan, at isang tatak-pangkalakal ng Mastodon gGmbH.",
|
||||||
|
"about.domain_blocks.no_reason_available": "Hindi makuha ang dahilan",
|
||||||
|
"about.domain_blocks.silenced.title": "Limitado",
|
||||||
|
"about.domain_blocks.suspended.title": "Suspendido",
|
||||||
|
"about.rules": "Mga alituntunin ng server",
|
||||||
|
"account.account_note_header": "Tala",
|
||||||
|
"account.add_or_remove_from_list": "I-dagdag o tanggalin mula sa mga listahan",
|
||||||
|
"account.badges.bot": "Pakusa",
|
||||||
|
"account.badges.group": "Pangkat",
|
||||||
|
"account.block": "Hadlangan si @{name}",
|
||||||
|
"account.block_domain": "Hadlangan ang domain na {domain}",
|
||||||
|
"account.block_short": "Hadlangan",
|
||||||
|
"account.blocked": "Hinadlangan",
|
||||||
|
"account.browse_more_on_origin_server": "Tingnan pa sa pangunahing profile",
|
||||||
|
"account.cancel_follow_request": "I-kansela ang pagsunod",
|
||||||
|
"account.copy": "I-sipi ang kawing sa profile",
|
||||||
|
"account.direct": "Palihim banggitin si @{name}",
|
||||||
|
"account.disable_notifications": "I-tigil ang pagpapaalam sa akin tuwing nagpopost si @{name}",
|
||||||
|
"account.domain_blocked": "Hinadlangan ang domain",
|
||||||
|
"account.edit_profile": "Baguhin ang profile",
|
||||||
|
"account.enable_notifications": "Ipaalam sa akin kapag nag-post si @{name}",
|
||||||
|
"account.endorse": "I-tampok sa profile",
|
||||||
|
"account.featured_tags.last_status_at": "Huling post noong {date}",
|
||||||
|
"account.featured_tags.last_status_never": "Walang mga post",
|
||||||
|
"account.featured_tags.title": "Nakatampok na hashtag ni {name}",
|
||||||
|
"account.follow": "Sundan",
|
||||||
|
"account.followers": "Mga tagasunod",
|
||||||
|
"account.followers.empty": "Wala pang sumusunod sa tagagamit na ito.",
|
||||||
|
"account.following": "Sinusundan",
|
||||||
|
"account.follows.empty": "Wala pang sinusundan ang tagagamit na ito.",
|
||||||
|
"account.follows_you": "Sinusunod ka",
|
||||||
|
"account.go_to_profile": "Pumunta sa profile",
|
||||||
|
"account.hide_reblogs": "Itago ang mga pagpapalakas mula sa {name}",
|
||||||
|
"account.in_memoriam": "Sa Alaala Ni.",
|
||||||
|
"account.joined_short": "Sumali",
|
||||||
|
"account.languages": "Palitan ang mga nakasumuscribing wika",
|
||||||
|
"account.link_verified_on": "Sinuri ang pagmamay-ari ng kawing ito sa {date}",
|
||||||
|
"account.locked_info": "Nakakandado ang pagsasariling kalagayan ng account na ito. Manomano sinusuri ng may-ari kung sino ang maaaring sumunod sa kanya.",
|
||||||
|
"account.media": "Medya",
|
||||||
|
"account.mention": "Banggitin si @{name}",
|
||||||
|
"account.moved_to": "Ipinahihiwatig ni {name} na ang kanilang bagong account ngayon ay:",
|
||||||
|
"bundle_column_error.error.title": "Naku!",
|
||||||
|
"bundle_column_error.network.body": "Nagkaroon ng kamalian habang sinusubukang i-karga ang pahinang ito. Maaaring dahil ito sa pansamantalang problema ng iyong koneksyon sa internet o ang server na ito.",
|
||||||
|
"bundle_column_error.network.title": "Kamaliang network",
|
||||||
|
"bundle_column_error.retry": "Subukang muli",
|
||||||
|
"bundle_column_error.return": "Bumalik sa tahanan",
|
||||||
|
"bundle_column_error.routing.body": "Hindi mahanap ang hiniling na pahina. Sigurado ka ba na ang URL sa address bar ay tama?",
|
||||||
|
"bundle_column_error.routing.title": "404",
|
||||||
|
"bundle_modal_error.close": "I-sara",
|
||||||
|
"bundle_modal_error.message": "May nangyaring mali habang kinakarga ang bahaging ito.",
|
||||||
|
"bundle_modal_error.retry": "Subukang muli",
|
||||||
|
"closed_registrations.other_server_instructions": "Dahil desentralisado ang Mastodon, pwede kang gumawa ng account sa iba pang server at makipag-ugnayan pa rin dito.",
|
||||||
|
"closed_registrations_modal.description": "Hindi pa pwedeng gumawa ng account sa {domain}, pero tandaan na hindi mo kailangan ng account partikular sa {domain} para gamitin ang Mastodon.",
|
||||||
|
"closed_registrations_modal.find_another_server": "Maghanap ng iba pang server",
|
||||||
|
"closed_registrations_modal.preamble": "Dahil desentralisado ang Mastodon, kahit saan ka pa gumawa ng account, maaari ka pa ring sumunod at makipag-ugnayan sa kahit-sino rito sa server na ito. Pwede mo pang i-host nang pasarili!",
|
||||||
|
"closed_registrations_modal.title": "Pagrerehistro sa Mastodon",
|
||||||
|
"column.about": "Tungkol dito",
|
||||||
|
"column.blocks": "Nakahadlang na mga tagagamit",
|
||||||
|
"column.bookmarks": "Mga bookmark",
|
||||||
|
"column.community": "Lokal na timeline",
|
||||||
|
"column.direct": "Mga palihim na banggit",
|
||||||
|
"column.directory": "Tingnan ang mga profile",
|
||||||
|
"column.domain_blocks": "Nakahadlang na mga domain",
|
||||||
|
"column.favourites": "Mga paborito",
|
||||||
|
"column.firehose": "Mga live feed",
|
||||||
|
"column.follow_requests": "Mga hiling para sundan",
|
||||||
|
"column.home": "Tahanan",
|
||||||
|
"column.lists": "Mga listahan",
|
||||||
|
"column.mutes": "Mga pinatahimik na tagagamit",
|
||||||
|
"column.notifications": "Mga abiso",
|
||||||
|
"column.pins": "Mga nakapaskil na post",
|
||||||
|
"column.public": "Pinagsamang timeline",
|
||||||
|
"column_back_button.label": "Bumalik",
|
||||||
|
"column_header.hide_settings": "I-tago ang mga setting",
|
||||||
|
"column_header.moveLeft_settings": "I-lipat ang hanay pakaliwa",
|
||||||
|
"column_header.moveRight_settings": "I-lipat ang hanay pakanan",
|
||||||
|
"column_header.pin": "I-paskil",
|
||||||
|
"column_header.show_settings": "Ipakita ang mga setting",
|
||||||
|
"column_header.unpin": "Tanggalin sa pagkapaskil",
|
||||||
|
"column_subheading.settings": "Mga setting",
|
||||||
|
"community.column_settings.local_only": "Lokal lamang",
|
||||||
|
"community.column_settings.media_only": "Medya Lamang",
|
||||||
|
"community.column_settings.remote_only": "Liblib lamang",
|
||||||
|
"compose.language.change": "Magpalit ng wika",
|
||||||
|
"compose.language.search": "Maghanap ng mga wika...",
|
||||||
|
"compose.published.body": "Nailathala ang post.",
|
||||||
|
"compose.published.open": "Buksan",
|
||||||
|
"compose.saved.body": "Nai-save ang post.",
|
||||||
|
"compose_form.direct_message_warning_learn_more": "Matuto pa",
|
||||||
|
"compose_form.encryption_warning": "Ang mga post sa Mastodon ay hindi naka-encrypt nang dulo-dulo. Huwag magbahagi ng anumang sensitibong impormasyon sa Mastodon.",
|
||||||
|
"compose_form.hashtag_warning": "Hindi maililista ang post na ito sa anumang hashtag dahil hindi ito nakapubliko. Mga nakapublikong post lamang ang mahahanap ayon sa hashtag.",
|
||||||
|
"copy_icon_button.copied": "Sinipi sa clipboard",
|
||||||
|
"copypaste.copied": "Sinipi",
|
||||||
|
"copypaste.copy_to_clipboard": "I-sipi sa clipboard",
|
||||||
|
"directory.federated": "Mula sa kilalang fediverse",
|
||||||
|
"directory.local": "Mula sa {domain} lamang",
|
||||||
|
"directory.new_arrivals": "Mga bagong dating",
|
||||||
|
"directory.recently_active": "Kamakailang aktibo",
|
||||||
|
"disabled_account_banner.account_settings": "Mga setting ng account",
|
||||||
|
"disabled_account_banner.text": "Ang iyong account na {disabledAccount} ay hindi pinapagana ngayon.",
|
||||||
|
"dismissable_banner.community_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong ang mga account hinohost ng {domain}.",
|
||||||
|
"dismissable_banner.dismiss": "Alisin",
|
||||||
|
"dismissable_banner.explore_links": "Ito ang mga balitang kwento na pinaka-binabahagi sa social web ngayon. Ang mga mas bagong balitang kwento na pinost ng mas marami pang mga iba't ibang tao ay tinataasan ng antas.",
|
||||||
|
"dismissable_banner.explore_statuses": "Ito ang mga sumisikat na mga post sa iba't ibang bahagi ng social web ngayon. Ang mga mas bagong post na mas marami ang mga pagpapalakas at paborito ay tinataasan ng antas.",
|
||||||
|
"dismissable_banner.explore_tags": "Ito ang mga sumisikat na mga hashtag sa iba't ibang bahagi ng social web ngayon. Ang mga hashtag ginagamit ng mas maraming mga iba't ibang tao ay tinataasan ng antas.",
|
||||||
|
"dismissable_banner.public_timeline": "Ito ang mga pinakamakailang nakapublikong post mula sa mga taong nasa social web na sinusundan ng mga tao sa {domain}.",
|
||||||
|
"embed.instructions": "I-embed ang post na ito sa iyong pook-sapot sa pamamagitan ng pagsipi ng kodigo sa ilalim.",
|
||||||
|
"embed.preview": "Ito ang magiging itsura:",
|
||||||
|
"emoji_button.activity": "Aktibidad",
|
||||||
|
"emoji_button.clear": "Linisin",
|
||||||
|
"emoji_button.custom": "Pasadya",
|
||||||
|
"emoji_button.flags": "Mga watawat",
|
||||||
|
"emoji_button.food": "Pagkain at Inumin",
|
||||||
|
"emoji_button.label": "Maglagay ng emoji",
|
||||||
|
"emoji_button.nature": "Kalikasan",
|
||||||
|
"emoji_button.not_found": "Walang mahanap na mga tugmang emoji",
|
||||||
|
"emoji_button.objects": "Mga bagay",
|
||||||
|
"emoji_button.people": "Mga tao",
|
||||||
|
"emoji_button.recent": "Madalas na ginagamit",
|
||||||
|
"emoji_button.search": "Maghanap...",
|
||||||
|
"emoji_button.search_results": "Resulta ng paghahanap",
|
||||||
|
"emoji_button.symbols": "Mga tanda",
|
||||||
|
"emoji_button.travel": "Paglakbay at Mga Lugar",
|
||||||
|
"empty_column.account_hides_collections": "Pinili ng tagagamit na ito na hindi makuha ang impormasyong ito",
|
||||||
|
"empty_column.account_suspended": "Sinuspinde ang account",
|
||||||
|
"empty_column.account_timeline": "Walang mga post dito!",
|
||||||
|
"empty_column.account_unavailable": "Hindi makuha ang profile",
|
||||||
|
"empty_column.blocks": "Hindi ka pa naghahadlang ng sinumang tagagamit.",
|
||||||
|
"empty_column.bookmarked_statuses": "Wala ka pang naka-bookmark na post. Kapag nag-bookmark ka ng isa, makikita yun dito.",
|
||||||
|
"empty_column.community": "Walang laman ang lokal na timeline. Magsulat ng anuman papubliko para makaandar tayo!",
|
||||||
|
"empty_column.direct": "Wala ka pang mga palihim na banggit. Kapag nagpadala o tumanggap ka ng isa, makikita yun dito.",
|
||||||
|
"empty_column.domain_blocks": "Wala pang nakahadlang na domain.",
|
||||||
|
"empty_column.explore_statuses": "Wala pang sumisikat sa ngayon. Balik na lang sa muli!",
|
||||||
|
"empty_column.favourited_statuses": "Wala ka pang mga paboritong post. Kapag nag-paborito ka ng isa, makikita yun dito.",
|
||||||
|
"empty_column.favourites": "Wala pang may paborito ng post na ito. Kung may sinumang nagpaborito, makikita sila rito.",
|
||||||
|
"empty_column.follow_requests": "Wala ka pang mga hiling para sundan ka. Kapag nakatanggap ka ng isa, makikita yun dito.",
|
||||||
|
"empty_column.followed_tags": "Wala ka pang sinusunod na hashtag. Kapag may sinundan ka na, makikita sila rito.",
|
||||||
|
"empty_column.hashtag": "Wala pang laman ang hashtag na ito.",
|
||||||
|
"empty_column.home": "Walang laman ang timeline ng tahanan mo! Sumunod sa marami pang tao para mapunan ito.",
|
||||||
|
"empty_column.list": "Wala pang laman ang listahang ito. Kapag naglathala ng mga bagong post ang mga miyembro ng listahang ito, makikita iyon dito.",
|
||||||
|
"empty_column.lists": "Wala ka pang mga listahan. Kapag gumawa ka ng isa, makikita yun dito."
|
||||||
|
}
|
||||||
|
|
23
app/javascript/mastodon/locales/ia.json
Normal file
23
app/javascript/mastodon/locales/ia.json
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"account.add_or_remove_from_list": "Adder o remover ab listas",
|
||||||
|
"account.copy": "Copiar ligamine a profilo",
|
||||||
|
"bundle_column_error.network.title": "Error de rete",
|
||||||
|
"bundle_modal_error.close": "Clauder",
|
||||||
|
"column.home": "Initio",
|
||||||
|
"column_subheading.settings": "Parametros",
|
||||||
|
"compose.language.search": "Cercar linguas...",
|
||||||
|
"compose.published.open": "Aperir",
|
||||||
|
"confirmation_modal.cancel": "Cancellar",
|
||||||
|
"confirmations.logout.confirm": "Clauder le session",
|
||||||
|
"copypaste.copy_to_clipboard": "Copiar al area de transferentia",
|
||||||
|
"dismissable_banner.dismiss": "Dimitter",
|
||||||
|
"firehose.local": "Iste servitor",
|
||||||
|
"footer.about": "A proposito de",
|
||||||
|
"home.pending_critical_update.link": "Vider actualisationes",
|
||||||
|
"keyboard_shortcuts.my_profile": "Aperir tu profilo",
|
||||||
|
"lightbox.close": "Clauder",
|
||||||
|
"lightbox.next": "Sequente",
|
||||||
|
"link_preview.author": "Per {name}",
|
||||||
|
"lists.account.add": "Adder al lista",
|
||||||
|
"navigation_bar.about": "A proposito de"
|
||||||
|
}
|
700
app/javascript/mastodon/locales/ie.json
Normal file
700
app/javascript/mastodon/locales/ie.json
Normal file
|
@ -0,0 +1,700 @@
|
||||||
|
{
|
||||||
|
"about.blocks": "Moderat servitores",
|
||||||
|
"about.contact": "Contacter:",
|
||||||
|
"about.disclaimer": "Mastodon es programmatura líber e con fonte apert, e un marca de fabrica de Mastodon dGmbH.",
|
||||||
|
"about.domain_blocks.no_reason_available": "Rason ne disponibil",
|
||||||
|
"about.domain_blocks.preamble": "Mastodon generalmen possibilisa regardar li contenete de, e li interaction con usatores de quelcunc altri servitor in li fediverse. Ci trova se li exceptiones fat de ti-ci particulari servitor.",
|
||||||
|
"about.domain_blocks.silenced.explanation": "Generalmen, li profiles e contenete de ti-ci servitor ne va aparir, except si on sercha les explicitmen o optionalisa it per sequer.",
|
||||||
|
"about.domain_blocks.silenced.title": "Limitat",
|
||||||
|
"about.domain_blocks.suspended.explanation": "Necun data de ti-ci servitor va esser tractat, inmagasinat o exchangeat, quel inpossibilisa li interaction o comunication de usatores de ti-ci servitor.",
|
||||||
|
"about.domain_blocks.suspended.title": "Suspendet",
|
||||||
|
"about.not_available": "On ne ha disponibilisat ti-ci information sur ti-ci servitor.",
|
||||||
|
"about.powered_by": "Decentralisat social medie disponibilisat de {mastodon}",
|
||||||
|
"about.rules": "Regules del servitor",
|
||||||
|
"account.account_note_header": "Nota",
|
||||||
|
"account.add_or_remove_from_list": "Adjunter o remover de listes",
|
||||||
|
"account.badges.bot": "Automatisat",
|
||||||
|
"account.badges.group": "Gruppe",
|
||||||
|
"account.block": "Bloccar @{name}",
|
||||||
|
"account.block_domain": "Bloccar dominia {domain}",
|
||||||
|
"account.block_short": "Bloccar",
|
||||||
|
"account.blocked": "Bloccat",
|
||||||
|
"account.browse_more_on_origin_server": "Navigar plu sur li profil original",
|
||||||
|
"account.cancel_follow_request": "Anullar sequer",
|
||||||
|
"account.copy": "Copiar ligament al profil",
|
||||||
|
"account.direct": "Privatmen mentionar @{name}",
|
||||||
|
"account.disable_notifications": "Cessa notificar me quande @{name} posta",
|
||||||
|
"account.domain_blocked": "Dominia bloccat",
|
||||||
|
"account.edit_profile": "Redacter profil",
|
||||||
|
"account.enable_notifications": "Notificar me quande @{name} posta",
|
||||||
|
"account.endorse": "Recomandar sur profil",
|
||||||
|
"account.featured_tags.last_status_at": "Ultim posta ye {date}",
|
||||||
|
"account.featured_tags.last_status_never": "Null postas",
|
||||||
|
"account.featured_tags.title": "Recomandat hashtags de {name}",
|
||||||
|
"account.follow": "Sequer",
|
||||||
|
"account.followers": "Sequitores",
|
||||||
|
"account.followers.empty": "Ancor nequi seque ti-ci usator.",
|
||||||
|
"account.followers_counter": "{count, plural, one {{counter} Sequitor} other {{counter} Sequitor}}",
|
||||||
|
"account.following": "Sequent",
|
||||||
|
"account.following_counter": "{count, plural, one {{counter} Sequent} other {{counter} Sequent}}",
|
||||||
|
"account.follows.empty": "Ti-ci usator ancor ne seque quemcunc.",
|
||||||
|
"account.follows_you": "Seque te",
|
||||||
|
"account.go_to_profile": "Ear a profil",
|
||||||
|
"account.hide_reblogs": "Celar boosts de @{name}",
|
||||||
|
"account.in_memoriam": "In Memoriam.",
|
||||||
|
"account.joined_short": "Adheret",
|
||||||
|
"account.languages": "Changear lingues de subscrition",
|
||||||
|
"account.link_verified_on": "Proprietá de ti-ci ligament esset verificat ye {date}",
|
||||||
|
"account.locked_info": "Li statu de confidentialitá de ti-ci conto es configurat quam cludet. Li proprietario decide manualmen qui posse sequer.",
|
||||||
|
"account.media": "Medie",
|
||||||
|
"account.mention": "Mentionar @{name}",
|
||||||
|
"account.moved_to": "{name} ha indicat que su nov conto es ja:",
|
||||||
|
"account.mute": "Silentiar @{name}",
|
||||||
|
"account.mute_notifications_short": "Silentiar notificationes",
|
||||||
|
"account.mute_short": "Silentiar",
|
||||||
|
"account.muted": "Silentiat",
|
||||||
|
"account.no_bio": "Null descrition providet.",
|
||||||
|
"account.open_original_page": "Aperter li págine original",
|
||||||
|
"account.posts": "Postas",
|
||||||
|
"account.posts_with_replies": "Postas e replicas",
|
||||||
|
"account.report": "Raportar @{name}",
|
||||||
|
"account.requested": "Atendent aprobation. Cliccar por anullar li petition de sequer",
|
||||||
|
"account.requested_follow": "{name} ha petit sequer te",
|
||||||
|
"account.share": "Distribuer li profil de @{name}",
|
||||||
|
"account.show_reblogs": "Monstrar boosts de @{name}",
|
||||||
|
"account.statuses_counter": "{count, plural, one {{counter} Posta} other {{counter} Postas}}",
|
||||||
|
"account.unblock": "Desbloccar @{name}",
|
||||||
|
"account.unblock_domain": "Desbloccar dominia {domain}",
|
||||||
|
"account.unblock_short": "Desbloccar",
|
||||||
|
"account.unendorse": "Ne recomandar sur profil",
|
||||||
|
"account.unfollow": "Dessequer",
|
||||||
|
"account.unmute": "Dessilentiar @{name}",
|
||||||
|
"account.unmute_notifications_short": "Dessilentiar notificationes",
|
||||||
|
"account.unmute_short": "Dessilentiar",
|
||||||
|
"account_note.placeholder": "Clicca por adjunter un nota",
|
||||||
|
"admin.dashboard.daily_retention": "Usator-retention per die pos registration",
|
||||||
|
"admin.dashboard.monthly_retention": "Usator-retention per mensu pos registration",
|
||||||
|
"admin.dashboard.retention.average": "Medial",
|
||||||
|
"admin.dashboard.retention.cohort": "Mensu de registration",
|
||||||
|
"admin.dashboard.retention.cohort_size": "Nov usatores",
|
||||||
|
"admin.impact_report.instance_accounts": "Conto-profiles to-ci vell deleter",
|
||||||
|
"admin.impact_report.instance_followers": "Sequitores queles nor usatores vell perdir",
|
||||||
|
"admin.impact_report.instance_follows": "Sequitores queles lor usatores vell perdir",
|
||||||
|
"admin.impact_report.title": "Resumate de impact",
|
||||||
|
"alert.rate_limited.message": "Ples reprovar pos {retry_time, time, medium}.",
|
||||||
|
"alert.rate_limited.title": "Frequentie limitat",
|
||||||
|
"alert.unexpected.message": "Un ínexpectat erra ha evenit.",
|
||||||
|
"alert.unexpected.title": "Ups!",
|
||||||
|
"announcement.announcement": "Proclamation",
|
||||||
|
"attachments_list.unprocessed": "(íntractat)",
|
||||||
|
"audio.hide": "Celar audio",
|
||||||
|
"autosuggest_hashtag.per_week": "{count} per semane",
|
||||||
|
"boost_modal.combo": "Li proxim vez tu posse pressar {combo} por passar to-ci",
|
||||||
|
"bundle_column_error.copy_stacktrace": "Copiar erra-raporte",
|
||||||
|
"bundle_column_error.error.body": "Li demandat págine ne posset esser rendit. Fórsan it es un problema in nor code, o un problema de compatibilitá con li navigator.",
|
||||||
|
"bundle_column_error.error.title": "O ve!",
|
||||||
|
"bundle_column_error.network.body": "Un erra evenit durant li cargation de ti-ci págine, possibilmen pro un temporari problema de tui conexion del internet o de ti-ci servitor.",
|
||||||
|
"bundle_column_error.network.title": "Erra de retage",
|
||||||
|
"bundle_column_error.retry": "Provar denov",
|
||||||
|
"bundle_column_error.return": "Retornar al comense",
|
||||||
|
"bundle_column_error.routing.body": "Li demandat págine ne trovat se. Esque tu es cert que li URL in li adresse-barre es corect?",
|
||||||
|
"bundle_column_error.routing.title": "404",
|
||||||
|
"bundle_modal_error.close": "Cluder",
|
||||||
|
"bundle_modal_error.message": "Alquo errat durant li cargation de ti-ci componente.",
|
||||||
|
"bundle_modal_error.retry": "Provar denov",
|
||||||
|
"closed_registrations.other_server_instructions": "Pro que Mastodon es decentralisat, on posse crear un conto che un altri servitor e ancor interacter con ti-ci.",
|
||||||
|
"closed_registrations_modal.description": "Crear un conto che {domain} ne es possibil actualmen, ma ples memorar que on ne besona un conto specificmen che {domain} por usar Mastodon.",
|
||||||
|
"closed_registrations_modal.find_another_server": "Serchar altri servitor",
|
||||||
|
"closed_registrations_modal.preamble": "Mastodon es descentralisat, do on posse ser e interacter con quicunc che ti-ci servitor, sin egarda de u on crea su conto. On mem posse self-albergar it!",
|
||||||
|
"closed_registrations_modal.title": "Registrar sur Mastodon",
|
||||||
|
"column.about": "Information",
|
||||||
|
"column.blocks": "Bloccat usatores",
|
||||||
|
"column.bookmarks": "Marcatores",
|
||||||
|
"column.community": "Local témpor-linea",
|
||||||
|
"column.direct": "Privat mentiones",
|
||||||
|
"column.directory": "Navigar profiles",
|
||||||
|
"column.domain_blocks": "Bloccat dominia",
|
||||||
|
"column.favourites": "Favorites",
|
||||||
|
"column.firehose": "Témpor-lineas",
|
||||||
|
"column.follow_requests": "Petitiones de sequer",
|
||||||
|
"column.home": "Comense",
|
||||||
|
"column.lists": "Listes",
|
||||||
|
"column.mutes": "Silentiat usatores",
|
||||||
|
"column.notifications": "Notificationes",
|
||||||
|
"column.pins": "Pinglat postas",
|
||||||
|
"column.public": "Federat témpor-linea",
|
||||||
|
"column_back_button.label": "Retornar",
|
||||||
|
"column_header.hide_settings": "Celar parametres",
|
||||||
|
"column_header.moveLeft_settings": "Mover columne al levul",
|
||||||
|
"column_header.moveRight_settings": "Mover columne al dextri",
|
||||||
|
"column_header.pin": "Pinglar",
|
||||||
|
"column_header.show_settings": "Monstrar parametres",
|
||||||
|
"column_header.unpin": "Despinglar",
|
||||||
|
"column_subheading.settings": "Parametres",
|
||||||
|
"community.column_settings.local_only": "Solmen local",
|
||||||
|
"community.column_settings.media_only": "Solmen medie",
|
||||||
|
"community.column_settings.remote_only": "Solmen external",
|
||||||
|
"compose.language.change": "Changear lingue",
|
||||||
|
"compose.language.search": "Serchar lingues...",
|
||||||
|
"compose.published.body": "Posta publicat.",
|
||||||
|
"compose.published.open": "Aperter",
|
||||||
|
"compose.saved.body": "Posta conservat.",
|
||||||
|
"compose_form.direct_message_warning_learn_more": "Aprender plu",
|
||||||
|
"compose_form.hashtag_warning": "Ti-ci posta ne va esser listat sur quelcunc hashtag pro que it ne es public. Solmen public postas posse esser serchat per hashtag.",
|
||||||
|
"compose_form.lock_disclaimer": "Tui conto ne es {locked}. Quicunc posse sequer te por vider tui postas solmen por sequitores.",
|
||||||
|
"compose_form.lock_disclaimer.lock": "cludet",
|
||||||
|
"compose_form.placeholder": "Quo es in tui spiritu?",
|
||||||
|
"compose_form.poll.add_option": "Adjunter un option",
|
||||||
|
"compose_form.poll.duration": "Duration del balotation",
|
||||||
|
"compose_form.poll.option_placeholder": "Option {number}",
|
||||||
|
"compose_form.poll.remove_option": "Remover ti-ci option",
|
||||||
|
"compose_form.poll.switch_to_multiple": "Changea li balotation por permisser multiplic selectiones",
|
||||||
|
"compose_form.poll.switch_to_single": "Changea li balotation por permisser un singul selection",
|
||||||
|
"compose_form.publish": "Publicar",
|
||||||
|
"compose_form.publish_form": "Nov posta",
|
||||||
|
"compose_form.publish_loud": "{publish}!",
|
||||||
|
"compose_form.save_changes": "Conservar changes",
|
||||||
|
"compose_form.sensitive.hide": "{count, plural, one {Marcar medie quam sensitiv} other {Marcar medie quam sensitiv}}",
|
||||||
|
"compose_form.sensitive.marked": "{count, plural, one {Medie es marcat quam sensitiv} other {Medie es marcat quam sensitiv}}",
|
||||||
|
"compose_form.sensitive.unmarked": "{count, plural, one {Medie ne es marcat quam sensitiv} other {Medie ne es marcat quam sensitiv}}",
|
||||||
|
"compose_form.spoiler.marked": "Remover avise pri li contenete",
|
||||||
|
"compose_form.spoiler.unmarked": "Adjunter avise pri li contenete",
|
||||||
|
"compose_form.spoiler_placeholder": "Scri tui avise ci",
|
||||||
|
"confirmation_modal.cancel": "Anullar",
|
||||||
|
"confirmations.block.block_and_report": "Bloccar & Raportar",
|
||||||
|
"confirmations.block.confirm": "Bloccar",
|
||||||
|
"confirmations.block.message": "Esque tu vermen vole bloccar {name}?",
|
||||||
|
"confirmations.cancel_follow_request.confirm": "Retraer petition",
|
||||||
|
"confirmations.cancel_follow_request.message": "Esque tu vermen vole retraer tui petition sequer {name}?",
|
||||||
|
"confirmations.delete.confirm": "Deleter",
|
||||||
|
"confirmations.delete.message": "Esque tu vermen vole deleter ti-ci posta?",
|
||||||
|
"confirmations.delete_list.confirm": "Deleter",
|
||||||
|
"confirmations.delete_list.message": "Esque tu vermen vole permanentmen deleter ti-ci liste?",
|
||||||
|
"confirmations.discard_edit_media.confirm": "Forjettar",
|
||||||
|
"confirmations.discard_edit_media.message": "Tu have ínconservat changes al descrition de medie o al previse, forjettar les sin egarda?",
|
||||||
|
"confirmations.domain_block.confirm": "Bloccar li tot dominia",
|
||||||
|
"confirmations.domain_block.message": "Esque tu es certissim que tu vole bloccar li tot {domain}? In mult casus, bloccar o silentiar quelc specific contos es suficent e preferibil. Tu ne va vider contenete de ti dominia in quelcunc public témpor-linea o in tui notificationes. Tui sequitores de ti dominia va esser removet.",
|
||||||
|
"confirmations.edit.confirm": "Redacter",
|
||||||
|
"confirmations.edit.message": "Redacter nu va remplazzar li missage quel tu actualmen composi. Esque tu vermen vole proceder?",
|
||||||
|
"confirmations.logout.confirm": "Exear",
|
||||||
|
"confirmations.logout.message": "Esque tu vermen vole exear?",
|
||||||
|
"confirmations.mute.confirm": "Silentiar",
|
||||||
|
"confirmations.mute.explanation": "To-ci va celar postas de ilu e postas mentionant ilu, ma it ancor va permisser ilu vider tui postas e sequer te.",
|
||||||
|
"confirmations.mute.message": "Esque tu vermen vole silentiar {name}?",
|
||||||
|
"confirmations.redraft.confirm": "Deleter & redacter",
|
||||||
|
"confirmations.redraft.message": "Esque tu vermen vole deleter ti-ci posta e redacter it? Favorites e boosts va esser perdit, e responses al posta original va esser orfanat.",
|
||||||
|
"confirmations.reply.confirm": "Responder",
|
||||||
|
"confirmations.reply.message": "Responder nu va remplazzar li missage quel tu actualmen composi. Esque tu vermen vole proceder?",
|
||||||
|
"confirmations.unfollow.confirm": "Dessequer",
|
||||||
|
"confirmations.unfollow.message": "Esque tu vermen vole dessequer {name}?",
|
||||||
|
"conversation.delete": "Deleter conversation",
|
||||||
|
"conversation.mark_as_read": "Marcar quam leet",
|
||||||
|
"conversation.open": "Vider conversation",
|
||||||
|
"conversation.with": "Con {names}",
|
||||||
|
"copypaste.copied": "Copiat",
|
||||||
|
"directory.federated": "Del conosset fediverse",
|
||||||
|
"directory.local": "De solmen {domain}",
|
||||||
|
"directory.new_arrivals": "Nov arivantes",
|
||||||
|
"directory.recently_active": "Recentmen activ",
|
||||||
|
"disabled_account_banner.account_settings": "Parametres del conto",
|
||||||
|
"dismissable_banner.community_timeline": "Tis-ci es li postas max recent de gente con contos che {domain}.",
|
||||||
|
"dismissable_banner.dismiss": "Demisser",
|
||||||
|
"dismissable_banner.explore_links": "Tis-ci es li novas max distribuet che li social retage hodie. Novas plu nov, postat de plu diferent persones, es monstrat plu alt.",
|
||||||
|
"dismissable_banner.explore_statuses": "Tis-ci es postas del social retage queles es popular hodie. Nov postas con plu mult boosts e favorites es monstrat plu alt.",
|
||||||
|
"dismissable_banner.explore_tags": "Tis-ci es hashtags queles es popular che li social retage hodie. Hashtags usat de plu mult persones diferent es monstrat plu alt.",
|
||||||
|
"dismissable_banner.public_timeline": "Tis-ci es li max recent public postas de persones che li social retage quem gente che {domain} seque.",
|
||||||
|
"embed.instructions": "Inbedar ti-ci posta per copiar li code in infra.",
|
||||||
|
"embed.preview": "Vi qualmen it va aspecter:",
|
||||||
|
"emoji_button.activity": "Activitá",
|
||||||
|
"emoji_button.clear": "Efaciar",
|
||||||
|
"emoji_button.custom": "Custom",
|
||||||
|
"emoji_button.flags": "Flaggas",
|
||||||
|
"emoji_button.food": "Manjage & Trincage",
|
||||||
|
"emoji_button.label": "Inserter emoji",
|
||||||
|
"emoji_button.nature": "Natura",
|
||||||
|
"emoji_button.not_found": "Null acordant emoji trovat",
|
||||||
|
"emoji_button.objects": "Objectes",
|
||||||
|
"emoji_button.people": "Gente",
|
||||||
|
"emoji_button.recent": "Frequentmen usat",
|
||||||
|
"emoji_button.search": "Sercha...",
|
||||||
|
"emoji_button.search_results": "Resultates de sercha",
|
||||||
|
"emoji_button.symbols": "Simboles",
|
||||||
|
"emoji_button.travel": "Viageation & Locos",
|
||||||
|
"empty_column.account_hides_collections": "Ti-ci usator ha selectet ne publicar ti-ci information",
|
||||||
|
"empty_column.account_suspended": "Conto suspendet",
|
||||||
|
"empty_column.account_timeline": "Null postas ci!",
|
||||||
|
"empty_column.account_unavailable": "Profil índisponibil",
|
||||||
|
"empty_column.blocks": "Tu ancor ha bloccat null usatores.",
|
||||||
|
"empty_column.bookmarked_statuses": "Tu ancor have null marcat postas. Quande tu marca un, it va aparir ci.",
|
||||||
|
"empty_column.community": "Li local témpor-linea es vacui. Scri alquo publicmen por initiar la festa!",
|
||||||
|
"empty_column.direct": "Tu ancor have null privat mentiones. Quande tu misse o recive un, it va aparir ci.",
|
||||||
|
"empty_column.domain_blocks": "Ancor hay null bloccat dominias.",
|
||||||
|
"empty_column.explore_statuses": "Nequo es popular actualmen. Retorna plu tarde!",
|
||||||
|
"empty_column.favourited_statuses": "Tu ancor have null favorit postas. Quande tu favoritisa un, it va aparir ci.",
|
||||||
|
"empty_column.favourites": "Ancor nequi ha favoritisat ti-ci posta. Quande alqui fa it, ilu va aparir ci.",
|
||||||
|
"empty_column.follow_requests": "Tu ancor have null petitiones de sequer. Quande tu recive un, it va aparir ci.",
|
||||||
|
"empty_column.followed_tags": "Tu ancor ha sequet null hashtags. Quande tu seque un, it va aparir ci.",
|
||||||
|
"empty_column.hashtag": "Hay nullcos en ti-ci hashtag ancor.",
|
||||||
|
"empty_column.home": "Tui hemal témpor-linea es vacui! Sequer plu gente por plenar it.",
|
||||||
|
"empty_column.list": "Ancor ne hay quocunc in ti-ci liste. Quande membres de ti-ci liste publica nov postas, ili va aparir ci.",
|
||||||
|
"empty_column.lists": "Tu ancor have null listes. Quande tu crea un, it va aparir ci.",
|
||||||
|
"empty_column.mutes": "Tu ancor ha silentiat null usatores.",
|
||||||
|
"empty_column.notifications": "Tu have null notificationes. Quande altri persones interacte con te, tu va vider it ci.",
|
||||||
|
"empty_column.public": "Hay nullcos ci! Scri alquo publicmen, o manualmen seque usatores de altri servitores por plenar to-ci",
|
||||||
|
"error.unexpected_crash.explanation": "Pro un error in nor code o un problema de compatibilitá in li navigator, ti-ci págine ne posset esser monstrat correctmen.",
|
||||||
|
"error.unexpected_crash.explanation_addons": "Ti-ci págine ne posset esser monstrat correctmen. Li error es probabilmen causat de un extension al navigator o instrumentes por automatic traduction.",
|
||||||
|
"error.unexpected_crash.next_steps": "Prova recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.",
|
||||||
|
"error.unexpected_crash.next_steps_addons": "Prova desactivisar les e recargar li págine. Si to ne auxilia, tu fórsan posse usar Mastodon per un diferent navigator o aplication.",
|
||||||
|
"errors.unexpected_crash.report_issue": "Raportar un problema",
|
||||||
|
"explore.search_results": "Resultates de sercha",
|
||||||
|
"explore.suggested_follows": "Gente",
|
||||||
|
"explore.title": "Explorar",
|
||||||
|
"explore.trending_links": "Novas",
|
||||||
|
"explore.trending_statuses": "Postas",
|
||||||
|
"explore.trending_tags": "Hashtags",
|
||||||
|
"filter_modal.added.context_mismatch_explanation": "Ti-ci filtre-categorie ne aplica al contextu in quel tu ha accessat ti-ci posta. Si tu vole que li posta es filtrat anc in ti-ci contextu, tu deve redacter li filtre.",
|
||||||
|
"filter_modal.added.context_mismatch_title": "Contextu íncompatibil!",
|
||||||
|
"filter_modal.added.expired_explanation": "Ti-ci filtre-categorie ha expirat, tu deve changear li date de expiration por far it aplicar.",
|
||||||
|
"filter_modal.added.expired_title": "Expirat filtre!",
|
||||||
|
"filter_modal.added.review_and_configure": "Por reviser e configurar ti-ci filtre-categorie, ea a {settings_link}.",
|
||||||
|
"filter_modal.added.review_and_configure_title": "Parametres pri filtres",
|
||||||
|
"filter_modal.added.settings_link": "págine por parametres",
|
||||||
|
"filter_modal.added.short_explanation": "Ti-ci post ha esset adjuntet al sequente filtre-categorie: {title}.",
|
||||||
|
"filter_modal.added.title": "Filtre adjuntet!",
|
||||||
|
"filter_modal.select_filter.context_mismatch": "ne aplica a ti-ci contextu",
|
||||||
|
"filter_modal.select_filter.expired": "expirat",
|
||||||
|
"filter_modal.select_filter.prompt_new": "Nov categorie: {name}",
|
||||||
|
"filter_modal.select_filter.search": "Serchar o crear",
|
||||||
|
"filter_modal.select_filter.subtitle": "Usar un existent categorie o crear nov",
|
||||||
|
"filter_modal.select_filter.title": "Filtrar ti-ci posta",
|
||||||
|
"filter_modal.title.status": "Filtrar un posta",
|
||||||
|
"firehose.all": "Omno",
|
||||||
|
"firehose.local": "Ti-ci servitor",
|
||||||
|
"firehose.remote": "Altri servitores",
|
||||||
|
"follow_request.authorize": "Autorisar",
|
||||||
|
"follow_request.reject": "Rejecter",
|
||||||
|
"follow_requests.unlocked_explanation": "Benque tu conto ne es cludet, li administratores de {domain} pensat que tu fórsan vell voler tractar seque-petitiones de tis-ci contos manualmen.",
|
||||||
|
"followed_tags": "Sequet hashtags",
|
||||||
|
"footer.about": "Information",
|
||||||
|
"footer.directory": "Profilarium",
|
||||||
|
"footer.get_app": "Obtener li aplication",
|
||||||
|
"footer.invite": "Invitar gente",
|
||||||
|
"footer.privacy_policy": "Politica pri privatie",
|
||||||
|
"footer.source_code": "Vider li fonte-code",
|
||||||
|
"footer.status": "Statu",
|
||||||
|
"generic.saved": "Conservat",
|
||||||
|
"getting_started.heading": "Qualmen comensar",
|
||||||
|
"hashtag.column_header.tag_mode.all": "e {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.any": "o {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.none": "sin {additional}",
|
||||||
|
"hashtag.column_settings.select.no_options_message": "Null suggestiones trovat",
|
||||||
|
"hashtag.column_settings.select.placeholder": "Inscrir hashtags…",
|
||||||
|
"hashtag.column_settings.tag_mode.all": "Omni tis",
|
||||||
|
"hashtag.column_settings.tag_mode.any": "Quelcunc de tis",
|
||||||
|
"hashtag.column_settings.tag_mode.none": "Necun de tis",
|
||||||
|
"hashtag.column_settings.tag_toggle": "Include additional hashtags in ti-ci columne",
|
||||||
|
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||||
|
"hashtag.counter_by_uses": "{count, plural, one {{counter} posta} other {{counter} postas}}",
|
||||||
|
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} posta} other {{counter} postas}} hodie",
|
||||||
|
"hashtag.follow": "Sequer hashtag",
|
||||||
|
"hashtag.unfollow": "Dessequer hashtag",
|
||||||
|
"hashtags.and_other": "…e {count, plural, other {# in plu}}",
|
||||||
|
"home.actions.go_to_explore": "Vider lu populari",
|
||||||
|
"home.actions.go_to_suggestions": "Trovar gente por sequer",
|
||||||
|
"home.column_settings.basic": "Basic",
|
||||||
|
"home.column_settings.show_reblogs": "Monstrar boosts",
|
||||||
|
"home.column_settings.show_replies": "Monstrar responses",
|
||||||
|
"home.explore_prompt.body": "Tui hemal témpor-linea have un mixtura del hashtags queles tu selectet sequer, li gente quem tu selectet sequer, e li postas queles ili boosta. Si to sembla tro quiet, tu fórsan vole:",
|
||||||
|
"home.explore_prompt.title": "To-ci es tui hemal págine in Mastodon.",
|
||||||
|
"home.hide_announcements": "Celar proclamationes",
|
||||||
|
"home.pending_critical_update.body": "Ples actualisar tui Mastodon-servitor tam rapid quam es possibil!",
|
||||||
|
"home.pending_critical_update.link": "Vider actualisationes",
|
||||||
|
"home.pending_critical_update.title": "Urgent actualisation de securitá disponibil!",
|
||||||
|
"home.show_announcements": "Monstrar proclamationes",
|
||||||
|
"interaction_modal.description.favourite": "Con un conto de Mastodon, tu posse favoritisar ti-ci posta por informar li autor pri quant mult tu aprecia it e conservar it por plu tard.",
|
||||||
|
"interaction_modal.description.follow": "Con un conto de Mastodon, tu posse sequer {name} por reciver su postas in tui hemal témpor-linea.",
|
||||||
|
"interaction_modal.description.reblog": "Con un conto de Mastodon, tu posse boostar ti-ci posta por distribuer it a tui propri sequitores.",
|
||||||
|
"interaction_modal.description.reply": "Con un conto de Mastodon, tu posse responder a ti-ci posta.",
|
||||||
|
"interaction_modal.login.action": "Retorna a hem",
|
||||||
|
"interaction_modal.login.prompt": "Dominia de tui hemal servitor, p.ex. mastodon.social",
|
||||||
|
"interaction_modal.no_account_yet": "Ne sur Mastodon?",
|
||||||
|
"interaction_modal.on_another_server": "Sur un servitor diferent",
|
||||||
|
"interaction_modal.on_this_server": "Sur ti-ci servitor",
|
||||||
|
"interaction_modal.sign_in": "Tu ne ha initiat session che ti-ci servitor. U logia tui conto?",
|
||||||
|
"interaction_modal.title.favourite": "Favoritisar li posta de {name}",
|
||||||
|
"interaction_modal.title.follow": "Sequer {name}",
|
||||||
|
"interaction_modal.title.reblog": "Boostar li posta de {name}",
|
||||||
|
"interaction_modal.title.reply": "Responder al posta de {name}",
|
||||||
|
"intervals.full.days": "{number, plural, one {# die} other {# dies}}",
|
||||||
|
"intervals.full.hours": "{number, plural, one {# hor} other {# hores}}",
|
||||||
|
"intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}",
|
||||||
|
"keyboard_shortcuts.back": "Retroear",
|
||||||
|
"keyboard_shortcuts.blocked": "Aperter li lista de bloccat usatores",
|
||||||
|
"keyboard_shortcuts.boost": "Boostar posta",
|
||||||
|
"keyboard_shortcuts.column": "Infocar columne",
|
||||||
|
"keyboard_shortcuts.compose": "Infocar li text-area de composition",
|
||||||
|
"keyboard_shortcuts.description": "Descrition",
|
||||||
|
"keyboard_shortcuts.direct": "por aperter li columne de privat mentiones",
|
||||||
|
"keyboard_shortcuts.down": "Mover ad-infra in li liste",
|
||||||
|
"keyboard_shortcuts.enter": "Aperter posta",
|
||||||
|
"keyboard_shortcuts.favourite": "Favoritisar posta",
|
||||||
|
"keyboard_shortcuts.favourites": "Aperter li liste de favorites",
|
||||||
|
"keyboard_shortcuts.federated": "Aperter li federat témpor-linea",
|
||||||
|
"keyboard_shortcuts.home": "Aperter li hemal témpor-linea",
|
||||||
|
"keyboard_shortcuts.local": "Aperter li local témpor-linea",
|
||||||
|
"keyboard_shortcuts.mention": "Mentionar li autor",
|
||||||
|
"keyboard_shortcuts.muted": "Aperter li lista de silentiat usatores",
|
||||||
|
"keyboard_shortcuts.my_profile": "Aperter tui profil",
|
||||||
|
"keyboard_shortcuts.notifications": "Aperter li columne de notificationes",
|
||||||
|
"keyboard_shortcuts.open_media": "Aperter medie",
|
||||||
|
"keyboard_shortcuts.pinned": "Aperter li liste de pinglat postas",
|
||||||
|
"keyboard_shortcuts.profile": "Aperter profil del autor",
|
||||||
|
"keyboard_shortcuts.reply": "Responder al posta",
|
||||||
|
"keyboard_shortcuts.requests": "Aperter liste de seque-petitiones",
|
||||||
|
"keyboard_shortcuts.toggle_sensitivity": "Monstrar/celar medie",
|
||||||
|
"keyboard_shortcuts.toot": "Crear un nov posta",
|
||||||
|
"keyboard_shortcuts.up": "Mover ad-supra in li liste",
|
||||||
|
"lightbox.close": "Cluder",
|
||||||
|
"lightbox.next": "Sequent",
|
||||||
|
"lightbox.previous": "Precedent",
|
||||||
|
"limited_account_hint.action": "Monstrar profil totvez",
|
||||||
|
"limited_account_hint.title": "Ti-ci profil ha esset celat del moderatores de {domain}.",
|
||||||
|
"link_preview.author": "De {name}",
|
||||||
|
"lists.account.add": "Adjunter a liste",
|
||||||
|
"lists.account.remove": "Remover de liste",
|
||||||
|
"lists.delete": "Deleter liste",
|
||||||
|
"lists.edit": "Redacter liste",
|
||||||
|
"lists.edit.submit": "Changear titul",
|
||||||
|
"lists.exclusive": "Celar ti-ci postas del hemal témpor-linea",
|
||||||
|
"lists.new.create": "Adjunter liste",
|
||||||
|
"lists.new.title_placeholder": "Titul del nov liste",
|
||||||
|
"lists.replies_policy.followed": "Quelcunc sequet usator",
|
||||||
|
"lists.replies_policy.list": "Membres del liste",
|
||||||
|
"lists.replies_policy.none": "Nequi",
|
||||||
|
"lists.replies_policy.title": "Monstrar responses a:",
|
||||||
|
"lists.search": "Serchar inter li persones quem tu seque",
|
||||||
|
"lists.subheading": "Tui listes",
|
||||||
|
"load_pending": "{count, plural, one {# nov element} other {# nov elementes}}",
|
||||||
|
"loading_indicator.label": "Cargant…",
|
||||||
|
"media_gallery.toggle_visible": "{number, plural, one {Celar image} other {Celar images}}",
|
||||||
|
"moved_to_account_banner.text": "Tui conto {disabledAccount} es actualmen desactivisat pro que tu movet te a {movedToAccount}.",
|
||||||
|
"mute_modal.duration": "Duration",
|
||||||
|
"mute_modal.hide_notifications": "Celar notificationes de ti-ci usator?",
|
||||||
|
"mute_modal.indefinite": "Índefinit",
|
||||||
|
"navigation_bar.about": "Information",
|
||||||
|
"navigation_bar.blocks": "Bloccat usatores",
|
||||||
|
"navigation_bar.bookmarks": "Marcatores",
|
||||||
|
"navigation_bar.community_timeline": "Local témpor-linea",
|
||||||
|
"navigation_bar.compose": "Composir un nov posta",
|
||||||
|
"navigation_bar.direct": "Privat mentiones",
|
||||||
|
"navigation_bar.discover": "Decovrir",
|
||||||
|
"navigation_bar.domain_blocks": "Bloccat dominias",
|
||||||
|
"navigation_bar.edit_profile": "Redacter profil",
|
||||||
|
"navigation_bar.explore": "Explorar",
|
||||||
|
"navigation_bar.favourites": "Favorites",
|
||||||
|
"navigation_bar.filters": "Silentiat paroles",
|
||||||
|
"navigation_bar.follow_requests": "Petitiones de sequer",
|
||||||
|
"navigation_bar.followed_tags": "Sequet hashtags",
|
||||||
|
"navigation_bar.follows_and_followers": "Sequetes e sequitores",
|
||||||
|
"navigation_bar.lists": "Listes",
|
||||||
|
"navigation_bar.logout": "Exear",
|
||||||
|
"navigation_bar.mutes": "Silentiat usatores",
|
||||||
|
"navigation_bar.personal": "Personal",
|
||||||
|
"navigation_bar.pins": "Pinglat postas",
|
||||||
|
"navigation_bar.preferences": "Preferenties",
|
||||||
|
"navigation_bar.public_timeline": "Federat témpor-linea",
|
||||||
|
"navigation_bar.search": "Sercha",
|
||||||
|
"navigation_bar.security": "Securitá",
|
||||||
|
"not_signed_in_indicator.not_signed_in": "On deve aperter session por accesser ti-ci ressurse.",
|
||||||
|
"notification.admin.report": "{name} raportat {target}",
|
||||||
|
"notification.admin.sign_up": "{name} adheret",
|
||||||
|
"notification.favourite": "{name} favoritisat tui posta",
|
||||||
|
"notification.follow": "{name} sequet te",
|
||||||
|
"notification.follow_request": "{name} ha petit sequer te",
|
||||||
|
"notification.mention": "{name} mentionat te",
|
||||||
|
"notification.own_poll": "Tui balotation ha finit",
|
||||||
|
"notification.poll": "Un balotation in quel tu votat ha finit",
|
||||||
|
"notification.reblog": "{name} boostat tui posta",
|
||||||
|
"notification.status": "{name} just postat",
|
||||||
|
"notification.update": "{name} modificat un posta",
|
||||||
|
"notifications.clear": "Aclarar notificationes",
|
||||||
|
"notifications.clear_confirmation": "Vole tu vermen permanentmen aclarar omni tui notificationes?",
|
||||||
|
"notifications.column_settings.admin.report": "Nov raportas:",
|
||||||
|
"notifications.column_settings.admin.sign_up": "Nov registrationes:",
|
||||||
|
"notifications.column_settings.favourite": "Favorites:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Monstrar omni categories",
|
||||||
|
"notifications.column_settings.follow": "Nov sequitores:",
|
||||||
|
"notifications.column_settings.follow_request": "Nov petitiones de sequer:",
|
||||||
|
"notifications.column_settings.mention": "Mentiones:",
|
||||||
|
"notifications.column_settings.poll": "Resultates del balotation:",
|
||||||
|
"notifications.column_settings.reblog": "Boosts:",
|
||||||
|
"notifications.column_settings.show": "Monstrar in columne",
|
||||||
|
"notifications.column_settings.sound": "Far son",
|
||||||
|
"notifications.column_settings.status": "Nov postas:",
|
||||||
|
"notifications.column_settings.unread_notifications.category": "Ínleet notificationes",
|
||||||
|
"notifications.column_settings.unread_notifications.highlight": "Marcar ínleet notificationes",
|
||||||
|
"notifications.column_settings.update": "Redactiones:",
|
||||||
|
"notifications.filter.all": "Omni",
|
||||||
|
"notifications.filter.boosts": "Boosts",
|
||||||
|
"notifications.filter.favourites": "Favorites",
|
||||||
|
"notifications.filter.follows": "Seques",
|
||||||
|
"notifications.filter.mentions": "Mentiones",
|
||||||
|
"notifications.filter.polls": "Resultates del balotation",
|
||||||
|
"notifications.filter.statuses": "Actualisationes de gente quem tu seque",
|
||||||
|
"notifications.grant_permission": "Dar permission.",
|
||||||
|
"notifications.group": "{count} notificationes",
|
||||||
|
"notifications.mark_as_read": "Marcar omni notificationes quam leet",
|
||||||
|
"onboarding.action.back": "Retroear",
|
||||||
|
"onboarding.actions.back": "Retroear",
|
||||||
|
"onboarding.actions.go_to_explore": "Ear a vider lu populari",
|
||||||
|
"onboarding.actions.go_to_home": "Ear al hemal témpor-linea",
|
||||||
|
"onboarding.compose.template": "Salute #Mastodon!",
|
||||||
|
"onboarding.follows.empty": "Ínfortunatmen, null resultates posse esser monstrat actualmen. Tu posse provar serchar o usar li \"Explorar\" págine por trovar gente por sequer, o prova denov plu tard.",
|
||||||
|
"onboarding.follows.lead": "Tui hemal témpor-linea es li primari maniere de experir Mastodon. Plu persones quem tu seque, plu activ e interessant it va esser. Por auxiliar te comensar, vi quelc suggestiones:",
|
||||||
|
"onboarding.follows.title": "Personalisar tui hemal témpor-linea",
|
||||||
|
"onboarding.profile.discoverable": "Fa mi profil decovribil",
|
||||||
|
"onboarding.profile.discoverable_hint": "Quande tu opta esser decovribil in Mastodon, tui postas posse aparir in resultates de sercha e tendenties, e tui profil posse esser suggestet a persones con interesses simil a tui.",
|
||||||
|
"onboarding.profile.display_name": "Nómine a monstrar",
|
||||||
|
"onboarding.profile.display_name_hint": "Tui complet nómine o tui amusant nómine…",
|
||||||
|
"onboarding.profile.lead": "Tu sempre posse completar ti-ci plu tard in li parametres, u mem plu optiones de customisation es disponibil.",
|
||||||
|
"onboarding.profile.note": "Biografie",
|
||||||
|
"onboarding.profile.note_hint": "Tu posse @mentionar altri persones o #hashtags…",
|
||||||
|
"onboarding.profile.save_and_continue": "Conservar e avansar",
|
||||||
|
"onboarding.profile.title": "Popular tu profil",
|
||||||
|
"onboarding.profile.upload_avatar": "Cargar profil-portrete",
|
||||||
|
"onboarding.profile.upload_header": "Cargar cap-image",
|
||||||
|
"onboarding.share.lead": "Di gente qualmen ili posse trovar te che Mastodon!",
|
||||||
|
"onboarding.share.message": "Yo es {username} che #Mastodon! Veni e seque me a {url}",
|
||||||
|
"onboarding.share.next_steps": "Possibil sequent passus:",
|
||||||
|
"onboarding.share.title": "Partir tui profil",
|
||||||
|
"onboarding.start.lead": "Tu es ja un parte de Mastodon, un unic, decentralisat platform de medie social in quel tu—ne un algoritme—selectiona tui propri experientie. Lass nos departer sur un nov frontiera social:",
|
||||||
|
"onboarding.start.skip": "Auxilie por comensar ne besonat?",
|
||||||
|
"onboarding.start.title": "Tu ha successat!",
|
||||||
|
"onboarding.steps.follow_people.body": "Sequer interessant gente es to quo importa in Mastodon.",
|
||||||
|
"onboarding.steps.follow_people.title": "Personalisar tui hemal témpor-linea",
|
||||||
|
"onboarding.steps.publish_status.body": "Saluta li munde con text, images, videos o balotationes {emoji}",
|
||||||
|
"onboarding.steps.publish_status.title": "Crear tui unesim posta",
|
||||||
|
"onboarding.steps.setup_profile.title": "Personalisar tui profil",
|
||||||
|
"onboarding.steps.share_profile.body": "Di tui amics qualmen trovar te che Mastodon",
|
||||||
|
"onboarding.steps.share_profile.title": "Partir tui profil Mastodon",
|
||||||
|
"password_confirmation.exceeds_maxlength": "Confirmation de passa-parol transpassa li maxim longore de passa-paroles",
|
||||||
|
"password_confirmation.mismatching": "Confirmation de passa-parol ne egala",
|
||||||
|
"picture_in_picture.restore": "Restaurar",
|
||||||
|
"poll.closed": "Finit",
|
||||||
|
"poll.refresh": "Recargar",
|
||||||
|
"poll.reveal": "Vider resultates",
|
||||||
|
"poll.total_people": "{count, plural, one {# person} other {# persones}}",
|
||||||
|
"poll.total_votes": "{count, plural, one {# vote} other {# votes}}",
|
||||||
|
"poll.vote": "Votar",
|
||||||
|
"poll.voted": "Tu votat por ti-ci option",
|
||||||
|
"poll.votes": "{votes, plural, one {# vote} other {# votes}}",
|
||||||
|
"poll_button.add_poll": "Adjunter un balotation",
|
||||||
|
"poll_button.remove_poll": "Remover balotation",
|
||||||
|
"privacy.change": "Changear li privatie del posta",
|
||||||
|
"privacy.direct.long": "Visibil solmen a mentionat usatores",
|
||||||
|
"privacy.direct.short": "Solmen persones mentionat",
|
||||||
|
"privacy.private.long": "Visibil solmen por sequitores",
|
||||||
|
"privacy.private.short": "Solmen sequitores",
|
||||||
|
"privacy.public.long": "Visibil a omnes",
|
||||||
|
"privacy.public.short": "Public",
|
||||||
|
"privacy.unlisted.long": "Visibil por omnes, ma excludet de functiones de decovrition",
|
||||||
|
"privacy.unlisted.short": "Delistat",
|
||||||
|
"privacy_policy.last_updated": "Ultimmen actualisat ye {date}",
|
||||||
|
"privacy_policy.title": "Politica pri Privatie",
|
||||||
|
"recommended": "Recomandat",
|
||||||
|
"refresh": "Recargar",
|
||||||
|
"regeneration_indicator.label": "Cargant…",
|
||||||
|
"regeneration_indicator.sublabel": "On es preparant tui hemal témpor-linea!",
|
||||||
|
"relative_time.days": "{number}d",
|
||||||
|
"relative_time.full.days": "Ante {number, plural, one {# die} other {# dies}}",
|
||||||
|
"relative_time.full.hours": "Ante {number, plural, one {# hor} other {# hores}}",
|
||||||
|
"relative_time.full.just_now": "just nu",
|
||||||
|
"relative_time.full.minutes": "Ante {number, plural, one {# minute} other {# minutes}}",
|
||||||
|
"relative_time.full.seconds": "Ante {number, plural, one {# second} other {# secondes}}",
|
||||||
|
"relative_time.hours": "{number}h",
|
||||||
|
"relative_time.just_now": "nu",
|
||||||
|
"relative_time.minutes": "{number}m",
|
||||||
|
"relative_time.seconds": "{number}s",
|
||||||
|
"relative_time.today": "hodie",
|
||||||
|
"reply_indicator.cancel": "Anullar",
|
||||||
|
"report.block": "Bloccar",
|
||||||
|
"report.block_explanation": "Tu ne va vider su postas. Li usator ni va posser vider tui postas, ni sequer te, ni va posser saver pri li statu de esser bloccat.",
|
||||||
|
"report.categories.legal": "Legal",
|
||||||
|
"report.categories.other": "Altricos",
|
||||||
|
"report.categories.spam": "Spam",
|
||||||
|
"report.categories.violation": "Contenete violant un o pluri regules del servitor",
|
||||||
|
"report.category.subtitle": "Selecte li max bon option",
|
||||||
|
"report.category.title": "Di nos quo passa con ti-ci {type}",
|
||||||
|
"report.category.title_account": "profil",
|
||||||
|
"report.category.title_status": "posta",
|
||||||
|
"report.close": "Finit",
|
||||||
|
"report.comment.title": "Hay alquo plu quel tu pensa que noi deve saver?",
|
||||||
|
"report.forward": "Misser anc a {target}",
|
||||||
|
"report.forward_hint": "Ti-ci conto es de un altri servitor. Misser un anonimisat copie del raporte anc a ta?",
|
||||||
|
"report.mute": "Silentiar",
|
||||||
|
"report.mute_explanation": "Tu ne va vider su postas. Ilu ancor posse sequer te e vider tui postas e ne va saver que ilu es silentiat.",
|
||||||
|
"report.next": "Sequent",
|
||||||
|
"report.placeholder": "Additional comentas",
|
||||||
|
"report.reasons.dislike": "It ne plese me",
|
||||||
|
"report.reasons.dislike_description": "It es alquo quel displese te",
|
||||||
|
"report.reasons.legal": "It es ínlegal",
|
||||||
|
"report.reasons.legal_description": "Tu crede que it viola un lege del land de te o de tui servitor",
|
||||||
|
"report.reasons.other": "It es altricos",
|
||||||
|
"report.reasons.other_description": "Li problema ne apartene in li altri categories",
|
||||||
|
"report.reasons.spam": "It es spam",
|
||||||
|
"report.reasons.spam_description": "Maliciosi ligamentes, fals activitá, o repetitiv responses",
|
||||||
|
"report.reasons.violation": "It viola li regules del servitor",
|
||||||
|
"report.reasons.violation_description": "Tu save que it viola specific regules",
|
||||||
|
"report.rules.subtitle": "Selecte omnes queles aplica",
|
||||||
|
"report.rules.title": "Quel regules es violat?",
|
||||||
|
"report.statuses.subtitle": "Selecte omnes queles aplica",
|
||||||
|
"report.statuses.title": "Hay postas queles posse subtener ti-ci raporte?",
|
||||||
|
"report.submit": "Misser",
|
||||||
|
"report.target": "Raportant {target}",
|
||||||
|
"report.thanks.take_action": "Tis-ci es tui optiones por controlar ti quel tu vide che Mastodon:",
|
||||||
|
"report.thanks.take_action_actionable": "Durante que noi tracta ti-ci, tu posse far lu sequent contra @{name}:",
|
||||||
|
"report.thanks.title": "Vole tu ne vider to?",
|
||||||
|
"report.thanks.title_actionable": "Mersí pro raportar, noi va investigar to.",
|
||||||
|
"report.unfollow": "Dessequer @{name}",
|
||||||
|
"report.unfollow_explanation": "Tu seque ti-ci conto. Por ne vider su postas en tui hemal témpor-linea, dessequer it.",
|
||||||
|
"report_notification.attached_statuses": "{count, plural, one {{count} posta} other {{count} postas}} atachat",
|
||||||
|
"report_notification.categories.legal": "Legal",
|
||||||
|
"report_notification.categories.other": "Altricos",
|
||||||
|
"report_notification.categories.spam": "Spam",
|
||||||
|
"report_notification.categories.violation": "Violation de regul",
|
||||||
|
"report_notification.open": "Aperter raporta",
|
||||||
|
"search.no_recent_searches": "Null recent serchas",
|
||||||
|
"search.placeholder": "Serchar",
|
||||||
|
"search.quick_action.account_search": "Profiles acordant con {x}",
|
||||||
|
"search.quick_action.go_to_account": "Ear al profil {x}",
|
||||||
|
"search.quick_action.go_to_hashtag": "Ear al hashtag {x}",
|
||||||
|
"search.quick_action.open_url": "Aperter URL in Mastodon",
|
||||||
|
"search.quick_action.status_search": "Postas acordant con {x}",
|
||||||
|
"search.search_or_paste": "Serchar o glutinar URL",
|
||||||
|
"search_popout.full_text_search_disabled_message": "Ne disponibil che {domain}.",
|
||||||
|
"search_popout.full_text_search_logged_out_message": "Solmen disponibil con session initiat.",
|
||||||
|
"search_popout.options": "Sercha-parametres",
|
||||||
|
"search_popout.quick_actions": "Rapid actiones",
|
||||||
|
"search_popout.recent": "Recent serchas",
|
||||||
|
"search_popout.specific_date": "specific date",
|
||||||
|
"search_popout.user": "usator",
|
||||||
|
"search_results.accounts": "Profiles",
|
||||||
|
"search_results.all": "Omni",
|
||||||
|
"search_results.hashtags": "Hashtags",
|
||||||
|
"search_results.nothing_found": "Trovat se nullcos por ti término de sercha",
|
||||||
|
"search_results.see_all": "Vider omni",
|
||||||
|
"search_results.statuses": "Postas",
|
||||||
|
"search_results.title": "Sercha por {q}",
|
||||||
|
"server_banner.about_active_users": "Gente usant ti-ci servitor durant li ultim 30 dies (Mensual Activ Usatores)",
|
||||||
|
"server_banner.active_users": "activ usatores",
|
||||||
|
"server_banner.administered_by": "Administrat de:",
|
||||||
|
"server_banner.introduction": "{domain} es un part del decentralisat social retage constructet sur {mastodon}.",
|
||||||
|
"server_banner.learn_more": "Aprender plu",
|
||||||
|
"server_banner.server_stats": "Statisticas pri li servitor:",
|
||||||
|
"sign_in_banner.create_account": "Crear un conto",
|
||||||
|
"sign_in_banner.sign_in": "Intrar",
|
||||||
|
"sign_in_banner.sso_redirect": "Intrar o registrar se",
|
||||||
|
"sign_in_banner.text": "Intrar por sequer profiles o hashtags, favoritisar, partir e responder a postas. Tu posse anc interacter per tui conto che un diferent servitor.",
|
||||||
|
"status.admin_account": "Aperter interfacie de moderation por @{name}",
|
||||||
|
"status.admin_domain": "Aperter interfacie de moderation por {domain}",
|
||||||
|
"status.admin_status": "Aperter ti-ci posta in li interfacie de moderation",
|
||||||
|
"status.block": "Bloccar @{name}",
|
||||||
|
"status.bookmark": "Marcar",
|
||||||
|
"status.copy": "Copiar ligament al posta",
|
||||||
|
"status.delete": "Deleter",
|
||||||
|
"status.detailed_status": "Detalliat vise de conversation",
|
||||||
|
"status.direct": "Privatmen mentionar @{name}",
|
||||||
|
"status.direct_indicator": "Privat mention",
|
||||||
|
"status.edit": "Modificar",
|
||||||
|
"status.edited": "Modificat ye {date}",
|
||||||
|
"status.edited_x_times": "Modificat {count, plural, one {{count} vez} other {{count} vezes}}",
|
||||||
|
"status.embed": "Inbedar",
|
||||||
|
"status.favourite": "Favoritisar",
|
||||||
|
"status.filter": "Filtrar ti-ci posta",
|
||||||
|
"status.filtered": "Filtrat",
|
||||||
|
"status.hide": "Celar posta",
|
||||||
|
"status.history.created": "creat de {name} ye {date}",
|
||||||
|
"status.history.edited": "modificat de {name} ye {date}",
|
||||||
|
"status.load_more": "Cargar plu",
|
||||||
|
"status.media.open": "Cliccar por aperter",
|
||||||
|
"status.media.show": "Cliccar por monstrar",
|
||||||
|
"status.media_hidden": "Medie celat",
|
||||||
|
"status.mention": "Mentionar @{name}",
|
||||||
|
"status.more": "Plu",
|
||||||
|
"status.mute": "Silentiar @{name}",
|
||||||
|
"status.mute_conversation": "Silentiar conversation",
|
||||||
|
"status.open": "Expander ti-ci posta",
|
||||||
|
"status.pin": "Pinglar sur profil",
|
||||||
|
"status.pinned": "Pinglat posta",
|
||||||
|
"status.read_more": "Leer plu",
|
||||||
|
"status.redraft": "Deleter & redacter",
|
||||||
|
"status.remove_bookmark": "Remover marcator",
|
||||||
|
"status.replied_to": "Respondet a {name}",
|
||||||
|
"status.reply": "Responder",
|
||||||
|
"status.replyAll": "Responder al fil",
|
||||||
|
"status.report": "Raportar @{name}",
|
||||||
|
"status.sensitive_warning": "Sensitiv contenete",
|
||||||
|
"status.share": "Partir",
|
||||||
|
"status.show_filter_reason": "Monstrar totvez",
|
||||||
|
"status.show_less": "Monstrar minu",
|
||||||
|
"status.show_less_all": "Monstrar minu por omno",
|
||||||
|
"status.show_more": "Monstrar plu",
|
||||||
|
"status.show_more_all": "Monstrar plu por omno",
|
||||||
|
"status.show_original": "Monstrar li original",
|
||||||
|
"status.title.with_attachments": "{user} postat {attachmentCount, plural, one {un atachament} other {{attachmentCount} atachamentes}}",
|
||||||
|
"status.translate": "Traducter",
|
||||||
|
"status.translated_from_with": "Traductet de {lang} per {provider}",
|
||||||
|
"status.uncached_media_warning": "Previse ne disponibil",
|
||||||
|
"status.unmute_conversation": "Dessilentiar conversation",
|
||||||
|
"status.unpin": "Despinglar de profil",
|
||||||
|
"subscribed_languages.lead": "Solmen postas in selectet lingues va aparir in tui hemal e listal témpor-lineas pos li change. Selecte null por reciver postas in omni lingues.",
|
||||||
|
"subscribed_languages.save": "Conservar changes",
|
||||||
|
"subscribed_languages.target": "Changear abonnat lingues por {target}",
|
||||||
|
"tabs_bar.home": "Hem",
|
||||||
|
"tabs_bar.notifications": "Notificationes",
|
||||||
|
"time_remaining.days": "{number, plural, one {# die} other {# dies}} resta",
|
||||||
|
"time_remaining.hours": "{number, plural, one {# hor} other {# hores}} resta",
|
||||||
|
"time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} resta",
|
||||||
|
"time_remaining.moments": "Momentes resta",
|
||||||
|
"time_remaining.seconds": "{number, plural, one {# second} other {# secondes}} resta",
|
||||||
|
"timeline_hint.remote_resource_not_displayed": "{resource} de altri servitores ne es monstrat.",
|
||||||
|
"timeline_hint.resources.followers": "Sequitores",
|
||||||
|
"timeline_hint.resources.follows": "Sequetes",
|
||||||
|
"timeline_hint.resources.statuses": "Plu old postas",
|
||||||
|
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} persones}} durant li ultim {days, plural, one {die} other {{days} dies}}",
|
||||||
|
"trends.trending_now": "Actualmen populari",
|
||||||
|
"ui.beforeunload": "Tui íncomplet posta va esser perdit si tu lassa Mastodon.",
|
||||||
|
"upload_area.title": "Trenar & lassar cader por cargar",
|
||||||
|
"upload_button.label": "Adjunter images, un video o un audio-file",
|
||||||
|
"upload_error.limit": "Límite de medie-cargationes transpassat.",
|
||||||
|
"upload_error.poll": "On ne es permisset cargar medie con balotationes.",
|
||||||
|
"upload_form.audio_description": "Descrir por persones qui es surd o ne audi bon",
|
||||||
|
"upload_form.description": "Descrir por persones qui es ciec o have mal vision",
|
||||||
|
"upload_form.description_missing": "Null descrition adjuntet",
|
||||||
|
"upload_form.edit": "Redacter",
|
||||||
|
"upload_form.thumbnail": "Changear previsual image",
|
||||||
|
"upload_form.undo": "Deleter",
|
||||||
|
"upload_form.video_description": "Descrir por persones qui es surd, ciec, ne audi bon, o have mal vision",
|
||||||
|
"upload_modal.analyzing_picture": "Analisant image…",
|
||||||
|
"upload_modal.apply": "Aplicar",
|
||||||
|
"upload_modal.applying": "Aplicant…",
|
||||||
|
"upload_modal.choose_image": "Selecter image",
|
||||||
|
"upload_modal.detect_text": "Detecter text del image",
|
||||||
|
"upload_modal.edit_media": "Redacter medie",
|
||||||
|
"upload_modal.hint": "Clicca o trena li circul por selecter li focal punctu quel va esser sempre visibil in omni previse-images.",
|
||||||
|
"upload_modal.preparing_ocr": "Preparant OCR…",
|
||||||
|
"upload_modal.preview_label": "Previse ({ratio})",
|
||||||
|
"upload_progress.label": "Cargant...",
|
||||||
|
"upload_progress.processing": "Tractant…",
|
||||||
|
"username.taken": "Ti usator-nómine es ja prendet. Trova altri",
|
||||||
|
"video.close": "Cluder video",
|
||||||
|
"video.download": "Descargar file",
|
||||||
|
"video.exit_fullscreen": "Exear plen-ecran",
|
||||||
|
"video.expand": "Expander video",
|
||||||
|
"video.fullscreen": "Plen-ecran",
|
||||||
|
"video.hide": "Celar video",
|
||||||
|
"video.mute": "Silentiar li son",
|
||||||
|
"video.pause": "Pausar",
|
||||||
|
"video.play": "Reproducter",
|
||||||
|
"video.unmute": "Dessilentiar li son"
|
||||||
|
}
|
|
@ -20,6 +20,7 @@
|
||||||
"account.blocked": "Blokusita",
|
"account.blocked": "Blokusita",
|
||||||
"account.browse_more_on_origin_server": "Videz pluse che la originala profilo",
|
"account.browse_more_on_origin_server": "Videz pluse che la originala profilo",
|
||||||
"account.cancel_follow_request": "Desendez sequodemando",
|
"account.cancel_follow_request": "Desendez sequodemando",
|
||||||
|
"account.copy": "Kopiez ligilo al profilo",
|
||||||
"account.direct": "Private mencionez @{name}",
|
"account.direct": "Private mencionez @{name}",
|
||||||
"account.disable_notifications": "Cesez avizar me kande @{name} postas",
|
"account.disable_notifications": "Cesez avizar me kande @{name} postas",
|
||||||
"account.domain_blocked": "Domain hidden",
|
"account.domain_blocked": "Domain hidden",
|
||||||
|
@ -38,7 +39,8 @@
|
||||||
"account.follows.empty": "Ca uzanto ne sequa irgu til nun.",
|
"account.follows.empty": "Ca uzanto ne sequa irgu til nun.",
|
||||||
"account.follows_you": "Sequas tu",
|
"account.follows_you": "Sequas tu",
|
||||||
"account.go_to_profile": "Irez al profilo",
|
"account.go_to_profile": "Irez al profilo",
|
||||||
"account.hide_reblogs": "Celez busti de @{name}",
|
"account.hide_reblogs": "Celez repeti de @{name}",
|
||||||
|
"account.in_memoriam": "Memorige.",
|
||||||
"account.joined_short": "Juntita",
|
"account.joined_short": "Juntita",
|
||||||
"account.languages": "Chanjez abonita lingui",
|
"account.languages": "Chanjez abonita lingui",
|
||||||
"account.link_verified_on": "Proprieteso di ca ligilo kontrolesis ye {date}",
|
"account.link_verified_on": "Proprieteso di ca ligilo kontrolesis ye {date}",
|
||||||
|
@ -58,7 +60,7 @@
|
||||||
"account.requested": "Vartante aprobo",
|
"account.requested": "Vartante aprobo",
|
||||||
"account.requested_follow": "{name} demandis sequar tu",
|
"account.requested_follow": "{name} demandis sequar tu",
|
||||||
"account.share": "Partigez profilo di @{name}",
|
"account.share": "Partigez profilo di @{name}",
|
||||||
"account.show_reblogs": "Montrez busti de @{name}",
|
"account.show_reblogs": "Montrez repeti de @{name}",
|
||||||
"account.statuses_counter": "{count, plural, one {{counter} Posto} other {{counter} Posti}}",
|
"account.statuses_counter": "{count, plural, one {{counter} Posto} other {{counter} Posti}}",
|
||||||
"account.unblock": "Desblokusar @{name}",
|
"account.unblock": "Desblokusar @{name}",
|
||||||
"account.unblock_domain": "Desblokusar {domain}",
|
"account.unblock_domain": "Desblokusar {domain}",
|
||||||
|
@ -86,7 +88,7 @@
|
||||||
"attachments_list.unprocessed": "(neprocedita)",
|
"attachments_list.unprocessed": "(neprocedita)",
|
||||||
"audio.hide": "Celez audio",
|
"audio.hide": "Celez audio",
|
||||||
"autosuggest_hashtag.per_week": "{count} dum singla semano",
|
"autosuggest_hashtag.per_week": "{count} dum singla semano",
|
||||||
"boost_modal.combo": "Tu povas presar sur {combo} por omisar co en la venonta foyo",
|
"boost_modal.combo": "Vu povas pulsar {combo} por omisar co venontafoye",
|
||||||
"bundle_column_error.copy_stacktrace": "Kopierorraporto",
|
"bundle_column_error.copy_stacktrace": "Kopierorraporto",
|
||||||
"bundle_column_error.error.body": "La demandita pagino ne povas strukturigesar. Forsan ol esas eroro en kodexo hike o vidilkoncilieblesproblemo.",
|
"bundle_column_error.error.body": "La demandita pagino ne povas strukturigesar. Forsan ol esas eroro en kodexo hike o vidilkoncilieblesproblemo.",
|
||||||
"bundle_column_error.error.title": "Ach!",
|
"bundle_column_error.error.title": "Ach!",
|
||||||
|
@ -180,7 +182,7 @@
|
||||||
"confirmations.mute.explanation": "Co celigos posti de oli e posti quo mencionas oli, ma ol ankore permisas oli vidar vua posti e sequar vu.",
|
"confirmations.mute.explanation": "Co celigos posti de oli e posti quo mencionas oli, ma ol ankore permisas oli vidar vua posti e sequar vu.",
|
||||||
"confirmations.mute.message": "Ka vu certe volas silencigar {name}?",
|
"confirmations.mute.message": "Ka vu certe volas silencigar {name}?",
|
||||||
"confirmations.redraft.confirm": "Efacez e riskisez",
|
"confirmations.redraft.confirm": "Efacez e riskisez",
|
||||||
"confirmations.redraft.message": "Ka vu certe volas efacar ca posto e riskisigar ol? Favoriziti e busti esos perdita, e respondi al posto originala esos orfanigita.",
|
"confirmations.redraft.message": "Ka vu certe volas efacar ca posto e riskisigar ol? Favoriziti e repeti esos perdita, e respondi al posto originala esos orfanigita.",
|
||||||
"confirmations.reply.confirm": "Respondez",
|
"confirmations.reply.confirm": "Respondez",
|
||||||
"confirmations.reply.message": "Respondar nun remplos mesajo quon vu nun igas. Ka vu certe volas durar?",
|
"confirmations.reply.message": "Respondar nun remplos mesajo quon vu nun igas. Ka vu certe volas durar?",
|
||||||
"confirmations.unfollow.confirm": "Desequez",
|
"confirmations.unfollow.confirm": "Desequez",
|
||||||
|
@ -189,6 +191,7 @@
|
||||||
"conversation.mark_as_read": "Markizez quale lektita",
|
"conversation.mark_as_read": "Markizez quale lektita",
|
||||||
"conversation.open": "Videz konverso",
|
"conversation.open": "Videz konverso",
|
||||||
"conversation.with": "Kun {names}",
|
"conversation.with": "Kun {names}",
|
||||||
|
"copy_icon_button.copied": "Kopiita",
|
||||||
"copypaste.copied": "Kopiesis",
|
"copypaste.copied": "Kopiesis",
|
||||||
"copypaste.copy_to_clipboard": "Kopiez",
|
"copypaste.copy_to_clipboard": "Kopiez",
|
||||||
"directory.federated": "De savita fediverso",
|
"directory.federated": "De savita fediverso",
|
||||||
|
@ -200,7 +203,7 @@
|
||||||
"dismissable_banner.community_timeline": "Co esas maxim recenta publika posti de personi quo havas konto quo hostigesas da {domain}.",
|
"dismissable_banner.community_timeline": "Co esas maxim recenta publika posti de personi quo havas konto quo hostigesas da {domain}.",
|
||||||
"dismissable_banner.dismiss": "Ignorez",
|
"dismissable_banner.dismiss": "Ignorez",
|
||||||
"dismissable_banner.explore_links": "Ca nova rakonti parolesas da personi che ca e altra servili di necentraligita situo nun.",
|
"dismissable_banner.explore_links": "Ca nova rakonti parolesas da personi che ca e altra servili di necentraligita situo nun.",
|
||||||
"dismissable_banner.explore_statuses": "Yen posti del tota reto sociala qui esas populara hodie. Posti plu nova kun plu busti e favoriziti esas rangizita plu alte.",
|
"dismissable_banner.explore_statuses": "Yen posti del tota reto sociala qui esas populara hodie. Posti plu nova kun plu repeti e favoriziti esas rangizita plu alte.",
|
||||||
"dismissable_banner.explore_tags": "Ca hashtagi bezonas plu famoza inter personi che ca e altra servili di la necentraligita situo nun.",
|
"dismissable_banner.explore_tags": "Ca hashtagi bezonas plu famoza inter personi che ca e altra servili di la necentraligita situo nun.",
|
||||||
"dismissable_banner.public_timeline": "Yen la posti maxim recenta da personi che la reto sociala quin personi che {domain} sequas.",
|
"dismissable_banner.public_timeline": "Yen la posti maxim recenta da personi che la reto sociala quin personi che {domain} sequas.",
|
||||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
"embed.instructions": "Embed this status on your website by copying the code below.",
|
||||||
|
@ -220,6 +223,7 @@
|
||||||
"emoji_button.search_results": "Trovuri",
|
"emoji_button.search_results": "Trovuri",
|
||||||
"emoji_button.symbols": "Simboli",
|
"emoji_button.symbols": "Simboli",
|
||||||
"emoji_button.travel": "Vizito & Plasi",
|
"emoji_button.travel": "Vizito & Plasi",
|
||||||
|
"empty_column.account_hides_collections": "Ca uzanto selektis ne publikigar ca informo",
|
||||||
"empty_column.account_suspended": "Konto restriktesis",
|
"empty_column.account_suspended": "Konto restriktesis",
|
||||||
"empty_column.account_timeline": "No toots here!",
|
"empty_column.account_timeline": "No toots here!",
|
||||||
"empty_column.account_unavailable": "Profilo esas nedisponebla",
|
"empty_column.account_unavailable": "Profilo esas nedisponebla",
|
||||||
|
@ -294,14 +298,18 @@
|
||||||
"hashtag.column_settings.tag_mode.any": "Irga co",
|
"hashtag.column_settings.tag_mode.any": "Irga co",
|
||||||
"hashtag.column_settings.tag_mode.none": "Nula co",
|
"hashtag.column_settings.tag_mode.none": "Nula co",
|
||||||
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
||||||
|
"hashtag.counter_by_accounts": "{count, plural, one {{counter} partoprenanto} other {{counter} partoprenanti}}",
|
||||||
|
"hashtag.counter_by_uses": "{count, plural, one {{counter} posto} other {{counter} posti}}",
|
||||||
|
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} posto} other {{counter} posti}} hodie",
|
||||||
"hashtag.follow": "Sequez hashtago",
|
"hashtag.follow": "Sequez hashtago",
|
||||||
"hashtag.unfollow": "Desequez hashtago",
|
"hashtag.unfollow": "Desequez hashtago",
|
||||||
|
"hashtags.and_other": "…e {count, plural, one {# plusa}other {# plusa}}",
|
||||||
"home.actions.go_to_explore": "Videz quo es populara nun",
|
"home.actions.go_to_explore": "Videz quo es populara nun",
|
||||||
"home.actions.go_to_suggestions": "Trovez personi por sequar",
|
"home.actions.go_to_suggestions": "Trovez personi por sequar",
|
||||||
"home.column_settings.basic": "Simpla",
|
"home.column_settings.basic": "Simpla",
|
||||||
"home.column_settings.show_reblogs": "Montrar repeti",
|
"home.column_settings.show_reblogs": "Montrar repeti",
|
||||||
"home.column_settings.show_replies": "Montrar respondi",
|
"home.column_settings.show_replies": "Montrar respondi",
|
||||||
"home.explore_prompt.body": "Vua hemala fluo havos mixuro de la hashtagi quin vu selektis sequar, la personi quin vu selektis sequar, e la posti quin ili bustis. Se to semblas tro tacanta, vu darfas volar:",
|
"home.explore_prompt.body": "Vua hemala fluo havos mixuro de la hashtagi quin vu selektis sequar, la personi quin vu selektis sequar, e la posti quin ili repetis. Se to semblas tro tacanta, vu darfas volar:",
|
||||||
"home.explore_prompt.title": "Co es vua hemo en Mastodon.",
|
"home.explore_prompt.title": "Co es vua hemo en Mastodon.",
|
||||||
"home.hide_announcements": "Celez anunci",
|
"home.hide_announcements": "Celez anunci",
|
||||||
"home.pending_critical_update.body": "Voluntez aktualigar vua Mastodon-servilo tam balde kam es posibla!",
|
"home.pending_critical_update.body": "Voluntez aktualigar vua Mastodon-servilo tam balde kam es posibla!",
|
||||||
|
@ -310,7 +318,7 @@
|
||||||
"home.show_announcements": "Montrez anunci",
|
"home.show_announcements": "Montrez anunci",
|
||||||
"interaction_modal.description.favourite": "Kun konto che Mastodon, vu povas favorizar ca posto por savigar la autoro ke vu prizas ol e sparar ol por pose.",
|
"interaction_modal.description.favourite": "Kun konto che Mastodon, vu povas favorizar ca posto por savigar la autoro ke vu prizas ol e sparar ol por pose.",
|
||||||
"interaction_modal.description.follow": "Per konto che Mastodon, vu povas sequar {name} por ganar ola posti en vua hemniuzeto.",
|
"interaction_modal.description.follow": "Per konto che Mastodon, vu povas sequar {name} por ganar ola posti en vua hemniuzeto.",
|
||||||
"interaction_modal.description.reblog": "Per konto che Mastodon, vu povas bustizar ca posti por partigar kun sua sequanti.",
|
"interaction_modal.description.reblog": "Per konto che Mastodon, vu povas repetar ca posti por dissemar lo a vua propra sequati.",
|
||||||
"interaction_modal.description.reply": "Per konto che Mastodon, vu povas respondar ca posto.",
|
"interaction_modal.description.reply": "Per konto che Mastodon, vu povas respondar ca posto.",
|
||||||
"interaction_modal.login.action": "Irar a hemo",
|
"interaction_modal.login.action": "Irar a hemo",
|
||||||
"interaction_modal.login.prompt": "Domeno di vua hemala servilo, ex. mastodon.social",
|
"interaction_modal.login.prompt": "Domeno di vua hemala servilo, ex. mastodon.social",
|
||||||
|
@ -321,14 +329,14 @@
|
||||||
"interaction_modal.sign_in_hint": "Averto: To es la retsituo ube vu kreis konto. Se vu ne rimemoras, serchez vua bonvenanta e-posto. Vu anke povas enpozar vua kompleta uzantnomo! (ex. @Mastodon@mastodon.social)",
|
"interaction_modal.sign_in_hint": "Averto: To es la retsituo ube vu kreis konto. Se vu ne rimemoras, serchez vua bonvenanta e-posto. Vu anke povas enpozar vua kompleta uzantnomo! (ex. @Mastodon@mastodon.social)",
|
||||||
"interaction_modal.title.favourite": "Favorizez ca posto da {name}",
|
"interaction_modal.title.favourite": "Favorizez ca posto da {name}",
|
||||||
"interaction_modal.title.follow": "Sequez {name}",
|
"interaction_modal.title.follow": "Sequez {name}",
|
||||||
"interaction_modal.title.reblog": "Bustizez posto di {name}",
|
"interaction_modal.title.reblog": "Repetez posto di {name}",
|
||||||
"interaction_modal.title.reply": "Respondez posto di {name}",
|
"interaction_modal.title.reply": "Respondez posto di {name}",
|
||||||
"intervals.full.days": "{number, plural, one {# dio} other {# dii}}",
|
"intervals.full.days": "{number, plural, one {# dio} other {# dii}}",
|
||||||
"intervals.full.hours": "{number, plural, one {# horo} other {# hori}}",
|
"intervals.full.hours": "{number, plural, one {# horo} other {# hori}}",
|
||||||
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",
|
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",
|
||||||
"keyboard_shortcuts.back": "to navigate back",
|
"keyboard_shortcuts.back": "to navigate back",
|
||||||
"keyboard_shortcuts.blocked": "to open blocked users list",
|
"keyboard_shortcuts.blocked": "to open blocked users list",
|
||||||
"keyboard_shortcuts.boost": "to boost",
|
"keyboard_shortcuts.boost": "Repetez posto",
|
||||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
||||||
"keyboard_shortcuts.description": "Deskripto",
|
"keyboard_shortcuts.description": "Deskripto",
|
||||||
|
@ -383,6 +391,7 @@
|
||||||
"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",
|
||||||
|
@ -448,7 +457,7 @@
|
||||||
"notifications.column_settings.unread_notifications.highlight": "Briligez nelektita avizi",
|
"notifications.column_settings.unread_notifications.highlight": "Briligez nelektita avizi",
|
||||||
"notifications.column_settings.update": "Modifikati:",
|
"notifications.column_settings.update": "Modifikati:",
|
||||||
"notifications.filter.all": "Omna",
|
"notifications.filter.all": "Omna",
|
||||||
"notifications.filter.boosts": "Busti",
|
"notifications.filter.boosts": "Repeti",
|
||||||
"notifications.filter.favourites": "Favoriziti",
|
"notifications.filter.favourites": "Favoriziti",
|
||||||
"notifications.filter.follows": "Sequati",
|
"notifications.filter.follows": "Sequati",
|
||||||
"notifications.filter.mentions": "Mencioni",
|
"notifications.filter.mentions": "Mencioni",
|
||||||
|
@ -471,6 +480,17 @@
|
||||||
"onboarding.follows.empty": "Regretinde, nula rezultajo povas montresar nune. Vu povas esforcar serchar, o irar al explorala pagino por trovar personi sequinda, o esforcar itere pose.",
|
"onboarding.follows.empty": "Regretinde, nula rezultajo povas montresar nune. Vu povas esforcar serchar, o irar al explorala pagino por trovar personi sequinda, o esforcar itere pose.",
|
||||||
"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": "Trovebligez mea profilo",
|
||||||
|
"onboarding.profile.discoverable_hint": "Se vu selektas deskovrebleso che Mastodon, vua posti povas aparar en sercho-rezultaji e populari, e vua profilo forsan sugestesos a personi kun interesi simila a vua.",
|
||||||
|
"onboarding.profile.display_name": "Publika nomo",
|
||||||
|
"onboarding.profile.display_name_hint": "Vua tota nomo o vua gaya nomo…",
|
||||||
|
"onboarding.profile.lead": "Vu sempre povas kompletigar co plu tarde en la opcioni, ube mem plua personalizanta opcioni es disponebla.",
|
||||||
|
"onboarding.profile.note": "Biografio",
|
||||||
|
"onboarding.profile.note_hint": "Vu povas @mencionar altra personi o #hashtagi…",
|
||||||
|
"onboarding.profile.save_and_continue": "Preservez e avancez",
|
||||||
|
"onboarding.profile.title": "Kompletigez la profilo",
|
||||||
|
"onboarding.profile.upload_avatar": "Kargez profiloportreto",
|
||||||
|
"onboarding.profile.upload_header": "Kargez profilokapimajo",
|
||||||
"onboarding.share.lead": "Savigez personi quale ili povas trovar vu che Mastodon!",
|
"onboarding.share.lead": "Savigez personi quale ili povas trovar vu che Mastodon!",
|
||||||
"onboarding.share.message": "Me esas {username} che #Mastodon! Venez e sequez me ye {url}",
|
"onboarding.share.message": "Me esas {username} che #Mastodon! Venez e sequez me ye {url}",
|
||||||
"onboarding.share.next_steps": "Kozi quin vu darfas volar facar sequante:",
|
"onboarding.share.next_steps": "Kozi quin vu darfas volar facar sequante:",
|
||||||
|
@ -482,7 +502,7 @@
|
||||||
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
||||||
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
||||||
"onboarding.steps.publish_status.title": "Facar vua unesma posto",
|
"onboarding.steps.publish_status.title": "Facar vua unesma posto",
|
||||||
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
|
"onboarding.steps.setup_profile.body": "Vu interagos plue kun profilo detalizita.",
|
||||||
"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": "Share your profile",
|
||||||
|
@ -510,6 +530,7 @@
|
||||||
"privacy.unlisted.short": "Ne enlistigota",
|
"privacy.unlisted.short": "Ne enlistigota",
|
||||||
"privacy_policy.last_updated": "Antea novajo ye {date}",
|
"privacy_policy.last_updated": "Antea novajo ye {date}",
|
||||||
"privacy_policy.title": "Privatesguidilo",
|
"privacy_policy.title": "Privatesguidilo",
|
||||||
|
"recommended": "Rekomendata",
|
||||||
"refresh": "Rifreshez",
|
"refresh": "Rifreshez",
|
||||||
"regeneration_indicator.label": "Chargas…",
|
"regeneration_indicator.label": "Chargas…",
|
||||||
"regeneration_indicator.sublabel": "Vua hemniuzeto preparesas!",
|
"regeneration_indicator.sublabel": "Vua hemniuzeto preparesas!",
|
||||||
|
@ -580,6 +601,8 @@
|
||||||
"search.quick_action.status_search": "Posti qui asortas {x}",
|
"search.quick_action.status_search": "Posti qui asortas {x}",
|
||||||
"search.search_or_paste": "Serchar o pozar URL",
|
"search.search_or_paste": "Serchar o pozar URL",
|
||||||
"search_popout.full_text_search_disabled_message": "Nedisponebla che {domain}.",
|
"search_popout.full_text_search_disabled_message": "Nedisponebla che {domain}.",
|
||||||
|
"search_popout.full_text_search_logged_out_message": "Nur disponebla enirite.",
|
||||||
|
"search_popout.language_code": "ISO linguokodexo",
|
||||||
"search_popout.options": "Opcioni serchala",
|
"search_popout.options": "Opcioni serchala",
|
||||||
"search_popout.quick_actions": "Agi rapida",
|
"search_popout.quick_actions": "Agi rapida",
|
||||||
"search_popout.recent": "Lasta serchi",
|
"search_popout.recent": "Lasta serchi",
|
||||||
|
@ -607,8 +630,8 @@
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "Open this status in the moderation interface",
|
||||||
"status.block": "Restriktez @{name}",
|
"status.block": "Restriktez @{name}",
|
||||||
"status.bookmark": "Libromarko",
|
"status.bookmark": "Libromarko",
|
||||||
"status.cancel_reblog_private": "Debustez",
|
"status.cancel_reblog_private": "Desrepetez",
|
||||||
"status.cannot_reblog": "Ca posto ne povas bustesas",
|
"status.cannot_reblog": "Ca posto ne povas repetesar",
|
||||||
"status.copy": "Copy link to status",
|
"status.copy": "Copy link to status",
|
||||||
"status.delete": "Efacar",
|
"status.delete": "Efacar",
|
||||||
"status.detailed_status": "Detala konversvido",
|
"status.detailed_status": "Detala konversvido",
|
||||||
|
@ -636,10 +659,10 @@
|
||||||
"status.pin": "Pinglagez che profilo",
|
"status.pin": "Pinglagez che profilo",
|
||||||
"status.pinned": "Pinned toot",
|
"status.pinned": "Pinned toot",
|
||||||
"status.read_more": "Lektez pluse",
|
"status.read_more": "Lektez pluse",
|
||||||
"status.reblog": "Repetar",
|
"status.reblog": "Repetez",
|
||||||
"status.reblog_private": "Bustez kun originala videbleso",
|
"status.reblog_private": "Repetez kun originala videbleso",
|
||||||
"status.reblogged_by": "{name} repetita",
|
"status.reblogged_by": "{name} repetis",
|
||||||
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
|
"status.reblogs.empty": "Nulu ja repetis ca posto. Kande ulu facas lo, lu montresos hike.",
|
||||||
"status.redraft": "Efacez e riskisigez",
|
"status.redraft": "Efacez e riskisigez",
|
||||||
"status.remove_bookmark": "Efacez libromarko",
|
"status.remove_bookmark": "Efacez libromarko",
|
||||||
"status.replied_to": "Respondis a {name}",
|
"status.replied_to": "Respondis a {name}",
|
||||||
|
|
|
@ -21,7 +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.copy": "プロフィールへのリンクをコピー",
|
||||||
"account.direct": "@{name}さんに非公開でメンション",
|
"account.direct": "@{name}さんに非公開でメンション",
|
||||||
"account.disable_notifications": "@{name}さんの投稿時の通知を停止",
|
"account.disable_notifications": "@{name}さんの投稿時の通知を停止",
|
||||||
"account.domain_blocked": "ドメインブロック中",
|
"account.domain_blocked": "ドメインブロック中",
|
||||||
|
@ -192,7 +192,7 @@
|
||||||
"conversation.mark_as_read": "既読にする",
|
"conversation.mark_as_read": "既読にする",
|
||||||
"conversation.open": "会話を表示",
|
"conversation.open": "会話を表示",
|
||||||
"conversation.with": "{names}",
|
"conversation.with": "{names}",
|
||||||
"copy_icon_button.copied": "クリップボードにコピーされた",
|
"copy_icon_button.copied": "コピーしました",
|
||||||
"copypaste.copied": "コピーしました",
|
"copypaste.copied": "コピーしました",
|
||||||
"copypaste.copy_to_clipboard": "クリップボードにコピー",
|
"copypaste.copy_to_clipboard": "クリップボードにコピー",
|
||||||
"directory.federated": "既知の連合より",
|
"directory.federated": "既知の連合より",
|
||||||
|
@ -392,7 +392,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": "ミュートする期間",
|
||||||
|
@ -481,17 +481,17 @@
|
||||||
"onboarding.follows.empty": "表示できる結果はありません。検索やエクスプローラーを使ったり、ほかのアカウントをフォローしたり、後でもう一度試しください。",
|
"onboarding.follows.empty": "表示できる結果はありません。検索やエクスプローラーを使ったり、ほかのアカウントをフォローしたり、後でもう一度試しください。",
|
||||||
"onboarding.follows.lead": "ホームタイムラインはMastodonの軸足となる場所です。たくさんのユーザーをフォローすることで、ホームタイムラインはよりにぎやかでおもしろいものになります。手はじめに、おすすめのアカウントから何人かフォローしてみましょう:",
|
"onboarding.follows.lead": "ホームタイムラインはMastodonの軸足となる場所です。たくさんのユーザーをフォローすることで、ホームタイムラインはよりにぎやかでおもしろいものになります。手はじめに、おすすめのアカウントから何人かフォローしてみましょう:",
|
||||||
"onboarding.follows.title": "ホームタイムラインを埋める",
|
"onboarding.follows.title": "ホームタイムラインを埋める",
|
||||||
"onboarding.profile.discoverable": "自分のプロフィールが発見できないようにする",
|
"onboarding.profile.discoverable": "自分のプロフィールが見つけられるようにする",
|
||||||
"onboarding.profile.discoverable_hint": "マストドンの見つけやすくする機能が個人情報を利用することに承諾すると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたのプロフィールがあなたと似た興味関心を持つ人に提案されることがあります。",
|
"onboarding.profile.discoverable_hint": "Mastodonの「見つける」機能にオプトインすると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたに似た関心を持つ人にプロフィールがおすすめされることがあります。",
|
||||||
"onboarding.profile.display_name": "表示名",
|
"onboarding.profile.display_name": "表示名",
|
||||||
"onboarding.profile.display_name_hint": "あなたのフルネーム、または楽しい名前…",
|
"onboarding.profile.display_name_hint": "フルネーム、あるいは面白い名前など",
|
||||||
"onboarding.profile.lead": "このことは後でいつでも設定から完了させることが出来ますし、設定では更に多くのカスタマイズが利用可能になっています。",
|
"onboarding.profile.lead": "あとでいつでも修正できますし、設定画面にはこれ以外のカスタマイズ項目もあります。",
|
||||||
"onboarding.profile.note": "自己紹介",
|
"onboarding.profile.note": "自己紹介",
|
||||||
"onboarding.profile.note_hint": "@を使用して他の人々にメンションをすることができます。また#でハッシュタグが使用できます",
|
"onboarding.profile.note_hint": "ほかの人に @言及 したり、#ハッシュタグ を付けたりできます",
|
||||||
"onboarding.profile.save_and_continue": "保存してから続行して下さい",
|
"onboarding.profile.save_and_continue": "保存して続ける",
|
||||||
"onboarding.profile.title": "プロフィールの設定",
|
"onboarding.profile.title": "プロフィールの設定",
|
||||||
"onboarding.profile.upload_avatar": "プロフィール画像をアップロードしてください",
|
"onboarding.profile.upload_avatar": "プロフィール画像をアップロード",
|
||||||
"onboarding.profile.upload_header": "プロフィールのヘッダー画像をアップロードして下さい",
|
"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": "次のステップに進む:",
|
||||||
|
@ -606,6 +606,7 @@
|
||||||
"search.quick_action.status_search": "{x}に該当する投稿",
|
"search.quick_action.status_search": "{x}に該当する投稿",
|
||||||
"search.search_or_paste": "検索またはURLを入力",
|
"search.search_or_paste": "検索またはURLを入力",
|
||||||
"search_popout.full_text_search_disabled_message": "{domain}では利用できません。",
|
"search_popout.full_text_search_disabled_message": "{domain}では利用できません。",
|
||||||
|
"search_popout.full_text_search_logged_out_message": "ログイン時のみ利用できます。",
|
||||||
"search_popout.language_code": "ISO言語コード",
|
"search_popout.language_code": "ISO言語コード",
|
||||||
"search_popout.options": "検索オプション",
|
"search_popout.options": "検索オプション",
|
||||||
"search_popout.quick_actions": "クイック操作",
|
"search_popout.quick_actions": "クイック操作",
|
||||||
|
|
649
app/javascript/mastodon/locales/lad.json
Normal file
649
app/javascript/mastodon/locales/lad.json
Normal file
|
@ -0,0 +1,649 @@
|
||||||
|
{
|
||||||
|
"about.blocks": "Sirvidores moderados",
|
||||||
|
"about.contact": "Kontakto:",
|
||||||
|
"about.disclaimer": "Mastodon es un programario libero, kon kodiche avierto i una marka komersiala de Mastodon gGmbH.",
|
||||||
|
"about.domain_blocks.no_reason_available": "Razon no desponivle",
|
||||||
|
"about.domain_blocks.preamble": "Mastodon djeneralmente te permete ver kontenido de i enteraktuar kon utilizadores de kualseker otro sirvidor en el fediverso. Estas son las eksepsiones en este sirvidor en partikolar.",
|
||||||
|
"about.domain_blocks.silenced.explanation": "\"Djeneralmente no veras profiles i kontenido de este sirvidor, salvo ke eksplisitamente lo bushkes o sigas algun kuento de el.",
|
||||||
|
"about.domain_blocks.silenced.title": "Limitado",
|
||||||
|
"about.domain_blocks.suspended.explanation": "Dingunos datos de este sirvidor sera prosesado, magazinado o enterkambiado kon este sirvidor. Enteraksyon o komunikasyon kon sus utilizadores sera imposivle.",
|
||||||
|
"about.domain_blocks.suspended.title": "Suspendido",
|
||||||
|
"about.not_available": "Esta enformasyon no esta desponivle en este sirvidor.",
|
||||||
|
"about.powered_by": "Redes sosyalas desentralizadas kon uzo de {mastodon}",
|
||||||
|
"about.rules": "Reglas del sirvidor",
|
||||||
|
"account.account_note_header": "Nota",
|
||||||
|
"account.add_or_remove_from_list": "Adjusta a o kita de listas",
|
||||||
|
"account.badges.bot": "Bot",
|
||||||
|
"account.badges.group": "Grupo",
|
||||||
|
"account.block": "Bloka @{name}",
|
||||||
|
"account.block_domain": "Bloka el domeno {domain}",
|
||||||
|
"account.block_short": "Bloka",
|
||||||
|
"account.blocked": "Blokado",
|
||||||
|
"account.browse_more_on_origin_server": "Ve mas en el profil orijinal",
|
||||||
|
"account.cancel_follow_request": "Anula solisitud de segir",
|
||||||
|
"account.copy": "Kopia atadijo de profil",
|
||||||
|
"account.direct": "Enmenta a @{name} en privado",
|
||||||
|
"account.disable_notifications": "No me avizes mas sovre publikasyones de @{name}",
|
||||||
|
"account.domain_blocked": "Domeno blokado",
|
||||||
|
"account.edit_profile": "Edita profil",
|
||||||
|
"account.enable_notifications": "Avizame kuando @{name} publike",
|
||||||
|
"account.endorse": "Avalia en profil",
|
||||||
|
"account.featured_tags.last_status_at": "Ultima publikasyon de {date}",
|
||||||
|
"account.featured_tags.last_status_never": "\"No ay publikasyones",
|
||||||
|
"account.featured_tags.title": "Etiketas avaliadas de {name}",
|
||||||
|
"account.follow": "Sige",
|
||||||
|
"account.followers": "Suivantes",
|
||||||
|
"account.followers.empty": "Por agora dingun no sige a este utilizador.",
|
||||||
|
"account.followers_counter": "{count, plural, one {{counter} suivante} other {{counter} suivantes}}",
|
||||||
|
"account.following": "Sigiendo",
|
||||||
|
"account.following_counter": "{count, plural, other {Sigiendo a {counter}}}",
|
||||||
|
"account.follows.empty": "Este utilizador ainda no sige a ningun.",
|
||||||
|
"account.follows_you": "Te sige",
|
||||||
|
"account.go_to_profile": "Va al profil",
|
||||||
|
"account.hide_reblogs": "Eskonde repartajasyones de @{name}",
|
||||||
|
"account.in_memoriam": "De bendicha memoria.",
|
||||||
|
"account.joined_short": "Adjunto",
|
||||||
|
"account.languages": "Troka linguas suskrividas",
|
||||||
|
"account.link_verified_on": "La propriedad de este atadijo fue verifikada el {date}",
|
||||||
|
"account.locked_info": "El estado de privasita de este konto esta konfigurado komo serado. El proprietario reviza manualmente kien le puede segir.",
|
||||||
|
"account.media": "Multimedia",
|
||||||
|
"account.mention": "Enmenta a @{name}",
|
||||||
|
"account.moved_to": "{name} tiene endikado ke su muevo kuento agora es:",
|
||||||
|
"account.mute": "Silensia a @{name}",
|
||||||
|
"account.mute_notifications_short": "Silensia avizos de @{name}",
|
||||||
|
"account.mute_short": "Silensia",
|
||||||
|
"account.muted": "Silensiado",
|
||||||
|
"account.no_bio": "No ay deskripsion.",
|
||||||
|
"account.open_original_page": "Avre pajina orijnala",
|
||||||
|
"account.posts": "Publikasyones",
|
||||||
|
"account.posts_with_replies": "Kon repuestas",
|
||||||
|
"account.report": "Raporta @{name}",
|
||||||
|
"account.requested": "Asperando achetasion. Klika para anular la solisitud de segimiento",
|
||||||
|
"account.requested_follow": "{name} tiene solisitado segirte",
|
||||||
|
"account.share": "Partaja el profil de @{name}",
|
||||||
|
"account.show_reblogs": "Amostra repartajasyones de @{name}",
|
||||||
|
"account.statuses_counter": "{count, plural, one {{counter} publikasyon} other {{counter} publikasyones}}",
|
||||||
|
"account.unblock": "Dezbloka @{name}",
|
||||||
|
"account.unblock_domain": "Dezbloka domeno {domain}",
|
||||||
|
"account.unblock_short": "Dezbloka",
|
||||||
|
"account.unendorse": "No avalia en profil",
|
||||||
|
"account.unfollow": "Desige",
|
||||||
|
"account.unmute": "Desilensia a @{name}",
|
||||||
|
"account.unmute_notifications_short": "Desilensia avizos",
|
||||||
|
"account.unmute_short": "Desilensia",
|
||||||
|
"account_note.placeholder": "Klika para adjustar nota",
|
||||||
|
"admin.dashboard.daily_retention": "Proporsyon de retensyon de utilizadores por diya dempues de enrejistrasyon",
|
||||||
|
"admin.dashboard.monthly_retention": "Proporsyon de retensyon de utilizadores por mez dempues de enrejistrasyon",
|
||||||
|
"admin.dashboard.retention.average": "Media",
|
||||||
|
"admin.dashboard.retention.cohort": "Mez de enrejistrasyon",
|
||||||
|
"admin.dashboard.retention.cohort_size": "Muevos utilizadores",
|
||||||
|
"alert.rate_limited.message": "Por favor aprova dempues de {retry_time, time, medium}.",
|
||||||
|
"alert.rate_limited.title": "Trafiko limitado",
|
||||||
|
"alert.unexpected.message": "Afito un yerro no asperado.",
|
||||||
|
"alert.unexpected.title": "Atyo!",
|
||||||
|
"announcement.announcement": "Pregon",
|
||||||
|
"attachments_list.unprocessed": "(no prosesado)",
|
||||||
|
"audio.hide": "Eskonder audio",
|
||||||
|
"autosuggest_hashtag.per_week": "{count} por semana",
|
||||||
|
"boost_modal.combo": "Puedes klikar {combo} para ometer esto la proksima vez",
|
||||||
|
"bundle_column_error.copy_stacktrace": "Kopia el raporto de yerro",
|
||||||
|
"bundle_column_error.error.body": "La pajina solisitada no pudo ser renderada. Podria ser por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador.",
|
||||||
|
"bundle_column_error.error.title": "Atyo, no!",
|
||||||
|
"bundle_column_error.network.body": "Uvo un yerro kon la prova de eskargar esta pajina. Esto puede ser por un problem temporal kon tu koneksyon a la internet o a este sirvidor.",
|
||||||
|
"bundle_column_error.network.title": "Yerro de red",
|
||||||
|
"bundle_column_error.retry": "Aprova de muevo",
|
||||||
|
"bundle_column_error.return": "Volta a la linya prinsipala",
|
||||||
|
"bundle_column_error.routing.body": "No se pudo trokar la pajina solisitada. Estas siguro ke el adreso URL en la vara de adreso es djusto?",
|
||||||
|
"bundle_column_error.routing.title": "404",
|
||||||
|
"bundle_modal_error.close": "Serra",
|
||||||
|
"bundle_modal_error.message": "Algo negro afito al eskargar este komponente.",
|
||||||
|
"bundle_modal_error.retry": "Aprova de muevo",
|
||||||
|
"closed_registrations.other_server_instructions": "Deke Mastodon es desentralizado, puedes kriyar un kuento en otro sirvidor i ainda enteraktuar kon este.",
|
||||||
|
"closed_registrations_modal.description": "Aktualmente no es posivle kriyar un kuento en {domain}, ama por favor akodrate de ke no ay menester de tener un kuento espesifikamente en {domain} para kulanear Mastodon.",
|
||||||
|
"closed_registrations_modal.find_another_server": "Bushka otro sirvidor",
|
||||||
|
"closed_registrations_modal.preamble": "Mastodon es desentralizado, estonses sin emportansya ande kriyas tu kuento, podras segir i enteraktuar kon kualseker persona en este sirvidor. Tamyen puedes balabayarlo tu mezmo!",
|
||||||
|
"closed_registrations_modal.title": "Enrerjistrate en Mastodon",
|
||||||
|
"column.about": "Sovre mozotros",
|
||||||
|
"column.blocks": "Utilizadores blokados",
|
||||||
|
"column.bookmarks": "Markadores",
|
||||||
|
"column.community": "Linya de tiempo lokala",
|
||||||
|
"column.direct": "Enmentaduras privadas",
|
||||||
|
"column.directory": "Eksplora profiles",
|
||||||
|
"column.domain_blocks": "Domenos blokados",
|
||||||
|
"column.favourites": "Te plazen",
|
||||||
|
"column.firehose": "Linyas en bivo",
|
||||||
|
"column.follow_requests": "Solisitudes de segimiento",
|
||||||
|
"column.home": "Linya prinsipala",
|
||||||
|
"column.lists": "Listas",
|
||||||
|
"column.mutes": "Utilizadores silensiados",
|
||||||
|
"column.notifications": "Avizos",
|
||||||
|
"column.pins": "Publikasyones fiksadas",
|
||||||
|
"column.public": "Linya de tiempo federada",
|
||||||
|
"column_back_button.label": "Atras",
|
||||||
|
"column_header.hide_settings": "Eskonde opsyones",
|
||||||
|
"column_header.moveLeft_settings": "Move kolumna a la siedra",
|
||||||
|
"column_header.moveRight_settings": "Move kolumna a la derecha",
|
||||||
|
"column_header.pin": "Fiksa",
|
||||||
|
"column_header.show_settings": "Amostra opsyones",
|
||||||
|
"column_header.unpin": "Defiksar",
|
||||||
|
"column_subheading.settings": "Opsyones",
|
||||||
|
"community.column_settings.local_only": "Solo lokalas",
|
||||||
|
"community.column_settings.media_only": "Solo multimedia",
|
||||||
|
"community.column_settings.remote_only": "Solo remotas",
|
||||||
|
"compose.language.change": "Troka lingua",
|
||||||
|
"compose.language.search": "Bushka linguas...",
|
||||||
|
"compose.published.body": "Publikasyon publikada.",
|
||||||
|
"compose.published.open": "Avre",
|
||||||
|
"compose.saved.body": "Publikasyon guadrada.",
|
||||||
|
"compose_form.direct_message_warning_learn_more": "Ambezate mas",
|
||||||
|
"compose_form.encryption_warning": "Publikasyones en Mastodon no son shifradas de lado a lado. No partajes dinguna enformasyon sensivle por Mastodon.",
|
||||||
|
"compose_form.hashtag_warning": "Esta publikasyon no sera amostrada debasho de dinguna etiketa si no es publika. Solo publikasyones publikas se pueden bushkar por la etiketa.",
|
||||||
|
"compose_form.lock_disclaimer": "Tu kuento no esta {locked}. Todos pueden segirte para ver tus publikasyones solo para suivantes.",
|
||||||
|
"compose_form.lock_disclaimer.lock": "serrado",
|
||||||
|
"compose_form.placeholder": "Ke haber?",
|
||||||
|
"compose_form.poll.add_option": "Adjusta opsyon",
|
||||||
|
"compose_form.poll.duration": "Durasion de anketa",
|
||||||
|
"compose_form.poll.option_placeholder": "Opsyon {number}",
|
||||||
|
"compose_form.poll.remove_option": "Kita esta opsyon",
|
||||||
|
"compose_form.poll.switch_to_multiple": "Trokar anketa para permeter a eskojer mas ke una opsyon",
|
||||||
|
"compose_form.poll.switch_to_single": "Trokar anketa para permeter a eskojer solo una opsyon",
|
||||||
|
"compose_form.publish": "Publika",
|
||||||
|
"compose_form.publish_form": "Mueva publikasyon",
|
||||||
|
"compose_form.publish_loud": "{publish}!",
|
||||||
|
"compose_form.save_changes": "Guadra trokamientos",
|
||||||
|
"compose_form.sensitive.hide": "{count, plural, one {Marka material komo sensivle} other {Marka material komo sensivle}}",
|
||||||
|
"compose_form.sensitive.marked": "{count, plural, one {Material markado komo sensivle} other {Material markado komo sensivle}}",
|
||||||
|
"compose_form.sensitive.unmarked": "{count, plural, one {Material no markado komo sensivle} other {Material no markado komo sensivle}}",
|
||||||
|
"compose_form.spoiler.marked": "Kita avertensya de kontenido",
|
||||||
|
"compose_form.spoiler.unmarked": "Adjusta avertensya de kontenido",
|
||||||
|
"compose_form.spoiler_placeholder": "Eskrive tu avertensya aki",
|
||||||
|
"confirmation_modal.cancel": "Anula",
|
||||||
|
"confirmations.block.block_and_report": "Bloka i raporta",
|
||||||
|
"confirmations.block.confirm": "Bloka",
|
||||||
|
"confirmations.block.message": "Estas siguro ke keres blokar a {name}?",
|
||||||
|
"confirmations.cancel_follow_request.confirm": "Anula solisitud",
|
||||||
|
"confirmations.cancel_follow_request.message": "Estas siguro ke keres anular tu solisitud de segir a {name}?",
|
||||||
|
"confirmations.delete.confirm": "Efasa",
|
||||||
|
"confirmations.delete.message": "Estas siguro ke keres efasar esta publikasyon?",
|
||||||
|
"confirmations.delete_list.confirm": "Efasa",
|
||||||
|
"confirmations.delete_list.message": "Estas siguro ke keres permanentemente efasar esta lista?",
|
||||||
|
"confirmations.discard_edit_media.confirm": "Anula",
|
||||||
|
"confirmations.discard_edit_media.message": "Tienes trokamientos no guadrados en la deskripsion o vista previa. Keres efasarlos entanto?",
|
||||||
|
"confirmations.domain_block.confirm": "Bloka domeno entero",
|
||||||
|
"confirmations.domain_block.message": "Estas totalmente siguro ke keres blokar todo el domeno {domain}? En djeneral unos kuantos blokos o silensiamientos son sufisientes i preferavles. No veras kontenido de akel domeno en dinguna linya de tiempo publika ni ent tus avizos. Tus suivantes de akel domeno seran kitados.",
|
||||||
|
"confirmations.edit.confirm": "Edita",
|
||||||
|
"confirmations.edit.message": "Editar agora kitara el mesaj kualo estas eskriviendo aktualmente. Estas siguro ke keres fazerlo?",
|
||||||
|
"confirmations.logout.confirm": "Sal",
|
||||||
|
"confirmations.logout.message": "Estas siguro ke keres salir de tu kuento?",
|
||||||
|
"confirmations.mute.confirm": "Silensia",
|
||||||
|
"confirmations.mute.explanation": "Esto eskondera las publikasyones de este kuento i publikasyones ke lo enmentan, pero ainda les permetera segirte.",
|
||||||
|
"confirmations.mute.message": "Estas siguro ke keres silensiar a {name}?",
|
||||||
|
"confirmations.redraft.confirm": "Efasar i reeskrivir",
|
||||||
|
"confirmations.redraft.message": "Estas siguro ke keres efasar esta publikasyon i reeskrivirla? Pedreras todos los favoritos i repartajasyones asosiados kon esta publikasyon i repuestas a eya seran guerfanadas.",
|
||||||
|
"confirmations.reply.confirm": "Arisponde",
|
||||||
|
"confirmations.reply.message": "Arispondir agora kitara el mesaj kualo estas eskriviendo aktualmente. Estas siguro ke keres fazerlo?",
|
||||||
|
"confirmations.unfollow.confirm": "Desige",
|
||||||
|
"confirmations.unfollow.message": "Estas siguro ke keres deshar de segir a {name}?",
|
||||||
|
"conversation.delete": "Efasa konversasyon",
|
||||||
|
"conversation.mark_as_read": "Marka komo meldado",
|
||||||
|
"conversation.open": "Ve konversasyon",
|
||||||
|
"conversation.with": "Kon {names}",
|
||||||
|
"copy_icon_button.copied": "Kopiado al portapapeles",
|
||||||
|
"copypaste.copied": "Kopiado",
|
||||||
|
"copypaste.copy_to_clipboard": "Kopia al portapapeles",
|
||||||
|
"directory.federated": "Dizde el fediverso konesido",
|
||||||
|
"directory.local": "Solo de {domain}",
|
||||||
|
"directory.new_arrivals": "Arivados resientemente",
|
||||||
|
"directory.recently_active": "Aktivos resientemente",
|
||||||
|
"disabled_account_banner.account_settings": "Preferensyas de kuento",
|
||||||
|
"disabled_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado.",
|
||||||
|
"dismissable_banner.community_timeline": "Estas son las publikasyones publikas mas resientes de las personas kualos kuentos estan balabayados en {domain}.",
|
||||||
|
"dismissable_banner.dismiss": "Kita",
|
||||||
|
"dismissable_banner.explore_links": "Estos haberes estan diskutidos agora por djente en este sirvidor i otros de la red desentralizada.",
|
||||||
|
"dismissable_banner.explore_statuses": "Estas publikasyones de este sirvidor i otros de la red desentralizada estan agora popularas. Publikasyones mas muevas, kon mas repartajasiones i favoritadas por mas djente aparesen primero.",
|
||||||
|
"dismissable_banner.explore_tags": "Estas etiketas estan agora popularas en la red sosyala. Etiketas uzadas por mas djente aparesen primero.",
|
||||||
|
"dismissable_banner.public_timeline": "Estas son las publikasyones publikas mas resientes de personas en la red sosyala a las kualas la djente de {domain} sige.",
|
||||||
|
"embed.instructions": "Enkrusta esta publikasyon en tu sitio internetiko kopiando este kodiche.",
|
||||||
|
"embed.preview": "Ansi paresera:",
|
||||||
|
"emoji_button.activity": "Aktivita",
|
||||||
|
"emoji_button.clear": "Alimpia",
|
||||||
|
"emoji_button.custom": "Personalizado",
|
||||||
|
"emoji_button.flags": "Bandieras",
|
||||||
|
"emoji_button.food": "Kumidas i beverajes",
|
||||||
|
"emoji_button.label": "Adjustar emoji",
|
||||||
|
"emoji_button.nature": "Natura",
|
||||||
|
"emoji_button.not_found": "Emojis no topados",
|
||||||
|
"emoji_button.objects": "Objektos",
|
||||||
|
"emoji_button.people": "Djente",
|
||||||
|
"emoji_button.recent": "Uzados frekuentemente",
|
||||||
|
"emoji_button.search": "Bushka...",
|
||||||
|
"emoji_button.search_results": "Rizultados de bushkeda",
|
||||||
|
"emoji_button.symbols": "Simbolos",
|
||||||
|
"emoji_button.travel": "Viajes i lugares",
|
||||||
|
"empty_column.account_suspended": "Kuento suspendido",
|
||||||
|
"empty_column.account_timeline": "No ay publikasyones aki!",
|
||||||
|
"empty_column.account_unavailable": "Profil no desponivle",
|
||||||
|
"empty_column.blocks": "Ainda no tienes blokado a dingun utilizador.",
|
||||||
|
"empty_column.bookmarked_statuses": "Ainda no tienes dinguna publikasyon kon markador. Kuando adjustes un markador a una, se amostrara aki.",
|
||||||
|
"empty_column.community": "La linya de tiempo lokala esta vaziya. Eskrive algo publikamente para ampesar la fiesta!",
|
||||||
|
"empty_column.direct": "Ainda no tienes enmentaduras privadas. Kuando embies o risives una, se amostra aki.",
|
||||||
|
"empty_column.domain_blocks": "Ainda no ay domenos blokados.",
|
||||||
|
"empty_column.explore_statuses": "No ay dingunos trendes agora. Mira mas tadre!",
|
||||||
|
"empty_column.favourited_statuses": "Ainda no tienes publikasyones favoritas. Kuando indikes ke una te plaze, se amostrara aki.",
|
||||||
|
"empty_column.favourites": "Nadie tiene indikado ke le plaze una de tus publikasyones. Kuando algun lo aga, se amostrara aki.",
|
||||||
|
"empty_column.follow_requests": "No tienes dinguna solisitud de suivante. Kuando risivas una, se amostrara aki.",
|
||||||
|
"empty_column.followed_tags": "Ainda no tienes segido dinguna etiketa. Kuando lo agas, se amostraran aki.",
|
||||||
|
"empty_column.hashtag": "Ainda no ay niente en esta etiketa.",
|
||||||
|
"empty_column.home": "Tu linya de tiempo esta vaziya! Sige a mas personas para inchirla.",
|
||||||
|
"empty_column.list": "Ainda no ay niente en esta lista. Kuando miembros de esta lista publiken muevas publikasyones, se amostraran aki.",
|
||||||
|
"empty_column.lists": "Ainda no tienes dinguna lista. Kuando kriyes una, aperesera aki.",
|
||||||
|
"empty_column.mutes": "Ainda no tienes silensiado a dingun utilizador.",
|
||||||
|
"empty_column.notifications": "Ainda no tienes dingun avizo. Kuando otras personas enteraktuen kontigo, se amostraran aki.",
|
||||||
|
"empty_column.public": "No ay niente aki! Eskrive algo publikamente o manualmente sige utilizadores de otros sirvidores para inchirlo",
|
||||||
|
"error.unexpected_crash.explanation": "Por un yerro en muestro kodiche o un problem de kompatibilita kon el navigador, no se puede amostrar esta pajina djustamente.",
|
||||||
|
"error.unexpected_crash.explanation_addons": "No se puede amostrar esta pajina djustamente. Este yerro probavlemente fue kauzado por un komplimento del navigador o por un enstrumento de traduksion.",
|
||||||
|
"error.unexpected_crash.next_steps": "Aprova arefreskar la pajina. Si esto no ayuda, es posivle ke ainda puedas kulaenar Mastodon kon otro navigador u otra aplikasyon nativa.",
|
||||||
|
"error.unexpected_crash.next_steps_addons": "Aprova inkapasitarlos i arefreskar la pajina. Si esto no ayuda, es posivle ke ainda puedas kulanear Mastodon kon otro navigador u otra aplikasyon nativa.",
|
||||||
|
"errors.unexpected_crash.copy_stacktrace": "Kopiar stacktrace al portapapeles",
|
||||||
|
"errors.unexpected_crash.report_issue": "Raportar problema",
|
||||||
|
"explore.search_results": "Rizultados de bushkeda",
|
||||||
|
"explore.suggested_follows": "Djente",
|
||||||
|
"explore.title": "Eksplorar",
|
||||||
|
"explore.trending_links": "Haberes",
|
||||||
|
"explore.trending_statuses": "Publikasyones",
|
||||||
|
"explore.trending_tags": "Etiketas",
|
||||||
|
"filter_modal.added.context_mismatch_explanation": "Esta kategoria del filtro no se aplika al konteksto en ke tienes aksesido esta publikasyon. Si keres ke la publikasyon sea filtrada en este konteksto tamyen, kale editar el filtro.",
|
||||||
|
"filter_modal.added.context_mismatch_title": "El konteksto no koensida!",
|
||||||
|
"filter_modal.added.expired_explanation": "Esta kategoria de filtros tiene kadukado. Kale ke trokar la data de kadukasion para aplikarla.",
|
||||||
|
"filter_modal.added.expired_title": "Filtro kadukado!",
|
||||||
|
"filter_modal.added.review_and_configure": "Para revizar i konfigurar esta kategoria de filtros, va a {settings_link}.",
|
||||||
|
"filter_modal.added.review_and_configure_title": "Konfigurasyon de filtro",
|
||||||
|
"filter_modal.added.settings_link": "pajina de konfigurasyon",
|
||||||
|
"filter_modal.added.short_explanation": "Esta publikasyon fue adjustada a la sigiente kategoria de filtros: {title}.",
|
||||||
|
"filter_modal.added.title": "Filtro adjustado!",
|
||||||
|
"filter_modal.select_filter.context_mismatch": "no se aplika a este konteksto",
|
||||||
|
"filter_modal.select_filter.expired": "kadukado",
|
||||||
|
"filter_modal.select_filter.prompt_new": "Mueva kategoria: {name}",
|
||||||
|
"filter_modal.select_filter.search": "Bushkar o kriyar",
|
||||||
|
"filter_modal.select_filter.subtitle": "Kulanear una kategoria egzistente o kriya mueva",
|
||||||
|
"filter_modal.select_filter.title": "Filtrar esta publikasyon",
|
||||||
|
"filter_modal.title.status": "Filtrar una publikasyon",
|
||||||
|
"firehose.all": "Todo",
|
||||||
|
"firehose.local": "Este sirvidor",
|
||||||
|
"firehose.remote": "Otros sirvidores",
|
||||||
|
"follow_request.authorize": "Autoriza",
|
||||||
|
"follow_request.reject": "Refuza",
|
||||||
|
"follow_requests.unlocked_explanation": "Aunke tu kuento no esta serrado, la taifa de {domain} kreye ke talvez keres revizar manualmente las solisitudes de segimento de estos kuentos.",
|
||||||
|
"followed_tags": "Etiketas segidas",
|
||||||
|
"footer.about": "Sovre mozotros",
|
||||||
|
"footer.directory": "Katalogo de profiles",
|
||||||
|
"footer.get_app": "Abasha aplikasyon",
|
||||||
|
"footer.invite": "Envitar a djente",
|
||||||
|
"footer.keyboard_shortcuts": "Akortamientos de klavye",
|
||||||
|
"footer.privacy_policy": "Politika de privasita",
|
||||||
|
"footer.source_code": "Ve kodiche fuente",
|
||||||
|
"footer.status": "Estado",
|
||||||
|
"generic.saved": "Guadrado",
|
||||||
|
"getting_started.heading": "Primos pasos",
|
||||||
|
"hashtag.column_header.tag_mode.all": "i {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.any": "o {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.none": "sin {additional}",
|
||||||
|
"hashtag.column_settings.select.no_options_message": "Rekomendasyones no topadas",
|
||||||
|
"hashtag.column_settings.select.placeholder": "Meter etiketas…",
|
||||||
|
"hashtag.column_settings.tag_mode.all": "Todos estos",
|
||||||
|
"hashtag.column_settings.tag_mode.any": "Kualsekera de estos",
|
||||||
|
"hashtag.column_settings.tag_mode.none": "Dinguno de estos",
|
||||||
|
"hashtag.column_settings.tag_toggle": "Inkluir etiketas adisionalas en esta kolumna",
|
||||||
|
"hashtag.follow": "Segir etiketa",
|
||||||
|
"hashtag.unfollow": "Desegir etiketa",
|
||||||
|
"home.column_settings.basic": "Opsyones bazikas",
|
||||||
|
"home.column_settings.show_reblogs": "Amostrar repartajasyones",
|
||||||
|
"home.column_settings.show_replies": "Amostrar repuestas",
|
||||||
|
"home.hide_announcements": "Eskonde pregones",
|
||||||
|
"home.pending_critical_update.link": "Ve aktualizasyones",
|
||||||
|
"home.show_announcements": "Amostra pregones",
|
||||||
|
"interaction_modal.description.favourite": "Kon un kuento en Mastodon, puedes markar esta publikasyon komo favorita para ke el autor sepa ke te plaze i para guadrarla para dempues.",
|
||||||
|
"interaction_modal.description.follow": "Kon un kuento en Mastodon, puedes segir a {name} para risivir sus publikasyones en tu linya temporal prinsipala.",
|
||||||
|
"interaction_modal.description.reblog": "Kon un kuento en Mastodon, puedes repartajar esta publikasyon para amostrarla a tus suivantes.",
|
||||||
|
"interaction_modal.description.reply": "Kon un kuento en Mastodon, puedes arispondir a esta publikasyon.",
|
||||||
|
"interaction_modal.on_another_server": "En otro sirvidor",
|
||||||
|
"interaction_modal.on_this_server": "En este sirvidor",
|
||||||
|
"interaction_modal.title.favourite": "Endika ke te plaze publikasyon de {name}",
|
||||||
|
"interaction_modal.title.follow": "Sige a {name}",
|
||||||
|
"interaction_modal.title.reblog": "Repartaja publikasyon de {name}",
|
||||||
|
"interaction_modal.title.reply": "Arisponde a publikasyon de {name}",
|
||||||
|
"intervals.full.days": "{number, plural, one {# diya} other {# diyas}}",
|
||||||
|
"intervals.full.hours": "{number, plural, one {# ora} other {# oras}}",
|
||||||
|
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
|
||||||
|
"keyboard_shortcuts.back": "Volta atras",
|
||||||
|
"keyboard_shortcuts.blocked": "Avre lista de utilizadores blokados",
|
||||||
|
"keyboard_shortcuts.boost": "Repartaja publikasyon",
|
||||||
|
"keyboard_shortcuts.column": "Enfoka en una kolumna",
|
||||||
|
"keyboard_shortcuts.compose": "Enfoka en el area de eskrivir publikasyon",
|
||||||
|
"keyboard_shortcuts.description": "Deskripsyon",
|
||||||
|
"keyboard_shortcuts.direct": "Avre la kolumna de enmentaduras privadas",
|
||||||
|
"keyboard_shortcuts.down": "Move verso abasho en la lista",
|
||||||
|
"keyboard_shortcuts.enter": "Avre publikasyon",
|
||||||
|
"keyboard_shortcuts.favourite": "Endika ke te plaze una publikasyon",
|
||||||
|
"keyboard_shortcuts.favourites": "Avre lista de favoritos",
|
||||||
|
"keyboard_shortcuts.federated": "Avre linya federada",
|
||||||
|
"keyboard_shortcuts.heading": "Akortamientos de klavye",
|
||||||
|
"keyboard_shortcuts.home": "Avre linya prinsipala",
|
||||||
|
"keyboard_shortcuts.hotkey": "Klave rapido",
|
||||||
|
"keyboard_shortcuts.legend": "Amostra esta lejenda",
|
||||||
|
"keyboard_shortcuts.local": "Avre linya lokala",
|
||||||
|
"keyboard_shortcuts.mention": "Enmenta al autor",
|
||||||
|
"keyboard_shortcuts.muted": "Avre lista de utilizadores silensiados",
|
||||||
|
"keyboard_shortcuts.my_profile": "Avre tu profil",
|
||||||
|
"keyboard_shortcuts.notifications": "Avre kolumna de avizos",
|
||||||
|
"keyboard_shortcuts.open_media": "Avre multimedia",
|
||||||
|
"keyboard_shortcuts.pinned": "Avre lista de publikasyones fiksadas",
|
||||||
|
"keyboard_shortcuts.profile": "Avre profil del autor",
|
||||||
|
"keyboard_shortcuts.reply": "Arisponde a publikasyon",
|
||||||
|
"keyboard_shortcuts.requests": "Avre lista de solisitudes de suivantes",
|
||||||
|
"keyboard_shortcuts.search": "Enfoka en la vara de bushkeda",
|
||||||
|
"keyboard_shortcuts.spoilers": "Amostra/eskonde el kampo de avertensya de kontenido (CW)",
|
||||||
|
"keyboard_shortcuts.start": "Avre la kolumna \"para ampesar\"",
|
||||||
|
"keyboard_shortcuts.toggle_hidden": "Amostra/eskonde teksto detras de avertensya de kontenido (CW)",
|
||||||
|
"keyboard_shortcuts.toggle_sensitivity": "Amostra/eskonde multimedia",
|
||||||
|
"keyboard_shortcuts.toot": "Eskrive mueva publikasyon",
|
||||||
|
"keyboard_shortcuts.unfocus": "No enfoka en el area de eskrivir/bushkeda",
|
||||||
|
"keyboard_shortcuts.up": "Move verso arriva en la lista",
|
||||||
|
"lightbox.close": "Serra",
|
||||||
|
"lightbox.compress": "Kompresa kuadro de imaje",
|
||||||
|
"lightbox.expand": "Espande kuadro de imaje",
|
||||||
|
"lightbox.next": "Sigiente",
|
||||||
|
"lightbox.previous": "Anterior",
|
||||||
|
"limited_account_hint.action": "Amostra el profil entanto",
|
||||||
|
"limited_account_hint.title": "Este profil fue eskondido por los moderadores de {domain}.",
|
||||||
|
"lists.account.add": "Adjusta a lista",
|
||||||
|
"lists.account.remove": "Kita de lista",
|
||||||
|
"lists.delete": "Efasa lista",
|
||||||
|
"lists.edit": "Edita lista",
|
||||||
|
"lists.edit.submit": "Troka titolo",
|
||||||
|
"lists.new.create": "Adjusta lista",
|
||||||
|
"lists.new.title_placeholder": "Titolo de mueva lista",
|
||||||
|
"lists.replies_policy.followed": "Kualseker utilizardo segido",
|
||||||
|
"lists.replies_policy.list": "Miembros de la lista",
|
||||||
|
"lists.replies_policy.none": "Dinguno",
|
||||||
|
"lists.replies_policy.title": "Amostra repuestas a:",
|
||||||
|
"lists.search": "Bushka entre personas a las kualas siges",
|
||||||
|
"lists.subheading": "Tus listas",
|
||||||
|
"load_pending": "{count, plural, one {# muevo elemento} other {# muevos elementos}}",
|
||||||
|
"loading_indicator.label": "Eskargando…",
|
||||||
|
"media_gallery.toggle_visible": "{number, plural, one {Eskonde imaje} other {Eskonde imajes}}",
|
||||||
|
"moved_to_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado porke transferates a {movedToAccount}.",
|
||||||
|
"mute_modal.duration": "Durasyon",
|
||||||
|
"mute_modal.hide_notifications": "Eskonder avizos de este utilizador?",
|
||||||
|
"mute_modal.indefinite": "Indefinida",
|
||||||
|
"navigation_bar.about": "Sovre mozotros",
|
||||||
|
"navigation_bar.blocks": "Utilizadores blokados",
|
||||||
|
"navigation_bar.bookmarks": "Markadores",
|
||||||
|
"navigation_bar.community_timeline": "Linya de tiempo lokala",
|
||||||
|
"navigation_bar.compose": "Eskrivir mueva publikasyon",
|
||||||
|
"navigation_bar.direct": "Enmentaduras privadas",
|
||||||
|
"navigation_bar.discover": "Diskuvre",
|
||||||
|
"navigation_bar.domain_blocks": "Domenos blokados",
|
||||||
|
"navigation_bar.edit_profile": "Edita profil",
|
||||||
|
"navigation_bar.explore": "Eksplorar",
|
||||||
|
"navigation_bar.favourites": "Te plazen",
|
||||||
|
"navigation_bar.filters": "Biervos silensiados",
|
||||||
|
"navigation_bar.follow_requests": "Solisitudes de segimiento",
|
||||||
|
"navigation_bar.followed_tags": "Etiketas segidas",
|
||||||
|
"navigation_bar.follows_and_followers": "Segidos i suivantes",
|
||||||
|
"navigation_bar.lists": "Listas",
|
||||||
|
"navigation_bar.logout": "Salir",
|
||||||
|
"navigation_bar.mutes": "Utilizadores silensiados",
|
||||||
|
"navigation_bar.personal": "Personal",
|
||||||
|
"navigation_bar.pins": "Publikasyones fiksadas",
|
||||||
|
"navigation_bar.preferences": "Preferensyas",
|
||||||
|
"navigation_bar.public_timeline": "Linya de tiempo federada",
|
||||||
|
"navigation_bar.search": "Bushka",
|
||||||
|
"navigation_bar.security": "Segurita",
|
||||||
|
"not_signed_in_indicator.not_signed_in": "Nesesitas konektarse kon tu kuento para akseder este rekurso.",
|
||||||
|
"notification.admin.report": "{name} raporto {target}",
|
||||||
|
"notification.admin.sign_up": "{name} kriyo un konto",
|
||||||
|
"notification.favourite": "A {name} le plaze tu publikasyon",
|
||||||
|
"notification.follow": "{name} te ampeso a segir",
|
||||||
|
"notification.follow_request": "{name} tiene solisitado segirte",
|
||||||
|
"notification.mention": "{name} te enmento",
|
||||||
|
"notification.own_poll": "Tu anketa eskapo",
|
||||||
|
"notification.poll": "Anketa en ke votates eskapo",
|
||||||
|
"notification.reblog": "{name} repartajo tu publikasyon",
|
||||||
|
"notification.status": "{name} publiko algo",
|
||||||
|
"notification.update": "{name} edito una publikasyon",
|
||||||
|
"notifications.clear": "Efasar avizos",
|
||||||
|
"notifications.clear_confirmation": "Estas siguro ke keres permanentemente efasar todos tus avizos?",
|
||||||
|
"notifications.column_settings.admin.report": "Muveos raportos:",
|
||||||
|
"notifications.column_settings.admin.sign_up": "Muevas enrejistrasyones:",
|
||||||
|
"notifications.column_settings.alert": "Avizos de ensimameza",
|
||||||
|
"notifications.column_settings.favourite": "Te plazen:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Amostra todas las kategorias",
|
||||||
|
"notifications.column_settings.filter_bar.category": "Vara de filtrado rapido",
|
||||||
|
"notifications.column_settings.filter_bar.show_bar": "Amostra vara de filtros",
|
||||||
|
"notifications.column_settings.follow": "Muevos suivantes:",
|
||||||
|
"notifications.column_settings.follow_request": "Muevas solisitudes de segimiento:",
|
||||||
|
"notifications.column_settings.mention": "Enmentaduras:",
|
||||||
|
"notifications.column_settings.poll": "Rizultados de anketas:",
|
||||||
|
"notifications.column_settings.push": "Avizos arrepushados",
|
||||||
|
"notifications.column_settings.reblog": "Repartajasyones:",
|
||||||
|
"notifications.column_settings.show": "Amostra en kolumna",
|
||||||
|
"notifications.column_settings.sound": "Reproduzir son",
|
||||||
|
"notifications.column_settings.status": "Publikasyones muevas:",
|
||||||
|
"notifications.column_settings.unread_notifications.category": "Avizos no meldados",
|
||||||
|
"notifications.column_settings.unread_notifications.highlight": "Avaliar avizos no meldados",
|
||||||
|
"notifications.column_settings.update": "Edisyones:",
|
||||||
|
"notifications.filter.all": "Todos",
|
||||||
|
"notifications.filter.boosts": "Repartajasyones",
|
||||||
|
"notifications.filter.favourites": "Te plazen",
|
||||||
|
"notifications.filter.follows": "Segidos",
|
||||||
|
"notifications.filter.mentions": "Enmentaduras",
|
||||||
|
"notifications.filter.polls": "Rizultados de anketa",
|
||||||
|
"notifications.filter.statuses": "Aktualizasyones de personas a las kualas siges",
|
||||||
|
"notifications.grant_permission": "Da permiso.",
|
||||||
|
"notifications.group": "{count} avizos",
|
||||||
|
"notifications.mark_as_read": "Marka todos avizos komo meldados",
|
||||||
|
"notifications.permission_denied": "Avizos de ensimameza no estan desponivles porke ya se tiene refuzado el permiso",
|
||||||
|
"notifications.permission_denied_alert": "\"No se pueden kapasitar los avizos de ensimameza, porke ya se tiene refuzado el permiso de navigador",
|
||||||
|
"notifications.permission_required": "Avizos de ensimameza no estan desponivles porke los nesesarios permisos no tienen sido risividos.",
|
||||||
|
"notifications_permission_banner.enable": "Kapasitar avizos de ensimameza",
|
||||||
|
"notifications_permission_banner.how_to_control": "Para risivir avizos kuando Mastodon no esta avierto, kapasita avizos de ensimameza. Puedes kontrolar presizamente kualos tipos de enteraksiones djeneren avizos de ensimameza kon el boton {icon} arriva kuando esten kapasitadas.",
|
||||||
|
"notifications_permission_banner.title": "Nunka te piedres niente",
|
||||||
|
"onboarding.action.back": "Va atras",
|
||||||
|
"onboarding.actions.back": "Va atras",
|
||||||
|
"onboarding.profile.display_name": "Nombre amostrado",
|
||||||
|
"picture_in_picture.restore": "Restora",
|
||||||
|
"poll.closed": "Serrado",
|
||||||
|
"poll.refresh": "Arefreska",
|
||||||
|
"poll.total_people": "{count, plural, one {# persona} other {# personas}}",
|
||||||
|
"poll.total_votes": "{count, plural, one {# voto} other {# votos}}",
|
||||||
|
"poll.vote": "Vota",
|
||||||
|
"poll.voted": "Votates por esta repuesta",
|
||||||
|
"poll.votes": "{votes, plural, one {# voto} other {# votos}}",
|
||||||
|
"poll_button.add_poll": "Adjusta anketa",
|
||||||
|
"poll_button.remove_poll": "Kita anketa",
|
||||||
|
"privacy.change": "Troka privasita de publikasyon",
|
||||||
|
"privacy.direct.long": "Vizivle solo para utilizadores enmentados",
|
||||||
|
"privacy.direct.short": "Solo personas enmentadas",
|
||||||
|
"privacy.private.long": "Vizivle solo para suivantes",
|
||||||
|
"privacy.private.short": "Solo suivantes",
|
||||||
|
"privacy.public.long": "Vizivle para todos",
|
||||||
|
"privacy.public.short": "Publiko",
|
||||||
|
"privacy.unlisted.long": "Vizivle para todos, ama eskluido de las fonksiones de diskuvrimyento",
|
||||||
|
"privacy.unlisted.short": "No listado",
|
||||||
|
"privacy_policy.last_updated": "Ultima aktualizasyon: {date}",
|
||||||
|
"privacy_policy.title": "Politika de privasita",
|
||||||
|
"refresh": "Arefreska",
|
||||||
|
"regeneration_indicator.label": "Eskargando…",
|
||||||
|
"regeneration_indicator.sublabel": "Tu linya de tiempo prinsipala esta preparando!",
|
||||||
|
"relative_time.days": "{number} d",
|
||||||
|
"relative_time.full.days": "antes {number, plural, one {# diya} other {# diyas}}",
|
||||||
|
"relative_time.full.hours": "antes {number, plural, one {# ora} other {# oras}}",
|
||||||
|
"relative_time.full.just_now": "agora",
|
||||||
|
"relative_time.full.minutes": "antes {number, plural, one {# minuto} other {# minutos}}",
|
||||||
|
"relative_time.full.seconds": "antes {number, plural, one {# sigundo} other {# sigundos}}",
|
||||||
|
"relative_time.hours": "{number} o",
|
||||||
|
"relative_time.just_now": "agora",
|
||||||
|
"relative_time.minutes": "{number} m",
|
||||||
|
"relative_time.seconds": "{number} s",
|
||||||
|
"relative_time.today": "oy",
|
||||||
|
"reply_indicator.cancel": "Anula",
|
||||||
|
"report.block": "Bloka",
|
||||||
|
"report.block_explanation": "No veras sus publikasyones. No podra ver tus publikasyones ni segirte. Podra saver ke le blokates.",
|
||||||
|
"report.categories.other": "Otros",
|
||||||
|
"report.categories.spam": "Spam",
|
||||||
|
"report.categories.violation": "El kontenido viola una o mas reglas del sirvidor",
|
||||||
|
"report.category.subtitle": "Eskoje la mijor koensidensya",
|
||||||
|
"report.category.title": "Deskrive el problem kon {type}",
|
||||||
|
"report.category.title_account": "profil",
|
||||||
|
"report.category.title_status": "publikasyon",
|
||||||
|
"report.close": "Fecho",
|
||||||
|
"report.comment.title": "Ay algo mas ke deveriamos saver?",
|
||||||
|
"report.forward": "Reembiar a {target}",
|
||||||
|
"report.forward_hint": "Este kuento es de otro sirvidor. Embiar una kopia anonimizada del raporto ayi tamyen?",
|
||||||
|
"report.mute": "Silensia",
|
||||||
|
"report.mute_explanation": "No veras sus publikasyones. Ainda pueden segirte i no va saver ke le silensiates.",
|
||||||
|
"report.placeholder": "Otros komentos",
|
||||||
|
"report.reasons.dislike": "No me plaze",
|
||||||
|
"report.reasons.dislike_description": "\"No es algo ke kero ver",
|
||||||
|
"report.reasons.other": "Es otra koza",
|
||||||
|
"report.reasons.other_description": "El problem no es de las otras kategorias",
|
||||||
|
"report.reasons.spam": "Es spam",
|
||||||
|
"report.reasons.spam_description": "Atadijos malisiozos, enteraksyones falsas o repuestas repetitivas",
|
||||||
|
"report.reasons.violation": "Viola las reglas del sirvidor",
|
||||||
|
"report.reasons.violation_description": "Saves ke viola reglas espesifikas",
|
||||||
|
"report.rules.subtitle": "Eskoje todas ke korespondan",
|
||||||
|
"report.rules.title": "Kualas reglas estan violadas?",
|
||||||
|
"report.statuses.subtitle": "Eskoje todas ke korespondan",
|
||||||
|
"report.statuses.title": "Ay alguna publikasyon ke suporta este raporto?",
|
||||||
|
"report.submit": "Embiar",
|
||||||
|
"report.target": "Raportando a {target}",
|
||||||
|
"report.thanks.take_action": "Aki estan tus opsyones para kontrolar lo ke ves en Mastodon:",
|
||||||
|
"report.thanks.take_action_actionable": "Mientres revizamos esto, puedes tomar aksyones kontra @{name}:",
|
||||||
|
"report.thanks.title": "No keres ver esto?",
|
||||||
|
"report.thanks.title_actionable": "Mersi por raportarlo, vamos revizarlo.",
|
||||||
|
"report.unfollow": "Desegir a @{name}",
|
||||||
|
"report.unfollow_explanation": "Estas sigiendo este kuento. Para no ver sus publikasyones en tu linya de tiempo, puedes deshar de segirlo.",
|
||||||
|
"report_notification.attached_statuses": "{count, plural, one {{count} publikasyon} other {{count} publikasyones}} atadas",
|
||||||
|
"report_notification.categories.other": "Otros",
|
||||||
|
"report_notification.categories.spam": "Spam",
|
||||||
|
"report_notification.categories.violation": "Violasion de reglas",
|
||||||
|
"report_notification.open": "Avre raporto",
|
||||||
|
"search.no_recent_searches": "No ay bushkedas resientes",
|
||||||
|
"search.placeholder": "Bushka",
|
||||||
|
"search.quick_action.account_search": "Profiles ke koresponden kon {x}",
|
||||||
|
"search.quick_action.go_to_account": "Va al profil {x}",
|
||||||
|
"search.quick_action.go_to_hashtag": "Va a la etiketa {x}",
|
||||||
|
"search.quick_action.open_url": "Avre URL en Mastodon",
|
||||||
|
"search.quick_action.status_search": "Publikasyones ke koresponden kon {x}",
|
||||||
|
"search.search_or_paste": "Bushka o apega URL",
|
||||||
|
"search_popout.quick_actions": "Aksiones rapidas",
|
||||||
|
"search_popout.recent": "Bushkedas resientes",
|
||||||
|
"search_results.accounts": "Profiles",
|
||||||
|
"search_results.all": "Todos",
|
||||||
|
"search_results.hashtags": "Etiketas",
|
||||||
|
"search_results.nothing_found": "No se pudo topar niente para estos terminos de bushkeda",
|
||||||
|
"search_results.see_all": "Ve todo",
|
||||||
|
"search_results.statuses": "Publikasyones",
|
||||||
|
"search_results.title": "Bushka por {q}",
|
||||||
|
"server_banner.about_active_users": "Utilizadores aktivos en este sirvidor durante los ultimos 30 diyas (utilizadores aktivos mensuales)",
|
||||||
|
"server_banner.active_users": "utilizadores aktivos",
|
||||||
|
"server_banner.administered_by": "Administrado por:",
|
||||||
|
"server_banner.introduction": "{domain} es parte de la red sosyala desentralizada liderada por {mastodon}.",
|
||||||
|
"server_banner.learn_more": "Ambezate mas",
|
||||||
|
"server_banner.server_stats": "Estatistikas del sirvidor:",
|
||||||
|
"sign_in_banner.create_account": "Kriya kuento",
|
||||||
|
"sign_in_banner.sign_in": "Konektate",
|
||||||
|
"sign_in_banner.sso_redirect": "Konektate o enrejistrate",
|
||||||
|
"status.filter": "Filtra esta publikasyon",
|
||||||
|
"status.filtered": "Filtrado",
|
||||||
|
"status.hide": "Eskonde publikasyon",
|
||||||
|
"status.history.created": "{name} kriyo {date}",
|
||||||
|
"status.history.edited": "{name} edito {date}",
|
||||||
|
"status.load_more": "Eskarga mas",
|
||||||
|
"status.media_hidden": "Multimedia eskondidos",
|
||||||
|
"status.mention": "Enmenta a @{name}",
|
||||||
|
"status.more": "Mas",
|
||||||
|
"status.mute": "Silensia a @{name}",
|
||||||
|
"status.mute_conversation": "Silensia konversasyon",
|
||||||
|
"status.open": "Espande publikasyon",
|
||||||
|
"status.pin": "Fiksa en profil",
|
||||||
|
"status.pinned": "Publikasyon fiksada",
|
||||||
|
"status.read_more": "Melda mas",
|
||||||
|
"status.reblog": "Repartaja",
|
||||||
|
"status.reblog_private": "Repartaja kon vizibilita orijinala",
|
||||||
|
"status.reblogged_by": "{name} repartajo",
|
||||||
|
"status.reblogs.empty": "Ainda nadie tiene repartajado esta publikasyon. Kuando algien lo aga, se amostrara aki.",
|
||||||
|
"status.redraft": "Efasa i eskrive de muevo",
|
||||||
|
"status.remove_bookmark": "Kita markador",
|
||||||
|
"status.replied_to": "Arispondio a {name}",
|
||||||
|
"status.reply": "Arisponde",
|
||||||
|
"status.replyAll": "Arisponde al filo",
|
||||||
|
"status.report": "Raporta @{name}",
|
||||||
|
"status.sensitive_warning": "Kontenido sensivle",
|
||||||
|
"status.share": "Partaja",
|
||||||
|
"status.show_filter_reason": "Amostra entanto",
|
||||||
|
"status.show_less": "Amostra manko",
|
||||||
|
"status.show_less_all": "Amostra manko para todo",
|
||||||
|
"status.show_more": "Amostra mas",
|
||||||
|
"status.show_more_all": "Amostra mas para todo",
|
||||||
|
"status.show_original": "Amostra orijinal",
|
||||||
|
"status.translate": "Trezlada",
|
||||||
|
"status.translated_from_with": "Trezladado dizde {lang} kon {provider}",
|
||||||
|
"status.uncached_media_warning": "Vista previa no desponivle",
|
||||||
|
"status.unmute_conversation": "Desilensiar konversasyon",
|
||||||
|
"status.unpin": "Defiksar del profil",
|
||||||
|
"subscribed_languages.lead": "Solo publikasyones en linguas eskojidas se amostraran en tus linya de tiempo prinsipala i listas dempues del trokamiento. Eskoje dinguna para risivir publikasyones en todas las linguas.",
|
||||||
|
"subscribed_languages.save": "Guadra trokamientos",
|
||||||
|
"subscribed_languages.target": "Troka linguas abonadas para {target}",
|
||||||
|
"tabs_bar.home": "Linya prinsipala",
|
||||||
|
"tabs_bar.notifications": "Avizos",
|
||||||
|
"time_remaining.days": "{number, plural, one {# diya restante} other {# diyas restantes}}",
|
||||||
|
"time_remaining.hours": "{number, plural, one {# ora restante} other {# oras restantes}}",
|
||||||
|
"time_remaining.minutes": "{number, plural, one {# minuto restante} other {# minutos restantes}}",
|
||||||
|
"time_remaining.moments": "Momentos restantes",
|
||||||
|
"time_remaining.seconds": "{number, plural, one {# sigundo restante} other {# sigundos restantes}}",
|
||||||
|
"timeline_hint.remote_resource_not_displayed": "{resource} de otros sirvidores no se amostran.",
|
||||||
|
"timeline_hint.resources.followers": "Suivantes",
|
||||||
|
"timeline_hint.resources.follows": "Segidos",
|
||||||
|
"timeline_hint.resources.statuses": "Publikasyones mas viejas",
|
||||||
|
"trends.counter_by_accounts": "{count, plural, one {{counter} kuento} other {{counter} kuentos}} en los ultimos {days, plural, one {diyas} other {{days} diyas}}",
|
||||||
|
"trends.trending_now": "Trendes",
|
||||||
|
"ui.beforeunload": "La publikasyon ke estas eskriviendo se pedrera si sales de Mastodon.",
|
||||||
|
"units.short.billion": "{count} MM",
|
||||||
|
"units.short.million": "{count} M",
|
||||||
|
"units.short.thousand": "{count} K",
|
||||||
|
"upload_area.title": "Arastra i mete para kargar",
|
||||||
|
"upload_button.label": "Adjusta imajes, un video or una dosya audio",
|
||||||
|
"upload_error.limit": "Limito de dosyas kargadas eksedido.",
|
||||||
|
"upload_error.poll": "No se permite kargar dosyas kon anketas.",
|
||||||
|
"upload_form.audio_description": "Deskrive para personas sodras o kon problemes auditivos",
|
||||||
|
"upload_form.description": "Deskrive para personas siegas o kon problemes vizuales",
|
||||||
|
"upload_form.description_missing": "No adjustates deskripsion",
|
||||||
|
"upload_form.edit": "Edita",
|
||||||
|
"upload_form.thumbnail": "Troka minyatura",
|
||||||
|
"upload_form.undo": "Efasa",
|
||||||
|
"upload_form.video_description": "Deskrive para personas sodras, kon problemes auditivos, siegas o kon problemes vizuales",
|
||||||
|
"upload_modal.analyzing_picture": "Analizando imaje…",
|
||||||
|
"upload_modal.apply": "Aplika",
|
||||||
|
"upload_modal.applying": "Aplikando…",
|
||||||
|
"upload_modal.choose_image": "Eskoje imaje",
|
||||||
|
"upload_modal.description_placeholder": "Lorem ipsum dolor sit amet",
|
||||||
|
"upload_modal.detect_text": "Detektar teksto de la imaje",
|
||||||
|
"upload_modal.edit_media": "Edita multimedia",
|
||||||
|
"upload_modal.hint": "Klika o arrastra el sirkolo en la vista previa para eskojer el punto fokal ke siempre estara en vista en todas las minyaturas.",
|
||||||
|
"upload_modal.preparing_ocr": "Preparando OCR…",
|
||||||
|
"upload_modal.preview_label": "Vista previa ({ratio})",
|
||||||
|
"upload_progress.label": "Kargando...",
|
||||||
|
"upload_progress.processing": "Prosesando…",
|
||||||
|
"video.close": "Serra video",
|
||||||
|
"video.download": "Abasha dosya",
|
||||||
|
"video.exit_fullscreen": "Sal de ekran kompleto",
|
||||||
|
"video.expand": "Espande video",
|
||||||
|
"video.fullscreen": "Ekran kompleto",
|
||||||
|
"video.hide": "Eskonde video",
|
||||||
|
"video.mute": "Silensia son",
|
||||||
|
"video.pause": "Pauza",
|
||||||
|
"video.play": "Reproduze",
|
||||||
|
"video.unmute": "Desilensia son"
|
||||||
|
}
|
|
@ -49,5 +49,32 @@
|
||||||
"admin.dashboard.retention.average": "औसत",
|
"admin.dashboard.retention.average": "औसत",
|
||||||
"admin.dashboard.retention.cohort_size": "नयाँ प्रयोगकर्ताहरू",
|
"admin.dashboard.retention.cohort_size": "नयाँ प्रयोगकर्ताहरू",
|
||||||
"alert.rate_limited.message": "कृपया {retry_time, time, medium} पछि पुन: प्रयास गर्नुहोस्।",
|
"alert.rate_limited.message": "कृपया {retry_time, time, medium} पछि पुन: प्रयास गर्नुहोस्।",
|
||||||
"alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।"
|
"alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।",
|
||||||
|
"bundle_column_error.retry": "पुन: प्रयास गर्नुहोस्",
|
||||||
|
"bundle_modal_error.close": "बन्द गर्नुहोस्",
|
||||||
|
"bundle_modal_error.message": "यो कम्पोनेन्ट लोड गर्दा केही गडबड भयो।",
|
||||||
|
"bundle_modal_error.retry": "Try again",
|
||||||
|
"closed_registrations.other_server_instructions": "Mastodon विकेन्द्रीकृत भएकोले, तपाइँ अर्को सर्भरमा खाता खोल्न सक्नुहुन्छ र पनि यो सर्भरसँग अन्तरक्रिया गर्न सक्नुहुन्छ।",
|
||||||
|
"closed_registrations_modal.description": "हाल {domain} मा खाता सिर्जना गर्न सम्भव छैन, तर कृपया ध्यान राख्नुहोस् कि तपाईंले Mastodon प्रयोग गर्नको लागि {domain} मा नै खाता खोल्न आवश्यक छैन।",
|
||||||
|
"closed_registrations_modal.find_another_server": "अर्को सर्भर खोज्नुहोस्",
|
||||||
|
"closed_registrations_modal.title": "Mastodon मा साइन अप गर्दै",
|
||||||
|
"column.blocks": "ब्लक गरिएको प्रयोगकर्ताहरु",
|
||||||
|
"column.directory": "प्रोफाइल ब्राउज गर्नुहोस्",
|
||||||
|
"column.domain_blocks": "ब्लक गरिएको डोमेन",
|
||||||
|
"column.follow_requests": "फलो अनुरोधहरू",
|
||||||
|
"column.lists": "सूचीहरू",
|
||||||
|
"column.notifications": "सूचनाहरू",
|
||||||
|
"column_header.hide_settings": "सेटिङ्हरू लुकाउनुहोस्",
|
||||||
|
"column_subheading.settings": "सेटिङहरू",
|
||||||
|
"compose.language.change": "भाषा परिवर्तन गर्नुहोस्",
|
||||||
|
"compose.language.search": "भाषाहरू खोज्नुहोस्...",
|
||||||
|
"compose_form.direct_message_warning_learn_more": "थप जान्नुहोस्",
|
||||||
|
"compose_form.poll.add_option": "विकल्प थप्नुहोस्",
|
||||||
|
"compose_form.poll.remove_option": "यो विकल्प हटाउनुहोस्",
|
||||||
|
"compose_form.publish_form": "नयाँ पोस्ट",
|
||||||
|
"compose_form.save_changes": "परिवर्तनहरू सेभ गर्नुहोस",
|
||||||
|
"compose_form.sensitive.hide": "{count, plural, one {संवेदनशील मिडियाको रूपमा चिन्ह लगाउनुहोस्} other {संवेदनशील मिडियाहरूको रूपमा चिन्ह लगाउनुहोस्}}",
|
||||||
|
"compose_form.sensitive.marked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छ} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छ}}",
|
||||||
|
"compose_form.sensitive.unmarked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छैन} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छैन}}",
|
||||||
|
"compose_form.spoiler_placeholder": "यहाँ आफ्नो चेतावनी लेख्नुहोस्"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,39 @@
|
||||||
{
|
{
|
||||||
"about.contact": "ਸੰਪਰਕ:",
|
"about.contact": "ਸੰਪਰਕ:",
|
||||||
|
"about.domain_blocks.silenced.title": "ਸੀਮਿਤ",
|
||||||
"about.domain_blocks.suspended.title": "ਮੁਅੱਤਲ ਕੀਤੀ",
|
"about.domain_blocks.suspended.title": "ਮੁਅੱਤਲ ਕੀਤੀ",
|
||||||
|
"about.rules": "ਸਰਵਰ ਨਿਯਮ",
|
||||||
"account.account_note_header": "ਨੋਟ",
|
"account.account_note_header": "ਨੋਟ",
|
||||||
"account.badges.bot": "Bot",
|
"account.add_or_remove_from_list": "ਸੂਚੀ ਵਿੱਚ ਜੋੜੋ ਜਾਂ ਹਟਾਓ",
|
||||||
|
"account.badges.bot": "ਆਟੋਮੇਟ ਕੀਤਾ",
|
||||||
"account.badges.group": "ਗਰੁੱਪ",
|
"account.badges.group": "ਗਰੁੱਪ",
|
||||||
|
"account.block": "@{name} ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
|
||||||
|
"account.block_domain": "{domain} ਡੋਮੇਨ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
|
||||||
|
"account.block_short": "ਪਾਬੰਦੀ",
|
||||||
"account.blocked": "ਪਾਬੰਦੀਸ਼ੁਦਾ",
|
"account.blocked": "ਪਾਬੰਦੀਸ਼ੁਦਾ",
|
||||||
"account.cancel_follow_request": "Withdraw follow request",
|
"account.cancel_follow_request": "ਫ਼ਾਲੋ ਕਰਨ ਨੂੰ ਰੱਦ ਕਰੋ",
|
||||||
"account.follow": "ਪ੍ਰਸ਼ੰਸਕ ਬਣੋ",
|
"account.edit_profile": "ਪਰੋਫਾਈਲ ਨੂੰ ਸੋਧੋ",
|
||||||
"account.followers": "ਪ੍ਰਸ਼ੰਸਕ",
|
"account.follow": "ਫ਼ਾਲੋ",
|
||||||
"account.following": "ਪ੍ਰਸ਼ੰਸਕ ਹਾਂ",
|
"account.followers": "ਫ਼ਾਲੋਅਰ",
|
||||||
|
"account.followers.empty": "ਇਸ ਵਰਤੋਂਕਾਰ ਨੂੰ ਹਾਲੇ ਕੋਈ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।",
|
||||||
|
"account.following": "ਫ਼ਾਲੋ ਕੀਤਾ",
|
||||||
|
"account.follows.empty": "ਇਹ ਵਰਤੋਂਕਾਰ ਹਾਲੇ ਕਿਸੇ ਨੂੰ ਫ਼ਾਲੋ ਨਹੀਂ ਕਰਦਾ ਹੈ।",
|
||||||
|
"account.follows_you": "ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
|
||||||
"account.media": "ਮੀਡੀਆ",
|
"account.media": "ਮੀਡੀਆ",
|
||||||
"account.muted": "ਮੌਨ ਕੀਤੀਆਂ",
|
"account.muted": "ਮੌਨ ਕੀਤੀਆਂ",
|
||||||
"account.posts": "Toots",
|
"account.posts": "ਪੋਸਟਾਂ",
|
||||||
"account.posts_with_replies": "Toots and replies",
|
"account.posts_with_replies": "ਪੋਸਤਾਂ ਅਤੇ ਜਵਾਬ",
|
||||||
"account.requested": "Awaiting approval",
|
"account.requested": "ਮਨਜ਼ੂਰੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ। ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ ਨੂੰ ਰੱਦ ਕਰਨ ਲਈ ਕਲਿੱਕ ਕਰੋ",
|
||||||
|
"account.requested_follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ",
|
||||||
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
|
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
|
||||||
|
"account.unblock": "@{name} ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ",
|
||||||
|
"account.unblock_domain": "{domain} ਡੋਮੇਨ ਤੋਂ ਪਾਬੰਦੀ ਹਟਾਓ",
|
||||||
"account.unblock_short": "ਪਾਬੰਦੀ ਹਟਾਓ",
|
"account.unblock_short": "ਪਾਬੰਦੀ ਹਟਾਓ",
|
||||||
"account.unfollow": "ਪ੍ਰਸ਼ੰਸਕੀ ਰੱਦ ਕਰੋ",
|
"account.unfollow": "ਅਣ-ਫ਼ਾਲੋ",
|
||||||
"account.unmute_short": "ਮੌਨ-ਰਹਿਤ ਕਰੋ",
|
"account.unmute_short": "ਮੌਨ-ਰਹਿਤ ਕਰੋ",
|
||||||
"account_note.placeholder": "Click to add a note",
|
"account_note.placeholder": "Click to add a note",
|
||||||
"admin.dashboard.retention.average": "ਔਸਤ",
|
"admin.dashboard.retention.average": "ਔਸਤ",
|
||||||
|
"admin.dashboard.retention.cohort_size": "ਨਵੇਂ ਵਰਤੋਂਕਾਰ",
|
||||||
"alert.unexpected.title": "ਓਹੋ!",
|
"alert.unexpected.title": "ਓਹੋ!",
|
||||||
"announcement.announcement": "ਹੋਕਾ",
|
"announcement.announcement": "ਹੋਕਾ",
|
||||||
"bundle_column_error.network.title": "ਨੈੱਟਵਰਕ ਦੀ ਸਮੱਸਿਆ",
|
"bundle_column_error.network.title": "ਨੈੱਟਵਰਕ ਦੀ ਸਮੱਸਿਆ",
|
||||||
|
@ -27,35 +41,50 @@
|
||||||
"bundle_modal_error.close": "ਬੰਦ ਕਰੋ",
|
"bundle_modal_error.close": "ਬੰਦ ਕਰੋ",
|
||||||
"bundle_modal_error.retry": "ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ",
|
"bundle_modal_error.retry": "ਮੁੜ-ਕੋਸ਼ਿਸ਼ ਕਰੋ",
|
||||||
"column.about": "ਸਾਡੇ ਬਾਰੇ",
|
"column.about": "ਸਾਡੇ ਬਾਰੇ",
|
||||||
|
"column.blocks": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰ",
|
||||||
"column.bookmarks": "ਬੁੱਕਮਾਰਕ",
|
"column.bookmarks": "ਬੁੱਕਮਾਰਕ",
|
||||||
"column.home": "ਮੁੱਖ ਪੰਨਾ",
|
"column.community": "ਲੋਕਲ ਸਮਾਂ-ਲਾਈਨ",
|
||||||
|
"column.direct": "ਨਿੱਜੀ ਜ਼ਿਕਰ",
|
||||||
|
"column.favourites": "ਮਨਪਸੰਦ",
|
||||||
|
"column.follow_requests": "ਫ਼ਾਲੋ ਦੀਆਂ ਬੇਨਤੀਆਂ",
|
||||||
|
"column.home": "ਮੁੱਖ ਸਫ਼ਾ",
|
||||||
"column.lists": "ਸੂਚੀਆਂ",
|
"column.lists": "ਸੂਚੀਆਂ",
|
||||||
"column.notifications": "ਸੂਚਨਾਵਾਂ",
|
"column.notifications": "ਸੂਚਨਾਵਾਂ",
|
||||||
"column.pins": "Pinned toot",
|
"column.pins": "ਟੰਗੀਆਂ ਪੋਸਟਾਂ",
|
||||||
"column_back_button.label": "ਪਿੱਛੇ",
|
"column_back_button.label": "ਪਿੱਛੇ",
|
||||||
|
"column_header.pin": "ਟੰਗੋ",
|
||||||
|
"column_header.show_settings": "ਸੈਟਿੰਗਾਂ ਦਿਖਾਓ",
|
||||||
|
"column_header.unpin": "ਲਾਹੋ",
|
||||||
"column_subheading.settings": "ਸੈਟਿੰਗਾਂ",
|
"column_subheading.settings": "ਸੈਟਿੰਗਾਂ",
|
||||||
"community.column_settings.media_only": "Media only",
|
"community.column_settings.local_only": "ਸਿਰਫ ਲੋਕਲ ਹੀ",
|
||||||
|
"community.column_settings.media_only": "ਸਿਰਫ ਮੀਡੀਆ ਹੀ",
|
||||||
|
"community.column_settings.remote_only": "ਸਿਰਫ਼ ਰਿਮੋਟ ਹੀ",
|
||||||
|
"compose.language.change": "ਭਾਸ਼ਾ ਬਦਲੋ",
|
||||||
|
"compose.language.search": "ਭਾਸ਼ਾਵਾਂ ਦੀ ਖੋਜ...",
|
||||||
|
"compose.published.open": "ਖੋਲ੍ਹੋ",
|
||||||
|
"compose.saved.body": "ਪੋਸਟ ਸੰਭਾਲੀ ਗਈ।",
|
||||||
"compose_form.direct_message_warning_learn_more": "ਹੋਰ ਜਾਣੋ",
|
"compose_form.direct_message_warning_learn_more": "ਹੋਰ ਜਾਣੋ",
|
||||||
"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.lock_disclaimer.lock": "ਲਾਕ ਹੈ",
|
||||||
"compose_form.placeholder": "What is on your mind?",
|
"compose_form.placeholder": "What is on your mind?",
|
||||||
"compose_form.publish": "ਪ੍ਰਕਾਸ਼ਨ ਕਰੋ",
|
"compose_form.publish": "ਪ੍ਰਕਾਸ਼ਨ ਕਰੋ",
|
||||||
"compose_form.publish_form": "Publish",
|
"compose_form.publish_form": "Publish",
|
||||||
"compose_form.save_changes": "ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ",
|
"compose_form.save_changes": "ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ",
|
||||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
"compose_form.spoiler.marked": "ਸਮੱਗਰੀ ਚੇਤਾਵਨੀ ਨੂੰ ਹਟਾਓ",
|
||||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
"compose_form.spoiler.unmarked": "ਸਮੱਗਰੀ ਬਾਰੇ ਚੇਤਾਵਨੀ ਜੋੜੋ",
|
||||||
"confirmation_modal.cancel": "ਰੱਦ ਕਰੋ",
|
"confirmation_modal.cancel": "ਰੱਦ ਕਰੋ",
|
||||||
"confirmations.block.confirm": "ਬਲਾਕ",
|
"confirmations.block.confirm": "ਪਾਬੰਦੀ",
|
||||||
"confirmations.delete.confirm": "ਮਿਟਾਓ",
|
"confirmations.delete.confirm": "ਹਟਾਓ",
|
||||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
"confirmations.delete.message": "ਕੀ ਤੁਸੀਂ ਇਹ ਪੋਸਟ ਨੂੰ ਹਟਾਉਣਾ ਚਾਹੁੰਦੇ ਹੋ?",
|
||||||
"confirmations.delete_list.confirm": "ਮਿਟਾਓ",
|
"confirmations.delete_list.confirm": "ਹਟਾਓ",
|
||||||
"confirmations.discard_edit_media.confirm": "ਰੱਦ ਕਰੋ",
|
"confirmations.discard_edit_media.confirm": "ਰੱਦ ਕਰੋ",
|
||||||
"confirmations.domain_block.confirm": "Hide entire domain",
|
"confirmations.domain_block.confirm": "ਪੂਰੀ ਡੋਮੇਨ ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
|
||||||
"confirmations.edit.confirm": "ਸੋਧ",
|
"confirmations.edit.confirm": "ਸੋਧ",
|
||||||
"confirmations.logout.confirm": "ਬਾਹਰ ਹੋਵੋ",
|
"confirmations.logout.confirm": "ਬਾਹਰ ਹੋਵੋ",
|
||||||
"confirmations.mute.confirm": "ਮੌਨ ਕਰੋ",
|
"confirmations.mute.confirm": "ਮੌਨ ਕਰੋ",
|
||||||
"confirmations.reply.confirm": "ਜਵਾਬ ਦੇਵੋ",
|
"confirmations.reply.confirm": "ਜਵਾਬ ਦੇਵੋ",
|
||||||
"confirmations.unfollow.confirm": "ਪ੍ਰਸ਼ੰਸਕੀ ਰੱਦ ਕਰੋ",
|
"confirmations.unfollow.confirm": "ਅਣ-ਫ਼ਾਲੋ",
|
||||||
"copypaste.copied": "ਕਾਪੀ ਕੀਤਾ",
|
"copypaste.copied": "ਕਾਪੀ ਕੀਤਾ",
|
||||||
"copypaste.copy_to_clipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
|
"copypaste.copy_to_clipboard": "ਕਲਿੱਪਬੋਰਡ 'ਤੇ ਕਾਪੀ ਕਰੋ",
|
||||||
"disabled_account_banner.account_settings": "ਖਾਤੇ ਦੀਆਂ ਸੈਟਿੰਗਾਂ",
|
"disabled_account_banner.account_settings": "ਖਾਤੇ ਦੀਆਂ ਸੈਟਿੰਗਾਂ",
|
||||||
|
@ -63,165 +92,252 @@
|
||||||
"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.",
|
||||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
"embed.instructions": "Embed this status on your website by copying the code below.",
|
||||||
"emoji_button.activity": "ਗਤੀਵਿਧੀਆਂ",
|
"emoji_button.activity": "ਗਤੀਵਿਧੀ",
|
||||||
"emoji_button.clear": "ਸਾਫ਼ ਕਰੋ",
|
"emoji_button.clear": "ਮਿਟਾਓ",
|
||||||
"emoji_button.custom": "ਕਸਟਮ",
|
"emoji_button.custom": "ਕਸਟਮ",
|
||||||
"emoji_button.flags": "ਝੰਡੀਆਂ",
|
"emoji_button.flags": "ਝੰਡੀਆਂ",
|
||||||
"emoji_button.food": "ਖਾਣਾ-ਪੀਣਾ",
|
"emoji_button.food": "ਖਾਣਾ-ਪੀਣਾ",
|
||||||
"emoji_button.nature": "ਕੁਦਰਤ",
|
"emoji_button.nature": "ਕੁਦਰਤ",
|
||||||
"emoji_button.objects": "ਇਕਾਈ",
|
"emoji_button.objects": "ਇਕਾਈ",
|
||||||
"emoji_button.people": "ਲੋਕ",
|
"emoji_button.people": "ਲੋਕ",
|
||||||
"empty_column.account_timeline": "No toots here!",
|
"emoji_button.search": "ਖੋਜ ਕਰੋ...",
|
||||||
|
"emoji_button.search_results": "ਖੋਜ ਨਤੀਜੇ",
|
||||||
|
"emoji_button.symbols": "ਚਿੰਨ੍ਹ",
|
||||||
|
"emoji_button.travel": "ਸੈਰ ਸਪਾਟਾ ਤੇ ਥਾਵਾਂ",
|
||||||
|
"empty_column.account_timeline": "ਇੱਥੇ ਕੋਈ ਪੋਸਟ ਨਹੀਂ ਹੈ!",
|
||||||
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
|
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",
|
||||||
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
|
"empty_column.home": "ਤੁਹਾਡੀ ਟਾਈਮ-ਲਾਈਨ ਖਾਲੀ ਹੈ! ਇਸ ਨੂੰ ਭਰਨ ਲਈ ਹੋਰ ਲੋਕਾਂ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ।",
|
||||||
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
||||||
"errors.unexpected_crash.report_issue": "ਮੁੱਦੇ ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
|
"errors.unexpected_crash.report_issue": "ਮੁੱਦੇ ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
|
||||||
"explore.suggested_follows": "ਲੋਕ",
|
"explore.suggested_follows": "ਲੋਕ",
|
||||||
"explore.title": "ਪੜਚੋਲ ਕਰੋ",
|
"explore.title": "ਪੜਚੋਲ ਕਰੋ",
|
||||||
"explore.trending_links": "ਖ਼ਬਰਾਂ",
|
"explore.trending_links": "ਖ਼ਬਰਾਂ",
|
||||||
"explore.trending_statuses": "ਸੰਪਾਦਨਾਵਾਂ",
|
"explore.trending_statuses": "ਪੋਸਟਾਂ",
|
||||||
"follow_request.reject": "ਅਸਵੀਕਾਰ ਕਰੋ",
|
"explore.trending_tags": "ਹੈਸ਼ਟੈਗ",
|
||||||
|
"filter_modal.added.settings_link": "ਸੈਟਿੰਗਾਂ ਸਫ਼ਾ",
|
||||||
|
"firehose.all": "ਸਭ",
|
||||||
|
"firehose.local": "ਇਹ ਸਰਵਰ",
|
||||||
|
"firehose.remote": "ਹੋਰ ਸਰਵਰ",
|
||||||
|
"follow_request.reject": "ਰੱਦ ਕਰੋ",
|
||||||
"footer.about": "ਸਾਡੇ ਬਾਰੇ",
|
"footer.about": "ਸਾਡੇ ਬਾਰੇ",
|
||||||
|
"footer.get_app": "ਐਪ ਲਵੋ",
|
||||||
|
"footer.invite": "ਲੋਕਾਂ ਨੂੰ ਸੱਦਾ ਭੇਜੋ",
|
||||||
"footer.keyboard_shortcuts": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ",
|
"footer.keyboard_shortcuts": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ",
|
||||||
|
"footer.privacy_policy": "ਪਰਦੇਦਾਰੀ ਨੀਤੀ",
|
||||||
|
"footer.source_code": "ਸਰੋਤ ਕੋਡ ਵੇਖੋ",
|
||||||
"footer.status": "ਹਾਲਤ",
|
"footer.status": "ਹਾਲਤ",
|
||||||
"generic.saved": "ਸਾਂਭੀ ਗਈ",
|
"generic.saved": "ਸਾਂਭੀ ਗਈ",
|
||||||
|
"getting_started.heading": "ਸ਼ੁਰੂ ਕਰੀਏ",
|
||||||
|
"hashtag.column_header.tag_mode.all": "ਅਤੇ {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.any": "ਜਾਂ {additional}",
|
||||||
|
"hashtag.column_header.tag_mode.none": "{additional} ਬਿਨਾਂ",
|
||||||
|
"hashtag.column_settings.tag_mode.any": "ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੋਈ",
|
||||||
|
"hashtag.column_settings.tag_mode.none": "ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੋਈ ਨਹੀਂ",
|
||||||
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
||||||
|
"hashtag.follow": "ਹੈਸ਼ਟੈਗ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
|
||||||
|
"hashtag.unfollow": "ਹੈਸ਼ਟੈਗ ਨੂੰ ਅਣ-ਫ਼ਾਲੋ ਕਰੋ",
|
||||||
"home.column_settings.basic": "ਆਮ",
|
"home.column_settings.basic": "ਆਮ",
|
||||||
"keyboard_shortcuts.back": "to navigate back",
|
"interaction_modal.title.follow": "{name} ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ",
|
||||||
"keyboard_shortcuts.blocked": "to open blocked users list",
|
"keyboard_shortcuts.back": "ਪਿੱਛੇ ਜਾਓ",
|
||||||
"keyboard_shortcuts.boost": "to boost",
|
"keyboard_shortcuts.blocked": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰਾਂ ਦੀ ਸੂਚੀ ਖੋਲ੍ਹੋ",
|
||||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
"keyboard_shortcuts.boost": "ਪੋਸਟ ਨੂੰ ਬੂਸਟ ਕਰੋ",
|
||||||
|
"keyboard_shortcuts.column": "ਫੋਕਸ ਕਾਲਮ",
|
||||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
||||||
"keyboard_shortcuts.description": "ਵਰਣਨ",
|
"keyboard_shortcuts.description": "ਵਰਣਨ",
|
||||||
"keyboard_shortcuts.direct": "to open direct messages column",
|
"keyboard_shortcuts.direct": "to open direct messages column",
|
||||||
"keyboard_shortcuts.down": "to move down in the list",
|
"keyboard_shortcuts.down": "to move down in the list",
|
||||||
"keyboard_shortcuts.enter": "to open status",
|
"keyboard_shortcuts.enter": "to open status",
|
||||||
"keyboard_shortcuts.federated": "to open federated timeline",
|
"keyboard_shortcuts.federated": "to open federated timeline",
|
||||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
"keyboard_shortcuts.heading": "ਕੀਬੋਰਡ ਸ਼ਾਰਟਕੱਟ",
|
||||||
"keyboard_shortcuts.home": "to open home timeline",
|
"keyboard_shortcuts.home": "to open home timeline",
|
||||||
"keyboard_shortcuts.legend": "to display this legend",
|
"keyboard_shortcuts.legend": "to display this legend",
|
||||||
"keyboard_shortcuts.local": "to open local timeline",
|
"keyboard_shortcuts.local": "to open local timeline",
|
||||||
"keyboard_shortcuts.mention": "to mention author",
|
"keyboard_shortcuts.mention": "to mention author",
|
||||||
"keyboard_shortcuts.muted": "to open muted users list",
|
"keyboard_shortcuts.muted": "to open muted users list",
|
||||||
"keyboard_shortcuts.my_profile": "to open your profile",
|
"keyboard_shortcuts.my_profile": "to open your profile",
|
||||||
"keyboard_shortcuts.notifications": "to open notifications column",
|
"keyboard_shortcuts.notifications": "ਨੋਟੀਫਿਕੇਸ਼ਨ ਕਾਲਮ ਖੋਲ੍ਹੋ",
|
||||||
"keyboard_shortcuts.open_media": "to open media",
|
"keyboard_shortcuts.open_media": "to open media",
|
||||||
"keyboard_shortcuts.pinned": "to open pinned toots list",
|
"keyboard_shortcuts.pinned": "to open pinned toots list",
|
||||||
"keyboard_shortcuts.profile": "to open author's profile",
|
"keyboard_shortcuts.profile": "ਲੇਖਕ ਦਾ ਪਰੋਫਾਈਲ ਖੋਲ੍ਹੋ",
|
||||||
"keyboard_shortcuts.reply": "to reply",
|
"keyboard_shortcuts.reply": "ਪੋਸਟ ਨੂੰ ਜਵਾਬ ਦਿਓ",
|
||||||
"keyboard_shortcuts.requests": "to open follow requests list",
|
"keyboard_shortcuts.requests": "to open follow requests list",
|
||||||
"keyboard_shortcuts.search": "to focus search",
|
"keyboard_shortcuts.search": "to focus search",
|
||||||
"keyboard_shortcuts.spoilers": "to show/hide CW field",
|
"keyboard_shortcuts.spoilers": "to show/hide CW field",
|
||||||
"keyboard_shortcuts.start": "to open \"get started\" column",
|
"keyboard_shortcuts.start": "to open \"get started\" column",
|
||||||
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
|
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
|
||||||
"keyboard_shortcuts.toggle_sensitivity": "to show/hide media",
|
"keyboard_shortcuts.toggle_sensitivity": "ਮੀਡੀਆ ਦਿਖਾਉਣ/ਲੁਕਾਉਣ ਲਈ",
|
||||||
"keyboard_shortcuts.toot": "to start a brand new toot",
|
"keyboard_shortcuts.toot": "ਨਵੀਂ ਪੋਸਟ ਸ਼ੁਰੂ ਕਰੋ",
|
||||||
"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",
|
||||||
"lightbox.close": "ਬੰਦ ਕਰੋ",
|
"lightbox.close": "ਬੰਦ ਕਰੋ",
|
||||||
"lightbox.next": "ਅਗਲੀ",
|
"lightbox.next": "ਅਗਲੀ",
|
||||||
"lightbox.previous": "ਪਿਛਲੀ",
|
"lightbox.previous": "ਪਿਛਲੀ",
|
||||||
"lists.delete": "ਸੂਚੀ ਮਿਟਾਓ",
|
"link_preview.author": "{name} ਵਲੋਂ",
|
||||||
|
"lists.account.add": "ਸੂਚੀ ਵਿੱਚ ਜੋੜੋ",
|
||||||
|
"lists.account.remove": "ਸੂਚੀ ਵਿਚੋਂ ਹਟਾਓ",
|
||||||
|
"lists.delete": "ਸੂਚੀ ਹਟਾਓ",
|
||||||
|
"lists.replies_policy.followed": "ਕੋਈ ਵੀ ਫ਼ਾਲੋ ਕੀਤਾ ਵਰਤੋਂਕਾਰ",
|
||||||
|
"lists.replies_policy.none": "ਕੋਈ ਨਹੀਂ",
|
||||||
|
"loading_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ…",
|
||||||
"mute_modal.duration": "ਮਿਆਦ",
|
"mute_modal.duration": "ਮਿਆਦ",
|
||||||
"navigation_bar.about": "ਸਾਡੇ ਬਾਰੇ",
|
"navigation_bar.about": "ਇਸ ਬਾਰੇ",
|
||||||
|
"navigation_bar.advanced_interface": "ਤਕਨੀਕੀ ਵੈੱਬ ਇੰਟਰਫੇਸ ਵਿੱਚ ਖੋਲ੍ਹੋ",
|
||||||
|
"navigation_bar.blocks": "ਪਾਬੰਦੀ ਲਾਏ ਵਰਤੋਂਕਾਰ",
|
||||||
"navigation_bar.bookmarks": "ਬੁੱਕਮਾਰਕ",
|
"navigation_bar.bookmarks": "ਬੁੱਕਮਾਰਕ",
|
||||||
"navigation_bar.compose": "Compose new toot",
|
"navigation_bar.community_timeline": "ਲੋਕਲ ਸਮਾਂ-ਲਾਈਨ",
|
||||||
|
"navigation_bar.compose": "ਨਵੀਂ ਪੋਸਟ ਲਿਖੋ",
|
||||||
|
"navigation_bar.direct": "ਨਿੱਜੀ ਜ਼ਿਕਰ",
|
||||||
"navigation_bar.discover": "ਖੋਜ",
|
"navigation_bar.discover": "ਖੋਜ",
|
||||||
"navigation_bar.domain_blocks": "Hidden domains",
|
"navigation_bar.domain_blocks": "ਪਾਬੰਦੀ ਲਾਏ ਡੋਮੇਨ",
|
||||||
|
"navigation_bar.edit_profile": "ਪਰੋਫਾਈਲ ਨੂੰ ਸੋਧੋ",
|
||||||
"navigation_bar.explore": "ਪੜਚੋਲ ਕਰੋ",
|
"navigation_bar.explore": "ਪੜਚੋਲ ਕਰੋ",
|
||||||
|
"navigation_bar.favourites": "ਮਨਪਸੰਦ",
|
||||||
|
"navigation_bar.follow_requests": "ਫ਼ਾਲੋ ਦੀਆਂ ਬੇਨਤੀਆਂ",
|
||||||
|
"navigation_bar.followed_tags": "ਫ਼ਾਲੋ ਕੀਤੇ ਹੈਸ਼ਟੈਗ",
|
||||||
|
"navigation_bar.follows_and_followers": "ਫ਼ਾਲੋ ਅਤੇ ਫ਼ਾਲੋ ਕਰਨ ਵਾਲੇ",
|
||||||
"navigation_bar.lists": "ਸੂਚੀਆਂ",
|
"navigation_bar.lists": "ਸੂਚੀਆਂ",
|
||||||
"navigation_bar.logout": "ਲਾੱਗ ਆਊਟ, ਬਾਹਰ ਆਉਣਾ",
|
"navigation_bar.logout": "ਲਾਗ ਆਉਟ",
|
||||||
"navigation_bar.personal": "ਨਿੱਜੀ",
|
"navigation_bar.personal": "ਨਿੱਜੀ",
|
||||||
"navigation_bar.pins": "Pinned toots",
|
"navigation_bar.pins": "ਟੰਗੀਆਂ ਪੋਸਟਾਂ",
|
||||||
"navigation_bar.preferences": "ਤਰਜੀਹਾਂ",
|
"navigation_bar.preferences": "ਪਸੰਦਾਂ",
|
||||||
"navigation_bar.search": "ਖੋਜੋ",
|
"navigation_bar.search": "ਖੋਜੋ",
|
||||||
"navigation_bar.security": "ਸੁਰੱਖਿਆ",
|
"navigation_bar.security": "ਸੁਰੱਖਿਆ",
|
||||||
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
|
"not_signed_in_indicator.not_signed_in": "ਇਹ ਸਰੋਤ ਵਰਤਣ ਲਈ ਤੁਹਾਨੂੰ ਲਾਗਇਨ ਕਰਨ ਦੀ ਲੋੜ ਹੈ।",
|
||||||
|
"notification.follow": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕੀਤਾ",
|
||||||
|
"notification.follow_request": "{name} ਨੇ ਤੁਹਾਨੂੰ ਫ਼ਾਲੋ ਕਰਨ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ",
|
||||||
"notification.reblog": "{name} boosted your status",
|
"notification.reblog": "{name} boosted your status",
|
||||||
"notifications.column_settings.status": "New toots:",
|
"notifications.column_settings.follow": "ਨਵੇਂ ਫ਼ਾਲੋਅਰ:",
|
||||||
|
"notifications.column_settings.follow_request": "ਨਵੀਆਂ ਫ਼ਾਲੋ ਬੇਨਤੀਆਂ:",
|
||||||
|
"notifications.column_settings.status": "ਨਵੀਆਂ ਪੋਸਟਾਂ:",
|
||||||
|
"notifications.column_settings.update": "ਸੋਧ:",
|
||||||
"notifications.filter.all": "ਸਭ",
|
"notifications.filter.all": "ਸਭ",
|
||||||
"notifications.filter.follows": "ਪ੍ਰਸ਼ੰਸਕ ਬਣਨ 'ਤੇ",
|
"notifications.filter.boosts": "ਬੂਸਟ",
|
||||||
"onboarding.actions.go_to_explore": "See what's trending",
|
"notifications.filter.favourites": "ਮਨਪਸੰਦ",
|
||||||
"onboarding.actions.go_to_home": "Go to your home feed",
|
"notifications.filter.follows": "ਫ਼ਾਲੋ",
|
||||||
"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!",
|
"notifications.filter.mentions": "ਜ਼ਿਕਰ",
|
||||||
"onboarding.follows.title": "Popular on Mastodon",
|
"onboarding.actions.go_to_explore": "ਮੈਨੂੰ ਰੁਝਾਨ ਵੇਖਾਓ",
|
||||||
|
"onboarding.actions.go_to_home": "ਮੇਰੀ ਮੁੱਖ ਫੀਡ ਉੱਤੇ ਲੈ ਜਾਓ",
|
||||||
|
"onboarding.follows.lead": "",
|
||||||
|
"onboarding.follows.title": "ਆਪਣੀ ਹੋਮ ਫੀਡ ਨੂੰ ਨਿੱਜੀ ਬਣਾਓ",
|
||||||
|
"onboarding.profile.note": "ਜਾਣਕਾਰੀ",
|
||||||
|
"onboarding.profile.save_and_continue": "ਸੰਭਾਲੋ ਅਤੇ ਜਾਰੀ ਰੱਖੋ",
|
||||||
|
"onboarding.profile.title": "ਪਰੋਫਾਈਲ ਸੈਟਅੱਪ",
|
||||||
|
"onboarding.profile.upload_avatar": "ਪਰੋਫਾਈਲ ਤਸਵੀਰ ਅੱਪਲੋਡ ਕਰੋ",
|
||||||
|
"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": "ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਮਦਦ ਨਹੀਂ ਚਾਹੀਦੀ ਹੈ?",
|
||||||
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
|
"onboarding.start.title": "ਤੁਸੀਂ ਪੂਰਾ ਕਰਨ ਲਿਆ!",
|
||||||
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
"onboarding.steps.follow_people.body": "ਦਿਲਚਸਪ ਲੋਕਾਂ ਨੂੰ ਫ਼ਾਲੋ ਕਰੋ, ਇਹ ਤਾਂ ਮਸਟਾਡੋਨ ਹੈ।",
|
||||||
|
"onboarding.steps.follow_people.title": "ਆਪਣੀ ਹੋਮ ਫੀਡ ਨੂੰ ਨਿੱਜੀ ਬਣਾਓ",
|
||||||
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
||||||
|
"onboarding.steps.publish_status.title": "ਆਪਣੀ ਪਹਿਲੀ ਪੋਸਟ ਕਰੋ",
|
||||||
"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": "ਆਪਣੇ ਪਰੋਫਾਈਲ ਨੂੰ ਆਪਣਾ ਬਣਾਓ",
|
||||||
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
|
"onboarding.steps.share_profile.body": "ਆਪਣੇ ਮਿੱਤਰਾਂ ਨੂੰ ਦੱਸੋ ਤੁਹਾਨੂੰ ਮਸਟਾਡੋਨ ਕਿਵੇਂ ਲੱਗਿਆ",
|
||||||
"onboarding.steps.share_profile.title": "Share your profile",
|
"onboarding.steps.share_profile.title": "ਆਪਣੇ ਮਸਟਾਡੋਨ ਪਰੋਫਾਈਲ ਨੂੰ ਸਾਂਝਾ ਕਰੋ",
|
||||||
"poll.closed": "ਬੰਦ ਹੋਇਆ",
|
"poll.closed": "ਬੰਦ ਹੈ",
|
||||||
"poll.refresh": "ਤਾਜ਼ਾ ਕਰੋ",
|
"poll.refresh": "ਤਾਜ਼ਾ ਕਰੋ",
|
||||||
"poll.vote": "ਵੋਟ ਪਾਓ",
|
"poll.vote": "ਵੋਟ ਪਾਓ",
|
||||||
"privacy.change": "Adjust status privacy",
|
"privacy.change": "ਪੋਸਟ ਦੀ ਪਰਦੇਦਾਰੀ ਨੂੰ ਬਦਲੋ",
|
||||||
"privacy.direct.short": "Direct",
|
"privacy.direct.short": "ਸਿੱਧਾ ਲੋਕਾਂ ਦਾ ਜ਼ਿਕਰ ਕਰੋ",
|
||||||
"privacy.private.short": "Followers-only",
|
"privacy.private.short": "ਸਿਰਫ਼ ਫ਼ਾਲੋਅਰ",
|
||||||
"privacy.public.short": "ਜਨਤਕ",
|
"privacy.public.short": "ਜਨਤਕ",
|
||||||
"privacy_policy.title": "ਪਰਦੇਦਾਰੀ ਨੀਤੀ",
|
"privacy_policy.title": "ਪਰਦੇਦਾਰੀ ਨੀਤੀ",
|
||||||
"refresh": "ਤਾਜ਼ਾ ਕਰੋ",
|
"refresh": "ਤਾਜ਼ਾ ਕਰੋ",
|
||||||
"regeneration_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...",
|
"regeneration_indicator.label": "ਲੋਡ ਹੋ ਰਿਹਾ ਹੈ...",
|
||||||
"relative_time.full.just_now": "ਹੁਣੇ ਹੀ",
|
"relative_time.full.just_now": "ਹੁਣੇ ਹੀ",
|
||||||
|
"relative_time.just_now": "ਹੁਣੇ",
|
||||||
|
"relative_time.minutes": "{number}ਮਿੰ",
|
||||||
|
"relative_time.seconds": "{number}ਸ",
|
||||||
"relative_time.today": "ਅੱਜ",
|
"relative_time.today": "ਅੱਜ",
|
||||||
"reply_indicator.cancel": "ਰੱਦ ਕਰੋ",
|
"reply_indicator.cancel": "ਰੱਦ ਕਰੋ",
|
||||||
"report.block": "ਬਲਾਕ",
|
"report.block": "ਬਲਾਕ",
|
||||||
|
"report.categories.legal": "ਕਨੂੰਨੀ",
|
||||||
"report.categories.other": "ਬਾਕੀ",
|
"report.categories.other": "ਬਾਕੀ",
|
||||||
"report.categories.spam": "ਸਪਾਮ",
|
"report.categories.spam": "ਸਪੈਮ",
|
||||||
"report.category.title_status": "ਸੰਪਾਦਨਾ",
|
"report.category.title_account": "ਪਰੋਫਾਈਲ",
|
||||||
|
"report.category.title_status": "ਪੋਸਟ",
|
||||||
"report.close": "ਮੁਕੰਮਲ",
|
"report.close": "ਮੁਕੰਮਲ",
|
||||||
"report.mute": "ਮੌਨ ਕਰੋ",
|
"report.mute": "ਮੌਨ ਕਰੋ",
|
||||||
"report.next": "ਅਗਲੀ",
|
"report.next": "ਅਗਲੀ",
|
||||||
"report.placeholder": "Type or paste additional comments",
|
"report.placeholder": "ਵਧੀਕ ਟਿੱਪਣੀਆਂ",
|
||||||
"report.submit": "Submit report",
|
"report.reasons.dislike": "ਮੈਨੂੰ ਇਹ ਪਸੰਦ ਨਹੀਂ ਹੈ",
|
||||||
"report.target": "Report {target}",
|
"report.reasons.spam": "ਇਹ ਸਪੈਮ ਹੈ",
|
||||||
|
"report.submit": "ਭੇਜੋ",
|
||||||
|
"report.target": "{target} ਰਿਪੋਰਟ",
|
||||||
|
"report.unfollow": "@{name} ਨੂੰ ਅਣ-ਫ਼ਾਲੋ ਕਰੋ",
|
||||||
"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": "ਬਾਕੀ",
|
"report_notification.categories.other": "ਬਾਕੀ",
|
||||||
"report_notification.categories.spam": "ਸਪਾਮ",
|
"report_notification.categories.spam": "ਸਪੈਮ",
|
||||||
|
"report_notification.categories.violation": "ਨਿਯਮ ਦੀ ਉਲੰਘਣਾ",
|
||||||
"search.placeholder": "ਖੋਜੋ",
|
"search.placeholder": "ਖੋਜੋ",
|
||||||
|
"search_popout.quick_actions": "ਫੌਰੀ ਕਾਰਵਾਈਆਂ",
|
||||||
|
"search_popout.specific_date": "ਖਾਸ ਤਾਰੀਖ",
|
||||||
|
"search_popout.user": "ਵਰਤੋਂਕਾਰ",
|
||||||
|
"search_results.accounts": "ਪਰੋਫਾਈਲ",
|
||||||
"search_results.all": "ਸਭ",
|
"search_results.all": "ਸਭ",
|
||||||
"search_results.statuses": "Toots",
|
"search_results.hashtags": "ਹੈਸ਼ਟੈਗ",
|
||||||
|
"search_results.statuses": "ਪੋਸਟਾਂ",
|
||||||
"server_banner.learn_more": "ਹੋਰ ਜਾਣੋ",
|
"server_banner.learn_more": "ਹੋਰ ਜਾਣੋ",
|
||||||
"sign_in_banner.create_account": "ਖਾਤਾ ਬਣਾਓ",
|
"sign_in_banner.create_account": "ਖਾਤਾ ਬਣਾਓ",
|
||||||
"sign_in_banner.sign_in": "Sign in",
|
"sign_in_banner.sign_in": "ਲਾਗਇਨ",
|
||||||
"status.admin_status": "Open this status in the moderation interface",
|
"status.admin_status": "",
|
||||||
"status.copy": "Copy link to status",
|
"status.block": "@{name} ਉੱਤੇ ਪਾਬੰਦੀ ਲਾਓ",
|
||||||
"status.delete": "ਮਿਟਾਓ",
|
"status.bookmark": "ਬੁੱਕਮਾਰਕ",
|
||||||
|
"status.copy": "ਪੋਸਟ ਲਈ ਲਿੰਕ ਕਾਪੀ ਕਰੋ",
|
||||||
|
"status.delete": "ਹਟਾਓ",
|
||||||
"status.edit": "ਸੋਧ",
|
"status.edit": "ਸੋਧ",
|
||||||
|
"status.edited": "{date} ਨੂੰ ਸੋਧਿਆ",
|
||||||
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
|
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
|
||||||
"status.embed": "ਮੜ੍ਹੋ",
|
"status.embed": "ਮੜ੍ਹੋ",
|
||||||
|
"status.favourite": "ਪਸੰਦ",
|
||||||
|
"status.history.created": "{name} ਨੇ {date} ਨੂੰ ਬਣਾਇਆ",
|
||||||
|
"status.history.edited": "{name} ਨੇ {date} ਨੂੰ ਸੋਧਿਆ",
|
||||||
"status.load_more": "ਹੋਰ ਦਿਖਾਓ",
|
"status.load_more": "ਹੋਰ ਦਿਖਾਓ",
|
||||||
|
"status.media.open": "ਖੋਲ੍ਹਣ ਲਈ ਕਲਿੱਕ ਕਰੋ",
|
||||||
|
"status.media.show": "ਵੇਖਾਉਣ ਲਈ ਕਲਿੱਕ ਕਰੋ",
|
||||||
|
"status.mention": "@{name} ਦਾ ਜ਼ਿਕਰ",
|
||||||
"status.more": "ਹੋਰ",
|
"status.more": "ਹੋਰ",
|
||||||
"status.open": "Expand this status",
|
"status.open": "ਇਹ ਪੋਸਟ ਨੂੰ ਫੈਲਾਓ",
|
||||||
"status.pinned": "Pinned toot",
|
"status.pin": "ਪਰੋਫਾਈਲ ਉੱਤੇ ਟੰਗੋ",
|
||||||
|
"status.pinned": "ਟੰਗੀ ਹੋਈ ਪੋਸਟ",
|
||||||
"status.read_more": "ਹੋਰ ਪੜ੍ਹੋ",
|
"status.read_more": "ਹੋਰ ਪੜ੍ਹੋ",
|
||||||
"status.reblog": "ਵਧਾਓ",
|
"status.reblog": "ਵਧਾਓ",
|
||||||
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
|
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
|
||||||
|
"status.replied_to": "{name} ਨੂੰ ਜਵਾਬ ਦਿੱਤਾ",
|
||||||
"status.reply": "ਜਵਾਬ ਦੇਵੋ",
|
"status.reply": "ਜਵਾਬ ਦੇਵੋ",
|
||||||
|
"status.replyAll": "ਮਾਮਲੇ ਨੂੰ ਜਵਾਬ ਦਿਓ",
|
||||||
|
"status.report": "@{name} ਦੀ ਰਿਪੋਰਟ ਕਰੋ",
|
||||||
|
"status.sensitive_warning": "ਸੰਵੇਦਨਸ਼ੀਲ ਸਮੱਗਰੀ",
|
||||||
"status.share": "ਸਾਂਝਾ ਕਰੋ",
|
"status.share": "ਸਾਂਝਾ ਕਰੋ",
|
||||||
|
"status.show_filter_reason": "ਕਿਵੇਂ ਵੀ ਵੇਖਾਓ",
|
||||||
"status.show_less": "ਘੱਟ ਦਿਖਾਓ",
|
"status.show_less": "ਘੱਟ ਦਿਖਾਓ",
|
||||||
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
|
"status.show_more": "ਹੋਰ ਦਿਖਾਓ",
|
||||||
"subscribed_languages.save": "ਤਬਦੀਲੀਆਂ ਸਾਂਭੋ",
|
"status.title.with_attachments": "{user} ਨੇ {attachmentCount, plural,one {ਅਟੈਚਮੈਂਟ} other {{attachmentCount}ਅਟੈਚਮੈਂਟਾਂ}} ਪੋਸਟ ਕੀਤੀਆਂ",
|
||||||
"tabs_bar.home": "ਮੁੱਖ ਪੰਨਾ",
|
"status.translate": "ਉਲੱਥਾ ਕਰੋ",
|
||||||
|
"subscribed_languages.save": "ਤਬਦੀਲੀਆਂ ਸੰਭਾਲੋ",
|
||||||
|
"tabs_bar.home": "ਘਰ",
|
||||||
"tabs_bar.notifications": "ਸੂਚਨਾਵਾਂ",
|
"tabs_bar.notifications": "ਸੂਚਨਾਵਾਂ",
|
||||||
"timeline_hint.resources.followers": "ਪ੍ਰਸ਼ੰਸਕ",
|
"timeline_hint.resources.followers": "ਫ਼ਾਲੋਅਰ",
|
||||||
"timeline_hint.resources.follows": "ਪ੍ਰਸ਼ੰਸਕ ਬਣਨ 'ਤੇ",
|
"timeline_hint.resources.follows": "ਫ਼ਾਲੋ",
|
||||||
"timeline_hint.resources.statuses": "Older toots",
|
"timeline_hint.resources.statuses": "ਪੂਰਾਣੀਆਂ ਪੋਸਟਾਂ",
|
||||||
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
|
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
|
||||||
"upload_form.audio_description": "Describe for people with hearing loss",
|
"units.short.billion": "{count}ਿਬ",
|
||||||
"upload_form.description": "Describe for the visually impaired",
|
"units.short.million": "{count}ਮਿ",
|
||||||
|
"units.short.thousand": "{count}ਹਜ਼ਾਰ",
|
||||||
|
"upload_form.audio_description": "ਬੋਲ਼ੇ ਜਾਂ ਸੁਣਨ ਵਿੱਚ ਮੁਸ਼ਕਿਲ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵੇ",
|
||||||
|
"upload_form.description": "ਅੰਨ੍ਹੇ ਜਾਂ ਦੇਖਣ ਲਈ ਮੁਸ਼ਕਲ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵੇ",
|
||||||
"upload_form.edit": "ਸੋਧ",
|
"upload_form.edit": "ਸੋਧ",
|
||||||
"upload_form.undo": "ਮਿਟਾਓ",
|
"upload_form.undo": "ਹਟਾਓ",
|
||||||
"upload_form.video_description": "Describe for people with hearing loss or visual impairment",
|
"upload_form.video_description": "ਬੋਲ਼ੇ, ਸੁਣਨ ਵਿੱਚ ਮੁਸ਼ਕਿਲ, ਅੰਨ੍ਹੇ ਜਾਂ ਘੱਟ ਨਿਗ੍ਹਾ ਵਾਲੇ ਲੋਕਾਂ ਲਈ ਵੇਰਵਾ",
|
||||||
"upload_modal.apply": "ਲਾਗੂ ਕਰੋ",
|
"upload_modal.apply": "ਲਾਗੂ ਕਰੋ",
|
||||||
|
"upload_modal.applying": "ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ…",
|
||||||
"upload_modal.choose_image": "ਤਸਵੀਰ ਚੁਣੋ",
|
"upload_modal.choose_image": "ਤਸਵੀਰ ਚੁਣੋ",
|
||||||
"upload_modal.edit_media": "ਮੀਡੀਆ ਸੋਧੋ",
|
"upload_modal.edit_media": "ਮੀਡੀਆ ਸੋਧੋ",
|
||||||
"upload_progress.label": "Uploading…",
|
"upload_progress.label": "ਅੱਪਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ...",
|
||||||
"upload_progress.processing": "ਕਾਰਜ ਅਧੀਨ ਹੈ…",
|
"upload_progress.processing": "ਕਾਰਵਾਈ ਚੱਲ ਰਹੀ ਹੈ…",
|
||||||
"video.exit_fullscreen": "ਪੂਰੀ ਸਕਰੀਨ ਵਿੱਚੋਂ ਬਾਹਰ ਨਿਕਲੋ",
|
"video.exit_fullscreen": "ਪੂਰੀ ਸਕਰੀਨ ਵਿੱਚੋਂ ਬਾਹਰ ਨਿਕਲੋ",
|
||||||
"video.fullscreen": "ਪੂਰੀ ਸਕਰੀਨ",
|
"video.fullscreen": "ਪੂਰੀ ਸਕਰੀਨ",
|
||||||
"video.pause": "ਰਹਾਉ",
|
"video.pause": "ਠਹਿਰੋ",
|
||||||
"video.play": "ਚਲਾਓ"
|
"video.play": "ਚਲਾਓ"
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,6 +488,7 @@
|
||||||
"onboarding.profile.note": "O tebe",
|
"onboarding.profile.note": "O tebe",
|
||||||
"onboarding.profile.note_hint": "Môžeš @spomenúť iných ľudí, alebo #haštagy…",
|
"onboarding.profile.note_hint": "Môžeš @spomenúť iných ľudí, alebo #haštagy…",
|
||||||
"onboarding.profile.save_and_continue": "Ulož a pokračuj",
|
"onboarding.profile.save_and_continue": "Ulož a pokračuj",
|
||||||
|
"onboarding.profile.title": "Nastavenie profilu",
|
||||||
"onboarding.profile.upload_avatar": "Nahraj profilový obrázok",
|
"onboarding.profile.upload_avatar": "Nahraj profilový obrázok",
|
||||||
"onboarding.profile.upload_header": "Nahraj profilové záhlavie",
|
"onboarding.profile.upload_header": "Nahraj profilové záhlavie",
|
||||||
"onboarding.share.lead": "Daj ľudom vedieť, ako ťa môžu na Mastodone nájsť!",
|
"onboarding.share.lead": "Daj ľudom vedieť, ako ťa môžu na Mastodone nájsť!",
|
||||||
|
|
|
@ -496,7 +496,7 @@
|
||||||
"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": "ตอนนี้คุณเป็นส่วนหนึ่งของ Mastodon แพลตฟอร์มสื่อสังคมที่มีเอกลักษณ์เฉพาะตัว กระจายศูนย์ ที่ซึ่งคุณ—ไม่ใช่อัลกอริทึม—เรียบเรียงประสบการณ์ของคุณเอง มาช่วยให้คุณเริ่มต้นใช้งานพรมแดนทางสังคมใหม่นี้กันเลย:",
|
"onboarding.start.lead": "ตอนนี้คุณเป็นส่วนหนึ่งของ Mastodon แพลตฟอร์มสื่อสังคมแบบกระจายศูนย์ที่มีเอกลักษณ์เฉพาะตัว ที่ซึ่งคุณ ไม่ใช่อัลกอริทึม เรียบเรียงประสบการณ์ของคุณเอง มาช่วยให้คุณเริ่มต้นใช้งานพรมแดนทางสังคมใหม่นี้กันเลย:",
|
||||||
"onboarding.start.skip": "ไม่ต้องการความช่วยเหลือในการเริ่มต้นใช้งาน?",
|
"onboarding.start.skip": "ไม่ต้องการความช่วยเหลือในการเริ่มต้นใช้งาน?",
|
||||||
"onboarding.start.title": "คุณทำสำเร็จแล้ว!",
|
"onboarding.start.title": "คุณทำสำเร็จแล้ว!",
|
||||||
"onboarding.steps.follow_people.body": "การติดตามผู้คนที่น่าสนใจคือสิ่งที่ Mastodon ให้ความสำคัญ",
|
"onboarding.steps.follow_people.body": "การติดตามผู้คนที่น่าสนใจคือสิ่งที่ Mastodon ให้ความสำคัญ",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
{
|
{
|
||||||
|
"about.blocks": "ئوتتۇراھال مۇلازىمېتىر",
|
||||||
|
"about.contact": "ئالاقىلاشقۇچى:",
|
||||||
"account.badges.bot": "Bot",
|
"account.badges.bot": "Bot",
|
||||||
"account.cancel_follow_request": "Withdraw follow request",
|
"account.cancel_follow_request": "Withdraw follow request",
|
||||||
"account.posts": "Toots",
|
"account.posts": "Toots",
|
||||||
|
|
|
@ -34,9 +34,9 @@
|
||||||
"account.follow": "跟隨",
|
"account.follow": "跟隨",
|
||||||
"account.followers": "跟隨者",
|
"account.followers": "跟隨者",
|
||||||
"account.followers.empty": "尚未有人跟隨這位使用者。",
|
"account.followers.empty": "尚未有人跟隨這位使用者。",
|
||||||
"account.followers_counter": "被 {count, plural,one {{counter} 人}other {{counter} 人}}跟隨",
|
"account.followers_counter": "被 {count, plural, other {{counter} 人}}跟隨",
|
||||||
"account.following": "跟隨中",
|
"account.following": "跟隨中",
|
||||||
"account.following_counter": "正在跟隨 {count, plural, one {{counter} 人} other {{counter} 人}}",
|
"account.following_counter": "正在跟隨 {count,plural,other {{counter} 人}}",
|
||||||
"account.follows.empty": "這位使用者尚未跟隨任何人。",
|
"account.follows.empty": "這位使用者尚未跟隨任何人。",
|
||||||
"account.follows_you": "跟隨了您",
|
"account.follows_you": "跟隨了您",
|
||||||
"account.go_to_profile": "前往個人檔案",
|
"account.go_to_profile": "前往個人檔案",
|
||||||
|
@ -72,8 +72,8 @@
|
||||||
"account.unmute_notifications_short": "取消靜音推播通知",
|
"account.unmute_notifications_short": "取消靜音推播通知",
|
||||||
"account.unmute_short": "解除靜音",
|
"account.unmute_short": "解除靜音",
|
||||||
"account_note.placeholder": "按此新增備註",
|
"account_note.placeholder": "按此新增備註",
|
||||||
"admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
|
"admin.dashboard.daily_retention": "註冊後使用者存留率(日)",
|
||||||
"admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
|
"admin.dashboard.monthly_retention": "註冊後使用者存留率(月)",
|
||||||
"admin.dashboard.retention.average": "平均",
|
"admin.dashboard.retention.average": "平均",
|
||||||
"admin.dashboard.retention.cohort": "註冊月份",
|
"admin.dashboard.retention.cohort": "註冊月份",
|
||||||
"admin.dashboard.retention.cohort_size": "新使用者",
|
"admin.dashboard.retention.cohort_size": "新使用者",
|
||||||
|
@ -103,9 +103,9 @@
|
||||||
"bundle_modal_error.message": "載入此元件時發生錯誤。",
|
"bundle_modal_error.message": "載入此元件時發生錯誤。",
|
||||||
"bundle_modal_error.retry": "重試",
|
"bundle_modal_error.retry": "重試",
|
||||||
"closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。",
|
"closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。",
|
||||||
"closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon 。",
|
"closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon。",
|
||||||
"closed_registrations_modal.find_another_server": "尋找另一個伺服器",
|
"closed_registrations_modal.find_another_server": "尋找另一個伺服器",
|
||||||
"closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架一個自己的伺服器!",
|
"closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架設一個自己的伺服器!",
|
||||||
"closed_registrations_modal.title": "註冊 Mastodon",
|
"closed_registrations_modal.title": "註冊 Mastodon",
|
||||||
"column.about": "關於",
|
"column.about": "關於",
|
||||||
"column.blocks": "已封鎖的使用者",
|
"column.blocks": "已封鎖的使用者",
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
"compose_form.publish_form": "嘟出去",
|
"compose_form.publish_form": "嘟出去",
|
||||||
"compose_form.publish_loud": "{publish}!",
|
"compose_form.publish_loud": "{publish}!",
|
||||||
"compose_form.save_changes": "儲存變更",
|
"compose_form.save_changes": "儲存變更",
|
||||||
"compose_form.sensitive.hide": "標記媒體為敏感內容",
|
"compose_form.sensitive.hide": "{count, plural, other {將媒體標記為敏感內容}}",
|
||||||
"compose_form.sensitive.marked": "此媒體被標記為敏感內容",
|
"compose_form.sensitive.marked": "此媒體被標記為敏感內容",
|
||||||
"compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容",
|
"compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容",
|
||||||
"compose_form.spoiler.marked": "移除內容警告",
|
"compose_form.spoiler.marked": "移除內容警告",
|
||||||
|
@ -452,7 +452,7 @@
|
||||||
"notifications.column_settings.push": "推播通知",
|
"notifications.column_settings.push": "推播通知",
|
||||||
"notifications.column_settings.reblog": "轉嘟:",
|
"notifications.column_settings.reblog": "轉嘟:",
|
||||||
"notifications.column_settings.show": "於欄位中顯示",
|
"notifications.column_settings.show": "於欄位中顯示",
|
||||||
"notifications.column_settings.sound": "播放聲音",
|
"notifications.column_settings.sound": "播放音效",
|
||||||
"notifications.column_settings.status": "新嘟文:",
|
"notifications.column_settings.status": "新嘟文:",
|
||||||
"notifications.column_settings.unread_notifications.category": "未讀通知",
|
"notifications.column_settings.unread_notifications.category": "未讀通知",
|
||||||
"notifications.column_settings.unread_notifications.highlight": "突顯未讀通知",
|
"notifications.column_settings.unread_notifications.highlight": "突顯未讀通知",
|
||||||
|
@ -540,7 +540,7 @@
|
||||||
"regeneration_indicator.label": "載入中…",
|
"regeneration_indicator.label": "載入中…",
|
||||||
"regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!",
|
"regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!",
|
||||||
"relative_time.days": "{number} 天",
|
"relative_time.days": "{number} 天",
|
||||||
"relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前",
|
"relative_time.full.days": "{number, plural, other {# 天}}前",
|
||||||
"relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前",
|
"relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前",
|
||||||
"relative_time.full.just_now": "剛剛",
|
"relative_time.full.just_now": "剛剛",
|
||||||
"relative_time.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}前",
|
"relative_time.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}前",
|
||||||
|
@ -620,7 +620,7 @@
|
||||||
"search_results.see_all": "檢視全部",
|
"search_results.see_all": "檢視全部",
|
||||||
"search_results.statuses": "嘟文",
|
"search_results.statuses": "嘟文",
|
||||||
"search_results.title": "搜尋:{q}",
|
"search_results.title": "搜尋:{q}",
|
||||||
"server_banner.about_active_users": "最近三十日內使用此伺服器的人 (月活躍使用者)",
|
"server_banner.about_active_users": "最近三十日內使用此伺服器的人(月活躍使用者)",
|
||||||
"server_banner.active_users": "活躍使用者",
|
"server_banner.active_users": "活躍使用者",
|
||||||
"server_banner.administered_by": "管理者:",
|
"server_banner.administered_by": "管理者:",
|
||||||
"server_banner.introduction": "{domain} 是由 {mastodon} 提供之去中心化社群網路一部分。",
|
"server_banner.introduction": "{domain} 是由 {mastodon} 提供之去中心化社群網路一部分。",
|
||||||
|
|
|
@ -2,13 +2,6 @@ import { Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
|
|
||||||
export let currentMedia = null;
|
|
||||||
|
|
||||||
export function setCurrentMedia(value) {
|
|
||||||
currentMedia = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
accept_content_types: [],
|
accept_content_types: [],
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
import {
|
||||||
|
isAsyncThunkAction,
|
||||||
|
isPending as isThunkActionPending,
|
||||||
|
isFulfilled as isThunkActionFulfilled,
|
||||||
|
isRejected as isThunkActionRejected,
|
||||||
|
} from '@reduxjs/toolkit';
|
||||||
import { showLoading, hideLoading } from 'react-redux-loading-bar';
|
import { showLoading, hideLoading } from 'react-redux-loading-bar';
|
||||||
import type { AnyAction, Middleware } from 'redux';
|
import type { AnyAction, Middleware } from 'redux';
|
||||||
|
|
||||||
|
@ -21,25 +27,43 @@ export const loadingBarMiddleware = (
|
||||||
return ({ dispatch }) =>
|
return ({ dispatch }) =>
|
||||||
(next) =>
|
(next) =>
|
||||||
(action: AnyAction) => {
|
(action: AnyAction) => {
|
||||||
if (action.type && !action.skipLoading) {
|
let isPending = false;
|
||||||
|
let isFulfilled = false;
|
||||||
|
let isRejected = false;
|
||||||
|
|
||||||
|
if (
|
||||||
|
isAsyncThunkAction(action)
|
||||||
|
// TODO: once we get the first use-case for it, add a check for skipLoading
|
||||||
|
) {
|
||||||
|
if (isThunkActionPending(action)) isPending = true;
|
||||||
|
else if (isThunkActionFulfilled(action)) isFulfilled = true;
|
||||||
|
else if (isThunkActionRejected(action)) isRejected = true;
|
||||||
|
} else if (
|
||||||
|
action.type &&
|
||||||
|
!action.skipLoading &&
|
||||||
|
typeof action.type === 'string'
|
||||||
|
) {
|
||||||
const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
|
const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
|
||||||
|
|
||||||
const isPending = new RegExp(`${PENDING}$`, 'g');
|
const isPendingRegexp = new RegExp(`${PENDING}$`, 'g');
|
||||||
const isFulfilled = new RegExp(`${FULFILLED}$`, 'g');
|
const isFulfilledRegexp = new RegExp(`${FULFILLED}$`, 'g');
|
||||||
const isRejected = new RegExp(`${REJECTED}$`, 'g');
|
const isRejectedRegexp = new RegExp(`${REJECTED}$`, 'g');
|
||||||
|
|
||||||
if (typeof action.type === 'string') {
|
if (action.type.match(isPendingRegexp)) {
|
||||||
if (action.type.match(isPending)) {
|
isPending = true;
|
||||||
dispatch(showLoading());
|
} else if (action.type.match(isFulfilledRegexp)) {
|
||||||
} else if (
|
isFulfilled = true;
|
||||||
action.type.match(isFulfilled) ??
|
} else if (action.type.match(isRejectedRegexp)) {
|
||||||
action.type.match(isRejected)
|
isRejected = true;
|
||||||
) {
|
|
||||||
dispatch(hideLoading());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isPending) {
|
||||||
|
dispatch(showLoading());
|
||||||
|
} else if (isFulfilled || isRejected) {
|
||||||
|
dispatch(hideLoading());
|
||||||
|
}
|
||||||
|
|
||||||
return next(action);
|
return next(action);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -4398,11 +4398,6 @@ a.status-card {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
@supports (display: grid) {
|
|
||||||
// hack to fix Chrome <57
|
|
||||||
contain: strict;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > span {
|
& > span {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,13 +37,13 @@ class InlineRenderer
|
||||||
private
|
private
|
||||||
|
|
||||||
def preload_associations_for_status
|
def preload_associations_for_status
|
||||||
ActiveRecord::Associations::Preloader.new(records: @object, associations: {
|
ActiveRecord::Associations::Preloader.new(records: [@object], associations: {
|
||||||
active_mentions: :account,
|
active_mentions: :account,
|
||||||
|
|
||||||
reblog: {
|
reblog: {
|
||||||
active_mentions: :account,
|
active_mentions: :account,
|
||||||
},
|
},
|
||||||
})
|
}).call
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
|
|
|
@ -52,7 +52,7 @@ class OStatus::TagManager
|
||||||
ActivityPub::TagManager.instance.uri_to_local_id(tag)
|
ActivityPub::TagManager.instance.uri_to_local_id(tag)
|
||||||
else
|
else
|
||||||
matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag)
|
matches = Regexp.new("objectId=([\\d]+):objectType=#{expected_type}").match(tag)
|
||||||
return matches[1] unless matches.nil?
|
matches[1] unless matches.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class PotentialFriendshipTracker
|
|
||||||
EXPIRE_AFTER = 90.days.seconds
|
|
||||||
MAX_ITEMS = 80
|
|
||||||
|
|
||||||
WEIGHTS = {
|
|
||||||
reply: 1,
|
|
||||||
favourite: 10,
|
|
||||||
reblog: 20,
|
|
||||||
}.freeze
|
|
||||||
|
|
||||||
class << self
|
|
||||||
include Redisable
|
|
||||||
|
|
||||||
def record(account_id, target_account_id, action)
|
|
||||||
return if account_id == target_account_id
|
|
||||||
|
|
||||||
key = "interactions:#{account_id}"
|
|
||||||
weight = WEIGHTS[action]
|
|
||||||
|
|
||||||
redis.zincrby(key, weight, target_account_id)
|
|
||||||
redis.zremrangebyrank(key, 0, -MAX_ITEMS)
|
|
||||||
redis.expire(key, EXPIRE_AFTER)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove(account_id, target_account_id)
|
|
||||||
redis.zrem("interactions:#{account_id}", target_account_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -12,7 +12,7 @@ class ApplicationMailer < ActionMailer::Base
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def locale_for_account(account, &block)
|
def locale_for_account(account, &block)
|
||||||
I18n.with_locale(account.user_locale || I18n.default_locale, &block)
|
I18n.with_locale(account.user_locale || I18n.locale || I18n.default_locale, &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_autoreply_headers!
|
def set_autoreply_headers!
|
||||||
|
|
|
@ -202,6 +202,6 @@ class UserMailer < Devise::Mailer
|
||||||
end
|
end
|
||||||
|
|
||||||
def locale
|
def locale
|
||||||
@resource.locale.presence || I18n.default_locale
|
@resource.locale.presence || I18n.locale || I18n.default_locale
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -457,8 +457,8 @@ class Account < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def inverse_alias(key, original_key)
|
def inverse_alias(key, original_key)
|
||||||
define_method("#{key}=") do |value|
|
define_method(:"#{key}=") do |value|
|
||||||
public_send("#{original_key}=", !ActiveModel::Type::Boolean.new.cast(value))
|
public_send(:"#{original_key}=", !ActiveModel::Type::Boolean.new.cast(value))
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method(key) do
|
define_method(key) do
|
||||||
|
|
|
@ -18,16 +18,17 @@ class AccountDomainBlock < ApplicationRecord
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
validates :domain, presence: true, uniqueness: { scope: :account_id }, domain: true
|
validates :domain, presence: true, uniqueness: { scope: :account_id }, domain: true
|
||||||
|
|
||||||
after_commit :remove_blocking_cache
|
after_commit :invalidate_domain_blocking_cache
|
||||||
after_commit :remove_relationship_cache
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def remove_blocking_cache
|
def invalidate_domain_blocking_cache
|
||||||
Rails.cache.delete("exclude_domains_for:#{account_id}")
|
Rails.cache.delete("exclude_domains_for:#{account_id}")
|
||||||
|
Rails.cache.delete(['exclude_domains', account_id, domain])
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_relationship_cache
|
def invalidate_follow_recommendations_cache
|
||||||
Rails.cache.delete_matched("relationship:#{account_id}:*")
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,28 +1,48 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountSuggestions
|
class AccountSuggestions
|
||||||
|
include DatabaseHelper
|
||||||
|
|
||||||
SOURCES = [
|
SOURCES = [
|
||||||
AccountSuggestions::SettingSource,
|
AccountSuggestions::SettingSource,
|
||||||
AccountSuggestions::PastInteractionsSource,
|
AccountSuggestions::FriendsOfFriendsSource,
|
||||||
|
AccountSuggestions::SimilarProfilesSource,
|
||||||
AccountSuggestions::GlobalSource,
|
AccountSuggestions::GlobalSource,
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
def self.get(account, limit)
|
BATCH_SIZE = 40
|
||||||
SOURCES.each_with_object([]) do |source_class, suggestions|
|
|
||||||
source_suggestions = source_class.new.get(
|
|
||||||
account,
|
|
||||||
skip_account_ids: suggestions.map(&:account_id),
|
|
||||||
limit: limit - suggestions.size
|
|
||||||
)
|
|
||||||
|
|
||||||
suggestions.concat(source_suggestions)
|
def initialize(account)
|
||||||
|
@account = account
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(limit, offset = 0)
|
||||||
|
with_read_replica do
|
||||||
|
account_ids_with_sources = Rails.cache.fetch("follow_recommendations/#{@account.id}", expires_in: 15.minutes) do
|
||||||
|
SOURCES.flat_map { |klass| klass.new.get(@account, limit: BATCH_SIZE) }.each_with_object({}) do |(account_id, source), h|
|
||||||
|
(h[account_id] ||= []).concat(Array(source).map(&:to_sym))
|
||||||
|
end.to_a.shuffle
|
||||||
|
end
|
||||||
|
|
||||||
|
# The sources deliver accounts that haven't yet been followed, are not blocked,
|
||||||
|
# and so on. Since we reset the cache on follows, blocks, and so on, we don't need
|
||||||
|
# a complicated query on this end.
|
||||||
|
|
||||||
|
account_ids = account_ids_with_sources[offset, limit]
|
||||||
|
accounts_map = Account.where(id: account_ids.map(&:first)).includes(:account_stat).index_by(&:id)
|
||||||
|
|
||||||
|
account_ids.filter_map do |(account_id, source)|
|
||||||
|
next unless accounts_map.key?(account_id)
|
||||||
|
|
||||||
|
AccountSuggestions::Suggestion.new(
|
||||||
|
account: accounts_map[account_id],
|
||||||
|
source: source
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.remove(account, target_account_id)
|
def remove(target_account_id)
|
||||||
SOURCES.each do |source_class|
|
FollowRecommendationMute.create(account_id: @account.id, target_account_id: target_account_id)
|
||||||
source = source_class.new
|
|
||||||
source.remove(account, target_account_id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
37
app/models/account_suggestions/friends_of_friends_source.rb
Normal file
37
app/models/account_suggestions/friends_of_friends_source.rb
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountSuggestions::FriendsOfFriendsSource < AccountSuggestions::Source
|
||||||
|
def get(account, limit: 10)
|
||||||
|
Account.find_by_sql([<<~SQL.squish, { id: account.id, limit: limit }]).map { |row| [row.id, key] }
|
||||||
|
WITH first_degree AS (
|
||||||
|
SELECT target_account_id
|
||||||
|
FROM follows
|
||||||
|
JOIN accounts AS target_accounts ON follows.target_account_id = target_accounts.id
|
||||||
|
WHERE account_id = :id
|
||||||
|
AND NOT target_accounts.hide_collections
|
||||||
|
)
|
||||||
|
SELECT accounts.id, COUNT(*) AS frequency
|
||||||
|
FROM accounts
|
||||||
|
JOIN follows ON follows.target_account_id = accounts.id
|
||||||
|
JOIN account_stats ON account_stats.account_id = accounts.id
|
||||||
|
LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = :id
|
||||||
|
WHERE follows.account_id IN (SELECT * FROM first_degree)
|
||||||
|
AND follows.target_account_id NOT IN (SELECT * FROM first_degree)
|
||||||
|
AND follows.target_account_id <> :id
|
||||||
|
AND accounts.discoverable
|
||||||
|
AND accounts.suspended_at IS NULL
|
||||||
|
AND accounts.silenced_at IS NULL
|
||||||
|
AND accounts.moved_to_account_id IS NULL
|
||||||
|
AND follow_recommendation_mutes.target_account_id IS NULL
|
||||||
|
GROUP BY accounts.id, account_stats.id
|
||||||
|
ORDER BY frequency DESC, account_stats.followers_count ASC
|
||||||
|
LIMIT :limit
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def key
|
||||||
|
:friends_of_friends
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,39 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountSuggestions::GlobalSource < AccountSuggestions::Source
|
class AccountSuggestions::GlobalSource < AccountSuggestions::Source
|
||||||
include Redisable
|
def get(account, limit: 10)
|
||||||
|
FollowRecommendation.localized(content_locale).joins(:account).merge(base_account_scope(account)).order(rank: :desc).limit(limit).pluck(:account_id, :reason)
|
||||||
def key
|
|
||||||
:global
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(account, skip_account_ids: [], limit: 40)
|
|
||||||
account_ids = account_ids_for_locale(I18n.locale.to_s.split(/[_-]/).first) - [account.id] - skip_account_ids
|
|
||||||
|
|
||||||
as_ordered_suggestions(
|
|
||||||
scope(account).where(id: account_ids),
|
|
||||||
account_ids
|
|
||||||
).take(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove(_account, _target_account_id)
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def scope(account)
|
def content_locale
|
||||||
Account.searchable
|
I18n.locale.to_s.split(/[_-]/).first
|
||||||
.followable_by(account)
|
|
||||||
.not_excluded_by_account(account)
|
|
||||||
.not_domain_blocked_by_account(account)
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_ids_for_locale(locale)
|
|
||||||
redis.zrevrange("follow_recommendations:#{locale}", 0, -1).map(&:to_i)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_ordered_list_key(account)
|
|
||||||
account.id
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class AccountSuggestions::PastInteractionsSource < AccountSuggestions::Source
|
|
||||||
include Redisable
|
|
||||||
|
|
||||||
def key
|
|
||||||
:past_interactions
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(account, skip_account_ids: [], limit: 40)
|
|
||||||
account_ids = account_ids_for_account(account.id, limit + skip_account_ids.size) - skip_account_ids
|
|
||||||
|
|
||||||
as_ordered_suggestions(
|
|
||||||
scope.where(id: account_ids),
|
|
||||||
account_ids
|
|
||||||
).take(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove(account, target_account_id)
|
|
||||||
redis.zrem("interactions:#{account.id}", target_account_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def scope
|
|
||||||
Account.searchable
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_ids_for_account(account_id, limit)
|
|
||||||
redis.zrevrange("interactions:#{account_id}", 0, limit).map(&:to_i)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_ordered_list_key(account)
|
|
||||||
account.id
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +1,18 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||||
def key
|
def get(account, limit: 10)
|
||||||
:staff
|
if setting_enabled?
|
||||||
end
|
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||||
|
else
|
||||||
def get(account, skip_account_ids: [], limit: 40)
|
[]
|
||||||
return [] unless setting_enabled?
|
end
|
||||||
|
|
||||||
as_ordered_suggestions(
|
|
||||||
scope(account).where(setting_to_where_condition).where.not(id: skip_account_ids),
|
|
||||||
usernames_and_domains
|
|
||||||
).take(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def remove(_account, _target_account_id)
|
|
||||||
nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def scope(account)
|
def key
|
||||||
Account.searchable
|
:featured
|
||||||
.followable_by(account)
|
|
||||||
.not_excluded_by_account(account)
|
|
||||||
.not_domain_blocked_by_account(account)
|
|
||||||
.where(locked: false)
|
|
||||||
.where.not(id: account.id)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def usernames_and_domains
|
def usernames_and_domains
|
||||||
|
@ -61,8 +47,4 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||||
def setting
|
def setting
|
||||||
Setting.bootstrap_timeline_accounts
|
Setting.bootstrap_timeline_accounts
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_ordered_list_key(account)
|
|
||||||
[account.username.downcase, account.domain&.downcase]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
67
app/models/account_suggestions/similar_profiles_source.rb
Normal file
67
app/models/account_suggestions/similar_profiles_source.rb
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccountSuggestions::SimilarProfilesSource < AccountSuggestions::Source
|
||||||
|
class QueryBuilder < AccountSearchService::QueryBuilder
|
||||||
|
def must_clauses
|
||||||
|
[
|
||||||
|
{
|
||||||
|
more_like_this: {
|
||||||
|
fields: %w(text text.stemmed),
|
||||||
|
like: @query.map { |id| { _index: 'accounts', _id: id } },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
term: {
|
||||||
|
properties: 'discoverable',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def must_not_clauses
|
||||||
|
[
|
||||||
|
{
|
||||||
|
terms: {
|
||||||
|
id: following_ids,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
term: {
|
||||||
|
properties: 'bot',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def should_clauses
|
||||||
|
{
|
||||||
|
term: {
|
||||||
|
properties: {
|
||||||
|
value: 'verified',
|
||||||
|
boost: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(account, limit: 10)
|
||||||
|
recently_followed_account_ids = account.active_relationships.recent.limit(5).pluck(:target_account_id)
|
||||||
|
|
||||||
|
if Chewy.enabled? && !recently_followed_account_ids.empty?
|
||||||
|
QueryBuilder.new(recently_followed_account_ids, account).build.limit(limit).hits.pluck('_id').map(&:to_i).zip([key].cycle)
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
rescue Faraday::ConnectionFailed
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def key
|
||||||
|
:similar_to_recently_followed
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,34 +1,18 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountSuggestions::Source
|
class AccountSuggestions::Source
|
||||||
def key
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
def get(_account, **kwargs)
|
def get(_account, **kwargs)
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove(_account, target_account_id)
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def as_ordered_suggestions(scope, ordered_list)
|
def base_account_scope(account)
|
||||||
return [] if ordered_list.empty?
|
Account.searchable
|
||||||
|
.followable_by(account)
|
||||||
map = scope.index_by { |account| to_ordered_list_key(account) }
|
.not_excluded_by_account(account)
|
||||||
|
.not_domain_blocked_by_account(account)
|
||||||
ordered_list.filter_map { |ordered_list_key| map[ordered_list_key] }.map do |account|
|
.where.not(id: account.id)
|
||||||
AccountSuggestions::Suggestion.new(
|
.joins("LEFT OUTER JOIN follow_recommendation_mutes ON follow_recommendation_mutes.target_account_id = accounts.id AND follow_recommendation_mutes.account_id = #{account.id}").where(follow_recommendation_mutes: { target_account_id: nil })
|
||||||
account: account,
|
|
||||||
source: key
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_ordered_list_key(_account)
|
|
||||||
raise NotImplementedError
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,9 +78,9 @@ class Announcement < ApplicationRecord
|
||||||
else
|
else
|
||||||
scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me")
|
scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me")
|
||||||
end
|
end
|
||||||
end
|
end.to_a
|
||||||
|
|
||||||
ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji)
|
ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call
|
||||||
records
|
records
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,15 +26,20 @@ class Block < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
before_validation :set_uri, only: :create
|
before_validation :set_uri, only: :create
|
||||||
after_commit :remove_blocking_cache
|
after_commit :invalidate_blocking_cache
|
||||||
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def remove_blocking_cache
|
def invalidate_blocking_cache
|
||||||
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
|
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
|
||||||
Rails.cache.delete("exclude_account_ids_for:#{target_account_id}")
|
Rails.cache.delete("exclude_account_ids_for:#{target_account_id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate_follow_recommendations_cache
|
||||||
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
|
end
|
||||||
|
|
||||||
def set_uri
|
def set_uri
|
||||||
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
|
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,6 +64,7 @@ module Account::Associations
|
||||||
has_one :deletion_request, class_name: 'AccountDeletionRequest', inverse_of: :account, dependent: :destroy
|
has_one :deletion_request, class_name: 'AccountDeletionRequest', inverse_of: :account, dependent: :destroy
|
||||||
|
|
||||||
# Follow recommendations
|
# Follow recommendations
|
||||||
|
has_one :follow_recommendation, inverse_of: :account, dependent: nil
|
||||||
has_one :follow_recommendation_suppression, inverse_of: :account, dependent: :destroy
|
has_one :follow_recommendation_suppression, inverse_of: :account, dependent: :destroy
|
||||||
|
|
||||||
# Account statuses cleanup policy
|
# Account statuses cleanup policy
|
||||||
|
|
|
@ -60,12 +60,6 @@ module Account::Interactions
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def domain_blocking_map(target_account_ids, account_id)
|
|
||||||
accounts_map = Account.where(id: target_account_ids).select('id, domain').each_with_object({}) { |a, h| h[a.id] = a.domain }
|
|
||||||
blocked_domains = domain_blocking_map_by_domain(accounts_map.values.compact, account_id)
|
|
||||||
accounts_map.reduce({}) { |h, (id, domain)| h.merge(id => blocked_domains[domain]) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def domain_blocking_map_by_domain(target_domains, account_id)
|
def domain_blocking_map_by_domain(target_domains, account_id)
|
||||||
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
|
follow_mapping(AccountDomainBlock.where(account_id: account_id, domain: target_domains), :domain)
|
||||||
end
|
end
|
||||||
|
@ -122,8 +116,6 @@ module Account::Interactions
|
||||||
|
|
||||||
rel.save! if rel.changed?
|
rel.save! if rel.changed?
|
||||||
|
|
||||||
remove_potential_friendship(other_account)
|
|
||||||
|
|
||||||
rel
|
rel
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,13 +129,10 @@ module Account::Interactions
|
||||||
|
|
||||||
rel.save! if rel.changed?
|
rel.save! if rel.changed?
|
||||||
|
|
||||||
remove_potential_friendship(other_account)
|
|
||||||
|
|
||||||
rel
|
rel
|
||||||
end
|
end
|
||||||
|
|
||||||
def block!(other_account, uri: nil)
|
def block!(other_account, uri: nil)
|
||||||
remove_potential_friendship(other_account)
|
|
||||||
block_relationships.create_with(uri: uri)
|
block_relationships.create_with(uri: uri)
|
||||||
.find_or_create_by!(target_account: other_account)
|
.find_or_create_by!(target_account: other_account)
|
||||||
end
|
end
|
||||||
|
@ -154,8 +143,6 @@ module Account::Interactions
|
||||||
mute.expires_in = duration.zero? ? nil : duration
|
mute.expires_in = duration.zero? ? nil : duration
|
||||||
mute.save!
|
mute.save!
|
||||||
|
|
||||||
remove_potential_friendship(other_account)
|
|
||||||
|
|
||||||
# When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
|
# When toggling a mute between hiding and allowing notifications, the mute will already exist, so the find_or_create_by! call will return the existing Mute without updating the hide_notifications attribute. Therefore, we check that hide_notifications? is what we want and set it if it isn't.
|
||||||
mute.update!(hide_notifications: notifications) if mute.hide_notifications? != notifications
|
mute.update!(hide_notifications: notifications) if mute.hide_notifications? != notifications
|
||||||
|
|
||||||
|
@ -313,10 +300,4 @@ module Account::Interactions
|
||||||
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
|
domain_blocking_by_domain: Account.domain_blocking_map_by_domain(domains, id),
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def remove_potential_friendship(other_account)
|
|
||||||
PotentialFriendshipTracker.remove(id, other_account.id)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -116,6 +116,7 @@ module Account::Search
|
||||||
[].tap do |properties|
|
[].tap do |properties|
|
||||||
properties << 'bot' if bot?
|
properties << 'bot' if bot?
|
||||||
properties << 'verified' if fields.any?(&:verified?)
|
properties << 'verified' if fields.any?(&:verified?)
|
||||||
|
properties << 'discoverable' if discoverable?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ module Account::Search
|
||||||
tsquery = generate_query_for_search(terms)
|
tsquery = generate_query_for_search(terms)
|
||||||
|
|
||||||
find_by_sql([BASIC_SEARCH_SQL, { limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
|
find_by_sql([BASIC_SEARCH_SQL, { limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
|
||||||
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
|
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ module Account::Search
|
||||||
sql_template = following ? ADVANCED_SEARCH_WITH_FOLLOWING : ADVANCED_SEARCH_WITHOUT_FOLLOWING
|
sql_template = following ? ADVANCED_SEARCH_WITH_FOLLOWING : ADVANCED_SEARCH_WITHOUT_FOLLOWING
|
||||||
|
|
||||||
find_by_sql([sql_template, { id: account.id, limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
|
find_by_sql([sql_template, { id: account.id, limit: limit, offset: offset, tsquery: tsquery }]).tap do |records|
|
||||||
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
|
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ module RelationshipCacheable
|
||||||
private
|
private
|
||||||
|
|
||||||
def remove_relationship_cache
|
def remove_relationship_cache
|
||||||
Rails.cache.delete("relationship:#{account_id}:#{target_account_id}")
|
Rails.cache.delete(['relationship', account_id, target_account_id])
|
||||||
Rails.cache.delete("relationship:#{target_account_id}:#{account_id}")
|
Rails.cache.delete(['relationship', target_account_id, account_id])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ module Remotable
|
||||||
def remotable_attachment(attachment_name, limit, suppress_errors: true, download_on_assign: true, attribute_name: nil)
|
def remotable_attachment(attachment_name, limit, suppress_errors: true, download_on_assign: true, attribute_name: nil)
|
||||||
attribute_name ||= :"#{attachment_name}_remote_url"
|
attribute_name ||= :"#{attachment_name}_remote_url"
|
||||||
|
|
||||||
define_method("download_#{attachment_name}!") do |url = nil|
|
define_method(:"download_#{attachment_name}!") do |url = nil|
|
||||||
url ||= self[attribute_name]
|
url ||= self[attribute_name]
|
||||||
|
|
||||||
return if url.blank?
|
return if url.blank?
|
||||||
|
@ -24,29 +24,29 @@ module Remotable
|
||||||
Request.new(:get, url).perform do |response|
|
Request.new(:get, url).perform do |response|
|
||||||
raise Mastodon::UnexpectedResponseError, response unless (200...300).cover?(response.code)
|
raise Mastodon::UnexpectedResponseError, response unless (200...300).cover?(response.code)
|
||||||
|
|
||||||
public_send("#{attachment_name}=", ResponseWithLimit.new(response, limit))
|
public_send(:"#{attachment_name}=", ResponseWithLimit.new(response, limit))
|
||||||
end
|
end
|
||||||
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e
|
rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e
|
||||||
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
||||||
public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
|
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
|
||||||
raise e unless suppress_errors
|
raise e unless suppress_errors
|
||||||
rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e
|
rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e
|
||||||
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
Rails.logger.debug { "Error fetching remote #{attachment_name}: #{e}" }
|
||||||
public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present?
|
public_send(:"#{attachment_name}=", nil) if public_send(:"#{attachment_name}_file_name").present?
|
||||||
end
|
end
|
||||||
|
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method("#{attribute_name}=") do |url|
|
define_method(:"#{attribute_name}=") do |url|
|
||||||
return if self[attribute_name] == url && public_send("#{attachment_name}_file_name").present?
|
return if self[attribute_name] == url && public_send(:"#{attachment_name}_file_name").present?
|
||||||
|
|
||||||
self[attribute_name] = url if has_attribute?(attribute_name)
|
self[attribute_name] = url if has_attribute?(attribute_name)
|
||||||
|
|
||||||
public_send("download_#{attachment_name}!", url) if download_on_assign
|
public_send(:"download_#{attachment_name}!", url) if download_on_assign
|
||||||
end
|
end
|
||||||
|
|
||||||
alias_method("reset_#{attachment_name}!", "download_#{attachment_name}!")
|
alias_method(:"reset_#{attachment_name}!", "download_#{attachment_name}!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -91,7 +91,7 @@ class CustomFilter < ApplicationRecord
|
||||||
filters_hash.values.map { |cache| [cache.delete(:filter), cache] }
|
filters_hash.values.map { |cache| [cache.delete(:filter), cache] }
|
||||||
end.to_a
|
end.to_a
|
||||||
|
|
||||||
active_filters.select { |custom_filter, _| !custom_filter.expired? }
|
active_filters.reject { |custom_filter, _| custom_filter.expired? }
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.apply_cached_filters(cached_filters, status)
|
def self.apply_cached_filters(cached_filters, status)
|
||||||
|
|
|
@ -44,10 +44,10 @@ class Follow < ApplicationRecord
|
||||||
|
|
||||||
before_validation :set_uri, only: :create
|
before_validation :set_uri, only: :create
|
||||||
after_create :increment_cache_counters
|
after_create :increment_cache_counters
|
||||||
after_create :invalidate_hash_cache
|
|
||||||
after_destroy :remove_endorsements
|
after_destroy :remove_endorsements
|
||||||
after_destroy :decrement_cache_counters
|
after_destroy :decrement_cache_counters
|
||||||
after_destroy :invalidate_hash_cache
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
after_commit :invalidate_hash_cache
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
@ -74,4 +74,8 @@ class Follow < ApplicationRecord
|
||||||
|
|
||||||
Rails.cache.delete("followers_hash:#{target_account_id}:#{account.synchronization_uri_prefix}")
|
Rails.cache.delete("followers_hash:#{target_account_id}:#{account.synchronization_uri_prefix}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate_follow_recommendations_cache
|
||||||
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -17,12 +17,9 @@ class FollowRecommendationFilter
|
||||||
|
|
||||||
def results
|
def results
|
||||||
if params['status'] == 'suppressed'
|
if params['status'] == 'suppressed'
|
||||||
Account.joins(:follow_recommendation_suppression).order(FollowRecommendationSuppression.arel_table[:id].desc).to_a
|
Account.includes(:account_stat).joins(:follow_recommendation_suppression).order(FollowRecommendationSuppression.arel_table[:id].desc)
|
||||||
else
|
else
|
||||||
account_ids = redis.zrevrange("follow_recommendations:#{@language}", 0, -1).map(&:to_i)
|
Account.includes(:account_stat).joins(:follow_recommendation).merge(FollowRecommendation.localized(@language).order(rank: :desc))
|
||||||
accounts = Account.where(id: account_ids).index_by(&:id)
|
|
||||||
|
|
||||||
account_ids.filter_map { |id| accounts[id] }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
26
app/models/follow_recommendation_mute.rb
Normal file
26
app/models/follow_recommendation_mute.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: follow_recommendation_mutes
|
||||||
|
#
|
||||||
|
# id :bigint(8) not null, primary key
|
||||||
|
# account_id :bigint(8) not null
|
||||||
|
# target_account_id :bigint(8) not null
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
#
|
||||||
|
class FollowRecommendationMute < ApplicationRecord
|
||||||
|
belongs_to :account
|
||||||
|
belongs_to :target_account, class_name: 'Account'
|
||||||
|
|
||||||
|
validates :target_account, uniqueness: { scope: :account_id }
|
||||||
|
|
||||||
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def invalidate_follow_recommendations_cache
|
||||||
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,19 +11,5 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class FollowRecommendationSuppression < ApplicationRecord
|
class FollowRecommendationSuppression < ApplicationRecord
|
||||||
include Redisable
|
|
||||||
|
|
||||||
belongs_to :account
|
belongs_to :account
|
||||||
|
|
||||||
after_commit :remove_follow_recommendations, on: :create
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def remove_follow_recommendations
|
|
||||||
redis.pipelined do |pipeline|
|
|
||||||
I18n.available_locales.each do |locale|
|
|
||||||
pipeline.zrem("follow_recommendations:#{locale}", account_id)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,10 +45,15 @@ class FollowRequest < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
before_validation :set_uri, only: :create
|
before_validation :set_uri, only: :create
|
||||||
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def set_uri
|
def set_uri
|
||||||
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
|
self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate_follow_recommendations_cache
|
||||||
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -84,7 +84,7 @@ class Form::AdminSettings
|
||||||
|
|
||||||
KEYS.each do |key|
|
KEYS.each do |key|
|
||||||
define_method(key) do
|
define_method(key) do
|
||||||
return instance_variable_get("@#{key}") if instance_variable_defined?("@#{key}")
|
return instance_variable_get(:"@#{key}") if instance_variable_defined?(:"@#{key}")
|
||||||
|
|
||||||
stored_value = if UPLOAD_KEYS.include?(key)
|
stored_value = if UPLOAD_KEYS.include?(key)
|
||||||
SiteUpload.where(var: key).first_or_initialize(var: key)
|
SiteUpload.where(var: key).first_or_initialize(var: key)
|
||||||
|
@ -94,12 +94,12 @@ class Form::AdminSettings
|
||||||
Setting.public_send(key)
|
Setting.public_send(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
instance_variable_set("@#{key}", stored_value)
|
instance_variable_set(:"@#{key}", stored_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
UPLOAD_KEYS.each do |key|
|
UPLOAD_KEYS.each do |key|
|
||||||
define_method("#{key}=") do |file|
|
define_method(:"#{key}=") do |file|
|
||||||
value = public_send(key)
|
value = public_send(key)
|
||||||
value.file = file
|
value.file = file
|
||||||
rescue Mastodon::DimensionsValidationError => e
|
rescue Mastodon::DimensionsValidationError => e
|
||||||
|
@ -114,13 +114,13 @@ class Form::AdminSettings
|
||||||
return false unless errors.empty? && valid?
|
return false unless errors.empty? && valid?
|
||||||
|
|
||||||
KEYS.each do |key|
|
KEYS.each do |key|
|
||||||
next unless instance_variable_defined?("@#{key}")
|
next unless instance_variable_defined?(:"@#{key}")
|
||||||
|
|
||||||
if UPLOAD_KEYS.include?(key)
|
if UPLOAD_KEYS.include?(key)
|
||||||
public_send(key).save
|
public_send(key).save
|
||||||
else
|
else
|
||||||
setting = Setting.where(var: key).first_or_initialize(var: key)
|
setting = Setting.where(var: key).first_or_initialize(var: key)
|
||||||
setting.update(value: typecast_value(key, instance_variable_get("@#{key}")))
|
setting.update(value: typecast_value(key, instance_variable_get(:"@#{key}")))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -139,9 +139,9 @@ class Form::AdminSettings
|
||||||
|
|
||||||
def validate_site_uploads
|
def validate_site_uploads
|
||||||
UPLOAD_KEYS.each do |key|
|
UPLOAD_KEYS.each do |key|
|
||||||
next unless instance_variable_defined?("@#{key}")
|
next unless instance_variable_defined?(:"@#{key}")
|
||||||
|
|
||||||
upload = instance_variable_get("@#{key}")
|
upload = instance_variable_get(:"@#{key}")
|
||||||
next if upload.valid?
|
next if upload.valid?
|
||||||
|
|
||||||
upload.errors.each do |error|
|
upload.errors.each do |error|
|
||||||
|
|
|
@ -43,14 +43,19 @@ class Form::Import
|
||||||
validate :validate_data
|
validate :validate_data
|
||||||
|
|
||||||
def guessed_type
|
def guessed_type
|
||||||
return :muting if csv_headers_match?('Hide notifications')
|
if csv_headers_match?('Hide notifications') || file_name_matches?('mutes') || file_name_matches?('muted_accounts')
|
||||||
return :following if csv_headers_match?('Show boosts') || csv_headers_match?('Notify on new posts') || csv_headers_match?('Languages')
|
:muting
|
||||||
return :following if file_name_matches?('follows') || file_name_matches?('following_accounts')
|
elsif csv_headers_match?('Show boosts') || csv_headers_match?('Notify on new posts') || csv_headers_match?('Languages') || file_name_matches?('follows') || file_name_matches?('following_accounts')
|
||||||
return :blocking if file_name_matches?('blocks') || file_name_matches?('blocked_accounts')
|
:following
|
||||||
return :muting if file_name_matches?('mutes') || file_name_matches?('muted_accounts')
|
elsif file_name_matches?('blocks') || file_name_matches?('blocked_accounts')
|
||||||
return :domain_blocking if file_name_matches?('domain_blocks') || file_name_matches?('blocked_domains')
|
:blocking
|
||||||
return :bookmarks if file_name_matches?('bookmarks')
|
elsif file_name_matches?('domain_blocks') || file_name_matches?('blocked_domains')
|
||||||
return :lists if file_name_matches?('lists')
|
:domain_blocking
|
||||||
|
elsif file_name_matches?('bookmarks')
|
||||||
|
:bookmarks
|
||||||
|
elsif file_name_matches?('lists')
|
||||||
|
:lists
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Whether the uploaded CSV file seems to correspond to a different import type than the one selected
|
# Whether the uploaded CSV file seems to correspond to a different import type than the one selected
|
||||||
|
|
|
@ -23,11 +23,16 @@ class Mute < ApplicationRecord
|
||||||
|
|
||||||
validates :account_id, uniqueness: { scope: :target_account_id }
|
validates :account_id, uniqueness: { scope: :target_account_id }
|
||||||
|
|
||||||
after_commit :remove_blocking_cache
|
after_commit :invalidate_blocking_cache
|
||||||
|
after_commit :invalidate_follow_recommendations_cache
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def remove_blocking_cache
|
def invalidate_blocking_cache
|
||||||
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
|
Rails.cache.delete("exclude_account_ids_for:#{account_id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def invalidate_follow_recommendations_cache
|
||||||
|
Rails.cache.delete("follow_recommendations/#{account_id}")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -111,7 +111,7 @@ class Notification < ApplicationRecord
|
||||||
|
|
||||||
# Instead of using the usual `includes`, manually preload each type.
|
# Instead of using the usual `includes`, manually preload each type.
|
||||||
# If polymorphic associations are loaded with the usual `includes`, other types of associations will be loaded more.
|
# If polymorphic associations are loaded with the usual `includes`, other types of associations will be loaded more.
|
||||||
ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations)
|
ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations).call
|
||||||
end
|
end
|
||||||
|
|
||||||
unique_target_statuses = notifications.filter_map(&:target_status).uniq
|
unique_target_statuses = notifications.filter_map(&:target_status).uniq
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#
|
#
|
||||||
# Table name: preview_cards_statuses
|
# Table name: preview_cards_statuses
|
||||||
#
|
#
|
||||||
# preview_card_id :bigint(8) not null
|
# preview_card_id :bigint(8) not null, primary key
|
||||||
# status_id :bigint(8) not null
|
# status_id :bigint(8) not null, primary key
|
||||||
# url :string
|
# url :string
|
||||||
#
|
#
|
||||||
class PreviewCardsStatus < ApplicationRecord
|
class PreviewCardsStatus < ApplicationRecord
|
||||||
|
|
|
@ -5,8 +5,9 @@ class AccountRelationshipsPresenter
|
||||||
:muting, :requested, :requested_by, :domain_blocking,
|
:muting, :requested, :requested_by, :domain_blocking,
|
||||||
:endorsed, :account_note
|
:endorsed, :account_note
|
||||||
|
|
||||||
def initialize(account_ids, current_account_id, **options)
|
def initialize(accounts, current_account_id, **options)
|
||||||
@account_ids = account_ids.map { |a| a.is_a?(Account) ? a.id : a.to_i }
|
@accounts = accounts.to_a
|
||||||
|
@account_ids = @accounts.pluck(:id)
|
||||||
@current_account_id = current_account_id
|
@current_account_id = current_account_id
|
||||||
|
|
||||||
@following = cached[:following].merge(Account.following_map(@uncached_account_ids, @current_account_id))
|
@following = cached[:following].merge(Account.following_map(@uncached_account_ids, @current_account_id))
|
||||||
|
@ -16,10 +17,11 @@ class AccountRelationshipsPresenter
|
||||||
@muting = cached[:muting].merge(Account.muting_map(@uncached_account_ids, @current_account_id))
|
@muting = cached[:muting].merge(Account.muting_map(@uncached_account_ids, @current_account_id))
|
||||||
@requested = cached[:requested].merge(Account.requested_map(@uncached_account_ids, @current_account_id))
|
@requested = cached[:requested].merge(Account.requested_map(@uncached_account_ids, @current_account_id))
|
||||||
@requested_by = cached[:requested_by].merge(Account.requested_by_map(@uncached_account_ids, @current_account_id))
|
@requested_by = cached[:requested_by].merge(Account.requested_by_map(@uncached_account_ids, @current_account_id))
|
||||||
@domain_blocking = cached[:domain_blocking].merge(Account.domain_blocking_map(@uncached_account_ids, @current_account_id))
|
|
||||||
@endorsed = cached[:endorsed].merge(Account.endorsed_map(@uncached_account_ids, @current_account_id))
|
@endorsed = cached[:endorsed].merge(Account.endorsed_map(@uncached_account_ids, @current_account_id))
|
||||||
@account_note = cached[:account_note].merge(Account.account_note_map(@uncached_account_ids, @current_account_id))
|
@account_note = cached[:account_note].merge(Account.account_note_map(@uncached_account_ids, @current_account_id))
|
||||||
|
|
||||||
|
@domain_blocking = domain_blocking_map
|
||||||
|
|
||||||
cache_uncached!
|
cache_uncached!
|
||||||
|
|
||||||
@following.merge!(options[:following_map] || {})
|
@following.merge!(options[:following_map] || {})
|
||||||
|
@ -36,6 +38,31 @@ class AccountRelationshipsPresenter
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def domain_blocking_map
|
||||||
|
target_domains = @accounts.pluck(:domain).compact.uniq
|
||||||
|
blocks_by_domain = {}
|
||||||
|
|
||||||
|
# Fetch from cache
|
||||||
|
cache_keys = target_domains.map { |domain| domain_cache_key(domain) }
|
||||||
|
Rails.cache.read_multi(*cache_keys).each do |key, blocking|
|
||||||
|
blocks_by_domain[key.last] = blocking
|
||||||
|
end
|
||||||
|
|
||||||
|
uncached_domains = target_domains - blocks_by_domain.keys
|
||||||
|
|
||||||
|
# Read uncached values from database
|
||||||
|
AccountDomainBlock.where(account_id: @current_account_id, domain: uncached_domains).pluck(:domain).each do |domain|
|
||||||
|
blocks_by_domain[domain] = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Write database reads to cache
|
||||||
|
to_cache = uncached_domains.to_h { |domain| [domain_cache_key(domain), blocks_by_domain[domain]] }
|
||||||
|
Rails.cache.write_multi(to_cache, expires_in: 1.day)
|
||||||
|
|
||||||
|
# Return formatted value
|
||||||
|
@accounts.each_with_object({}) { |account, h| h[account.id] = blocks_by_domain[account.domain] }
|
||||||
|
end
|
||||||
|
|
||||||
def cached
|
def cached
|
||||||
return @cached if defined?(@cached)
|
return @cached if defined?(@cached)
|
||||||
|
|
||||||
|
@ -47,28 +74,23 @@ class AccountRelationshipsPresenter
|
||||||
muting: {},
|
muting: {},
|
||||||
requested: {},
|
requested: {},
|
||||||
requested_by: {},
|
requested_by: {},
|
||||||
domain_blocking: {},
|
|
||||||
endorsed: {},
|
endorsed: {},
|
||||||
account_note: {},
|
account_note: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@uncached_account_ids = []
|
@uncached_account_ids = @account_ids.uniq
|
||||||
|
|
||||||
@account_ids.each do |account_id|
|
cache_ids = @account_ids.map { |account_id| relationship_cache_key(account_id) }
|
||||||
maps_for_account = Rails.cache.read("relationship:#{@current_account_id}:#{account_id}")
|
Rails.cache.read_multi(*cache_ids).each do |key, maps_for_account|
|
||||||
|
@cached.deep_merge!(maps_for_account)
|
||||||
if maps_for_account.is_a?(Hash)
|
@uncached_account_ids.delete(key.last)
|
||||||
@cached.deep_merge!(maps_for_account)
|
|
||||||
else
|
|
||||||
@uncached_account_ids << account_id
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@cached
|
@cached
|
||||||
end
|
end
|
||||||
|
|
||||||
def cache_uncached!
|
def cache_uncached!
|
||||||
@uncached_account_ids.each do |account_id|
|
to_cache = @uncached_account_ids.to_h do |account_id|
|
||||||
maps_for_account = {
|
maps_for_account = {
|
||||||
following: { account_id => following[account_id] },
|
following: { account_id => following[account_id] },
|
||||||
followed_by: { account_id => followed_by[account_id] },
|
followed_by: { account_id => followed_by[account_id] },
|
||||||
|
@ -77,12 +99,21 @@ class AccountRelationshipsPresenter
|
||||||
muting: { account_id => muting[account_id] },
|
muting: { account_id => muting[account_id] },
|
||||||
requested: { account_id => requested[account_id] },
|
requested: { account_id => requested[account_id] },
|
||||||
requested_by: { account_id => requested_by[account_id] },
|
requested_by: { account_id => requested_by[account_id] },
|
||||||
domain_blocking: { account_id => domain_blocking[account_id] },
|
|
||||||
endorsed: { account_id => endorsed[account_id] },
|
endorsed: { account_id => endorsed[account_id] },
|
||||||
account_note: { account_id => account_note[account_id] },
|
account_note: { account_id => account_note[account_id] },
|
||||||
}
|
}
|
||||||
|
|
||||||
Rails.cache.write("relationship:#{@current_account_id}:#{account_id}", maps_for_account, expires_in: 1.day)
|
[relationship_cache_key(account_id), maps_for_account]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Rails.cache.write_multi(to_cache, expires_in: 1.day)
|
||||||
|
end
|
||||||
|
|
||||||
|
def domain_cache_key(domain)
|
||||||
|
['exclude_domains', @current_account_id, domain]
|
||||||
|
end
|
||||||
|
|
||||||
|
def relationship_cache_key(account_id)
|
||||||
|
['relationship', @current_account_id, account_id]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -13,29 +13,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
has_one :role, serializer: REST::RoleSerializer
|
has_one :role, serializer: REST::RoleSerializer
|
||||||
|
|
||||||
def meta
|
def meta
|
||||||
store = {
|
store = default_meta_store
|
||||||
streaming_api_base_url: Rails.configuration.x.streaming_api_base_url,
|
|
||||||
access_token: object.token,
|
|
||||||
locale: I18n.locale,
|
|
||||||
domain: Addressable::IDNA.to_unicode(instance_presenter.domain),
|
|
||||||
title: instance_presenter.title,
|
|
||||||
admin: object.admin&.id&.to_s,
|
|
||||||
search_enabled: Chewy.enabled?,
|
|
||||||
repository: Mastodon::Version.repository,
|
|
||||||
source_url: instance_presenter.source_url,
|
|
||||||
version: instance_presenter.version,
|
|
||||||
limited_federation_mode: Rails.configuration.x.limited_federation_mode,
|
|
||||||
mascot: instance_presenter.mascot&.file&.url,
|
|
||||||
profile_directory: Setting.profile_directory,
|
|
||||||
trends_enabled: Setting.trends,
|
|
||||||
registrations_open: Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode,
|
|
||||||
timeline_preview: Setting.timeline_preview,
|
|
||||||
activity_api_enabled: Setting.activity_api_enabled,
|
|
||||||
single_user_mode: Rails.configuration.x.single_user_mode,
|
|
||||||
trends_as_landing_page: Setting.trends_as_landing_page,
|
|
||||||
status_page_url: Setting.status_page_url,
|
|
||||||
sso_redirect: sso_redirect,
|
|
||||||
}
|
|
||||||
|
|
||||||
if object.current_account
|
if object.current_account
|
||||||
store[:me] = object.current_account.id.to_s
|
store[:me] = object.current_account.id.to_s
|
||||||
|
@ -86,8 +64,8 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
ActiveRecord::Associations::Preloader.new(
|
ActiveRecord::Associations::Preloader.new(
|
||||||
records: [object.current_account, object.admin, object.owner, object.disabled_account, object.moved_to_account].compact,
|
records: [object.current_account, object.admin, object.owner, object.disabled_account, object.moved_to_account].compact,
|
||||||
associations: [:account_stat, :user, { moved_to_account: [:account_stat, :user] }]
|
associations: [:account_stat, { user: :role, moved_to_account: [:account_stat, { user: :role }] }]
|
||||||
)
|
).call
|
||||||
|
|
||||||
store[object.current_account.id.to_s] = serialized_account(object.current_account) if object.current_account
|
store[object.current_account.id.to_s] = serialized_account(object.current_account) if object.current_account
|
||||||
store[object.admin.id.to_s] = serialized_account(object.admin) if object.admin
|
store[object.admin.id.to_s] = serialized_account(object.admin) if object.admin
|
||||||
|
@ -108,6 +86,32 @@ class InitialStateSerializer < ActiveModel::Serializer
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def default_meta_store
|
||||||
|
{
|
||||||
|
access_token: object.token,
|
||||||
|
activity_api_enabled: Setting.activity_api_enabled,
|
||||||
|
admin: object.admin&.id&.to_s,
|
||||||
|
domain: Addressable::IDNA.to_unicode(instance_presenter.domain),
|
||||||
|
limited_federation_mode: Rails.configuration.x.limited_federation_mode,
|
||||||
|
locale: I18n.locale,
|
||||||
|
mascot: instance_presenter.mascot&.file&.url,
|
||||||
|
profile_directory: Setting.profile_directory,
|
||||||
|
registrations_open: Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode,
|
||||||
|
repository: Mastodon::Version.repository,
|
||||||
|
search_enabled: Chewy.enabled?,
|
||||||
|
single_user_mode: Rails.configuration.x.single_user_mode,
|
||||||
|
source_url: instance_presenter.source_url,
|
||||||
|
sso_redirect: sso_redirect,
|
||||||
|
status_page_url: Setting.status_page_url,
|
||||||
|
streaming_api_base_url: Rails.configuration.x.streaming_api_base_url,
|
||||||
|
timeline_preview: Setting.timeline_preview,
|
||||||
|
title: instance_presenter.title,
|
||||||
|
trends_as_landing_page: Setting.trends_as_landing_page,
|
||||||
|
trends_enabled: Setting.trends,
|
||||||
|
version: instance_presenter.version,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def object_account_user
|
def object_account_user
|
||||||
object.current_account.user
|
object.current_account.user
|
||||||
end
|
end
|
||||||
|
|
|
@ -23,6 +23,7 @@ class AccountSearchService < BaseService
|
||||||
query: {
|
query: {
|
||||||
bool: {
|
bool: {
|
||||||
must: must_clauses,
|
must: must_clauses,
|
||||||
|
must_not: must_not_clauses,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -49,6 +50,10 @@ class AccountSearchService < BaseService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def must_not_clauses
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
def should_clauses
|
def should_clauses
|
||||||
if @account && !@options[:following]
|
if @account && !@options[:following]
|
||||||
[boost_following_query]
|
[boost_following_query]
|
||||||
|
@ -218,7 +223,7 @@ class AccountSearchService < BaseService
|
||||||
|
|
||||||
records = query_builder.build.limit(limit_for_non_exact_results).offset(offset).objects.compact
|
records = query_builder.build.limit(limit_for_non_exact_results).offset(offset).objects.compact
|
||||||
|
|
||||||
ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat)
|
ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call
|
||||||
|
|
||||||
records
|
records
|
||||||
rescue Faraday::ConnectionFailed, Parslet::ParseFailed
|
rescue Faraday::ConnectionFailed, Parslet::ParseFailed
|
||||||
|
|
|
@ -11,7 +11,7 @@ class BatchedRemoveStatusService < BaseService
|
||||||
ActiveRecord::Associations::Preloader.new(
|
ActiveRecord::Associations::Preloader.new(
|
||||||
records: statuses,
|
records: statuses,
|
||||||
associations: options[:skip_side_effects] ? :reblogs : [:account, :tags, reblogs: :account]
|
associations: options[:skip_side_effects] ? :reblogs : [:account, :tags, reblogs: :account]
|
||||||
)
|
).call
|
||||||
|
|
||||||
statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs }
|
statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs }
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ class BatchedRemoveStatusService < BaseService
|
||||||
ActiveRecord::Associations::Preloader.new(
|
ActiveRecord::Associations::Preloader.new(
|
||||||
records: statuses_with_account_conversations,
|
records: statuses_with_account_conversations,
|
||||||
associations: [mentions: :account]
|
associations: [mentions: :account]
|
||||||
)
|
).call
|
||||||
|
|
||||||
statuses_with_account_conversations.each(&:unlink_from_conversations!)
|
statuses_with_account_conversations.each(&:unlink_from_conversations!)
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,15 @@ class FanOutOnWriteService < BaseService
|
||||||
LocalNotificationWorker.push_bulk(mentions) do |mention|
|
LocalNotificationWorker.push_bulk(mentions) do |mention|
|
||||||
[mention.account_id, mention.id, 'Mention', 'mention']
|
[mention.account_id, mention.id, 'Mention', 'mention']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
next unless update?
|
||||||
|
|
||||||
|
# This may result in duplicate update payloads, but this ensures clients
|
||||||
|
# are aware of edits to posts only appearing in mention notifications
|
||||||
|
# (e.g. private mentions or mentions by people they do not follow)
|
||||||
|
PushUpdateWorker.push_bulk(mentions.filter { |mention| subscribed_to_streaming_api?(mention.account_id) }) do |mention|
|
||||||
|
[mention.account_id, @status.id, "timeline:#{mention.account_id}:notifications", { 'update' => true }]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -162,4 +171,8 @@ class FanOutOnWriteService < BaseService
|
||||||
def broadcastable?
|
def broadcastable?
|
||||||
@status.public_visibility? && !@status.reblog? && !@account.silenced?
|
@status.public_visibility? && !@status.reblog? && !@account.silenced?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def subscribed_to_streaming_api?(account_id)
|
||||||
|
redis.exists?("subscribed:timeline:#{account_id}") || redis.exists?("subscribed:timeline:#{account_id}:notifications")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,7 +20,7 @@ class FavouriteService < BaseService
|
||||||
Trends.statuses.register(status)
|
Trends.statuses.register(status)
|
||||||
|
|
||||||
create_notification(favourite)
|
create_notification(favourite)
|
||||||
bump_potential_friendship(account, status)
|
increment_statistics
|
||||||
|
|
||||||
favourite
|
favourite
|
||||||
end
|
end
|
||||||
|
@ -37,11 +37,8 @@ class FavouriteService < BaseService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def bump_potential_friendship(account, status)
|
def increment_statistics
|
||||||
ActivityTracker.increment('activity:interactions')
|
ActivityTracker.increment('activity:interactions')
|
||||||
return if account.following?(status.account_id)
|
|
||||||
|
|
||||||
PotentialFriendshipTracker.record(account.id, status.account_id, :favourite)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_json(favourite)
|
def build_json(favourite)
|
||||||
|
|
|
@ -100,7 +100,7 @@ class FetchOEmbedService
|
||||||
end
|
end
|
||||||
|
|
||||||
def validate(oembed)
|
def validate(oembed)
|
||||||
oembed if oembed[:version].to_s == '1.0' && oembed[:type].present?
|
oembed if oembed.present? && oembed[:version].to_s == '1.0' && oembed[:type].present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def html
|
def html
|
||||||
|
|
|
@ -178,9 +178,6 @@ class PostStatusService < BaseService
|
||||||
return if !@status.reply? || @account.id == @status.in_reply_to_account_id
|
return if !@status.reply? || @account.id == @status.in_reply_to_account_id
|
||||||
|
|
||||||
ActivityTracker.increment('activity:interactions')
|
ActivityTracker.increment('activity:interactions')
|
||||||
return if @account.following?(@status.in_reply_to_account_id)
|
|
||||||
|
|
||||||
PotentialFriendshipTracker.record(@account.id, @status.in_reply_to_account_id, :reply)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def status_attributes
|
def status_attributes
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ReblogService < BaseService
|
||||||
ActivityPub::DistributionWorker.perform_async(reblog.id)
|
ActivityPub::DistributionWorker.perform_async(reblog.id)
|
||||||
|
|
||||||
create_notification(reblog)
|
create_notification(reblog)
|
||||||
bump_potential_friendship(account, reblog)
|
increment_statistics
|
||||||
|
|
||||||
reblog
|
reblog
|
||||||
end
|
end
|
||||||
|
@ -50,12 +50,8 @@ class ReblogService < BaseService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def bump_potential_friendship(account, reblog)
|
def increment_statistics
|
||||||
ActivityTracker.increment('activity:interactions')
|
ActivityTracker.increment('activity:interactions')
|
||||||
|
|
||||||
return if account.following?(reblog.reblog.account_id)
|
|
||||||
|
|
||||||
PotentialFriendshipTracker.record(account.id, reblog.reblog.account_id, :reblog)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_json(reblog)
|
def build_json(reblog)
|
||||||
|
|
|
@ -21,7 +21,7 @@ class UpdateAccountService < BaseService
|
||||||
|
|
||||||
def authorize_all_follow_requests(account)
|
def authorize_all_follow_requests(account)
|
||||||
follow_requests = FollowRequest.where(target_account: account)
|
follow_requests = FollowRequest.where(target_account: account)
|
||||||
follow_requests = follow_requests.preload(:account).select { |req| !req.account.silenced? }
|
follow_requests = follow_requests.preload(:account).reject { |req| req.account.silenced? }
|
||||||
AuthorizeFollowWorker.push_bulk(follow_requests, limit: 1_000) do |req|
|
AuthorizeFollowWorker.push_bulk(follow_requests, limit: 1_000) do |req|
|
||||||
[req.account_id, req.target_account_id]
|
[req.account_id, req.target_account_id]
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
%p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible')
|
%p.muted-hint= deletion_request.present? ? t('admin.accounts.suspension_reversible_hint_html', date: content_tag(:strong, l(deletion_request.due_at.to_date))) : t('admin.accounts.suspension_irreversible')
|
||||||
= link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account)
|
= link_to t('admin.accounts.undo_suspension'), unsuspend_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsuspend, account)
|
||||||
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote?
|
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account) && account.suspension_origin_remote?
|
||||||
- if deletion_request.present?
|
- if deletion_request.present? && can?(:destroy, account)
|
||||||
= link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, account)
|
= link_to t('admin.accounts.delete'), admin_account_path(account.id), method: :delete, class: 'button button--destructive', data: { confirm: t('admin.accounts.are_you_sure') }
|
||||||
- else
|
- else
|
||||||
.action-buttons
|
.action-buttons
|
||||||
%div
|
%div
|
||||||
|
@ -15,8 +15,8 @@
|
||||||
= link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account)
|
= link_to t('admin.accounts.warn'), new_admin_account_action_path(account.id, type: 'none'), class: 'button' if can?(:warn, account)
|
||||||
- if account.user_disabled?
|
- if account.user_disabled?
|
||||||
= link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user)
|
= link_to t('admin.accounts.enable'), enable_admin_account_path(account.id), method: :post, class: 'button' if can?(:enable, account.user)
|
||||||
- else
|
- elsif can?(:disable, account.user)
|
||||||
= link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button' if can?(:disable, account.user)
|
= link_to t('admin.accounts.disable'), new_admin_account_action_path(account.id, type: 'disable'), class: 'button'
|
||||||
- if account.sensitized?
|
- if account.sensitized?
|
||||||
= link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account)
|
= link_to t('admin.accounts.undo_sensitized'), unsensitive_admin_account_path(account.id), method: :post, class: 'button' if can?(:unsensitive, account)
|
||||||
- elsif !account.local? || account.user_approved?
|
- elsif !account.local? || account.user_approved?
|
||||||
|
@ -29,13 +29,13 @@
|
||||||
- if account.user_pending?
|
- if account.user_pending?
|
||||||
= link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user)
|
= link_to t('admin.accounts.approve'), approve_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:approve, account.user)
|
||||||
= link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user)
|
= link_to t('admin.accounts.reject'), reject_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:reject, account.user)
|
||||||
- unless account.user_confirmed?
|
- if !account.user_confirmed? && can?(:confirm, account.user)
|
||||||
= link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button' if can?(:confirm, account.user)
|
= link_to t('admin.accounts.confirm'), admin_account_confirmation_path(account.id), method: :post, class: 'button'
|
||||||
- if !account.local? || account.user_approved?
|
- if (!account.local? || account.user_approved?) && can?(:suspend, account)
|
||||||
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button' if can?(:suspend, account)
|
= link_to t('admin.accounts.perform_full_suspension'), new_admin_account_action_path(account.id, type: 'suspend'), class: 'button'
|
||||||
%div
|
%div
|
||||||
- if account.local?
|
- if account.local?
|
||||||
- if !account.memorial? && account.user_approved?
|
- if !account.memorial? && account.user_approved? && can?(:memorialize, account)
|
||||||
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' if can?(:memorialize, account)
|
= link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive'
|
||||||
- else
|
- elsif can?(:redownload, account)
|
||||||
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button' if can?(:redownload, account)
|
= link_to t('admin.accounts.redownload'), redownload_admin_account_path(account.id), method: :post, class: 'button'
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
- else
|
- else
|
||||||
= t 'admin.accounts.security_measures.only_password'
|
= t 'admin.accounts.security_measures.only_password'
|
||||||
%td
|
%td
|
||||||
- if account.user&.two_factor_enabled?
|
- if account.user&.two_factor_enabled? && can?(:disable_2fa, account.user)
|
||||||
= table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(account.user.id), method: :delete if can?(:disable_2fa, account.user)
|
= table_link_to 'unlock', t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(account.user.id), method: :delete
|
||||||
- if can?(:reset_password, account.user)
|
- if can?(:reset_password, account.user)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
|
|
|
@ -38,3 +38,5 @@
|
||||||
= nothing_here 'nothing-here--under-tabs'
|
= nothing_here 'nothing-here--under-tabs'
|
||||||
- else
|
- else
|
||||||
= render partial: 'account', collection: @accounts, locals: { f: f }
|
= render partial: 'account', collection: @accounts, locals: { f: f }
|
||||||
|
|
||||||
|
= paginate @accounts
|
||||||
|
|
|
@ -2,61 +2,11 @@
|
||||||
|
|
||||||
class Scheduler::FollowRecommendationsScheduler
|
class Scheduler::FollowRecommendationsScheduler
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
include Redisable
|
|
||||||
|
|
||||||
sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i
|
sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i
|
||||||
|
|
||||||
# The maximum number of accounts that can be requested in one page from the
|
|
||||||
# API is 80, and the suggestions API does not allow pagination. This number
|
|
||||||
# leaves some room for accounts being filtered during live access
|
|
||||||
SET_SIZE = 100
|
|
||||||
|
|
||||||
def perform
|
def perform
|
||||||
# Maintaining a materialized view speeds-up subsequent queries significantly
|
|
||||||
AccountSummary.refresh
|
AccountSummary.refresh
|
||||||
FollowRecommendation.refresh
|
FollowRecommendation.refresh
|
||||||
|
|
||||||
fallback_recommendations = FollowRecommendation.order(rank: :desc).limit(SET_SIZE)
|
|
||||||
|
|
||||||
Trends.available_locales.each do |locale|
|
|
||||||
recommendations = if AccountSummary.safe.filtered.localized(locale).exists? # We can skip the work if no accounts with that language exist
|
|
||||||
FollowRecommendation.localized(locale).order(rank: :desc).limit(SET_SIZE).map { |recommendation| [recommendation.rank, recommendation.account_id] }
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Use language-agnostic results if there are not enough language-specific ones
|
|
||||||
missing = SET_SIZE - recommendations.size
|
|
||||||
|
|
||||||
if missing.positive? && fallback_recommendations.size.positive?
|
|
||||||
max_fallback_rank = fallback_recommendations.first.rank || 0
|
|
||||||
|
|
||||||
# Language-specific results should be above language-agnostic ones,
|
|
||||||
# otherwise language-agnostic ones will always overshadow them
|
|
||||||
recommendations.map! { |(rank, account_id)| [rank + max_fallback_rank, account_id] }
|
|
||||||
|
|
||||||
added = 0
|
|
||||||
|
|
||||||
fallback_recommendations.each do |recommendation|
|
|
||||||
next if recommendations.any? { |(_, account_id)| account_id == recommendation.account_id }
|
|
||||||
|
|
||||||
recommendations << [recommendation.rank, recommendation.account_id]
|
|
||||||
added += 1
|
|
||||||
|
|
||||||
break if added >= missing
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
redis.multi do |multi|
|
|
||||||
multi.del(key(locale))
|
|
||||||
multi.zadd(key(locale), recommendations)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def key(locale)
|
|
||||||
"follow_recommendations:#{locale}"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -63,13 +63,6 @@ module Mastodon
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
config.load_defaults 7.0
|
config.load_defaults 7.0
|
||||||
|
|
||||||
# TODO: Release a version which uses the 7.0 defaults as specified above,
|
|
||||||
# but preserves the 6.1 cache format as set below. In a subsequent change,
|
|
||||||
# remove this line setting to 6.1 cache format, and then release another version.
|
|
||||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format
|
|
||||||
# https://github.com/mastodon/mastodon/pull/24241#discussion_r1162890242
|
|
||||||
config.active_support.cache_format_version = 6.1
|
|
||||||
|
|
||||||
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
||||||
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
||||||
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
# Common ones are `templates`, `generators`, or `middleware`, for example.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
unless ENV.key?('RAILS_ENV')
|
unless ENV.key?('RAILS_ENV')
|
||||||
STDERR.puts 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".'
|
warn 'ERROR: Missing RAILS_ENV environment variable, please set it to "production", "development", or "test".'
|
||||||
exit 1
|
exit 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ Devise.setup do |config|
|
||||||
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic)
|
oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic)
|
||||||
scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED
|
scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED
|
||||||
scopes = scope_string.split(',')
|
scopes = scope_string.split(',')
|
||||||
oidc_options[:scope] = scopes.map { |x| x.to_sym }
|
oidc_options[:scope] = scopes.map(&:to_sym)
|
||||||
oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code)
|
oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code)
|
||||||
oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query)
|
oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query)
|
||||||
oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page)
|
oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page)
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# TODO: Remove after 4.2.0
|
# TODO: remove this file some time after 4.3.0
|
||||||
Rails.application.configure do
|
|
||||||
config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1
|
|
||||||
end
|
|
||||||
|
|
||||||
Rails.application.config.after_initialize do
|
Rails.application.config.after_initialize do
|
||||||
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
|
Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies|
|
||||||
|
@ -12,9 +9,8 @@ Rails.application.config.after_initialize do
|
||||||
|
|
||||||
secret_key_base = Rails.application.secret_key_base
|
secret_key_base = Rails.application.secret_key_base
|
||||||
|
|
||||||
# TODO: Switch to SHA1 after 4.2.0
|
|
||||||
key_generator = ActiveSupport::KeyGenerator.new(
|
key_generator = ActiveSupport::KeyGenerator.new(
|
||||||
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256
|
secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1
|
||||||
)
|
)
|
||||||
key_len = ActiveSupport::MessageEncryptor.key_len
|
key_len = ActiveSupport::MessageEncryptor.key_len
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ SimpleForm.setup do |config|
|
||||||
# config.item_wrapper_class = nil
|
# config.item_wrapper_class = nil
|
||||||
|
|
||||||
# How the label text should be generated altogether with the required text.
|
# How the label text should be generated altogether with the required text.
|
||||||
config.label_text = lambda { |label, required, _explicit_label| "#{label} #{required}" }
|
config.label_text = ->(label, required, _explicit_label) { "#{label} #{required}" }
|
||||||
|
|
||||||
# You can define the class to use on all labels. Default is nil.
|
# You can define the class to use on all labels. Default is nil.
|
||||||
# config.label_class = nil
|
# config.label_class = nil
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Rack
|
unless Rails.application.config.action_dispatch.trusted_proxies.nil?
|
||||||
class Request
|
# Rack is configured with a default collection of trusted proxies
|
||||||
def trusted_proxy?(ip)
|
# If Rails has been configured to use a specific list, configure
|
||||||
if Rails.application.config.action_dispatch.trusted_proxies.nil?
|
# Rack to use this Proc, which enforces the Rails-configured list.
|
||||||
super
|
Rack::Request.ip_filter = ->(ip) { Rails.application.config.action_dispatch.trusted_proxies.include?(ip) }
|
||||||
else
|
|
||||||
Rails.application.config.action_dispatch.trusted_proxies.any? { |proxy| proxy === ip }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
8
config/locales/activerecord.ia.yml
Normal file
8
config/locales/activerecord.ia.yml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
ia:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
user:
|
||||||
|
password: Contrasigno
|
||||||
|
user/account:
|
||||||
|
username: Nomine de usator
|
9
config/locales/activerecord.ie.yml
Normal file
9
config/locales/activerecord.ie.yml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
---
|
||||||
|
ie:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
poll:
|
||||||
|
expires_at: Cludent date
|
||||||
|
options: Optiones
|
||||||
|
user:
|
||||||
|
password: Passa-parol
|
51
config/locales/activerecord.lad.yml
Normal file
51
config/locales/activerecord.lad.yml
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
---
|
||||||
|
lad:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
poll:
|
||||||
|
expires_at: Limito temporal
|
||||||
|
options: Opsyones
|
||||||
|
user:
|
||||||
|
agreement: Akodro de servisyo
|
||||||
|
email: Adreso de posta elektronika
|
||||||
|
locale: Lingua
|
||||||
|
password: Kod
|
||||||
|
user/account:
|
||||||
|
username: Nombre de uzador
|
||||||
|
user/invite_request:
|
||||||
|
text: Razon
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
account:
|
||||||
|
attributes:
|
||||||
|
username:
|
||||||
|
invalid: solo puede kontener letras, shifras i sulinyados
|
||||||
|
reserved: esta rezervado
|
||||||
|
admin/webhook:
|
||||||
|
attributes:
|
||||||
|
url:
|
||||||
|
invalid: no es adreso URL valido
|
||||||
|
doorkeeper/application:
|
||||||
|
attributes:
|
||||||
|
website:
|
||||||
|
invalid: no es adreso URL valido
|
||||||
|
import:
|
||||||
|
attributes:
|
||||||
|
data:
|
||||||
|
malformed: tiene formato yerrado
|
||||||
|
user:
|
||||||
|
attributes:
|
||||||
|
email:
|
||||||
|
blocked: uza un prokurador de posta no autorizado
|
||||||
|
unreachable: no parese existir
|
||||||
|
role_id:
|
||||||
|
elevated: no puede ser mas alto ke tu rolo aktual
|
||||||
|
user_role:
|
||||||
|
attributes:
|
||||||
|
permissions_as_keys:
|
||||||
|
dangerous: inkluir permisos ke no son siguros para el rolo de baza
|
||||||
|
elevated: no se puede inkluir permisos kualos no tiene tu rolo aktual
|
||||||
|
own_role: no se puede trokar kon tu rolo aktual
|
||||||
|
position:
|
||||||
|
elevated: no puede ser mas alto ke tu rolo aktual
|
||||||
|
own_role: no se puede trokar kon tu rolo aktual
|
|
@ -1 +1,23 @@
|
||||||
|
---
|
||||||
pa:
|
pa:
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
poll:
|
||||||
|
expires_at: ਆਖਰੀ ਤਾਰੀਖ
|
||||||
|
options: ਚੋਣਾਂ
|
||||||
|
user:
|
||||||
|
agreement: ਸੇਵਾ ਸਮਝੌਤਾ
|
||||||
|
email: ਈਮੇਲ ਪਤਾ
|
||||||
|
locale: ਲੋਕੇਲ
|
||||||
|
password: ਪਾਸਵਰਡ
|
||||||
|
user/account:
|
||||||
|
username: ਵਰਤੋਂਕਾਰ-ਨਾਂ
|
||||||
|
user/invite_request:
|
||||||
|
text: ਕਾਰਨ
|
||||||
|
errors:
|
||||||
|
models:
|
||||||
|
account:
|
||||||
|
attributes:
|
||||||
|
username:
|
||||||
|
invalid: ਸਿਰਫ਼ ਅੱਖਰ, ਅੰਕ ਅਤੇ ਹੇਠਾਂ-ਰੇਖਾ ਹੀ ਹੋੋਣੀ ਚਾਹੀਦੀ ਹੈ
|
||||||
|
reserved: ਰਾਖਵਾਂ ਹੈ
|
||||||
|
|
|
@ -28,7 +28,7 @@ zh-TW:
|
||||||
doorkeeper/application:
|
doorkeeper/application:
|
||||||
attributes:
|
attributes:
|
||||||
website:
|
website:
|
||||||
invalid: 不是有效的 URL
|
invalid: 不是有效的網址
|
||||||
import:
|
import:
|
||||||
attributes:
|
attributes:
|
||||||
data:
|
data:
|
||||||
|
|
1
config/locales/devise.ia.yml
Normal file
1
config/locales/devise.ia.yml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ia:
|
28
config/locales/devise.ie.yml
Normal file
28
config/locales/devise.ie.yml
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
ie:
|
||||||
|
devise:
|
||||||
|
failure:
|
||||||
|
invalid: Ínvalid %{authentication_keys} o passa-parol.
|
||||||
|
not_found_in_database: Ínvalid %{authentication_keys} o passa-parol.
|
||||||
|
mailer:
|
||||||
|
email_changed:
|
||||||
|
extra: Si tu ne changeat tui email-adresse, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto.
|
||||||
|
password_change:
|
||||||
|
explanation: Li passa-parol de tui conto ha esset changeat.
|
||||||
|
extra: Si tu ne changeat tui passa-parol, it es probabil que alqui ha ganiat accesse a tui conto. Ples changear tui passa-parol strax o contacter li administrator del servitor si tu ne posse intrar tui conto.
|
||||||
|
subject: 'Mastodon: Passa-parol changeat'
|
||||||
|
title: Passa-parol changeat
|
||||||
|
reset_password_instructions:
|
||||||
|
action: Changear passa-parol
|
||||||
|
explanation: Tu demandat un nov passa-parol por tui conto.
|
||||||
|
extra: Si tu ne demandat to-ci, ples ignorar ti-ci email. Tui passa-parol ne va changear til que tu accessaye li ligament supra e crear un nov.
|
||||||
|
subject: 'Mastodon: Instructiones por reiniciar li passa-parol'
|
||||||
|
title: Reiniciar passa-parol
|
||||||
|
two_factor_disabled:
|
||||||
|
explanation: 2-factor autentication por tui conto ha esset desactivisat. Aperter session nu es possibil solmen per email-adresse e passa-parol.
|
||||||
|
passwords:
|
||||||
|
no_token: Tu ne posse accessar ti-ci págine sin venir de un email pri reiniciar li passa-parol. Si tu ha venit de un email pri reiniciar li passa-parol, ples far cert que tu usat li complet URL providet.
|
||||||
|
send_instructions: Si tui email-adresse existe in nor database, tu va reciver un ligament por recuperar li passa-parol a tui email-adresse in quelc minutes. Ples vider tui spam-emails si tu ne recivet ti email.
|
||||||
|
send_paranoid_instructions: Si tui email-adresse existe in nor database, tu va reciver un ligament por recuperar li passa-parol a tui email-adresse in quelc minutes. Ples vider tui spam-emails si tu ne recivet ti email.
|
||||||
|
updated: Tui passa-parol ha esset changeat successosimen. Tu nu ha apertet session.
|
||||||
|
updated_not_active: Tui passa-parol ha esset changeat successosimen.
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue