Merge pull request #850 from kmycode/upstream-20240926
Upstream 20240926
This commit is contained in:
commit
5a0a7ac123
517 changed files with 4284 additions and 3891 deletions
|
@ -69,7 +69,7 @@ services:
|
|||
hard: -1
|
||||
|
||||
libretranslate:
|
||||
image: libretranslate/libretranslate:v1.6.0
|
||||
image: libretranslate/libretranslate:v1.6.1
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- lt-data:/home/libretranslate/.local
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -47,7 +47,6 @@ gem 'color_diff', '~> 0.1'
|
|||
gem 'csv', '~> 3.2'
|
||||
gem 'discard', '~> 1.2'
|
||||
gem 'doorkeeper', '~> 5.6'
|
||||
gem 'ed25519', '~> 1.3'
|
||||
gem 'fast_blank', '~> 1.0'
|
||||
gem 'fastimage'
|
||||
gem 'hiredis', '~> 0.6'
|
||||
|
|
32
Gemfile.lock
32
Gemfile.lock
|
@ -100,20 +100,20 @@ GEM
|
|||
attr_required (1.0.2)
|
||||
awrence (1.2.1)
|
||||
aws-eventstream (1.3.0)
|
||||
aws-partitions (1.974.0)
|
||||
aws-sdk-core (3.205.0)
|
||||
aws-partitions (1.978.0)
|
||||
aws-sdk-core (3.209.0)
|
||||
aws-eventstream (~> 1, >= 1.3.0)
|
||||
aws-partitions (~> 1, >= 1.651.0)
|
||||
aws-sigv4 (~> 1.9)
|
||||
jmespath (~> 1, >= 1.6.1)
|
||||
aws-sdk-kms (1.91.0)
|
||||
aws-sdk-core (~> 3, >= 3.205.0)
|
||||
aws-sdk-kms (1.94.0)
|
||||
aws-sdk-core (~> 3, >= 3.207.0)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sdk-s3 (1.162.0)
|
||||
aws-sdk-core (~> 3, >= 3.205.0)
|
||||
aws-sdk-s3 (1.166.0)
|
||||
aws-sdk-core (~> 3, >= 3.207.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.5)
|
||||
aws-sigv4 (1.9.1)
|
||||
aws-sigv4 (1.10.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
azure-storage-blob (2.0.3)
|
||||
azure-storage-common (~> 2.0)
|
||||
|
@ -197,7 +197,7 @@ GEM
|
|||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (5.1.0)
|
||||
devise-two-factor (6.0.0)
|
||||
activesupport (~> 7.0)
|
||||
devise (~> 4.0)
|
||||
railties (~> 7.0)
|
||||
|
@ -212,9 +212,8 @@ GEM
|
|||
domain_name (0.6.20240107)
|
||||
doorkeeper (5.7.1)
|
||||
railties (>= 5)
|
||||
dotenv (3.1.2)
|
||||
dotenv (3.1.4)
|
||||
drb (2.2.1)
|
||||
ed25519 (1.3.0)
|
||||
elasticsearch (7.17.11)
|
||||
elasticsearch-api (= 7.17.11)
|
||||
elasticsearch-transport (= 7.17.11)
|
||||
|
@ -290,7 +289,7 @@ GEM
|
|||
raabro (~> 1.4)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
google-protobuf (3.25.4)
|
||||
google-protobuf (3.25.5)
|
||||
googleapis-common-protos-types (1.15.0)
|
||||
google-protobuf (>= 3.18, < 5.a)
|
||||
haml (6.3.0)
|
||||
|
@ -407,7 +406,7 @@ GEM
|
|||
llhttp-ffi (0.5.0)
|
||||
ffi-compiler (~> 1.0)
|
||||
rake (~> 13.0)
|
||||
logger (1.6.0)
|
||||
logger (1.6.1)
|
||||
lograge (0.14.0)
|
||||
actionpack (>= 4)
|
||||
activesupport (>= 4)
|
||||
|
@ -429,7 +428,7 @@ GEM
|
|||
addressable (~> 2.5)
|
||||
azure-storage-blob (~> 2.0.1)
|
||||
hashie (~> 5.0)
|
||||
memory_profiler (1.0.2)
|
||||
memory_profiler (1.1.0)
|
||||
mime-types (3.5.2)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2024.0820)
|
||||
|
@ -610,7 +609,7 @@ GEM
|
|||
psych (5.1.2)
|
||||
stringio
|
||||
public_suffix (6.0.1)
|
||||
puma (6.4.2)
|
||||
puma (6.4.3)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
|
@ -782,7 +781,7 @@ GEM
|
|||
scenic (1.8.0)
|
||||
activerecord (>= 4.0.0)
|
||||
railties (>= 4.0.0)
|
||||
selenium-webdriver (4.24.0)
|
||||
selenium-webdriver (4.25.0)
|
||||
base64 (~> 0.2)
|
||||
logger (~> 1.4)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
|
@ -894,7 +893,7 @@ GEM
|
|||
rack-proxy (>= 0.6.1)
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.1)
|
||||
webrick (1.8.2)
|
||||
websocket (1.2.11)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
|
@ -937,7 +936,6 @@ DEPENDENCIES
|
|||
discard (~> 1.2)
|
||||
doorkeeper (~> 5.6)
|
||||
dotenv
|
||||
ed25519 (~> 1.3)
|
||||
email_spec
|
||||
fabrication (~> 2.30)
|
||||
faker (~> 3.2)
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::ClaimsController < ActivityPub::BaseController
|
||||
skip_before_action :authenticate_user!
|
||||
|
||||
before_action :require_account_signature!
|
||||
before_action :set_claim_result
|
||||
|
||||
def create
|
||||
render json: @claim_result, serializer: ActivityPub::OneTimeKeySerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_claim_result
|
||||
@claim_result = ::Keys::ClaimService.new.call(@account.id, params[:id])
|
||||
end
|
||||
end
|
|
@ -22,8 +22,6 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
@items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) }
|
||||
when 'tags'
|
||||
@items = for_signed_account { @account.featured_tags }
|
||||
when 'devices'
|
||||
@items = @account.devices
|
||||
else
|
||||
not_found
|
||||
end
|
||||
|
@ -31,7 +29,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
|
||||
def set_size
|
||||
case params[:id]
|
||||
when 'featured', 'devices', 'tags'
|
||||
when 'featured', 'tags'
|
||||
@size = @items.size
|
||||
else
|
||||
not_found
|
||||
|
@ -42,7 +40,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
case params[:id]
|
||||
when 'featured'
|
||||
@type = :ordered
|
||||
when 'devices', 'tags'
|
||||
when 'tags'
|
||||
@type = :unordered
|
||||
else
|
||||
not_found
|
||||
|
|
36
app/controllers/activitypub/likes_controller.rb
Normal file
36
app/controllers/activitypub/likes_controller.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::LikesController < ActivityPub::BaseController
|
||||
include Authorization
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_status
|
||||
|
||||
def index
|
||||
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||
render json: likes_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pundit_user
|
||||
signed_request_account
|
||||
end
|
||||
|
||||
def set_status
|
||||
@status = @account.statuses.find(params[:status_id])
|
||||
authorize @status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
not_found
|
||||
end
|
||||
|
||||
def likes_collection_presenter
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: account_status_likes_url(@account, @status),
|
||||
type: :unordered,
|
||||
size: @status.favourites_count
|
||||
)
|
||||
end
|
||||
end
|
|
@ -69,6 +69,7 @@ class ActivityPub::ReferencesController < ActivityPub::BaseController
|
|||
ActivityPub::CollectionPresenter.new(
|
||||
type: :unordered,
|
||||
id: ActivityPub::TagManager.instance.references_uri_for(@status),
|
||||
size: @status.status_referred_by_count,
|
||||
first: page
|
||||
)
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
|||
before_action :set_replies
|
||||
|
||||
def index
|
||||
expires_in 0, public: public_fetch_mode?
|
||||
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||
render json: replies_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json', skip_activities: true
|
||||
end
|
||||
|
||||
|
|
36
app/controllers/activitypub/shares_controller.rb
Normal file
36
app/controllers/activitypub/shares_controller.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::SharesController < ActivityPub::BaseController
|
||||
include Authorization
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_status
|
||||
|
||||
def index
|
||||
expires_in 0, public: @status.distributable? && public_fetch_mode?
|
||||
render json: shares_collection_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def pundit_user
|
||||
signed_request_account
|
||||
end
|
||||
|
||||
def set_status
|
||||
@status = @account.statuses.find(params[:status_id])
|
||||
authorize @status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
not_found
|
||||
end
|
||||
|
||||
def shares_collection_presenter
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: account_status_shares_url(@account, @status),
|
||||
type: :unordered,
|
||||
size: @status.reblogs_count
|
||||
)
|
||||
end
|
||||
end
|
|
@ -7,7 +7,7 @@ class Api::OEmbedController < Api::BaseController
|
|||
before_action :require_public_status!
|
||||
|
||||
def show
|
||||
render json: @status, serializer: OEmbedSerializer, width: maxwidth_or_default, height: maxheight_or_default
|
||||
render json: @status, serializer: OEmbedSerializer, width: params[:maxwidth], height: params[:maxheight]
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -23,12 +23,4 @@ class Api::OEmbedController < Api::BaseController
|
|||
def status_finder
|
||||
StatusFinder.new(params[:url])
|
||||
end
|
||||
|
||||
def maxwidth_or_default
|
||||
(params[:maxwidth].presence || 400).to_i
|
||||
end
|
||||
|
||||
def maxheight_or_default
|
||||
params[:maxheight].present? ? params[:maxheight].to_i : nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::DeliveriesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
before_action :set_current_device
|
||||
|
||||
def create
|
||||
devices.each do |device_params|
|
||||
DeliverToDeviceService.new.call(current_account, @current_device, device_params)
|
||||
end
|
||||
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_current_device
|
||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:device)
|
||||
params.permit(device: [:account_id, :device_id, :type, :body, :hmac])
|
||||
end
|
||||
|
||||
def devices
|
||||
Array(resource_params[:device])
|
||||
end
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController
|
||||
LIMIT = 80
|
||||
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
before_action :set_current_device
|
||||
|
||||
before_action :set_encrypted_messages, only: :index
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
def index
|
||||
render json: @encrypted_messages, each_serializer: REST::EncryptedMessageSerializer
|
||||
end
|
||||
|
||||
def clear
|
||||
@current_device.encrypted_messages.up_to(params[:up_to_id]).delete_all
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_current_device
|
||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
||||
end
|
||||
|
||||
def set_encrypted_messages
|
||||
@encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_crypto_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue?
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty?
|
||||
end
|
||||
|
||||
def pagination_collection
|
||||
@encrypted_messages
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@encrypted_messages.size == limit_param(LIMIT)
|
||||
end
|
||||
end
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
before_action :set_claim_results
|
||||
|
||||
def create
|
||||
render json: @claim_results, each_serializer: REST::Keys::ClaimResultSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_claim_results
|
||||
@claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) }
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.permit(device: [:account_id, :device_id])
|
||||
end
|
||||
|
||||
def devices
|
||||
Array(resource_params[:device])
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::Keys::CountsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
before_action :set_current_device
|
||||
|
||||
def show
|
||||
render json: { one_time_keys: @current_device.one_time_keys.count }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_current_device
|
||||
@current_device = Device.find_by!(access_token: doorkeeper_token)
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::Keys::QueriesController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
before_action :set_accounts
|
||||
before_action :set_query_results
|
||||
|
||||
def create
|
||||
render json: @query_results, each_serializer: REST::Keys::QueryResultSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_accounts
|
||||
@accounts = Account.where(id: account_ids).includes(:devices)
|
||||
end
|
||||
|
||||
def set_query_results
|
||||
@query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) }
|
||||
end
|
||||
|
||||
def account_ids
|
||||
Array(params[:id]).map(&:to_i)
|
||||
end
|
||||
end
|
|
@ -1,29 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Crypto::Keys::UploadsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :crypto }
|
||||
before_action :require_user!
|
||||
|
||||
def create
|
||||
device = Device.find_or_initialize_by(access_token: doorkeeper_token)
|
||||
|
||||
device.transaction do
|
||||
device.account = current_account
|
||||
device.update!(resource_params[:device])
|
||||
|
||||
if resource_params[:one_time_keys].present? && resource_params[:one_time_keys].is_a?(Enumerable)
|
||||
resource_params[:one_time_keys].each do |one_time_key_params|
|
||||
device.one_time_keys.create!(one_time_key_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
render json: device, serializer: REST::Keys::DeviceSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def resource_params
|
||||
params.permit(device: [:device_id, :name, :fingerprint_key, :identity_key], one_time_keys: [:key_id, :key, :signature])
|
||||
end
|
||||
end
|
27
app/controllers/api/v1/domain_blocks/previews_controller.rb
Normal file
27
app/controllers/api/v1/domain_blocks/previews_controller.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::DomainBlocks::PreviewsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }
|
||||
before_action :require_user!
|
||||
before_action :set_domain
|
||||
before_action :set_domain_block_preview
|
||||
|
||||
def show
|
||||
render json: @domain_block_preview, serializer: REST::DomainBlockPreviewSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_domain
|
||||
@domain = TagManager.instance.normalize_domain(params[:domain])
|
||||
end
|
||||
|
||||
def set_domain_block_preview
|
||||
@domain_block_preview = with_read_replica do
|
||||
DomainBlockPreviewPresenter.new(
|
||||
following_count: current_account.following.where(domain: @domain).count,
|
||||
followers_count: current_account.followers.where(domain: @domain).count
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -7,6 +7,8 @@ class Api::V1::Peers::SearchController < Api::BaseController
|
|||
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
|
||||
skip_around_action :set_locale
|
||||
|
||||
LIMIT = 10
|
||||
|
||||
vary_by ''
|
||||
|
||||
def index
|
||||
|
@ -35,10 +37,10 @@ class Api::V1::Peers::SearchController < Api::BaseController
|
|||
field: 'accounts_count',
|
||||
modifier: 'log2p',
|
||||
},
|
||||
}).limit(10).pluck(:domain)
|
||||
}).limit(LIMIT).pluck(:domain)
|
||||
else
|
||||
domain = normalized_domain
|
||||
@domains = Instance.searchable.domain_starts_with(domain).limit(10).pluck(:domain)
|
||||
@domains = Instance.searchable.domain_starts_with(domain).limit(LIMIT).pluck(:domain)
|
||||
end
|
||||
rescue Addressable::URI::InvalidURIError
|
||||
@domains = []
|
||||
|
|
|
@ -9,7 +9,7 @@ class Api::Web::EmbedsController < Api::Web::BaseController
|
|||
return not_found if @status.hidden?
|
||||
|
||||
if @status.local?
|
||||
render json: @status, serializer: OEmbedSerializer, width: 400
|
||||
render json: @status, serializer: OEmbedSerializer
|
||||
else
|
||||
return not_found unless user_signed_in?
|
||||
|
||||
|
|
|
@ -20,11 +20,6 @@ class Auth::SessionsController < Devise::SessionsController
|
|||
p.form_action(false)
|
||||
end
|
||||
|
||||
def check_suspicious!
|
||||
user = find_user
|
||||
@login_is_suspicious = suspicious_sign_in?(user) unless user.nil?
|
||||
end
|
||||
|
||||
def create
|
||||
super do |resource|
|
||||
# We only need to call this if this hasn't already been
|
||||
|
@ -105,6 +100,11 @@ class Auth::SessionsController < Devise::SessionsController
|
|||
|
||||
private
|
||||
|
||||
def check_suspicious!
|
||||
user = find_user
|
||||
@login_is_suspicious = suspicious_sign_in?(user) unless user.nil?
|
||||
end
|
||||
|
||||
def home_paths(resource)
|
||||
paths = [about_path, '/explore']
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ module WebAppControllerConcern
|
|||
def redirect_unauthenticated_to_permalinks!
|
||||
return if user_signed_in? && current_account.moved_to_account_id.nil?
|
||||
|
||||
permalink_redirector = PermalinkRedirector.new(request.path)
|
||||
permalink_redirector = PermalinkRedirector.new(request.original_fullpath)
|
||||
return if permalink_redirector.redirect_path.blank?
|
||||
|
||||
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
|
||||
|
|
|
@ -32,23 +32,6 @@ module ContextHelper
|
|||
quote_uri: { 'fedibird' => 'http://fedibird.com/ns#', 'quoteUri' => 'fedibird:quoteUri' },
|
||||
keywords: { 'schema' => 'http://schema.org#', 'keywords' => 'schema:keywords' },
|
||||
license: { 'schema' => 'http://schema.org#', 'license' => 'schema:license' },
|
||||
olm: {
|
||||
'toot' => 'http://joinmastodon.org/ns#',
|
||||
'Device' => 'toot:Device',
|
||||
'Ed25519Signature' => 'toot:Ed25519Signature',
|
||||
'Ed25519Key' => 'toot:Ed25519Key',
|
||||
'Curve25519Key' => 'toot:Curve25519Key',
|
||||
'EncryptedMessage' => 'toot:EncryptedMessage',
|
||||
'publicKeyBase64' => 'toot:publicKeyBase64',
|
||||
'deviceId' => 'toot:deviceId',
|
||||
'claim' => { '@type' => '@id', '@id' => 'toot:claim' },
|
||||
'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' },
|
||||
'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' },
|
||||
'devices' => { '@type' => '@id', '@id' => 'toot:devices' },
|
||||
'messageFranking' => 'toot:messageFranking',
|
||||
'messageType' => 'toot:messageType',
|
||||
'cipherText' => 'toot:cipherText',
|
||||
},
|
||||
suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' },
|
||||
attribution_domains: { 'toot' => 'http://joinmastodon.org/ns#', 'attributionDomains' => { '@id' => 'toot:attributionDomains', '@type' => '@id' } },
|
||||
}.freeze
|
||||
|
|
31
app/javascript/hooks/useSearchParam.ts
Normal file
31
app/javascript/hooks/useSearchParam.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { useMemo, useCallback } from 'react';
|
||||
|
||||
import { useLocation, useHistory } from 'react-router';
|
||||
|
||||
export function useSearchParams() {
|
||||
const { search } = useLocation();
|
||||
|
||||
return useMemo(() => new URLSearchParams(search), [search]);
|
||||
}
|
||||
|
||||
export function useSearchParam(name: string, defaultValue?: string) {
|
||||
const searchParams = useSearchParams();
|
||||
const history = useHistory();
|
||||
|
||||
const value = searchParams.get(name) ?? defaultValue;
|
||||
|
||||
const setValue = useCallback(
|
||||
(value: string | null) => {
|
||||
if (value === null) {
|
||||
searchParams.delete(name);
|
||||
} else {
|
||||
searchParams.set(name, value);
|
||||
}
|
||||
|
||||
history.push({ search: searchParams.toString() });
|
||||
},
|
||||
[history, name, searchParams],
|
||||
);
|
||||
|
||||
return [value, setValue] as const;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import { browserHistory } from 'mastodon/components/router';
|
||||
import { debounceWithDispatchAndArguments } from 'mastodon/utils/debounce';
|
||||
|
||||
import api, { getLinks } from '../api';
|
||||
|
||||
|
@ -449,6 +450,20 @@ export function expandFollowingFail(id, error) {
|
|||
};
|
||||
}
|
||||
|
||||
const debouncedFetchRelationships = debounceWithDispatchAndArguments((dispatch, ...newAccountIds) => {
|
||||
if (newAccountIds.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(fetchRelationshipsRequest(newAccountIds));
|
||||
|
||||
api().get(`/api/v1/accounts/relationships?with_suspended=true&${newAccountIds.map(id => `id[]=${id}`).join('&')}`).then(response => {
|
||||
dispatch(fetchRelationshipsSuccess({ relationships: response.data }));
|
||||
}).catch(error => {
|
||||
dispatch(fetchRelationshipsFail(error));
|
||||
});
|
||||
}, { delay: 500 });
|
||||
|
||||
export function fetchRelationships(accountIds) {
|
||||
return (dispatch, getState) => {
|
||||
const state = getState();
|
||||
|
@ -460,13 +475,7 @@ export function fetchRelationships(accountIds) {
|
|||
return;
|
||||
}
|
||||
|
||||
dispatch(fetchRelationshipsRequest(newAccountIds));
|
||||
|
||||
api().get(`/api/v1/accounts/relationships?with_suspended=true&${newAccountIds.map(id => `id[]=${id}`).join('&')}`).then(response => {
|
||||
dispatch(fetchRelationshipsSuccess({ relationships: response.data }));
|
||||
}).catch(error => {
|
||||
dispatch(fetchRelationshipsFail(error));
|
||||
});
|
||||
debouncedFetchRelationships(dispatch, ...newAccountIds);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import { defineMessages } from 'react-intl';
|
||||
|
||||
import { AxiosError } from 'axios';
|
||||
|
||||
const messages = defineMessages({
|
||||
unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' },
|
||||
unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' },
|
||||
|
@ -50,6 +52,11 @@ export const showAlertForError = (error, skipNotFound = false) => {
|
|||
});
|
||||
}
|
||||
|
||||
// An aborted request, e.g. due to reloading the browser window, it not really error
|
||||
if (error.code === AxiosError.ECONNABORTED) {
|
||||
return { type: ALERT_NOOP };
|
||||
}
|
||||
|
||||
console.error(error);
|
||||
|
||||
return showAlert({
|
||||
|
|
|
@ -68,10 +68,15 @@ function dispatchAssociatedRecords(
|
|||
dispatch(importFetchedStatuses(fetchedStatuses));
|
||||
}
|
||||
|
||||
const supportedGroupedNotificationTypes = ['favourite', 'reblog'];
|
||||
|
||||
export const fetchNotifications = createDataLoadingThunk(
|
||||
'notificationGroups/fetch',
|
||||
async (_params, { getState }) =>
|
||||
apiFetchNotificationGroups({ exclude_types: getExcludedTypes(getState()) }),
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
({ notifications, accounts, statuses }, { dispatch }) => {
|
||||
dispatch(importFetchedAccounts(accounts));
|
||||
dispatch(importFetchedStatuses(statuses));
|
||||
|
@ -93,6 +98,7 @@ export const fetchNotificationsGap = createDataLoadingThunk(
|
|||
'notificationGroups/fetchGap',
|
||||
async (params: { gap: NotificationGap }, { getState }) =>
|
||||
apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
max_id: params.gap.maxId,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
}),
|
||||
|
@ -109,6 +115,7 @@ export const pollRecentNotifications = createDataLoadingThunk(
|
|||
'notificationGroups/pollRecentNotifications',
|
||||
async (_params, { getState }) => {
|
||||
return apiFetchNotificationGroups({
|
||||
grouped_types: supportedGroupedNotificationTypes,
|
||||
max_id: undefined,
|
||||
exclude_types: getExcludedTypes(getState()),
|
||||
// In slow mode, we don't want to include notifications that duplicate the already-displayed ones
|
||||
|
|
|
@ -17,6 +17,6 @@ export const updateNotificationsPolicy = createDataLoadingThunk(
|
|||
(policy: Partial<NotificationPolicy>) => apiUpdateNotificationsPolicy(policy),
|
||||
);
|
||||
|
||||
export const decreasePendingNotificationsCount = createAction<number>(
|
||||
'notificationPolicy/decreasePendingNotificationCount',
|
||||
export const decreasePendingRequestsCount = createAction<number>(
|
||||
'notificationPolicy/decreasePendingRequestsCount',
|
||||
);
|
||||
|
|
|
@ -13,11 +13,11 @@ import type {
|
|||
ApiNotificationJSON,
|
||||
} from 'mastodon/api_types/notifications';
|
||||
import type { ApiStatusJSON } from 'mastodon/api_types/statuses';
|
||||
import type { AppDispatch, RootState } from 'mastodon/store';
|
||||
import type { AppDispatch } from 'mastodon/store';
|
||||
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||
|
||||
import { importFetchedAccounts, importFetchedStatuses } from './importer';
|
||||
import { decreasePendingNotificationsCount } from './notification_policies';
|
||||
import { decreasePendingRequestsCount } from './notification_policies';
|
||||
|
||||
// TODO: refactor with notification_groups
|
||||
function dispatchAssociatedRecords(
|
||||
|
@ -169,19 +169,11 @@ export const expandNotificationsForRequest = createDataLoadingThunk(
|
|||
},
|
||||
);
|
||||
|
||||
const selectNotificationCountForRequest = (state: RootState, id: string) => {
|
||||
const requests = state.notificationRequests.items;
|
||||
const thisRequest = requests.find((request) => request.id === id);
|
||||
return thisRequest ? thisRequest.notifications_count : 0;
|
||||
};
|
||||
|
||||
export const acceptNotificationRequest = createDataLoadingThunk(
|
||||
'notificationRequest/accept',
|
||||
({ id }: { id: string }) => apiAcceptNotificationRequest(id),
|
||||
(_data, { dispatch, getState, discardLoadData, actionArg: { id } }) => {
|
||||
const count = selectNotificationCountForRequest(getState(), id);
|
||||
|
||||
dispatch(decreasePendingNotificationsCount(count));
|
||||
(_data, { dispatch, discardLoadData }) => {
|
||||
dispatch(decreasePendingRequestsCount(1));
|
||||
|
||||
// The payload is not used in any functions
|
||||
return discardLoadData;
|
||||
|
@ -191,10 +183,8 @@ export const acceptNotificationRequest = createDataLoadingThunk(
|
|||
export const dismissNotificationRequest = createDataLoadingThunk(
|
||||
'notificationRequest/dismiss',
|
||||
({ id }: { id: string }) => apiDismissNotificationRequest(id),
|
||||
(_data, { dispatch, getState, discardLoadData, actionArg: { id } }) => {
|
||||
const count = selectNotificationCountForRequest(getState(), id);
|
||||
|
||||
dispatch(decreasePendingNotificationsCount(count));
|
||||
(_data, { dispatch, discardLoadData }) => {
|
||||
dispatch(decreasePendingRequestsCount(1));
|
||||
|
||||
// The payload is not used in any functions
|
||||
return discardLoadData;
|
||||
|
@ -204,13 +194,8 @@ export const dismissNotificationRequest = createDataLoadingThunk(
|
|||
export const acceptNotificationRequests = createDataLoadingThunk(
|
||||
'notificationRequests/acceptBulk',
|
||||
({ ids }: { ids: string[] }) => apiAcceptNotificationRequests(ids),
|
||||
(_data, { dispatch, getState, discardLoadData, actionArg: { ids } }) => {
|
||||
const count = ids.reduce(
|
||||
(count, id) => count + selectNotificationCountForRequest(getState(), id),
|
||||
0,
|
||||
);
|
||||
|
||||
dispatch(decreasePendingNotificationsCount(count));
|
||||
(_data, { dispatch, discardLoadData, actionArg: { ids } }) => {
|
||||
dispatch(decreasePendingRequestsCount(ids.length));
|
||||
|
||||
// The payload is not used in any functions
|
||||
return discardLoadData;
|
||||
|
@ -220,13 +205,8 @@ export const acceptNotificationRequests = createDataLoadingThunk(
|
|||
export const dismissNotificationRequests = createDataLoadingThunk(
|
||||
'notificationRequests/dismissBulk',
|
||||
({ ids }: { ids: string[] }) => apiDismissNotificationRequests(ids),
|
||||
(_data, { dispatch, getState, discardLoadData, actionArg: { ids } }) => {
|
||||
const count = ids.reduce(
|
||||
(count, id) => count + selectNotificationCountForRequest(getState(), id),
|
||||
0,
|
||||
);
|
||||
|
||||
dispatch(decreasePendingNotificationsCount(count));
|
||||
(_data, { dispatch, discardLoadData, actionArg: { ids } }) => {
|
||||
dispatch(decreasePendingRequestsCount(ids.length));
|
||||
|
||||
// The payload is not used in any functions
|
||||
return discardLoadData;
|
||||
|
|
|
@ -10,7 +10,7 @@ import api, { getLinks } from '../api';
|
|||
import { unescapeHTML } from '../utils/html';
|
||||
import { requestNotificationPermission } from '../utils/notifications';
|
||||
|
||||
import { fetchFollowRequests, fetchRelationships } from './accounts';
|
||||
import { fetchFollowRequests } from './accounts';
|
||||
import {
|
||||
importFetchedAccount,
|
||||
importFetchedAccounts,
|
||||
|
@ -69,14 +69,6 @@ const messages = defineMessages({
|
|||
message_update: { id: 'notification.update', defaultMessage: '{name} edited a post' },
|
||||
});
|
||||
|
||||
const fetchRelatedRelationships = (dispatch, notifications) => {
|
||||
const accountIds = notifications.filter(item => ['follow', 'follow_request', 'admin.sign_up'].indexOf(item.type) !== -1).map(item => item.account.id);
|
||||
|
||||
if (accountIds.length > 0) {
|
||||
dispatch(fetchRelationships(accountIds));
|
||||
}
|
||||
};
|
||||
|
||||
export const loadPending = () => ({
|
||||
type: NOTIFICATIONS_LOAD_PENDING,
|
||||
});
|
||||
|
@ -127,8 +119,6 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
|
|||
|
||||
|
||||
dispatch(notificationsUpdate({ notification, preferPendingItems, playSound: playSound && !filtered}));
|
||||
|
||||
fetchRelatedRelationships(dispatch, [notification]);
|
||||
} else if (playSound && !filtered) {
|
||||
dispatch({
|
||||
type: NOTIFICATIONS_UPDATE_NOOP,
|
||||
|
@ -232,7 +222,6 @@ export function expandNotifications({ maxId = undefined, forceLoad = false }) {
|
|||
dispatch(importFetchedAccounts(response.data.filter(item => item.report).map(item => item.report.target_account)));
|
||||
|
||||
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems));
|
||||
fetchRelatedRelationships(dispatch, response.data);
|
||||
dispatch(submitMarkers());
|
||||
} catch(error) {
|
||||
dispatch(expandNotificationsFail(error, isLoadingMore));
|
||||
|
|
|
@ -42,6 +42,9 @@ const authorizationTokenFromInitialState = (): RawAxiosRequestHeaders => {
|
|||
// eslint-disable-next-line import/no-default-export
|
||||
export default function api(withAuthorization = true) {
|
||||
return axios.create({
|
||||
transitional: {
|
||||
clarifyTimeoutError: true,
|
||||
},
|
||||
headers: {
|
||||
...csrfHeader,
|
||||
...(withAuthorization ? authorizationTokenFromInitialState() : {}),
|
||||
|
@ -67,6 +70,7 @@ export async function apiRequest<ApiResponse = unknown>(
|
|||
args: {
|
||||
params?: RequestParamsOrData;
|
||||
data?: RequestParamsOrData;
|
||||
timeout?: number;
|
||||
} = {},
|
||||
) {
|
||||
const { data } = await api().request<ApiResponse>({
|
||||
|
|
|
@ -44,6 +44,7 @@ export const apiFetchNotifications = async (
|
|||
|
||||
export const apiFetchNotificationGroups = async (params?: {
|
||||
url?: string;
|
||||
grouped_types?: string[];
|
||||
exclude_types?: string[];
|
||||
max_id?: string;
|
||||
since_id?: string;
|
||||
|
@ -104,5 +105,5 @@ export const apiAcceptNotificationRequests = async (id: string[]) => {
|
|||
};
|
||||
|
||||
export const apiDismissNotificationRequests = async (id: string[]) => {
|
||||
return apiRequestPost('v1/notifications/dismiss/dismiss', { id });
|
||||
return apiRequestPost('v1/notifications/requests/dismiss', { id });
|
||||
};
|
||||
|
|
|
@ -7,6 +7,7 @@ interface BaseProps
|
|||
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
|
||||
block?: boolean;
|
||||
secondary?: boolean;
|
||||
dangerous?: boolean;
|
||||
}
|
||||
|
||||
interface PropsChildren extends PropsWithChildren<BaseProps> {
|
||||
|
@ -26,6 +27,7 @@ export const Button: React.FC<Props> = ({
|
|||
disabled,
|
||||
block,
|
||||
secondary,
|
||||
dangerous,
|
||||
className,
|
||||
title,
|
||||
text,
|
||||
|
@ -46,6 +48,7 @@ export const Button: React.FC<Props> = ({
|
|||
className={classNames('button', className, {
|
||||
'button-secondary': secondary,
|
||||
'button--block': block,
|
||||
'button--dangerous': dangerous,
|
||||
})}
|
||||
disabled={disabled}
|
||||
onClick={handleClick}
|
||||
|
|
|
@ -148,7 +148,7 @@ class ModalRoot extends PureComponent {
|
|||
return (
|
||||
<div className='modal-root' ref={this.setRef}>
|
||||
<div style={{ pointerEvents: visible ? 'auto' : 'none' }}>
|
||||
<div role='presentation' className='modal-root__overlay' onClick={onClose} style={{ backgroundColor: backgroundColor ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, 0.7)` : null }} />
|
||||
<div role='presentation' className='modal-root__overlay' onClick={onClose} style={{ backgroundColor: backgroundColor ? `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, 0.9)` : null }} />
|
||||
<div role='dialog' className='modal-root__container'>{children}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -4,22 +4,22 @@ import AccountNavigation from 'mastodon/features/account/navigation';
|
|||
import Trends from 'mastodon/features/getting_started/containers/trends_container';
|
||||
import { showTrends } from 'mastodon/initial_state';
|
||||
|
||||
const DefaultNavigation: React.FC = () =>
|
||||
showTrends ? (
|
||||
<>
|
||||
<div className='flex-spacer' />
|
||||
<Trends />
|
||||
</>
|
||||
) : null;
|
||||
const DefaultNavigation: React.FC = () => (showTrends ? <Trends /> : null);
|
||||
|
||||
export const NavigationPortal: React.FC = () => (
|
||||
<Switch>
|
||||
<Route path='/@:acct' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/tagged/:tagged?' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/with_replies' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/followers' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/following' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/media' exact component={AccountNavigation} />
|
||||
<Route component={DefaultNavigation} />
|
||||
</Switch>
|
||||
<div className='navigation-panel__portal'>
|
||||
<Switch>
|
||||
<Route path='/@:acct' exact component={AccountNavigation} />
|
||||
<Route
|
||||
path='/@:acct/tagged/:tagged?'
|
||||
exact
|
||||
component={AccountNavigation}
|
||||
/>
|
||||
<Route path='/@:acct/with_replies' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/followers' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/following' exact component={AccountNavigation} />
|
||||
<Route path='/@:acct/media' exact component={AccountNavigation} />
|
||||
<Route component={DefaultNavigation} />
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -51,7 +51,8 @@ function normalizePath(
|
|||
|
||||
if (
|
||||
layoutFromWindow() === 'multi-column' &&
|
||||
!location.pathname?.startsWith('/deck')
|
||||
location.pathname &&
|
||||
!location.pathname.startsWith('/deck')
|
||||
) {
|
||||
location.pathname = `/deck${location.pathname}`;
|
||||
}
|
||||
|
|
|
@ -497,36 +497,45 @@ class StatusActionBar extends ImmutablePureComponent {
|
|||
|
||||
return (
|
||||
<div className='status__action-bar'>
|
||||
<IconButton className='status__action-bar__button' title={replyTitle} icon={isReply ? 'reply' : replyIcon} iconComponent={isReply ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
|
||||
{reblogMenu.length === 0 ? reblogButton : (
|
||||
<div className='status__action-bar__button-wrapper'>
|
||||
<IconButton className='status__action-bar__button' title={replyTitle} icon={isReply ? 'reply' : replyIcon} iconComponent={isReply ? ReplyIcon : replyIconComponent} onClick={this.handleReplyClick} counter={status.get('replies_count')} />
|
||||
</div>
|
||||
<div className='status__action-bar__button-wrapper'>
|
||||
{reblogMenu.length === 0 ? reblogButton : (
|
||||
<DropdownMenuContainer
|
||||
className={classNames('status__action-bar__button', { reblogPrivate })}
|
||||
scrollKey={scrollKey}
|
||||
status={status}
|
||||
items={reblogMenu}
|
||||
icon='retweet'
|
||||
iconComponent={reblogIconComponent}
|
||||
direction='right'
|
||||
title={reblogTitle}
|
||||
active={status.get('reblogged')}
|
||||
disabled={!publicStatus && !reblogPrivate}
|
||||
>
|
||||
{reblogButton}
|
||||
</DropdownMenuContainer>
|
||||
)}
|
||||
</div>
|
||||
<div className='status__action-bar__button-wrapper'>
|
||||
<IconButton className='status__action-bar__button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
||||
</div>
|
||||
<div className='status__action-bar__button-wrapper'>
|
||||
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
||||
</div>
|
||||
{emojiPickerDropdown}
|
||||
<div className='status__action-bar__button-wrapper'>
|
||||
<DropdownMenuContainer
|
||||
className={classNames('status__action-bar__button', { reblogPrivate })}
|
||||
scrollKey={scrollKey}
|
||||
status={status}
|
||||
items={reblogMenu}
|
||||
icon='retweet'
|
||||
iconComponent={reblogIconComponent}
|
||||
items={menu}
|
||||
icon='ellipsis-h'
|
||||
iconComponent={MoreHorizIcon}
|
||||
direction='right'
|
||||
title={reblogTitle}
|
||||
active={status.get('reblogged')}
|
||||
disabled={!publicStatus && !reblogPrivate}
|
||||
>
|
||||
{reblogButton}
|
||||
</DropdownMenuContainer>
|
||||
)}
|
||||
<IconButton className='status__action-bar__button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' iconComponent={status.get('favourited') ? StarIcon : StarBorderIcon} onClick={this.handleFavouriteClick} counter={withCounters ? status.get('favourites_count') : undefined} />
|
||||
<IconButton className='status__action-bar__button bookmark-icon' disabled={!signedIn} active={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' iconComponent={status.get('bookmarked') ? BookmarkIcon : BookmarkBorderIcon} onClick={this.handleBookmarkClick} />
|
||||
{emojiPickerDropdown}
|
||||
|
||||
<DropdownMenuContainer
|
||||
scrollKey={scrollKey}
|
||||
status={status}
|
||||
items={menu}
|
||||
icon='ellipsis-h'
|
||||
iconComponent={MoreHorizIcon}
|
||||
direction='right'
|
||||
title={intl.formatMessage(messages.more)}
|
||||
/>
|
||||
title={intl.formatMessage(messages.more)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -43,10 +43,7 @@ class AccountNavigation extends PureComponent {
|
|||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='flex-spacer' />
|
||||
<FeaturedTags accountId={accountId} tagged={tagged} />
|
||||
</>
|
||||
<FeaturedTags accountId={accountId} tagged={tagged} />
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { ChangeEventHandler } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
|
@ -23,6 +23,8 @@ import { RadioButton } from 'mastodon/components/radio_button';
|
|||
import ScrollContainer from 'mastodon/containers/scroll_container';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { useSearchParam } from '../../../hooks/useSearchParam';
|
||||
|
||||
import { AccountCard } from './components/account_card';
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -47,18 +49,19 @@ export const Directory: React.FC<{
|
|||
const intl = useIntl();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [state, setState] = useState<{
|
||||
order: string | null;
|
||||
local: boolean | null;
|
||||
}>({
|
||||
order: null,
|
||||
local: null,
|
||||
});
|
||||
|
||||
const column = useRef<Column>(null);
|
||||
|
||||
const order = state.order ?? params?.order ?? 'active';
|
||||
const local = state.local ?? params?.local ?? false;
|
||||
const [orderParam, setOrderParam] = useSearchParam('order');
|
||||
const [localParam, setLocalParam] = useSearchParam('local');
|
||||
|
||||
let localParamBool: boolean | undefined;
|
||||
|
||||
if (localParam === 'false') {
|
||||
localParamBool = false;
|
||||
}
|
||||
|
||||
const order = orderParam ?? params?.order ?? 'active';
|
||||
const local = localParamBool ?? params?.local ?? true;
|
||||
|
||||
const handlePin = useCallback(() => {
|
||||
if (columnId) {
|
||||
|
@ -101,10 +104,10 @@ export const Directory: React.FC<{
|
|||
if (columnId) {
|
||||
dispatch(changeColumnParams(columnId, ['order'], e.target.value));
|
||||
} else {
|
||||
setState((s) => ({ order: e.target.value, local: s.local }));
|
||||
setOrderParam(e.target.value);
|
||||
}
|
||||
},
|
||||
[dispatch, columnId],
|
||||
[dispatch, columnId, setOrderParam],
|
||||
);
|
||||
|
||||
const handleChangeLocal = useCallback<ChangeEventHandler<HTMLInputElement>>(
|
||||
|
@ -113,11 +116,13 @@ export const Directory: React.FC<{
|
|||
dispatch(
|
||||
changeColumnParams(columnId, ['local'], e.target.value === '1'),
|
||||
);
|
||||
} else if (e.target.value === '1') {
|
||||
setLocalParam('true');
|
||||
} else {
|
||||
setState((s) => ({ local: e.target.value === '1', order: s.order }));
|
||||
setLocalParam('false');
|
||||
}
|
||||
},
|
||||
[dispatch, columnId],
|
||||
[dispatch, columnId, setLocalParam],
|
||||
);
|
||||
|
||||
const handleLoadMore = useCallback(() => {
|
||||
|
|
|
@ -31,7 +31,7 @@ export const FilteredNotificationsIconButton: React.FC<{
|
|||
history.push('/notifications/requests');
|
||||
}, [history]);
|
||||
|
||||
if (policy === null || policy.summary.pending_notifications_count === 0) {
|
||||
if (policy === null || policy.summary.pending_requests_count <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ export const FilteredNotificationsBanner: React.FC = () => {
|
|||
};
|
||||
}, [dispatch]);
|
||||
|
||||
if (policy === null || policy.summary.pending_notifications_count === 0) {
|
||||
if (policy === null || policy.summary.pending_requests_count <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ export const BlockModal = ({ accountId, acct }) => {
|
|||
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
|
||||
</button>
|
||||
|
||||
<Button onClick={handleClick} autoFocus>
|
||||
<Button onClick={handleClick} dangerous autoFocus>
|
||||
<FormattedMessage id='confirmations.block.confirm' defaultMessage='Block' />
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
|
|||
import classNames from 'classnames';
|
||||
import { useRouteMatch, NavLink } from 'react-router-dom';
|
||||
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
|
||||
const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text, to, href, method, badge, transparent, children, ...other }) => {
|
||||
const ColumnLink = ({ icon, activeIcon, iconComponent, activeIconComponent, text, to, href, method, badge, transparent, optional, children, ...other }) => {
|
||||
const match = useRouteMatch(to);
|
||||
const className = classNames('column-link', { 'column-link--transparent': transparent });
|
||||
const className = classNames('column-link', { 'column-link--transparent': transparent, 'column-link--optional': optional });
|
||||
const badgeElement = typeof badge !== 'undefined' ? <span className='column-link__badge'>{badge}</span> : null;
|
||||
const iconElement = (typeof icon === 'string' || iconComponent) ? <Icon id={icon} icon={iconComponent} className='column-link__icon' /> : icon;
|
||||
const activeIconElement = activeIcon ?? (activeIconComponent ? <Icon id={icon} icon={activeIconComponent} className='column-link__icon' /> : iconElement);
|
||||
|
@ -46,6 +46,7 @@ ColumnLink.propTypes = {
|
|||
badge: PropTypes.node,
|
||||
transparent: PropTypes.bool,
|
||||
children: PropTypes.any,
|
||||
optional: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ColumnLink;
|
||||
|
|
|
@ -4,8 +4,6 @@ import { Children, cloneElement, useCallback } from 'react';
|
|||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||
|
||||
import { scrollRight } from '../../../scroll';
|
||||
import BundleContainer from '../containers/bundle_container';
|
||||
import {
|
||||
|
@ -74,17 +72,13 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
};
|
||||
|
||||
// Corresponds to (max-width: $no-gap-breakpoint - 1px) in SCSS
|
||||
mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 1206px)');
|
||||
mediaQuery = 'matchMedia' in window && window.matchMedia('(max-width: 1174px)');
|
||||
|
||||
state = {
|
||||
renderComposePanel: !(this.mediaQuery && this.mediaQuery.matches),
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
if (!this.props.singleColumn) {
|
||||
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
}
|
||||
|
||||
if (this.mediaQuery) {
|
||||
if (this.mediaQuery.addEventListener) {
|
||||
this.mediaQuery.addEventListener('change', this.handleLayoutChange);
|
||||
|
@ -97,23 +91,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl');
|
||||
}
|
||||
|
||||
UNSAFE_componentWillUpdate(nextProps) {
|
||||
if (this.props.singleColumn !== nextProps.singleColumn && nextProps.singleColumn) {
|
||||
this.node.removeEventListener('wheel', this.handleWheel);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.singleColumn !== prevProps.singleColumn && !this.props.singleColumn) {
|
||||
this.node.addEventListener('wheel', this.handleWheel, supportsPassiveEvents ? { passive: true } : false);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
if (!this.props.singleColumn) {
|
||||
this.node.removeEventListener('wheel', this.handleWheel);
|
||||
}
|
||||
|
||||
if (this.mediaQuery) {
|
||||
if (this.mediaQuery.removeEventListener) {
|
||||
this.mediaQuery.removeEventListener('change', this.handleLayoutChange);
|
||||
|
@ -126,7 +104,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
handleChildrenContentChange() {
|
||||
if (!this.props.singleColumn) {
|
||||
const modifier = this.isRtlLayout ? -1 : 1;
|
||||
this._interruptScrollAnimation = scrollRight(this.node, (this.node.scrollWidth - window.innerWidth) * modifier);
|
||||
scrollRight(this.node, (this.node.scrollWidth - window.innerWidth) * modifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,14 +112,6 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
|||
this.setState({ renderComposePanel: !e.matches });
|
||||
};
|
||||
|
||||
handleWheel = () => {
|
||||
if (typeof this._interruptScrollAnimation !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
this._interruptScrollAnimation();
|
||||
};
|
||||
|
||||
setRef = (node) => {
|
||||
this.node = node;
|
||||
};
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
||||
import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react';
|
||||
import DomainDisabledIcon from '@/material-icons/400-24px/domain_disabled.svg?react';
|
||||
import HistoryIcon from '@/material-icons/400-24px/history.svg?react';
|
||||
import PersonRemoveIcon from '@/material-icons/400-24px/person_remove.svg?react';
|
||||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
|
||||
import { blockAccount } from 'mastodon/actions/accounts';
|
||||
import { blockDomain } from 'mastodon/actions/domain_blocks';
|
||||
import { closeModal } from 'mastodon/actions/modal';
|
||||
import { Button } from 'mastodon/components/button';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
|
||||
export const DomainBlockModal = ({ domain, accountId, acct }) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
dispatch(blockDomain(domain));
|
||||
}, [dispatch, domain]);
|
||||
|
||||
const handleSecondaryClick = useCallback(() => {
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
dispatch(blockAccount(accountId));
|
||||
}, [dispatch, accountId]);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal safety-action-modal'>
|
||||
<div className='safety-action-modal__top'>
|
||||
<div className='safety-action-modal__header'>
|
||||
<div className='safety-action-modal__header__icon'>
|
||||
<Icon icon={DomainDisabledIcon} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1><FormattedMessage id='domain_block_modal.title' defaultMessage='Block domain?' /></h1>
|
||||
<div>{domain}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bullet-points'>
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'><Icon icon={CampaignIcon} /></div>
|
||||
<div><FormattedMessage id='domain_block_modal.they_wont_know' defaultMessage="They won't know they've been blocked." /></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'><Icon icon={VisibilityOffIcon} /></div>
|
||||
<div><FormattedMessage id='domain_block_modal.you_wont_see_posts' defaultMessage="You won't see posts or notifications from users on this server." /></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'><Icon icon={PersonRemoveIcon} /></div>
|
||||
<div><FormattedMessage id='domain_block_modal.you_will_lose_followers' defaultMessage='All your followers from this server will be removed.' /></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'><Icon icon={ReplyIcon} /></div>
|
||||
<div><FormattedMessage id='domain_block_modal.they_cant_follow' defaultMessage='Nobody from this server can follow you.' /></div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'><Icon icon={HistoryIcon} /></div>
|
||||
<div><FormattedMessage id='domain_block_modal.they_can_interact_with_old_posts' defaultMessage='People from this server can interact with your old posts.' /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bottom'>
|
||||
<div className='safety-action-modal__actions'>
|
||||
<Button onClick={handleSecondaryClick} secondary>
|
||||
<FormattedMessage id='domain_block_modal.block_account_instead' defaultMessage='Block @{name} instead' values={{ name: acct.split('@')[0] }} />
|
||||
</Button>
|
||||
|
||||
<div className='spacer' />
|
||||
|
||||
<button onClick={handleCancel} className='link-button'>
|
||||
<FormattedMessage id='confirmation_modal.cancel' defaultMessage='Cancel' />
|
||||
</button>
|
||||
|
||||
<Button onClick={handleClick} autoFocus>
|
||||
<FormattedMessage id='domain_block_modal.block' defaultMessage='Block server' />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
DomainBlockModal.propTypes = {
|
||||
domain: PropTypes.string.isRequired,
|
||||
accountId: PropTypes.string.isRequired,
|
||||
acct: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
export default DomainBlockModal;
|
|
@ -0,0 +1,204 @@
|
|||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import CampaignIcon from '@/material-icons/400-24px/campaign.svg?react';
|
||||
import DomainDisabledIcon from '@/material-icons/400-24px/domain_disabled.svg?react';
|
||||
import HistoryIcon from '@/material-icons/400-24px/history.svg?react';
|
||||
import PersonRemoveIcon from '@/material-icons/400-24px/person_remove.svg?react';
|
||||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?react';
|
||||
import { blockAccount } from 'mastodon/actions/accounts';
|
||||
import { blockDomain } from 'mastodon/actions/domain_blocks';
|
||||
import { closeModal } from 'mastodon/actions/modal';
|
||||
import { apiRequest } from 'mastodon/api';
|
||||
import { Button } from 'mastodon/components/button';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import { ShortNumber } from 'mastodon/components/short_number';
|
||||
import { useAppDispatch } from 'mastodon/store';
|
||||
|
||||
interface DomainBlockPreviewResponse {
|
||||
following_count: number;
|
||||
followers_count: number;
|
||||
}
|
||||
|
||||
export const DomainBlockModal: React.FC<{
|
||||
domain: string;
|
||||
accountId: string;
|
||||
acct: string;
|
||||
}> = ({ domain, accountId, acct }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [preview, setPreview] = useState<DomainBlockPreviewResponse | null>(
|
||||
null,
|
||||
);
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (loading) {
|
||||
return; // Prevent destructive action before the preview finishes loading or times out
|
||||
}
|
||||
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
dispatch(blockDomain(domain));
|
||||
}, [dispatch, loading, domain]);
|
||||
|
||||
const handleSecondaryClick = useCallback(() => {
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
dispatch(blockAccount(accountId));
|
||||
}, [dispatch, accountId]);
|
||||
|
||||
const handleCancel = useCallback(() => {
|
||||
dispatch(closeModal({ modalType: undefined, ignoreFocus: false }));
|
||||
}, [dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
|
||||
apiRequest<DomainBlockPreviewResponse>('GET', 'v1/domain_blocks/preview', {
|
||||
params: { domain },
|
||||
timeout: 5000,
|
||||
})
|
||||
.then((data) => {
|
||||
setPreview(data);
|
||||
setLoading(false);
|
||||
return '';
|
||||
})
|
||||
.catch(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}, [setPreview, setLoading, domain]);
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal safety-action-modal' aria-live='polite'>
|
||||
<div className='safety-action-modal__top'>
|
||||
<div className='safety-action-modal__header'>
|
||||
<div className='safety-action-modal__header__icon'>
|
||||
<Icon id='' icon={DomainDisabledIcon} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.title'
|
||||
defaultMessage='Block domain?'
|
||||
/>
|
||||
</h1>
|
||||
<div>{domain}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bullet-points'>
|
||||
{preview && preview.followers_count + preview.following_count > 0 && (
|
||||
<div>
|
||||
<div className='safety-action-modal__bullet-points__icon'>
|
||||
<Icon id='' icon={PersonRemoveIcon} />
|
||||
</div>
|
||||
<div>
|
||||
<strong>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.you_will_lose_num_followers'
|
||||
defaultMessage='You will lose {followersCount, plural, one {{followersCountDisplay} follower} other {{followersCountDisplay} followers}} and {followingCount, plural, one {{followingCountDisplay} person you follow} other {{followingCountDisplay} people you follow}}.'
|
||||
values={{
|
||||
followersCount: preview.followers_count,
|
||||
followersCountDisplay: (
|
||||
<ShortNumber value={preview.followers_count} />
|
||||
),
|
||||
followingCount: preview.following_count,
|
||||
followingCountDisplay: (
|
||||
<ShortNumber value={preview.following_count} />
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='safety-action-modal__bullet-points--deemphasized'>
|
||||
<div className='safety-action-modal__bullet-points__icon'>
|
||||
<Icon id='' icon={CampaignIcon} />
|
||||
</div>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.they_wont_know'
|
||||
defaultMessage="They won't know they've been blocked."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bullet-points--deemphasized'>
|
||||
<div className='safety-action-modal__bullet-points__icon'>
|
||||
<Icon id='' icon={VisibilityOffIcon} />
|
||||
</div>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.you_wont_see_posts'
|
||||
defaultMessage="You won't see posts or notifications from users on this server."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bullet-points--deemphasized'>
|
||||
<div className='safety-action-modal__bullet-points__icon'>
|
||||
<Icon id='' icon={ReplyIcon} />
|
||||
</div>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.they_cant_follow'
|
||||
defaultMessage='Nobody from this server can follow you.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bullet-points--deemphasized'>
|
||||
<div className='safety-action-modal__bullet-points__icon'>
|
||||
<Icon id='' icon={HistoryIcon} />
|
||||
</div>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.they_can_interact_with_old_posts'
|
||||
defaultMessage='People from this server can interact with your old posts.'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='safety-action-modal__bottom'>
|
||||
<div className='safety-action-modal__actions'>
|
||||
<Button onClick={handleSecondaryClick} secondary>
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.block_account_instead'
|
||||
defaultMessage='Block @{name} instead'
|
||||
values={{ name: acct.split('@')[0] }}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
<div className='spacer' />
|
||||
|
||||
<button onClick={handleCancel} className='link-button'>
|
||||
<FormattedMessage
|
||||
id='confirmation_modal.cancel'
|
||||
defaultMessage='Cancel'
|
||||
/>
|
||||
</button>
|
||||
|
||||
<Button onClick={handleClick} dangerous aria-busy={loading}>
|
||||
{loading ? (
|
||||
<LoadingIndicator />
|
||||
) : (
|
||||
<FormattedMessage
|
||||
id='domain_block_modal.block'
|
||||
defaultMessage='Block server'
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default DomainBlockModal;
|
|
@ -17,7 +17,7 @@ export default class ImageLoader extends PureComponent {
|
|||
width: PropTypes.number,
|
||||
height: PropTypes.number,
|
||||
onClick: PropTypes.func,
|
||||
zoomButtonHidden: PropTypes.bool,
|
||||
zoomedIn: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -134,7 +134,7 @@ export default class ImageLoader extends PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { alt, lang, src, width, height, onClick } = this.props;
|
||||
const { alt, lang, src, width, height, onClick, zoomedIn } = this.props;
|
||||
const { loading } = this.state;
|
||||
|
||||
const className = classNames('image-loader', {
|
||||
|
@ -149,6 +149,7 @@ export default class ImageLoader extends PureComponent {
|
|||
<div className='loading-bar__container' style={{ width: this.state.width || width }}>
|
||||
<LoadingBar className='loading-bar' loading={1} />
|
||||
</div>
|
||||
|
||||
<canvas
|
||||
className='image-loader__preview-canvas'
|
||||
ref={this.setCanvasRef}
|
||||
|
@ -164,7 +165,7 @@ export default class ImageLoader extends PureComponent {
|
|||
onClick={onClick}
|
||||
width={width}
|
||||
height={height}
|
||||
zoomButtonHidden={this.props.zoomButtonHidden}
|
||||
zoomedIn={zoomedIn}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,8 @@ import ReactSwipeableViews from 'react-swipeable-views';
|
|||
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
|
||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
|
||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||
import FitScreenIcon from '@/material-icons/400-24px/fit_screen.svg?react';
|
||||
import ActualSizeIcon from '@/svg-icons/actual_size.svg?react';
|
||||
import { getAverageFromBlurhash } from 'mastodon/blurhash';
|
||||
import { GIFV } from 'mastodon/components/gifv';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
|
@ -26,6 +28,8 @@ const messages = defineMessages({
|
|||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
previous: { id: 'lightbox.previous', defaultMessage: 'Previous' },
|
||||
next: { id: 'lightbox.next', defaultMessage: 'Next' },
|
||||
zoomIn: { id: 'lightbox.zoom_in', defaultMessage: 'Zoom to actual size' },
|
||||
zoomOut: { id: 'lightbox.zoom_out', defaultMessage: 'Zoom to fit' },
|
||||
});
|
||||
|
||||
class MediaModal extends ImmutablePureComponent {
|
||||
|
@ -46,30 +50,39 @@ class MediaModal extends ImmutablePureComponent {
|
|||
state = {
|
||||
index: null,
|
||||
navigationHidden: false,
|
||||
zoomButtonHidden: false,
|
||||
zoomedIn: false,
|
||||
};
|
||||
|
||||
handleZoomClick = () => {
|
||||
this.setState(prevState => ({
|
||||
zoomedIn: !prevState.zoomedIn,
|
||||
}));
|
||||
};
|
||||
|
||||
handleSwipe = (index) => {
|
||||
this.setState({ index: index % this.props.media.size });
|
||||
this.setState({
|
||||
index: index % this.props.media.size,
|
||||
zoomedIn: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleTransitionEnd = () => {
|
||||
this.setState({
|
||||
zoomButtonHidden: false,
|
||||
zoomedIn: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleNextClick = () => {
|
||||
this.setState({
|
||||
index: (this.getIndex() + 1) % this.props.media.size,
|
||||
zoomButtonHidden: true,
|
||||
zoomedIn: false,
|
||||
});
|
||||
};
|
||||
|
||||
handlePrevClick = () => {
|
||||
this.setState({
|
||||
index: (this.props.media.size + this.getIndex() - 1) % this.props.media.size,
|
||||
zoomButtonHidden: true,
|
||||
zoomedIn: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -78,7 +91,7 @@ class MediaModal extends ImmutablePureComponent {
|
|||
|
||||
this.setState({
|
||||
index: index % this.props.media.size,
|
||||
zoomButtonHidden: true,
|
||||
zoomedIn: false,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -130,15 +143,22 @@ class MediaModal extends ImmutablePureComponent {
|
|||
return this.state.index !== null ? this.state.index : this.props.index;
|
||||
}
|
||||
|
||||
toggleNavigation = () => {
|
||||
handleToggleNavigation = () => {
|
||||
this.setState(prevState => ({
|
||||
navigationHidden: !prevState.navigationHidden,
|
||||
}));
|
||||
};
|
||||
|
||||
setRef = c => {
|
||||
this.setState({
|
||||
viewportWidth: c?.clientWidth,
|
||||
viewportHeight: c?.clientHeight,
|
||||
});
|
||||
};
|
||||
|
||||
render () {
|
||||
const { media, statusId, lang, intl, onClose } = this.props;
|
||||
const { navigationHidden } = this.state;
|
||||
const { navigationHidden, zoomedIn, viewportWidth, viewportHeight } = this.state;
|
||||
|
||||
const index = this.getIndex();
|
||||
|
||||
|
@ -160,8 +180,8 @@ class MediaModal extends ImmutablePureComponent {
|
|||
alt={description}
|
||||
lang={lang}
|
||||
key={image.get('url')}
|
||||
onClick={this.toggleNavigation}
|
||||
zoomButtonHidden={this.state.zoomButtonHidden}
|
||||
onClick={this.handleToggleNavigation}
|
||||
zoomedIn={zoomedIn}
|
||||
/>
|
||||
);
|
||||
} else if (image.get('type') === 'video') {
|
||||
|
@ -230,9 +250,12 @@ class MediaModal extends ImmutablePureComponent {
|
|||
));
|
||||
}
|
||||
|
||||
const currentMedia = media.get(index);
|
||||
const zoomable = currentMedia.get('type') === 'image' && (currentMedia.getIn(['meta', 'original', 'width']) > viewportWidth || currentMedia.getIn(['meta', 'original', 'height']) > viewportHeight);
|
||||
|
||||
return (
|
||||
<div className='modal-root__modal media-modal'>
|
||||
<div className='media-modal__closer' role='presentation' onClick={onClose} >
|
||||
<div className='modal-root__modal media-modal' ref={this.setRef}>
|
||||
<div className='media-modal__closer' role='presentation' onClick={onClose}>
|
||||
<ReactSwipeableViews
|
||||
style={swipeableViewsStyle}
|
||||
containerStyle={containerStyle}
|
||||
|
@ -246,7 +269,10 @@ class MediaModal extends ImmutablePureComponent {
|
|||
</div>
|
||||
|
||||
<div className={navigationClassName}>
|
||||
<IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' iconComponent={CloseIcon} onClick={onClose} size={40} />
|
||||
<div className='media-modal__buttons'>
|
||||
{zoomable && <IconButton title={intl.formatMessage(zoomedIn ? messages.zoomOut : messages.zoomIn)} iconComponent={zoomedIn ? FitScreenIcon : ActualSizeIcon} onClick={this.handleZoomClick} />}
|
||||
<IconButton title={intl.formatMessage(messages.close)} icon='times' iconComponent={CloseIcon} onClick={onClose} />
|
||||
</div>
|
||||
|
||||
{leftNav}
|
||||
{rightNav}
|
||||
|
|
|
@ -137,14 +137,17 @@ class NavigationPanel extends Component {
|
|||
|
||||
let banner = undefined;
|
||||
|
||||
if(transientSingleColumn)
|
||||
banner = (<div className='switch-to-advanced'>
|
||||
{intl.formatMessage(messages.openedInClassicInterface)}
|
||||
{" "}
|
||||
<a href={`/deck${location.pathname}`} className='switch-to-advanced__toggle'>
|
||||
{intl.formatMessage(messages.advancedInterface)}
|
||||
</a>
|
||||
</div>);
|
||||
if (transientSingleColumn) {
|
||||
banner = (
|
||||
<div className='switch-to-advanced'>
|
||||
{intl.formatMessage(messages.openedInClassicInterface)}
|
||||
{" "}
|
||||
<a href={`/deck${location.pathname}`} className='switch-to-advanced__toggle'>
|
||||
{intl.formatMessage(messages.advancedInterface)}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='navigation-panel'>
|
||||
|
@ -158,75 +161,79 @@ class NavigationPanel extends Component {
|
|||
</div>
|
||||
}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/home' icon='home' iconComponent={HomeIcon} activeIconComponent={HomeActiveIcon} text={intl.formatMessage(messages.home)} />
|
||||
<NotificationsLink />
|
||||
</>
|
||||
)}
|
||||
<div className='navigation-panel__menu'>
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/home' icon='home' iconComponent={HomeIcon} activeIconComponent={HomeActiveIcon} text={intl.formatMessage(messages.home)} />
|
||||
<NotificationsLink />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && enableLocalTimeline && (
|
||||
<ColumnLink transparent to='/public/local/fixed' icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.local)} />
|
||||
)}
|
||||
{signedIn && enableLocalTimeline && (
|
||||
<ColumnLink transparent to='/public/local/fixed' icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.local)} />
|
||||
)}
|
||||
|
||||
{signedIn && enableDtlMenu && dtlTag && (
|
||||
<ColumnLink transparent to={`/tags/${dtlTag}`} icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.deepLocal)} />
|
||||
)}
|
||||
{signedIn && enableDtlMenu && dtlTag && (
|
||||
<ColumnLink transparent to={`/tags/${dtlTag}`} icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.deepLocal)} />
|
||||
)}
|
||||
|
||||
{!signedIn && explorer}
|
||||
{!signedIn && explorer}
|
||||
|
||||
{signedIn && (
|
||||
<ColumnLink transparent to='/public' isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
{signedIn && (
|
||||
<ColumnLink transparent to='/public' isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
|
||||
{(!signedIn && timelinePreview) && (
|
||||
<ColumnLink transparent to={enableLocalTimeline ? '/public/local' : '/public'} isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
{(!signedIn && timelinePreview) && (
|
||||
<ColumnLink transparent to={enableLocalTimeline ? '/public/local' : '/public'} isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ListPanel />
|
||||
{signedIn && (
|
||||
<>
|
||||
<ListPanel />
|
||||
<hr />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/lists' icon='list-ul' iconComponent={ListAltIcon} activeIconComponent={ListAltActiveIcon} text={intl.formatMessage(messages.lists)} />
|
||||
<ColumnLink transparent to='/antennasw' icon='wifi' iconComponent={AntennaIcon} text={intl.formatMessage(messages.antennas)} isActive={this.isAntennasActive} />
|
||||
<ColumnLink transparent to='/circles' icon='user-circle' iconComponent={CirclesIcon} text={intl.formatMessage(messages.circles)} />
|
||||
<FollowRequestsLink />
|
||||
<ColumnLink transparent to='/conversations' icon='at' iconComponent={AlternateEmailIcon} text={intl.formatMessage(messages.direct)} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && explorer}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/bookmark_categories' icon='bookmarks' iconComponent={BookmarksIcon} activeIconComponent={BookmarksActiveIcon} text={intl.formatMessage(messages.bookmarks)} />
|
||||
{ !isHideItem('favourite_menu') && <ColumnLink transparent to='/favourites' icon='star' iconComponent={StarIcon} activeIconComponent={StarActiveIcon} text={intl.formatMessage(messages.favourites)} /> }
|
||||
<hr />
|
||||
|
||||
<ColumnLink transparent href='/settings/preferences' icon='cog' iconComponent={SettingsIcon} text={intl.formatMessage(messages.preferences)} />
|
||||
|
||||
{canManageReports(permissions) && <ColumnLink transparent href='/admin/reports' icon='flag' iconComponent={ModerationIcon} text={intl.formatMessage(messages.moderation)} />}
|
||||
{canViewAdminDashboard(permissions) && <ColumnLink transparent href='/admin/dashboard' icon='tachometer' iconComponent={AdministrationIcon} text={intl.formatMessage(messages.administration)} />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{!signedIn && (
|
||||
<div className='navigation-panel__sign-in-banner'>
|
||||
<hr />
|
||||
{ disabledAccountId ? <DisabledAccountBanner /> : <SignInBanner /> }
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='navigation-panel__legal'>
|
||||
<hr />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/lists' icon='list-ul' iconComponent={ListAltIcon} activeIconComponent={ListAltActiveIcon} text={intl.formatMessage(messages.lists)} />
|
||||
<ColumnLink transparent to='/antennasw' icon='wifi' iconComponent={AntennaIcon} text={intl.formatMessage(messages.antennas)} isActive={this.isAntennasActive} />
|
||||
<ColumnLink transparent to='/circles' icon='user-circle' iconComponent={CirclesIcon} text={intl.formatMessage(messages.circles)} />
|
||||
<FollowRequestsLink />
|
||||
<ColumnLink transparent to='/conversations' icon='at' iconComponent={AlternateEmailIcon} text={intl.formatMessage(messages.direct)} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && explorer}
|
||||
|
||||
{signedIn && (
|
||||
<>
|
||||
<ColumnLink transparent to='/bookmark_categories' icon='bookmarks' iconComponent={BookmarksIcon} activeIconComponent={BookmarksActiveIcon} text={intl.formatMessage(messages.bookmarks)} />
|
||||
{ !isHideItem('favourite_menu') && <ColumnLink transparent to='/favourites' icon='star' iconComponent={StarIcon} activeIconComponent={StarActiveIcon} text={intl.formatMessage(messages.favourites)} /> }
|
||||
<hr />
|
||||
|
||||
<ColumnLink transparent href='/settings/preferences' icon='cog' iconComponent={SettingsIcon} text={intl.formatMessage(messages.preferences)} />
|
||||
|
||||
{canManageReports(permissions) && <ColumnLink transparent href='/admin/reports' icon='flag' iconComponent={ModerationIcon} text={intl.formatMessage(messages.moderation)} />}
|
||||
{canViewAdminDashboard(permissions) && <ColumnLink transparent href='/admin/dashboard' icon='tachometer' iconComponent={AdministrationIcon} text={intl.formatMessage(messages.administration)} />}
|
||||
</>
|
||||
)}
|
||||
|
||||
{!signedIn && (
|
||||
<div className='navigation-panel__sign-in-banner'>
|
||||
<hr />
|
||||
{ disabledAccountId ? <DisabledAccountBanner /> : <SignInBanner /> }
|
||||
<ColumnLink transparent to='/about' icon='ellipsis-h' iconComponent={MoreHorizIcon} text={intl.formatMessage(messages.about)} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='navigation-panel__legal'>
|
||||
<hr />
|
||||
<ColumnLink transparent to='/about' icon='ellipsis-h' iconComponent={MoreHorizIcon} text={intl.formatMessage(messages.about)} />
|
||||
</div>
|
||||
|
||||
<div className='flex-spacer' />
|
||||
|
||||
<NavigationPortal />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,17 +1,6 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import { PureComponent } from 'react';
|
||||
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import FullscreenExitIcon from '@/material-icons/400-24px/fullscreen_exit.svg?react';
|
||||
import RectangleIcon from '@/material-icons/400-24px/rectangle.svg?react';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
|
||||
const messages = defineMessages({
|
||||
compress: { id: 'lightbox.compress', defaultMessage: 'Compress image view box' },
|
||||
expand: { id: 'lightbox.expand', defaultMessage: 'Expand image view box' },
|
||||
});
|
||||
|
||||
const MIN_SCALE = 1;
|
||||
const MAX_SCALE = 4;
|
||||
const NAV_BAR_HEIGHT = 66;
|
||||
|
@ -104,8 +93,7 @@ class ZoomableImage extends PureComponent {
|
|||
width: PropTypes.number,
|
||||
height: PropTypes.number,
|
||||
onClick: PropTypes.func,
|
||||
zoomButtonHidden: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
zoomedIn: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -131,8 +119,6 @@ class ZoomableImage extends PureComponent {
|
|||
translateX: null,
|
||||
translateY: null,
|
||||
},
|
||||
zoomState: 'expand', // 'expand' 'compress'
|
||||
navigationHidden: false,
|
||||
dragPosition: { top: 0, left: 0, x: 0, y: 0 },
|
||||
dragged: false,
|
||||
lockScroll: { x: 0, y: 0 },
|
||||
|
@ -169,35 +155,20 @@ class ZoomableImage extends PureComponent {
|
|||
this.container.addEventListener('DOMMouseScroll', handler);
|
||||
this.removers.push(() => this.container.removeEventListener('DOMMouseScroll', handler));
|
||||
|
||||
this.initZoomMatrix();
|
||||
this._initZoomMatrix();
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.removeEventListeners();
|
||||
this._removeEventListeners();
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
this.setState({ zoomState: this.state.scale >= this.state.zoomMatrix.rate ? 'compress' : 'expand' });
|
||||
|
||||
if (this.state.scale === MIN_SCALE) {
|
||||
this.container.style.removeProperty('cursor');
|
||||
componentDidUpdate (prevProps) {
|
||||
if (prevProps.zoomedIn !== this.props.zoomedIn) {
|
||||
this._toggleZoom();
|
||||
}
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps () {
|
||||
// reset when slide to next image
|
||||
if (this.props.zoomButtonHidden) {
|
||||
this.setState({
|
||||
scale: MIN_SCALE,
|
||||
lockTranslate: { x: 0, y: 0 },
|
||||
}, () => {
|
||||
this.container.scrollLeft = 0;
|
||||
this.container.scrollTop = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
removeEventListeners () {
|
||||
_removeEventListeners () {
|
||||
this.removers.forEach(listeners => listeners());
|
||||
this.removers = [];
|
||||
}
|
||||
|
@ -220,9 +191,6 @@ class ZoomableImage extends PureComponent {
|
|||
};
|
||||
|
||||
mouseDownHandler = e => {
|
||||
this.container.style.cursor = 'grabbing';
|
||||
this.container.style.userSelect = 'none';
|
||||
|
||||
this.setState({ dragPosition: {
|
||||
left: this.container.scrollLeft,
|
||||
top: this.container.scrollTop,
|
||||
|
@ -246,9 +214,6 @@ class ZoomableImage extends PureComponent {
|
|||
};
|
||||
|
||||
mouseUpHandler = () => {
|
||||
this.container.style.cursor = 'grab';
|
||||
this.container.style.removeProperty('user-select');
|
||||
|
||||
this.image.removeEventListener('mousemove', this.mouseMoveHandler);
|
||||
this.image.removeEventListener('mouseup', this.mouseUpHandler);
|
||||
};
|
||||
|
@ -276,13 +241,13 @@ class ZoomableImage extends PureComponent {
|
|||
const _MAX_SCALE = Math.max(MAX_SCALE, this.state.zoomMatrix.rate);
|
||||
const scale = clamp(MIN_SCALE, _MAX_SCALE, this.state.scale * distance / this.lastDistance);
|
||||
|
||||
this.zoom(scale, midpoint);
|
||||
this._zoom(scale, midpoint);
|
||||
|
||||
this.lastMidpoint = midpoint;
|
||||
this.lastDistance = distance;
|
||||
};
|
||||
|
||||
zoom(nextScale, midpoint) {
|
||||
_zoom(nextScale, midpoint) {
|
||||
const { scale, zoomMatrix } = this.state;
|
||||
const { scrollLeft, scrollTop } = this.container;
|
||||
|
||||
|
@ -318,14 +283,13 @@ class ZoomableImage extends PureComponent {
|
|||
if (dragged) return;
|
||||
const handler = this.props.onClick;
|
||||
if (handler) handler();
|
||||
this.setState({ navigationHidden: !this.state.navigationHidden });
|
||||
};
|
||||
|
||||
handleMouseDown = e => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
initZoomMatrix = () => {
|
||||
_initZoomMatrix = () => {
|
||||
const { width, height } = this.props;
|
||||
const { clientWidth, clientHeight } = this.container;
|
||||
const { offsetWidth, offsetHeight } = this.image;
|
||||
|
@ -357,10 +321,7 @@ class ZoomableImage extends PureComponent {
|
|||
});
|
||||
};
|
||||
|
||||
handleZoomClick = e => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
_toggleZoom () {
|
||||
const { scale, zoomMatrix } = this.state;
|
||||
|
||||
if ( scale >= zoomMatrix.rate ) {
|
||||
|
@ -394,10 +355,7 @@ class ZoomableImage extends PureComponent {
|
|||
this.container.scrollTop = zoomMatrix.scrollTop;
|
||||
});
|
||||
}
|
||||
|
||||
this.container.style.cursor = 'grab';
|
||||
this.container.style.removeProperty('user-select');
|
||||
};
|
||||
}
|
||||
|
||||
setContainerRef = c => {
|
||||
this.container = c;
|
||||
|
@ -408,52 +366,37 @@ class ZoomableImage extends PureComponent {
|
|||
};
|
||||
|
||||
render () {
|
||||
const { alt, lang, src, width, height, intl } = this.props;
|
||||
const { scale, lockTranslate } = this.state;
|
||||
const { alt, lang, src, width, height } = this.props;
|
||||
const { scale, lockTranslate, dragged } = this.state;
|
||||
const overflow = scale === MIN_SCALE ? 'hidden' : 'scroll';
|
||||
const zoomButtonShouldHide = this.state.navigationHidden || this.props.zoomButtonHidden || this.state.zoomMatrix.rate <= MIN_SCALE ? 'media-modal__zoom-button--hidden' : '';
|
||||
const zoomButtonTitle = this.state.zoomState === 'compress' ? intl.formatMessage(messages.compress) : intl.formatMessage(messages.expand);
|
||||
const cursor = scale === MIN_SCALE ? null : (dragged ? 'grabbing' : 'grab');
|
||||
|
||||
return (
|
||||
<>
|
||||
<IconButton
|
||||
className={`media-modal__zoom-button ${zoomButtonShouldHide}`}
|
||||
title={zoomButtonTitle}
|
||||
icon={this.state.zoomState}
|
||||
iconComponent={this.state.zoomState === 'compress' ? FullscreenExitIcon : RectangleIcon}
|
||||
onClick={this.handleZoomClick}
|
||||
size={40}
|
||||
<div
|
||||
className='zoomable-image'
|
||||
ref={this.setContainerRef}
|
||||
style={{ overflow, cursor, userSelect: 'none' }}
|
||||
>
|
||||
<img
|
||||
role='presentation'
|
||||
ref={this.setImageRef}
|
||||
alt={alt}
|
||||
title={alt}
|
||||
lang={lang}
|
||||
src={src}
|
||||
width={width}
|
||||
height={height}
|
||||
style={{
|
||||
fontSize: '30px', /* Fontawesome's fa-compress fa-expand is larger than fa-close */
|
||||
transform: `scale(${scale}) translate(-${lockTranslate.x}px, -${lockTranslate.y}px)`,
|
||||
transformOrigin: '0 0',
|
||||
}}
|
||||
draggable={false}
|
||||
onClick={this.handleClick}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
/>
|
||||
<div
|
||||
className='zoomable-image'
|
||||
ref={this.setContainerRef}
|
||||
style={{ overflow }}
|
||||
>
|
||||
<img
|
||||
role='presentation'
|
||||
ref={this.setImageRef}
|
||||
alt={alt}
|
||||
title={alt}
|
||||
lang={lang}
|
||||
src={src}
|
||||
width={width}
|
||||
height={height}
|
||||
style={{
|
||||
transform: `scale(${scale}) translate(-${lockTranslate.x}px, -${lockTranslate.y}px)`,
|
||||
transformOrigin: '0 0',
|
||||
}}
|
||||
draggable={false}
|
||||
onClick={this.handleClick}
|
||||
onMouseDown={this.handleMouseDown}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(ZoomableImage);
|
||||
export default ZoomableImage;
|
||||
|
|
|
@ -200,7 +200,7 @@ class SwitchingColumnsArea extends PureComponent {
|
|||
{redirect}
|
||||
|
||||
{singleColumn ? <Redirect from='/deck' to='/home' exact /> : null}
|
||||
{singleColumn && pathName.startsWith('/deck/') ? <Redirect from={pathName} to={pathName.slice(5)} /> : null}
|
||||
{singleColumn && pathName.startsWith('/deck/') ? <Redirect from={pathName} to={{...this.props.location, pathname: pathName.slice(5)}} /> : null}
|
||||
{/* Redirect old bookmarks (without /deck) with home-like routes to the advanced interface */}
|
||||
{!singleColumn && pathName === '/getting-started' ? <Redirect from='/getting-started' to='/deck/getting-started' exact /> : null}
|
||||
{!singleColumn && pathName === '/home' ? <Redirect from='/home' to='/deck/getting-started' exact /> : null}
|
||||
|
|
|
@ -288,8 +288,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Retirar lo foco d'a caixa de redacción/busqueda",
|
||||
"keyboard_shortcuts.up": "Ir enta alto en a lista",
|
||||
"lightbox.close": "Zarrar",
|
||||
"lightbox.compress": "Comprimir quadro de visualización d'imachen",
|
||||
"lightbox.expand": "Expandir quadro de visualización d'imachen",
|
||||
"lightbox.next": "Siguient",
|
||||
"lightbox.previous": "Anterior",
|
||||
"limited_account_hint.action": "Amostrar perfil de totz modos",
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
"account.followers.empty": "لا أحدَ يُتابع هذا المُستخدم إلى حد الآن.",
|
||||
"account.followers_counter": "{count, plural, zero{لا مُتابع} one {مُتابعٌ واحِد} two {مُتابعانِ اِثنان} few {{counter} مُتابِعين} many {{counter} مُتابِعًا} other {{counter} مُتابع}}",
|
||||
"account.following": "الاشتراكات",
|
||||
"account.following_counter": "{count, plural, zero{لا يُتابِع أحدًا} one {يُتابِعُ واحد} two{يُتابِعُ اِثنان} few{يُتابِعُ {counter}} many{يُتابِعُ {counter}} other {يُتابِعُ {counter}}}",
|
||||
"account.follows.empty": "لا يُتابع هذا المُستخدمُ أيَّ أحدٍ حتى الآن.",
|
||||
"account.go_to_profile": "اذهب إلى الملف الشخصي",
|
||||
"account.hide_reblogs": "إخفاء المعاد نشرها مِن @{name}",
|
||||
|
@ -309,7 +310,7 @@
|
|||
"follow_request.authorize": "ترخيص",
|
||||
"follow_request.reject": "رفض",
|
||||
"follow_requests.unlocked_explanation": "حتى وإن كان حسابك غير مقفل، يعتقد فريق {domain} أنك قد ترغب في مراجعة طلبات المتابعة من هذه الحسابات يدوياً.",
|
||||
"follow_suggestions.curated_suggestion": "اختيار الموظفين",
|
||||
"follow_suggestions.curated_suggestion": "انتقاه الفريق",
|
||||
"follow_suggestions.dismiss": "لا تُظهرها مجدّدًا",
|
||||
"follow_suggestions.featured_longer": "مختار يدوياً من قِبل فريق {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "مشهور بين الأشخاص الذين تتابعهم",
|
||||
|
@ -419,8 +420,6 @@
|
|||
"keyboard_shortcuts.unfocus": "لإلغاء التركيز على حقل النص أو نافذة البحث",
|
||||
"keyboard_shortcuts.up": "للانتقال إلى أعلى القائمة",
|
||||
"lightbox.close": "إغلاق",
|
||||
"lightbox.compress": "ضغط مربع عرض الصورة",
|
||||
"lightbox.expand": "توسيع مربع عرض الصور",
|
||||
"lightbox.next": "التالي",
|
||||
"lightbox.previous": "العودة",
|
||||
"limited_account_hint.action": "إظهار الملف التعريفي على أي حال",
|
||||
|
@ -752,7 +751,7 @@
|
|||
"status.edit": "تعديل",
|
||||
"status.edited": "آخر تعديل يوم {date}",
|
||||
"status.edited_x_times": "عُدّل {count, plural, zero {} one {مرةً واحدة} two {مرّتان} few {{count} مرات} many {{count} مرة} other {{count} مرة}}",
|
||||
"status.embed": "الحصول على شفرة الإدماج",
|
||||
"status.embed": "الحصول على شيفرة الدمج",
|
||||
"status.favourite": "فضّل",
|
||||
"status.favourites": "{count, plural, zero {}one {مفضلة واحدة} two {مفضلتان} few {# مفضلات} many {# مفضلات} other {# مفضلات}}",
|
||||
"status.filter": "تصفية هذا المنشور",
|
||||
|
@ -773,7 +772,7 @@
|
|||
"status.reblog": "إعادة النشر",
|
||||
"status.reblog_private": "إعادة النشر إلى الجمهور الأصلي",
|
||||
"status.reblogged_by": "شارَكَه {name}",
|
||||
"status.reblogs": "{count, plural, one {تعزيز واحد} two {تعزيزتان} few {# تعزيزات} many {# تعزيزات} other {# تعزيزات}}",
|
||||
"status.reblogs": "{count, plural, one {إعادة نشر واحدة} two {معاد نشرها مرتان} few {# إعادات نشر} many {# إعادات نشر} other {# إعادة نشر}}",
|
||||
"status.reblogs.empty": "لم يقم أي أحد بمشاركة هذا المنشور بعد. عندما يقوم أحدهم بذلك سوف يظهر هنا.",
|
||||
"status.redraft": "إزالة وإعادة الصياغة",
|
||||
"status.remove_bookmark": "احذفه مِن الفواصل المرجعية",
|
||||
|
|
|
@ -412,8 +412,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Расфакусаваць тэкставую вобласць/пошукавы радок",
|
||||
"keyboard_shortcuts.up": "Перамясціцца ўверх па спісе",
|
||||
"lightbox.close": "Закрыць",
|
||||
"lightbox.compress": "Сціснуць бачную вобласць выявы",
|
||||
"lightbox.expand": "Павялічыць бачную вобласць выявы",
|
||||
"lightbox.next": "Далей",
|
||||
"lightbox.previous": "Назад",
|
||||
"limited_account_hint.action": "Усе роўна паказваць профіль",
|
||||
|
|
|
@ -419,8 +419,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Разфокусиране на текстовото поле за съставяне/търсене",
|
||||
"keyboard_shortcuts.up": "Преместване нагоре в списъка",
|
||||
"lightbox.close": "Затваряне",
|
||||
"lightbox.compress": "Свиване на полето за преглед на образи",
|
||||
"lightbox.expand": "Разгъване на полето за преглед на образи",
|
||||
"lightbox.next": "Напред",
|
||||
"lightbox.previous": "Назад",
|
||||
"limited_account_hint.action": "Показване на профила въпреки това",
|
||||
|
|
|
@ -338,8 +338,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Difokus an dachenn testenn/klask",
|
||||
"keyboard_shortcuts.up": "Pignat er roll",
|
||||
"lightbox.close": "Serriñ",
|
||||
"lightbox.compress": "Bihanaat boest hewel ar skeudenn",
|
||||
"lightbox.expand": "Ledanaat boest hewel ar skeudenn",
|
||||
"lightbox.next": "Da-heul",
|
||||
"lightbox.previous": "A-raok",
|
||||
"limited_account_hint.action": "Diskouez an aelad memes tra",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Descentra l'àrea de composició de text/cerca",
|
||||
"keyboard_shortcuts.up": "Apuja a la llista",
|
||||
"lightbox.close": "Tanca",
|
||||
"lightbox.compress": "Comprimeix el quadre de visualització d’imatge",
|
||||
"lightbox.expand": "Amplia el quadre de visualització d’imatge",
|
||||
"lightbox.next": "Següent",
|
||||
"lightbox.previous": "Anterior",
|
||||
"lightbox.zoom_in": "Amplia fins a la mida real",
|
||||
"lightbox.zoom_out": "Amplia fins a encabir",
|
||||
"limited_account_hint.action": "Mostra el perfil de totes maneres",
|
||||
"limited_account_hint.title": "Aquest perfil l'han amagat els moderadors de {domain}.",
|
||||
"link_preview.author": "Per {name}",
|
||||
|
|
|
@ -335,8 +335,6 @@
|
|||
"keyboard_shortcuts.unfocus": "بۆ دروستکردنی ناوچەی دەق/گەڕان",
|
||||
"keyboard_shortcuts.up": "بۆ ئەوەی لە لیستەکەدا بڕۆیت",
|
||||
"lightbox.close": "دابخە",
|
||||
"lightbox.compress": "سندوقی نیشاندانی وێنە بپەستێنە",
|
||||
"lightbox.expand": "فراوانکردنی سندوقی بینینی وێنە",
|
||||
"lightbox.next": "داهاتوو",
|
||||
"lightbox.previous": "پێشوو",
|
||||
"limited_account_hint.action": "بەهەر حاڵ پڕۆفایلی پیشان بدە",
|
||||
|
|
|
@ -196,8 +196,6 @@
|
|||
"keyboard_shortcuts.unfocus": "ùn fucalizà più l'area di testu",
|
||||
"keyboard_shortcuts.up": "cullà indè a lista",
|
||||
"lightbox.close": "Chjudà",
|
||||
"lightbox.compress": "Cumprime a finestra d'affissera di i ritratti",
|
||||
"lightbox.expand": "Ingrandà a finestra d'affissera di i ritratti",
|
||||
"lightbox.next": "Siguente",
|
||||
"lightbox.previous": "Pricidente",
|
||||
"lists.account.add": "Aghjunghje à a lista",
|
||||
|
|
|
@ -410,8 +410,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Zrušit zaměření na nový příspěvek/hledání",
|
||||
"keyboard_shortcuts.up": "Posunout v seznamu nahoru",
|
||||
"lightbox.close": "Zavřít",
|
||||
"lightbox.compress": "Sbalit pole zobrazení obrázku",
|
||||
"lightbox.expand": "Rozbalit pole zobrazení obrázku",
|
||||
"lightbox.next": "Další",
|
||||
"lightbox.previous": "Předchozí",
|
||||
"limited_account_hint.action": "Přesto profil zobrazit",
|
||||
|
|
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Dad-ffocysu ardal cyfansoddi testun/chwilio",
|
||||
"keyboard_shortcuts.up": "Symud yn uwch yn y rhestr",
|
||||
"lightbox.close": "Cau",
|
||||
"lightbox.compress": "Cywasgu blwch gweld delwedd",
|
||||
"lightbox.expand": "Ehangu blwch gweld delwedd",
|
||||
"lightbox.next": "Nesaf",
|
||||
"lightbox.previous": "Blaenorol",
|
||||
"limited_account_hint.action": "Dangos y proffil beth bynnag",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Fjern fokus fra tekstskrivningsområde/søgning",
|
||||
"keyboard_shortcuts.up": "Flyt opad på listen",
|
||||
"lightbox.close": "Luk",
|
||||
"lightbox.compress": "Komprimér billedvisningsfelt",
|
||||
"lightbox.expand": "Udvid billedvisningsfelt",
|
||||
"lightbox.next": "Næste",
|
||||
"lightbox.previous": "Forrige",
|
||||
"lightbox.zoom_in": "Zoom til faktisk størrelse",
|
||||
"lightbox.zoom_out": "Zoom for at tilpasse",
|
||||
"limited_account_hint.action": "Vis profil alligevel",
|
||||
"limited_account_hint.title": "Denne profil er blevet skjult af {domain}-moderatorerne.",
|
||||
"link_preview.author": "Af {name}",
|
||||
|
|
|
@ -155,7 +155,7 @@
|
|||
"compose_form.lock_disclaimer.lock": "geschützt",
|
||||
"compose_form.placeholder": "Was gibt’s Neues?",
|
||||
"compose_form.poll.duration": "Umfragedauer",
|
||||
"compose_form.poll.multiple": "Multiple-Choice",
|
||||
"compose_form.poll.multiple": "Mehrfachauswahl",
|
||||
"compose_form.poll.option_placeholder": "Option {number}",
|
||||
"compose_form.poll.single": "Einfachauswahl",
|
||||
"compose_form.poll.switch_to_multiple": "Mehrfachauswahl erlauben",
|
||||
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Eingabefeld/Suche nicht mehr fokussieren",
|
||||
"keyboard_shortcuts.up": "Ansicht nach oben bewegen",
|
||||
"lightbox.close": "Schließen",
|
||||
"lightbox.compress": "Bildansicht verkleinern",
|
||||
"lightbox.expand": "Bildansicht vergrößern",
|
||||
"lightbox.next": "Vor",
|
||||
"lightbox.previous": "Zurück",
|
||||
"lightbox.zoom_in": "In Originalgröße anzeigen",
|
||||
"lightbox.zoom_out": "In angepasster Größe anzeigen",
|
||||
"limited_account_hint.action": "Profil trotzdem anzeigen",
|
||||
"limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen von {domain} ausgeblendet.",
|
||||
"link_preview.author": "Von {name}",
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
"block_modal.title": "Αποκλεισμός χρήστη;",
|
||||
"block_modal.you_wont_see_mentions": "Δε θα βλέπεις τις αναρτήσεις που τον αναφέρουν.",
|
||||
"boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις την επόμενη φορά",
|
||||
"boost_modal.reblog": "Ενίσχυση ανάρτησης;",
|
||||
"boost_modal.undo_reblog": "Αναίρεση ενίσχυσης;",
|
||||
"bundle_column_error.copy_stacktrace": "Αντιγραφή αναφοράς σφάλματος",
|
||||
"bundle_column_error.error.body": "Δεν ήταν δυνατή η απόδοση της σελίδας που ζήτησες. Μπορεί να οφείλεται σε σφάλμα στον κώδικά μας ή σε πρόβλημα συμβατότητας του προγράμματος περιήγησης.",
|
||||
"bundle_column_error.error.title": "Ωχ όχι!",
|
||||
|
@ -192,6 +194,8 @@
|
|||
"confirmations.unfollow.confirm": "Άρση ακολούθησης",
|
||||
"confirmations.unfollow.message": "Σίγουρα θες να πάψεις να ακολουθείς τον/την {name};",
|
||||
"confirmations.unfollow.title": "Άρση ακολούθησης;",
|
||||
"content_warning.hide": "Απόκρυψη ανάρτησης",
|
||||
"content_warning.show": "Εμφάνιση ούτως ή άλλως",
|
||||
"conversation.delete": "Διαγραφή συζήτησης",
|
||||
"conversation.mark_as_read": "Σήμανση ως αναγνωσμένο",
|
||||
"conversation.open": "Προβολή συνομιλίας",
|
||||
|
@ -299,6 +303,7 @@
|
|||
"filter_modal.select_filter.subtitle": "Χρησιμοποιήστε μια υπάρχουσα κατηγορία ή δημιουργήστε μια νέα",
|
||||
"filter_modal.select_filter.title": "Φιλτράρισμα αυτής της ανάρτησης",
|
||||
"filter_modal.title.status": "Φιλτράρισμα μιας ανάρτησης",
|
||||
"filter_warning.matches_filter": "Ταιριάζει με το φίλτρο “{title}”",
|
||||
"filtered_notifications_banner.pending_requests": "Από {count, plural, =0 {κανένα} one {ένα άτομο} other {# άτομα}} που μπορεί να ξέρεις",
|
||||
"filtered_notifications_banner.title": "Φιλτραρισμένες ειδοποιήσεις",
|
||||
"firehose.all": "Όλα",
|
||||
|
@ -427,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Αποεστίαση του πεδίου σύνθεσης/αναζήτησης",
|
||||
"keyboard_shortcuts.up": "Μετακίνηση προς τα πάνω στη λίστα",
|
||||
"lightbox.close": "Κλείσιμο",
|
||||
"lightbox.compress": "Συμπίεση πλαισίου προβολής εικόνας",
|
||||
"lightbox.expand": "Ανάπτυξη πλαισίου εμφάνισης εικόνας",
|
||||
"lightbox.next": "Επόμενο",
|
||||
"lightbox.previous": "Προηγούμενο",
|
||||
"lightbox.zoom_in": "Εστίαση στο πραγματικό μέγεθος",
|
||||
"lightbox.zoom_out": "Εστίαση για προσαρμογή",
|
||||
"limited_account_hint.action": "Εμφάνιση προφίλ ούτως ή άλλως",
|
||||
"limited_account_hint.title": "Αυτό το προφίλ έχει αποκρυφτεί από τους διαχειριστές του διακομιστή {domain}.",
|
||||
"link_preview.author": "Από {name}",
|
||||
|
@ -452,6 +457,7 @@
|
|||
"lists.subheading": "Οι λίστες σου",
|
||||
"load_pending": "{count, plural, one {# νέο στοιχείο} other {# νέα στοιχεία}}",
|
||||
"loading_indicator.label": "Φόρτωση…",
|
||||
"media_gallery.hide": "Απόκρυψη",
|
||||
"moved_to_account_banner.text": "Ο λογαριασμός σου {disabledAccount} είναι προσωρινά απενεργοποιημένος επειδή μεταφέρθηκες στον {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Απόκρυψη από ειδοποιήσεις",
|
||||
"mute_modal.hide_options": "Απόκρυψη επιλογών",
|
||||
|
@ -463,6 +469,7 @@
|
|||
"mute_modal.you_wont_see_mentions": "Δε θα βλέπεις τις αναρτήσεις που τον αναφέρουν.",
|
||||
"mute_modal.you_wont_see_posts": "Μπορεί ακόμα να δει τις αναρτήσεις σου, αλλά δε θα βλέπεις τις δικές του.",
|
||||
"navigation_bar.about": "Σχετικά με",
|
||||
"navigation_bar.administration": "Διαχείριση",
|
||||
"navigation_bar.advanced_interface": "Άνοιγμα σε προηγμένη διεπαφή ιστού",
|
||||
"navigation_bar.blocks": "Αποκλεισμένοι χρήστες",
|
||||
"navigation_bar.bookmarks": "Σελιδοδείκτες",
|
||||
|
@ -479,6 +486,7 @@
|
|||
"navigation_bar.follows_and_followers": "Ακολουθείς και σε ακολουθούν",
|
||||
"navigation_bar.lists": "Λίστες",
|
||||
"navigation_bar.logout": "Αποσύνδεση",
|
||||
"navigation_bar.moderation": "Συντονισμός",
|
||||
"navigation_bar.mutes": "Αποσιωπημένοι χρήστες",
|
||||
"navigation_bar.opened_in_classic_interface": "Δημοσιεύσεις, λογαριασμοί και άλλες συγκεκριμένες σελίδες ανοίγονται από προεπιλογή στην κλασική διεπαφή ιστού.",
|
||||
"navigation_bar.personal": "Προσωπικά",
|
||||
|
@ -770,6 +778,7 @@
|
|||
"status.bookmark": "Σελιδοδείκτης",
|
||||
"status.cancel_reblog_private": "Ακύρωση ενίσχυσης",
|
||||
"status.cannot_reblog": "Αυτή η ανάρτηση δεν μπορεί να ενισχυθεί",
|
||||
"status.continued_thread": "Συνεχιζόμενο νήματος",
|
||||
"status.copy": "Αντιγραφή συνδέσμου ανάρτησης",
|
||||
"status.delete": "Διαγραφή",
|
||||
"status.detailed_status": "Προβολή λεπτομερούς συζήτησης",
|
||||
|
@ -778,6 +787,7 @@
|
|||
"status.edit": "Επεξεργασία",
|
||||
"status.edited": "Τελευταία επεξεργασία {date}",
|
||||
"status.edited_x_times": "Επεξεργάστηκε {count, plural, one {{count} φορά} other {{count} φορές}}",
|
||||
"status.embed": "Απόκτηση κώδικα ενσωμάτωσης",
|
||||
"status.favourite": "Αγαπημένα",
|
||||
"status.favourites": "{count, plural, one {# αγαπημένο} other {# αγαπημένα}}",
|
||||
"status.filter": "Φιλτράρισμα αυτής της ανάρτησης",
|
||||
|
@ -802,6 +812,7 @@
|
|||
"status.reblogs.empty": "Κανείς δεν ενίσχυσε αυτή την ανάρτηση ακόμα. Μόλις το κάνει κάποιος, θα εμφανιστεί εδώ.",
|
||||
"status.redraft": "Σβήσε & ξαναγράψε",
|
||||
"status.remove_bookmark": "Αφαίρεση σελιδοδείκτη",
|
||||
"status.replied_in_thread": "Απαντήθηκε σε νήμα",
|
||||
"status.replied_to": "Απάντησε στον {name}",
|
||||
"status.reply": "Απάντησε",
|
||||
"status.replyAll": "Απάντησε στο νήμα συζήτησης",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Move up in the list",
|
||||
"lightbox.close": "Close",
|
||||
"lightbox.compress": "Compress image view box",
|
||||
"lightbox.expand": "Expand image view box",
|
||||
"lightbox.next": "Next",
|
||||
"lightbox.previous": "Previous",
|
||||
"lightbox.zoom_in": "Zoom to actual size",
|
||||
"lightbox.zoom_out": "Zoom to fit",
|
||||
"limited_account_hint.action": "Show profile anyway",
|
||||
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
|
||||
"link_preview.author": "By {name}",
|
||||
|
|
|
@ -315,7 +315,7 @@
|
|||
"domain_block_modal.they_cant_follow": "Nobody from this server can follow you.",
|
||||
"domain_block_modal.they_wont_know": "They won't know they've been blocked.",
|
||||
"domain_block_modal.title": "Block domain?",
|
||||
"domain_block_modal.you_will_lose_followers": "All your followers from this server will be removed.",
|
||||
"domain_block_modal.you_will_lose_num_followers": "You will lose {followersCount, plural, one {{followersCountDisplay} follower} other {{followersCountDisplay} followers}} and {followingCount, plural, one {{followingCountDisplay} person you follow} other {{followingCountDisplay} people you follow}}.",
|
||||
"domain_block_modal.you_wont_see_posts": "You won't see posts or notifications from users on this server.",
|
||||
"domain_pill.activitypub_lets_connect": "It lets you connect and interact with people not just on Mastodon, but across different social apps too.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub is like the language Mastodon speaks with other social networks.",
|
||||
|
@ -538,10 +538,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Unfocus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Move up in the list",
|
||||
"lightbox.close": "Close",
|
||||
"lightbox.compress": "Compress image view box",
|
||||
"lightbox.expand": "Expand image view box",
|
||||
"lightbox.next": "Next",
|
||||
"lightbox.previous": "Previous",
|
||||
"lightbox.zoom_in": "Zoom to actual size",
|
||||
"lightbox.zoom_out": "Zoom to fit",
|
||||
"limited_account_hint.action": "Show profile anyway",
|
||||
"limited_account_hint.title": "This profile has been hidden by the moderators of {domain}.",
|
||||
"link_preview.author": "By {name}",
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
"block_modal.title": "Ĉu bloki uzanton?",
|
||||
"block_modal.you_wont_see_mentions": "Vi ne vidos afiŝojn, ke mencii ilin.",
|
||||
"boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje",
|
||||
"boost_modal.reblog": "Ĉu diskonigi afiŝon?",
|
||||
"boost_modal.undo_reblog": "Ĉu ĉesi diskonigi afiŝon?",
|
||||
"bundle_column_error.copy_stacktrace": "Kopii la eraran raporton",
|
||||
"bundle_column_error.error.body": "La petita paĝo ne povas redonitis. Eble estas eraro.",
|
||||
"bundle_column_error.error.title": "Ho, ve!",
|
||||
|
@ -188,8 +190,12 @@
|
|||
"confirmations.redraft.title": "Ĉu forigi kaj redakcii afiŝon?",
|
||||
"confirmations.reply.confirm": "Respondi",
|
||||
"confirmations.reply.message": "Respondi nun anstataŭigos la skribatan afiŝon. Ĉu vi certas, ke vi volas daŭrigi?",
|
||||
"confirmations.reply.title": "Ĉu superskribi afiŝon?",
|
||||
"confirmations.unfollow.confirm": "Ne plu sekvi",
|
||||
"confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?",
|
||||
"confirmations.unfollow.title": "Ĉu ĉesi sekvi uzanton?",
|
||||
"content_warning.hide": "Kaŝi afiŝon",
|
||||
"content_warning.show": "Montri ĉiukaze",
|
||||
"conversation.delete": "Forigi konversacion",
|
||||
"conversation.mark_as_read": "Marki legita",
|
||||
"conversation.open": "Vidi konversacion",
|
||||
|
@ -209,6 +215,27 @@
|
|||
"dismissable_banner.explore_statuses": "Ĉi tioj estas afiŝoj de socia reto kiu populariĝas hodiau.",
|
||||
"dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.",
|
||||
"dismissable_banner.public_timeline": "Ĉi tioj estas plej lastaj publikaj afiŝoj de personoj ĉe socia reto kiu personoj ĉe {domain} sekvas.",
|
||||
"domain_block_modal.block": "Bloki servilon",
|
||||
"domain_block_modal.block_account_instead": "Bloki @{name} anstataŭe",
|
||||
"domain_block_modal.they_can_interact_with_old_posts": "Homoj de ĉi tiu servilo povas interagi kun viaj malnovaj afiŝoj.",
|
||||
"domain_block_modal.they_cant_follow": "Neniu el ĉi tiu servilo povas sekvi vin.",
|
||||
"domain_block_modal.they_wont_know": "Ili ne scios, ke ili estas blokitaj.",
|
||||
"domain_block_modal.title": "Ĉu bloki la domajnon?",
|
||||
"domain_block_modal.you_will_lose_followers": "Ĉiuj viaj sekvantoj de ĉi tiu servilo estos forigitaj.",
|
||||
"domain_block_modal.you_wont_see_posts": "Vi ne vidos afiŝojn aŭ sciigojn de uzantoj sur ĉi tiu servilo.",
|
||||
"domain_pill.activitypub_lets_connect": "Ĝi ebligas vin konekti kaj interagi kun homoj ne nur sur Mastodon, sed ankaŭ tra diversaj sociaj apoj.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub estas kiel la lingvo kiun Mastodon parolas kun aliaj sociaj retoj.",
|
||||
"domain_pill.server": "Servilo",
|
||||
"domain_pill.their_handle": "Ilia identigo:",
|
||||
"domain_pill.their_server": "Ilia cifereca hejmo, kie ĉiuj iliaj afiŝoj loĝas.",
|
||||
"domain_pill.their_username": "Ilia unika identigilo sur ilia servilo. Eblas trovi uzantojn kun la sama uzantnomo sur malsamaj serviloj.",
|
||||
"domain_pill.username": "Uzantnomo",
|
||||
"domain_pill.whats_in_a_handle": "Kio estas en identigo?",
|
||||
"domain_pill.who_they_are": "Ĉar identigoj diras, kiu iu estas kaj kie ili estas, vi povas interagi kun homoj tra la socia reto de <button>ActivityPub-funkciigitaj platformoj</button>.",
|
||||
"domain_pill.who_you_are": "Ĉar via identigo diras kiu vi estas kaj kie vi estas, homoj povas interagi kun vi tra la socia reto de <button>ActivityPub-funkciigitaj platformoj</button>.",
|
||||
"domain_pill.your_handle": "Via identigo:",
|
||||
"domain_pill.your_server": "Via cifereca hejmo, kie loĝas ĉiuj viaj afiŝoj. Ĉu vi ne ŝatas ĉi tiun? Transloku servilojn iam ajn kaj alportu ankaŭ viajn sekvantojn.",
|
||||
"domain_pill.your_username": "Via unika identigilo sur ĉi tiu servilo. Eblas trovi uzantojn kun la sama uzantnomo sur malsamaj serviloj.",
|
||||
"embed.instructions": "Enkorpigu ĉi tiun afiŝon en vian retejon per kopio de la suba kodo.",
|
||||
"embed.preview": "Ĝi aperos tiel:",
|
||||
"emoji_button.activity": "Agadoj",
|
||||
|
@ -245,6 +272,7 @@
|
|||
"empty_column.list": "Ankoraŭ estas nenio en ĉi tiu listo. Kiam membroj de ĉi tiu listo afiŝos novajn afiŝojn, ili aperos ĉi tie.",
|
||||
"empty_column.lists": "Vi ankoraŭ ne havas liston. Kiam vi kreos iun, ĝi aperos ĉi tie.",
|
||||
"empty_column.mutes": "Vi ne ankoraŭ silentigis iun uzanton.",
|
||||
"empty_column.notification_requests": "Ĉio klara! Estas nenio tie ĉi. Kiam vi ricevas novajn sciigojn, ili aperos ĉi tie laŭ viaj agordoj.",
|
||||
"empty_column.notifications": "Vi ankoraŭ ne havas sciigojn. Interagu kun aliaj por komenci konversacion.",
|
||||
"empty_column.public": "Estas nenio ĉi tie! Publike skribu ion, aŭ mane sekvu uzantojn de aliaj serviloj por plenigi la publikan tempolinion",
|
||||
"error.unexpected_crash.explanation": "Pro eraro en nia kodo, aŭ problemo de kongruo en via retumilo, ĉi tiu paĝo ne povis esti montrata ĝuste.",
|
||||
|
@ -275,12 +303,30 @@
|
|||
"filter_modal.select_filter.subtitle": "Uzu ekzistantan kategorion aŭ kreu novan",
|
||||
"filter_modal.select_filter.title": "Filtri ĉi tiun afiŝon",
|
||||
"filter_modal.title.status": "Filtri mesaĝon",
|
||||
"filter_warning.matches_filter": "Filtrilo de kongruoj “{title}”",
|
||||
"filtered_notifications_banner.pending_requests": "El {count, plural, =0 {neniu} one {unu persono} other {# homoj}} vi eble konas",
|
||||
"filtered_notifications_banner.title": "Filtritaj sciigoj",
|
||||
"firehose.all": "Ĉiuj",
|
||||
"firehose.local": "Ĉi tiu servilo",
|
||||
"firehose.remote": "Aliaj serviloj",
|
||||
"follow_request.authorize": "Rajtigi",
|
||||
"follow_request.reject": "Rifuzi",
|
||||
"follow_requests.unlocked_explanation": "Kvankam via konto ne estas ŝlosita, la dungitaro de {domain} opinias, ke vi eble volas revizii petojn pri sekvado de ĉi tiuj kontoj permane.",
|
||||
"follow_suggestions.curated_suggestion": "Elekto de stabo",
|
||||
"follow_suggestions.dismiss": "Ne montri denove",
|
||||
"follow_suggestions.featured_longer": "Mane elektita de la teamo de {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "Populara inter homoj, kiujn vi sekvas",
|
||||
"follow_suggestions.hints.featured": "Ĉi tiu profilo estis mane elektita de la teamo de {domain}.",
|
||||
"follow_suggestions.hints.friends_of_friends": "Ĉi tiu profilo estas populara inter la homoj, kiujn vi sekvas.",
|
||||
"follow_suggestions.hints.most_followed": "Ĉi tiu profilo estas unu el la plej sekvataj en {domain}.",
|
||||
"follow_suggestions.hints.most_interactions": "Ĉi tiu profilo lastatempe ricevis multe da atento sur {domain}.",
|
||||
"follow_suggestions.hints.similar_to_recently_followed": "Ĉi tiu profilo similas al la profiloj kiujn vi plej lastatempe sekvis.",
|
||||
"follow_suggestions.personalized_suggestion": "Agordita propono",
|
||||
"follow_suggestions.popular_suggestion": "Popularaj proponoj",
|
||||
"follow_suggestions.popular_suggestion_longer": "Populara en {domain}",
|
||||
"follow_suggestions.similar_to_recently_followed_longer": "Simile al profiloj, kiujn vi lastatempe sekvis",
|
||||
"follow_suggestions.view_all": "Vidi ĉiujn",
|
||||
"follow_suggestions.who_to_follow": "Kiun sekvi",
|
||||
"followed_tags": "Sekvataj kradvortoj",
|
||||
"footer.about": "Pri",
|
||||
"footer.directory": "Profilujo",
|
||||
|
@ -307,6 +353,14 @@
|
|||
"hashtag.follow": "Sekvi la kradvorton",
|
||||
"hashtag.unfollow": "Ne plu sekvi la kradvorton",
|
||||
"hashtags.and_other": "…kaj {count, plural,other {# pli}}",
|
||||
"hints.profiles.followers_may_be_missing": "Sekvantoj por ĉi tiu profilo eble mankas.",
|
||||
"hints.profiles.follows_may_be_missing": "Sekvatoj de ĉi tiu profilo eble mankas.",
|
||||
"hints.profiles.posts_may_be_missing": "Iuj afiŝoj de ĉi tiu profilo eble mankas.",
|
||||
"hints.profiles.see_more_followers": "Vidi pli da sekvantoj sur {domain}",
|
||||
"hints.profiles.see_more_follows": "Vidi pli da sekvatoj sur {domain}",
|
||||
"hints.profiles.see_more_posts": "Vidi pli da afiŝoj sur {domain}",
|
||||
"hints.threads.replies_may_be_missing": "Respondoj de aliaj serviloj eble mankas.",
|
||||
"hints.threads.see_more": "Vidi pli da respondoj sur {domain}",
|
||||
"home.column_settings.show_reblogs": "Montri diskonigojn",
|
||||
"home.column_settings.show_replies": "Montri respondojn",
|
||||
"home.hide_announcements": "Kaŝi la anoncojn",
|
||||
|
@ -314,6 +368,17 @@
|
|||
"home.pending_critical_update.link": "Vidi ĝisdatigojn",
|
||||
"home.pending_critical_update.title": "Kritika sekurĝisdatigo estas disponebla!",
|
||||
"home.show_announcements": "Montri anoncojn",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon ne povas informi uzantojn, ke vi ignoris iliajn sciigojn. Ignori sciigojn ne malhelpos la mesaĝojn mem esti senditaj.",
|
||||
"ignore_notifications_modal.filter_instead": "Filtri anstataŭe",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Vi ankoraŭ povos akcepti, malakcepti aŭ raporti uzantojn",
|
||||
"ignore_notifications_modal.filter_to_avoid_confusion": "Filtrado helpas eviti eblan konfuzon",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Vi povas revizii filtritajn sciigojn aparte",
|
||||
"ignore_notifications_modal.ignore": "Ignori sciigojn",
|
||||
"ignore_notifications_modal.limited_accounts_title": "Ĉu ignori sciigojn de moderigitaj kontoj?",
|
||||
"ignore_notifications_modal.new_accounts_title": "Ĉu ignori sciigojn de novaj kontoj?",
|
||||
"ignore_notifications_modal.not_followers_title": "Ĉu ignori sciigojn de homoj, kiuj ne sekvas vin?",
|
||||
"ignore_notifications_modal.not_following_title": "Ĉu ignori sciigojn de homoj, kiujn vi ne sekvas?",
|
||||
"ignore_notifications_modal.private_mentions_title": "Ĉu ignori sciigojn de nepetitaj privataj mencioj?",
|
||||
"interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.",
|
||||
"interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povos sekvi {name} por vidi ties mesaĝojn en via hejmo.",
|
||||
"interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.",
|
||||
|
@ -367,13 +432,15 @@
|
|||
"keyboard_shortcuts.unfocus": "malenfokusigi la tekstujon aŭ la serĉilon",
|
||||
"keyboard_shortcuts.up": "iri supren en la listo",
|
||||
"lightbox.close": "Fermi",
|
||||
"lightbox.compress": "Kunpremi bildan vidkeston",
|
||||
"lightbox.expand": "Pligrandigi bildan vidkeston",
|
||||
"lightbox.next": "Antaŭen",
|
||||
"lightbox.previous": "Malantaŭen",
|
||||
"lightbox.zoom_in": "Zomi al reala grandeco",
|
||||
"lightbox.zoom_out": "Zomi por konveni",
|
||||
"limited_account_hint.action": "Montru profilon ĉiukaze",
|
||||
"limited_account_hint.title": "La profilo estas kaŝita de la moderigantoj de {domain}.",
|
||||
"link_preview.author": "De {name}",
|
||||
"link_preview.more_from_author": "Pli de {name}",
|
||||
"link_preview.shares": "{count, plural, one {{counter} afiŝo} other {{counter} afiŝoj}}",
|
||||
"lists.account.add": "Aldoni al la listo",
|
||||
"lists.account.remove": "Forigi de la listo",
|
||||
"lists.delete": "Forigi la liston",
|
||||
|
@ -390,8 +457,19 @@
|
|||
"lists.subheading": "Viaj listoj",
|
||||
"load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}",
|
||||
"loading_indicator.label": "Ŝargado…",
|
||||
"media_gallery.hide": "Kaŝi",
|
||||
"moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Kaŝi de sciigoj",
|
||||
"mute_modal.hide_options": "Kaŝi agordojn",
|
||||
"mute_modal.indefinite": "Ĝis mi malsilentas ilin",
|
||||
"mute_modal.show_options": "Montri agordojn",
|
||||
"mute_modal.they_can_mention_and_follow": "Ili povas mencii kaj sekvi vin, sed vi ne vidos ilin.",
|
||||
"mute_modal.they_wont_know": "Ili ne scios, ke ili estas silentigitaj.",
|
||||
"mute_modal.title": "Ĉu silentigi uzanton?",
|
||||
"mute_modal.you_wont_see_mentions": "Vi ne vidos afiŝojn, kiuj mencias ilin.",
|
||||
"mute_modal.you_wont_see_posts": "Ili ankoraŭ povas vidi viajn afiŝojn, sed vi ne vidos iliajn.",
|
||||
"navigation_bar.about": "Pri",
|
||||
"navigation_bar.administration": "Administrado",
|
||||
"navigation_bar.advanced_interface": "Malfermi altnivelan retpaĝan interfacon",
|
||||
"navigation_bar.blocks": "Blokitaj uzantoj",
|
||||
"navigation_bar.bookmarks": "Legosignoj",
|
||||
|
@ -408,6 +486,7 @@
|
|||
"navigation_bar.follows_and_followers": "Sekvatoj kaj sekvantoj",
|
||||
"navigation_bar.lists": "Listoj",
|
||||
"navigation_bar.logout": "Adiaŭi",
|
||||
"navigation_bar.moderation": "Modereco",
|
||||
"navigation_bar.mutes": "Silentigitaj uzantoj",
|
||||
"navigation_bar.opened_in_classic_interface": "Afiŝoj, kontoj, kaj aliaj specifaj paĝoj kiuj estas malfermititaj defaulta en la klasika reta interfaco.",
|
||||
"navigation_bar.personal": "Persone",
|
||||
|
@ -418,20 +497,71 @@
|
|||
"navigation_bar.security": "Sekureco",
|
||||
"not_signed_in_indicator.not_signed_in": "Necesas saluti por aliri tiun rimedon.",
|
||||
"notification.admin.report": "{name} raportis {target}",
|
||||
"notification.admin.report_account": "{name} raportis {count, plural, one {afiŝon} other {# afiŝojn}} de {target} por {category}",
|
||||
"notification.admin.report_account_other": "{name} raportis {count, plural, one {afiŝon} other {# afiŝojn}} de {target}",
|
||||
"notification.admin.report_statuses": "{name} raportis {target} por {category}",
|
||||
"notification.admin.report_statuses_other": "{name} raportis {target}",
|
||||
"notification.admin.sign_up": "{name} kreis konton",
|
||||
"notification.admin.sign_up.name_and_others": "{name} kaj {count, plural, one {# alia} other {# aliaj}} kreis konton",
|
||||
"notification.favourite": "{name} stelumis vian afiŝon",
|
||||
"notification.favourite.name_and_others_with_link": "{name} kaj <a>{count, plural, one {# alia} other {# aliaj}}</a> ŝatis vian afiŝon",
|
||||
"notification.follow": "{name} eksekvis vin",
|
||||
"notification.follow.name_and_others": "{name} kaj {count, plural, one {# alia} other {# aliaj}} sekvis vin",
|
||||
"notification.follow_request": "{name} petis sekvi vin",
|
||||
"notification.follow_request.name_and_others": "{name} kaj {count, plural, one {# alia} other {# aliaj}} petis sekvi vin",
|
||||
"notification.label.mention": "Mencii",
|
||||
"notification.label.private_mention": "Privata mencio",
|
||||
"notification.label.private_reply": "Privata respondo",
|
||||
"notification.label.reply": "Respondi",
|
||||
"notification.mention": "Mencii",
|
||||
"notification.moderation-warning.learn_more": "Lerni pli",
|
||||
"notification.moderation_warning": "Vi ricevis moderigan averton",
|
||||
"notification.moderation_warning.action_delete_statuses": "Kelkaj el viaj afiŝoj estis forigitaj.",
|
||||
"notification.moderation_warning.action_disable": "Via konto estas malŝaltita.",
|
||||
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Kelkaj el viaj afiŝoj estis markitaj kiel sentemaj.",
|
||||
"notification.moderation_warning.action_none": "Via konto ricevis moderigan averton.",
|
||||
"notification.moderation_warning.action_sensitive": "Viaj afiŝoj estos markitaj kiel sentemaj ekde nun.",
|
||||
"notification.moderation_warning.action_silence": "Via konto estis limigita.",
|
||||
"notification.moderation_warning.action_suspend": "Via konto estas malakceptita.",
|
||||
"notification.own_poll": "Via enketo finiĝis",
|
||||
"notification.poll": "Balotenketo, en kiu vi voĉdonis, finiĝis",
|
||||
"notification.reblog": "{name} diskonigis vian afiŝon",
|
||||
"notification.reblog.name_and_others_with_link": "{name} kaj <a>{count, plural, one {# alia} other {# aliaj}}</a> diskonigis vian afiŝon",
|
||||
"notification.relationships_severance_event": "Perditaj konektoj kun {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Administranto de {from} malakceptis {target}, kio signifas, ke vi ne plu povas ricevi ĝisdatigojn de ili aŭ interagi kun ili.",
|
||||
"notification.relationships_severance_event.domain_block": "Administranto de {from} blokis {target}, inkluzive de {followersCount} de viaj sekvantoj kaj {followingCount, plural, one {# konto} other {# kontoj}} kiujn vi sekvas.",
|
||||
"notification.relationships_severance_event.learn_more": "Lerni pli",
|
||||
"notification.relationships_severance_event.user_domain_block": "Vi blokis {target}, forigante {followersCount} de viaj sekvantoj kaj {followingCount, plural, one {# konto} other {# kontoj}} kiujn vi sekvas.",
|
||||
"notification.status": "{name} ĵus afiŝis",
|
||||
"notification.update": "{name} redaktis afiŝon",
|
||||
"notification_requests.accept": "Akcepti",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {Akcepti # peton…} other {Akcepti # petojn…}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Akcepti peton} other {Akcepti petojn}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Vi estas akceptonta {count, plural, one {unu sciigan peton} other {# sciigajn petojn}}. Ĉu vi certas, ke vi volas daŭrigi?",
|
||||
"notification_requests.confirm_accept_multiple.title": "Ĉu akcepti sciigajn petojn?",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Malakcepti peton} other {Malakcepti petojn}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "Vi estas malakceptonta {count, plural, one {unu sciigan peton} other {# sciigajn petojn}}. Vi ne povos facile aliri {count, plural, one {ĝin} other {ilin}} denove. Ĉu vi certas, ke vi volas daŭrigi?",
|
||||
"notification_requests.confirm_dismiss_multiple.title": "Ĉu malakcepti sciigajn petojn?",
|
||||
"notification_requests.dismiss": "Forĵeti",
|
||||
"notification_requests.dismiss_multiple": "{count, plural, one {Malakcepti # peton…} other {# Malakcepti # petojn…}}",
|
||||
"notification_requests.edit_selection": "Redakti",
|
||||
"notification_requests.exit_selection": "Farita",
|
||||
"notification_requests.explainer_for_limited_account": "Sciigoj de ĉi tiu konto estis filtritaj ĉar la konto estis limigita de moderanto.",
|
||||
"notification_requests.explainer_for_limited_remote_account": "Sciigoj de ĉi tiu konto estis filtritaj ĉar la konto aŭ ĝia servilo estis limigitaj de moderanto.",
|
||||
"notification_requests.maximize": "Maksimumigi",
|
||||
"notification_requests.minimize_banner": "Minimumigi filtritajn sciigojn-rubandon",
|
||||
"notification_requests.notifications_from": "Sciigoj de {name}",
|
||||
"notification_requests.title": "Filtritaj sciigoj",
|
||||
"notification_requests.view": "Vidi sciigojn",
|
||||
"notifications.clear": "Forviŝi sciigojn",
|
||||
"notifications.clear_confirmation": "Ĉu vi certas, ke vi volas porĉiame forviŝi ĉiujn viajn sciigojn?",
|
||||
"notifications.clear_title": "Ĉu forigi sciigojn?",
|
||||
"notifications.column_settings.admin.report": "Novaj raportoj:",
|
||||
"notifications.column_settings.admin.sign_up": "Novaj registriĝoj:",
|
||||
"notifications.column_settings.alert": "Sciigoj de la retumilo",
|
||||
"notifications.column_settings.favourite": "Stelumoj:",
|
||||
"notifications.column_settings.filter_bar.advanced": "Montri ĉiujn kategoriojn",
|
||||
"notifications.column_settings.filter_bar.category": "Rapida filtrila breto",
|
||||
"notifications.column_settings.follow": "Novaj sekvantoj:",
|
||||
"notifications.column_settings.follow_request": "Novaj petoj de sekvado:",
|
||||
"notifications.column_settings.mention": "Mencioj:",
|
||||
|
@ -447,7 +577,7 @@
|
|||
"notifications.filter.all": "Ĉiuj",
|
||||
"notifications.filter.boosts": "Diskonigoj",
|
||||
"notifications.filter.favourites": "Stelumoj",
|
||||
"notifications.filter.follows": "Sekvoj",
|
||||
"notifications.filter.follows": "Sekvatoj",
|
||||
"notifications.filter.mentions": "Mencioj",
|
||||
"notifications.filter.polls": "Balotenketaj rezultoj",
|
||||
"notifications.filter.statuses": "Ĝisdatigoj de homoj, kiujn vi sekvas",
|
||||
|
@ -457,6 +587,23 @@
|
|||
"notifications.permission_denied": "Labortablaj sciigoj ne disponeblas pro peto antaŭe rifuzita de retumiloj",
|
||||
"notifications.permission_denied_alert": "Labortablaj sciigoj ne povas esti ebligitaj, ĉar retumilpermeso antaŭe estis rifuzita",
|
||||
"notifications.permission_required": "Labortablaj sciigoj ne disponeblas ĉar la bezonata permeso ne estis donita.",
|
||||
"notifications.policy.accept": "Akcepti",
|
||||
"notifications.policy.accept_hint": "Montri en sciigoj",
|
||||
"notifications.policy.drop": "Ignori",
|
||||
"notifications.policy.drop_hint": "Sendi al la malpleno, por neniam esti vidita denove",
|
||||
"notifications.policy.filter": "Filtri",
|
||||
"notifications.policy.filter_hint": "Sendi al filtritaj sciigoj-enirkesto",
|
||||
"notifications.policy.filter_limited_accounts_hint": "Limigita de servilaj moderigantoj",
|
||||
"notifications.policy.filter_limited_accounts_title": "Moderigitaj kontoj",
|
||||
"notifications.policy.filter_new_accounts.hint": "Kreite en la {days, plural, one {lasta tago} other {# lastaj tagoj}}",
|
||||
"notifications.policy.filter_new_accounts_title": "Novaj kontoj",
|
||||
"notifications.policy.filter_not_followers_hint": "Inkluzive de homoj, kiuj sekvis vin malpli ol {days, plural, one {unu tago} other {# tagoj}}",
|
||||
"notifications.policy.filter_not_followers_title": "Homoj, kiuj ne sekvas vin",
|
||||
"notifications.policy.filter_not_following_hint": "Ĝis vi permane aprobas ilin",
|
||||
"notifications.policy.filter_not_following_title": "Homoj, kiujn vi ne sekvas",
|
||||
"notifications.policy.filter_private_mentions_hint": "Filtrite krom se ĝi respondas al via propra mencio aŭ se vi sekvas la sendinton",
|
||||
"notifications.policy.filter_private_mentions_title": "Nepetitaj privataj mencioj",
|
||||
"notifications.policy.title": "Administri sciigojn de…",
|
||||
"notifications_permission_banner.enable": "Ŝalti retumilajn sciigojn",
|
||||
"notifications_permission_banner.how_to_control": "Por ricevi sciigojn kiam Mastodon ne estas malfermita, ebligu labortablajn sciigojn. Vi povas regi precize kiuj specoj de interagoj generas labortablajn sciigojn per la supra butono {icon} post kiam ili estas ebligitaj.",
|
||||
"notifications_permission_banner.title": "Neniam preterlasas iun ajn",
|
||||
|
@ -466,8 +613,8 @@
|
|||
"onboarding.actions.go_to_home": "Go to your home feed",
|
||||
"onboarding.compose.template": "Saluton #Mastodon!",
|
||||
"onboarding.follows.empty": "Bedaŭrinde, neniu rezulto estas montrebla nuntempe. Vi povas provi serĉi aŭ foliumi la esploran paĝon por trovi kontojn por sekvi, aŭ retrovi baldaŭ.",
|
||||
"onboarding.follows.lead": "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.lead": "Via hejma fluo estas la ĉefa maniero sperti Mastodon. Ju pli da homoj vi sekvas, des pli aktiva kaj interesa ĝi estos. Por komenci, jen kelkaj sugestoj:",
|
||||
"onboarding.follows.title": "Agordi vian hejman fluon",
|
||||
"onboarding.profile.discoverable": "Trovebligi mian profilon",
|
||||
"onboarding.profile.discoverable_hint": "Kiam vi aliĝi al trovebleco ĉe Mastodon, viaj afiŝoj eble aperos en serĉaj rezultoj kaj populariĝoj, kaj via profilo eble estas sugestota al personoj kun similaj intereseoj al vi.",
|
||||
"onboarding.profile.display_name": "Publika nomo",
|
||||
|
@ -488,7 +635,7 @@
|
|||
"onboarding.start.title": "Vi atingas ĝin!",
|
||||
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
|
||||
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
||||
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
||||
"onboarding.steps.publish_status.body": "Salutu la mondon per teksto, fotoj, filmetoj aŭ balotenketoj {emoji}",
|
||||
"onboarding.steps.publish_status.title": "Fari vian unuan afiŝon",
|
||||
"onboarding.steps.setup_profile.body": "Others are more likely to interact with you with a filled out profile.",
|
||||
"onboarding.steps.setup_profile.title": "Customize your profile",
|
||||
|
@ -518,6 +665,7 @@
|
|||
"privacy.private.short": "Sekvantoj",
|
||||
"privacy.public.long": "Ĉiujn ajn ĉe kaj ekster Mastodon",
|
||||
"privacy.public.short": "Publika",
|
||||
"privacy.unlisted.additional": "Ĉi tio kondutas ekzakte kiel publika, krom ke la afiŝo ne aperos en vivaj fluoj aŭ kradvortoj, esploro aŭ Mastodon-serĉo, eĉ se vi estas enskribita en la tuta konto.",
|
||||
"privacy.unlisted.long": "Malpli algoritmaj fanfaroj",
|
||||
"privacy.unlisted.short": "Diskrete publika",
|
||||
"privacy_policy.last_updated": "Laste ĝisdatigita en {date}",
|
||||
|
@ -537,7 +685,9 @@
|
|||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"relative_time.today": "hodiaŭ",
|
||||
"reply_indicator.attachments": "{count, plural, one {# aldonaĵo} other {# aldonaĵoj}}",
|
||||
"reply_indicator.cancel": "Nuligi",
|
||||
"reply_indicator.poll": "Balotenketo",
|
||||
"report.block": "Bloki",
|
||||
"report.block_explanation": "Vi ne vidos iliajn afiŝojn. Ili ne povos vidi viajn afiŝojn, nek sekvi vin. Ili ne scios, ke vi blokas ilin.",
|
||||
"report.categories.legal": "Laŭleĝa",
|
||||
|
@ -580,9 +730,13 @@
|
|||
"report.unfollow_explanation": "Vi sekvas ĉi tiun konton. Por ne plu vidi ĝiajn afiŝojn en via hejma templinio, ĉesu sekvi ĝin.",
|
||||
"report_notification.attached_statuses": "{count, plural, one {{count} afiŝo almetita} other {{count} afiŝoj almetitaj}}",
|
||||
"report_notification.categories.legal": "Laŭleĝa",
|
||||
"report_notification.categories.legal_sentence": "kontraŭleĝa enhavo",
|
||||
"report_notification.categories.other": "Alia",
|
||||
"report_notification.categories.other_sentence": "alia",
|
||||
"report_notification.categories.spam": "Trudmesaĝo",
|
||||
"report_notification.categories.spam_sentence": "trudmesaĝo",
|
||||
"report_notification.categories.violation": "Malobservo de la regulo",
|
||||
"report_notification.categories.violation_sentence": "malobservo de la regulo",
|
||||
"report_notification.open": "Malfermi la raporton",
|
||||
"search.no_recent_searches": "Neniuj lastaj serĉoj",
|
||||
"search.placeholder": "Serĉi",
|
||||
|
@ -610,8 +764,11 @@
|
|||
"server_banner.about_active_users": "Personoj uzantaj ĉi tiun servilon dum la lastaj 30 tagoj (Aktivaj Uzantoj Monate)",
|
||||
"server_banner.active_users": "aktivaj uzantoj",
|
||||
"server_banner.administered_by": "Administrata de:",
|
||||
"server_banner.is_one_of_many": "{domain} estas unu el la multaj sendependaj Mastodon-serviloj, kiujn vi povas uzi por partopreni en la fediverso.",
|
||||
"server_banner.server_stats": "Statistikoj de la servilo:",
|
||||
"sign_in_banner.create_account": "Krei konton",
|
||||
"sign_in_banner.follow_anyone": "Sekvi iun ajn tra la fediverso kaj vidi ĉion en kronologia ordo. Neniuj algoritmoj, reklamoj aŭ klakbetoj videblas.",
|
||||
"sign_in_banner.mastodon_is": "Mastodonto estas la plej bona maniero por resti flank-al-flanke kun kio okazas.",
|
||||
"sign_in_banner.sign_in": "Saluti",
|
||||
"sign_in_banner.sso_redirect": "Ensalutu aŭ Registriĝi",
|
||||
"status.admin_account": "Malfermi fasadon de moderigado por @{name}",
|
||||
|
@ -621,14 +778,18 @@
|
|||
"status.bookmark": "Aldoni al la legosignoj",
|
||||
"status.cancel_reblog_private": "Ne plu diskonigi",
|
||||
"status.cannot_reblog": "Ĉi tiun afiŝon ne eblas diskonigi",
|
||||
"status.continued_thread": "Daŭrigis fadenon",
|
||||
"status.copy": "Kopii la ligilon al la mesaĝo",
|
||||
"status.delete": "Forigi",
|
||||
"status.detailed_status": "Detala konversacia vido",
|
||||
"status.direct": "Private mencii @{name}",
|
||||
"status.direct_indicator": "Privata mencio",
|
||||
"status.edit": "Redakti",
|
||||
"status.edited": "Laste redaktita {date}",
|
||||
"status.edited_x_times": "Redactita {count, plural, one {{count} fojon} other {{count} fojojn}}",
|
||||
"status.embed": "Akiri enkorpigan kodon",
|
||||
"status.favourite": "Ŝatata",
|
||||
"status.favourites": "{count, plural, one {plej ŝatata} other {plej ŝatataj}}",
|
||||
"status.filter": "Filtri ĉi tiun afiŝon",
|
||||
"status.history.created": "{name} kreis {date}",
|
||||
"status.history.edited": "{name} redaktis {date}",
|
||||
|
@ -647,9 +808,11 @@
|
|||
"status.reblog": "Diskonigi",
|
||||
"status.reblog_private": "Diskonigi kun la sama videbleco",
|
||||
"status.reblogged_by": "{name} diskonigis",
|
||||
"status.reblogs": "{count, plural, one {diskonigo} other {diskonigoj}}",
|
||||
"status.reblogs.empty": "Ankoraŭ neniu diskonigis tiun afiŝon. Kiam iu faras tion, ri aperos ĉi tie.",
|
||||
"status.redraft": "Forigi kaj reskribi",
|
||||
"status.remove_bookmark": "Forigi legosignon",
|
||||
"status.replied_in_thread": "Respondis en fadeno",
|
||||
"status.replied_to": "Respondis al {name}",
|
||||
"status.reply": "Respondi",
|
||||
"status.replyAll": "Respondi al la fadeno",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Quitar el foco del área de texto de redacción o de búsqueda",
|
||||
"keyboard_shortcuts.up": "Subir en la lista",
|
||||
"lightbox.close": "Cerrar",
|
||||
"lightbox.compress": "Comprimir cuadro de vista de imagen",
|
||||
"lightbox.expand": "Expandir cuadro de vista de imagen",
|
||||
"lightbox.next": "Siguiente",
|
||||
"lightbox.previous": "Anterior",
|
||||
"lightbox.zoom_in": "Ampliar al tamaño real",
|
||||
"lightbox.zoom_out": "Ampliar hasta ajustar",
|
||||
"limited_account_hint.action": "Mostrar perfil de todos modos",
|
||||
"limited_account_hint.title": "Este perfil fue ocultado por los moderadores de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
|
|
|
@ -39,11 +39,11 @@
|
|||
"account.following_counter": "{count, plural, one {{counter} siguiendo} other {{counter} siguiendo}}",
|
||||
"account.follows.empty": "Este usuario todavía no sigue a nadie.",
|
||||
"account.go_to_profile": "Ir al perfil",
|
||||
"account.hide_reblogs": "Ocultar retoots de @{name}",
|
||||
"account.hide_reblogs": "Ocultar impulsos de @{name}",
|
||||
"account.in_memoriam": "En memoria.",
|
||||
"account.joined_short": "Se unió",
|
||||
"account.languages": "Cambiar idiomas suscritos",
|
||||
"account.link_verified_on": "El proprietario de este link fue comprobado el {date}",
|
||||
"account.link_verified_on": "El proprietario de este enlace fue comprobado el {date}",
|
||||
"account.locked_info": "El estado de privacidad de esta cuenta està configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.",
|
||||
"account.media": "Multimedia",
|
||||
"account.mention": "Mencionar a @{name}",
|
||||
|
@ -61,7 +61,7 @@
|
|||
"account.requested": "Esperando aprobación. Haga clic para cancelar la solicitud de seguimiento",
|
||||
"account.requested_follow": "{name} ha solicitado seguirte",
|
||||
"account.share": "Compartir el perfil de @{name}",
|
||||
"account.show_reblogs": "Mostrar retoots de @{name}",
|
||||
"account.show_reblogs": "Mostrar impulsos de @{name}",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
"account.unblock": "Desbloquear a @{name}",
|
||||
"account.unblock_domain": "Mostrar a {domain}",
|
||||
|
@ -70,8 +70,8 @@
|
|||
"account.unfollow": "Dejar de seguir",
|
||||
"account.unmute": "Dejar de silenciar a @{name}",
|
||||
"account.unmute_notifications_short": "Dejar de silenciar notificaciones",
|
||||
"account.unmute_short": "Desmutear",
|
||||
"account_note.placeholder": "Clic para añadir nota",
|
||||
"account.unmute_short": "Dejar de silenciar",
|
||||
"account_note.placeholder": "Haz clic para agregar una nota",
|
||||
"admin.dashboard.daily_retention": "Tasa de retención de usuarios por día después de unirse",
|
||||
"admin.dashboard.monthly_retention": "Tasa de retención de usuarios por mes después de unirse",
|
||||
"admin.dashboard.retention.average": "Promedio",
|
||||
|
@ -97,7 +97,7 @@
|
|||
"block_modal.title": "¿Bloquear usuario?",
|
||||
"block_modal.you_wont_see_mentions": "No verás publicaciones que los mencionen.",
|
||||
"boost_modal.combo": "Puedes hacer clic en {combo} para saltar este aviso la próxima vez",
|
||||
"boost_modal.reblog": "¿Impulsar la publicación?",
|
||||
"boost_modal.reblog": "¿Deseas impulsar la publicación?",
|
||||
"boost_modal.undo_reblog": "¿Dejar de impulsar la publicación?",
|
||||
"bundle_column_error.copy_stacktrace": "Copiar informe de error",
|
||||
"bundle_column_error.error.body": "La página solicitada no pudo ser renderizada. Podría deberse a un error en nuestro código o a un problema de compatibilidad con el navegador.",
|
||||
|
@ -130,7 +130,7 @@
|
|||
"column.lists": "Listas",
|
||||
"column.mutes": "Usuarios silenciados",
|
||||
"column.notifications": "Notificaciones",
|
||||
"column.pins": "Toots fijados",
|
||||
"column.pins": "Publicaciones fijadas",
|
||||
"column.public": "Línea de tiempo federada",
|
||||
"column_back_button.label": "Atrás",
|
||||
"column_header.hide_settings": "Ocultar configuración",
|
||||
|
@ -148,10 +148,10 @@
|
|||
"compose.published.body": "Publicado.",
|
||||
"compose.published.open": "Abrir",
|
||||
"compose.saved.body": "Publicación guardada.",
|
||||
"compose_form.direct_message_warning_learn_more": "Aprender mas",
|
||||
"compose_form.direct_message_warning_learn_more": "Saber más",
|
||||
"compose_form.encryption_warning": "Las publicaciones en Mastodon no están cifradas de extremo a extremo. No comparta ninguna información sensible en Mastodon.",
|
||||
"compose_form.hashtag_warning": "Este toot no será listado bajo ningún hashtag dado que no es público. Solo toots públicos pueden ser buscados por hashtag.",
|
||||
"compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
|
||||
"compose_form.hashtag_warning": "Esta publicación no será listada bajo ninguna etiqueta dado que no es pública. Solo publicaciones públicas pueden ser buscadas por etiqueta.",
|
||||
"compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus publicaciones solo para seguidores.",
|
||||
"compose_form.lock_disclaimer.lock": "bloqueado",
|
||||
"compose_form.placeholder": "¿En qué estás pensando?",
|
||||
"compose_form.poll.duration": "Duración de la encuesta",
|
||||
|
@ -165,32 +165,32 @@
|
|||
"compose_form.publish_form": "Publicar",
|
||||
"compose_form.reply": "Respuesta",
|
||||
"compose_form.save_changes": "Actualización",
|
||||
"compose_form.spoiler.marked": "Texto oculto tras la advertencia",
|
||||
"compose_form.spoiler.unmarked": "Texto no oculto",
|
||||
"compose_form.spoiler.marked": "Quitar advertencia de contenido",
|
||||
"compose_form.spoiler.unmarked": "Añadir advertencia de contenido",
|
||||
"compose_form.spoiler_placeholder": "Advertencia de contenido (opcional)",
|
||||
"confirmation_modal.cancel": "Cancelar",
|
||||
"confirmations.block.confirm": "Bloquear",
|
||||
"confirmations.delete.confirm": "Eliminar",
|
||||
"confirmations.delete.message": "¿Estás seguro de que quieres borrar este toot?",
|
||||
"confirmations.delete.message": "¿Estás seguro de que quieres borrar esta publicación?",
|
||||
"confirmations.delete.title": "¿Eliminar publicación?",
|
||||
"confirmations.delete_list.confirm": "Eliminar",
|
||||
"confirmations.delete_list.message": "¿Seguro que quieres borrar esta lista permanentemente?",
|
||||
"confirmations.delete_list.title": "¿Eliminar lista?",
|
||||
"confirmations.delete_list.title": "¿Deseas eliminar la lista?",
|
||||
"confirmations.discard_edit_media.confirm": "Descartar",
|
||||
"confirmations.discard_edit_media.message": "Tienes cambios sin guardar en la descripción o vista previa del archivo, ¿deseas descartarlos de cualquier manera?",
|
||||
"confirmations.edit.confirm": "Editar",
|
||||
"confirmations.edit.message": "Editar sobrescribirá el mensaje que estás escribiendo. ¿Estás seguro de que deseas continuar?",
|
||||
"confirmations.edit.title": "¿Sobrescribir publicación?",
|
||||
"confirmations.edit.title": "¿Sobreescribir publicación?",
|
||||
"confirmations.logout.confirm": "Cerrar sesión",
|
||||
"confirmations.logout.message": "¿Estás seguro de querer cerrar la sesión?",
|
||||
"confirmations.logout.title": "¿Cerrar sesión?",
|
||||
"confirmations.logout.message": "¿Estás seguro de que quieres cerrar la sesión?",
|
||||
"confirmations.logout.title": "¿Deseas cerrar sesión?",
|
||||
"confirmations.mute.confirm": "Silenciar",
|
||||
"confirmations.redraft.confirm": "Borrar y volver a borrador",
|
||||
"confirmations.redraft.message": "¿Estás seguro que quieres borrar esta publicación y editarla? Los favoritos e impulsos se perderán, y las respuestas a la publicación original quedarán separadas.",
|
||||
"confirmations.redraft.title": "¿Borrar y volver a redactar la publicación?",
|
||||
"confirmations.reply.confirm": "Responder",
|
||||
"confirmations.reply.message": "Responder sobrescribirá el mensaje que estás escribiendo. ¿Estás seguro de que deseas continuar?",
|
||||
"confirmations.reply.title": "¿Sobrescribir publicación?",
|
||||
"confirmations.reply.title": "¿Sobreescribir publicación?",
|
||||
"confirmations.unfollow.confirm": "Dejar de seguir",
|
||||
"confirmations.unfollow.message": "¿Estás seguro de que quieres dejar de seguir a {name}?",
|
||||
"confirmations.unfollow.title": "¿Dejar de seguir al usuario?",
|
||||
|
@ -213,8 +213,8 @@
|
|||
"dismissable_banner.dismiss": "Descartar",
|
||||
"dismissable_banner.explore_links": "Estas noticias están siendo discutidas por personas en este y otros servidores de la red descentralizada en este momento.",
|
||||
"dismissable_banner.explore_statuses": "Estas son las publicaciones que están en tendencia en la red ahora. Las publicaciones recientes con más impulsos y favoritos se muestran más arriba.",
|
||||
"dismissable_banner.explore_tags": "Se trata de hashtags que están ganando adeptos en las redes sociales hoy en día. Los hashtags que son utilizados por más personas diferentes se clasifican mejor.",
|
||||
"dismissable_banner.public_timeline": "Estos son los toots públicos más recientes de personas en la web social a las que sigue la gente en {domain}.",
|
||||
"dismissable_banner.explore_tags": "Se trata de etiquetas que están ganando adeptos en las redes sociales hoy en día. Las etiquetas que son utilizadas por más personas diferentes se clasifican mejor.",
|
||||
"dismissable_banner.public_timeline": "Estas son las publicaciones públicas más recientes de personas en la web social a las que sigue la gente en {domain}.",
|
||||
"domain_block_modal.block": "Bloquear servidor",
|
||||
"domain_block_modal.block_account_instead": "Bloquear @{name} en su lugar",
|
||||
"domain_block_modal.they_can_interact_with_old_posts": "Las personas de este servidor pueden interactuar con tus publicaciones antiguas.",
|
||||
|
@ -236,7 +236,7 @@
|
|||
"domain_pill.your_handle": "Tu alias:",
|
||||
"domain_pill.your_server": "Tu hogar digital, donde residen todas tus publicaciones. ¿No te gusta este sitio? Muévete a otro servidor en cualquier momento y llévate a tus seguidores.",
|
||||
"domain_pill.your_username": "Tu identificador único en este servidor. Es posible encontrar usuarios con el mismo nombre de usuario en diferentes servidores.",
|
||||
"embed.instructions": "Añade este toot a tu sitio web con el siguiente código.",
|
||||
"embed.instructions": "Añade esta publicación a tu sitio web con el siguiente código.",
|
||||
"embed.preview": "Así es como se verá:",
|
||||
"emoji_button.activity": "Actividad",
|
||||
"emoji_button.clear": "Borrar",
|
||||
|
@ -249,16 +249,16 @@
|
|||
"emoji_button.objects": "Objetos",
|
||||
"emoji_button.people": "Gente",
|
||||
"emoji_button.recent": "Usados frecuentemente",
|
||||
"emoji_button.search": "Buscar…",
|
||||
"emoji_button.search": "Buscar...",
|
||||
"emoji_button.search_results": "Resultados de búsqueda",
|
||||
"emoji_button.symbols": "Símbolos",
|
||||
"emoji_button.travel": "Viajes y lugares",
|
||||
"empty_column.account_hides_collections": "Este usuario ha elegido no hacer disponible esta información",
|
||||
"empty_column.account_suspended": "Cuenta suspendida",
|
||||
"empty_column.account_timeline": "¡No hay toots aquí!",
|
||||
"empty_column.account_timeline": "¡No hay publicaciones aquí!",
|
||||
"empty_column.account_unavailable": "Perfil no disponible",
|
||||
"empty_column.blocks": "Aún no has bloqueado a ningún usuario.",
|
||||
"empty_column.bookmarked_statuses": "Aún no tienes ningún toot guardado como marcador. Cuando guardes uno, se mostrará aquí.",
|
||||
"empty_column.bookmarked_statuses": "Aún no tienes ninguna publicación guardada como marcador. Cuando guardes una, se mostrará aquí.",
|
||||
"empty_column.community": "La línea de tiempo local está vacía. ¡Escribe algo para empezar la fiesta!",
|
||||
"empty_column.direct": "Aún no tienes menciones privadas. Cuando envíes o recibas una, aparecerán aquí.",
|
||||
"empty_column.domain_blocks": "Todavía no hay dominios ocultos.",
|
||||
|
@ -266,8 +266,8 @@
|
|||
"empty_column.favourited_statuses": "Todavía no tienes publicaciones favoritas. Cuando le des favorito a una publicación se mostrarán acá.",
|
||||
"empty_column.favourites": "Todavía nadie marcó como favorito esta publicación. Cuando alguien lo haga, se mostrará aquí.",
|
||||
"empty_column.follow_requests": "No tienes ninguna petición de seguidor. Cuando recibas una, se mostrará aquí.",
|
||||
"empty_column.followed_tags": "No estás siguiendo ningún hashtag todavía. Cuando lo hagas, aparecerá aquí.",
|
||||
"empty_column.hashtag": "No hay nada en este hashtag aún.",
|
||||
"empty_column.followed_tags": "No estás siguiendo ninguna etiqueta todavía. Cuando lo hagas, aparecerá aquí.",
|
||||
"empty_column.hashtag": "No hay nada en esta etiqueta aún.",
|
||||
"empty_column.home": "No estás siguiendo a nadie aún. Visita {public} o haz búsquedas para empezar y conocer gente nueva.",
|
||||
"empty_column.list": "No hay nada en esta lista aún. Cuando miembros de esta lista publiquen nuevos estatus, estos aparecerán qui.",
|
||||
"empty_column.lists": "No tienes ninguna lista. cuando crees una, se mostrará aquí.",
|
||||
|
@ -304,7 +304,7 @@
|
|||
"filter_modal.select_filter.title": "Filtrar esta publicación",
|
||||
"filter_modal.title.status": "Filtrar una publicación",
|
||||
"filter_warning.matches_filter": "Coincide con el filtro “{title}”",
|
||||
"filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nadie} one {una persona} other {# personas}} que puede que conozcas",
|
||||
"filtered_notifications_banner.pending_requests": "De {count, plural, =0 {nadie} one {una persona} other {# people}} que puede que tú conozcas",
|
||||
"filtered_notifications_banner.title": "Notificaciones filtradas",
|
||||
"firehose.all": "Todas",
|
||||
"firehose.local": "Este servidor",
|
||||
|
@ -315,7 +315,7 @@
|
|||
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
|
||||
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
||||
"follow_suggestions.featured_longer": "Escogidos por el equipo de {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "Populares entre las personas a las que sigues",
|
||||
"follow_suggestions.friends_of_friends_longer": "Popular entre las personas a las que sigues",
|
||||
"follow_suggestions.hints.featured": "Este perfil ha sido seleccionado a mano por el equipo de {domain}.",
|
||||
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
|
||||
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
||||
|
@ -323,11 +323,11 @@
|
|||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
|
||||
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
||||
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
||||
"follow_suggestions.popular_suggestion_longer": "Populares en {domain}",
|
||||
"follow_suggestions.popular_suggestion_longer": "Popular en {domain}",
|
||||
"follow_suggestions.similar_to_recently_followed_longer": "Similares a los perfiles que has seguido recientemente",
|
||||
"follow_suggestions.view_all": "Ver todo",
|
||||
"follow_suggestions.who_to_follow": "Recomendamos seguir",
|
||||
"followed_tags": "Hashtags seguidos",
|
||||
"followed_tags": "Etiquetas seguidas",
|
||||
"footer.about": "Acerca de",
|
||||
"footer.directory": "Directorio de perfiles",
|
||||
"footer.get_app": "Obtener la aplicación",
|
||||
|
@ -344,8 +344,8 @@
|
|||
"hashtag.column_settings.select.no_options_message": "No se encontraron sugerencias",
|
||||
"hashtag.column_settings.select.placeholder": "Introducir etiquetas…",
|
||||
"hashtag.column_settings.tag_mode.all": "Todos estos",
|
||||
"hashtag.column_settings.tag_mode.any": "Cualquiera de estos",
|
||||
"hashtag.column_settings.tag_mode.none": "Ninguno de estos",
|
||||
"hashtag.column_settings.tag_mode.any": "Cualquiera de estas",
|
||||
"hashtag.column_settings.tag_mode.none": "Ninguna de estas",
|
||||
"hashtag.column_settings.tag_toggle": "Incluye etiquetas adicionales para esta columna",
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} participante} other {{counter} participantes}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
|
||||
|
@ -361,7 +361,7 @@
|
|||
"hints.profiles.see_more_posts": "Ver más publicaciones en {domain}",
|
||||
"hints.threads.replies_may_be_missing": "Puede que no se muestren algunas respuestas de otros servidores.",
|
||||
"hints.threads.see_more": "Ver más respuestas en {domain}",
|
||||
"home.column_settings.show_reblogs": "Mostrar retoots",
|
||||
"home.column_settings.show_reblogs": "Mostrar impulsos",
|
||||
"home.column_settings.show_replies": "Mostrar respuestas",
|
||||
"home.hide_announcements": "Ocultar anuncios",
|
||||
"home.pending_critical_update.body": "¡Por favor actualiza tu servidor Mastodon lo antes posible!",
|
||||
|
@ -369,7 +369,7 @@
|
|||
"home.pending_critical_update.title": "¡Actualización de seguridad crítica disponible!",
|
||||
"home.show_announcements": "Mostrar anuncios",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon no puede informar a los usuarios que has ignorado sus notificaciones. Ignorar notificaciones no impedirá que se sigan enviando los mensajes.",
|
||||
"ignore_notifications_modal.filter_instead": "Filtrar en vez de ignorar",
|
||||
"ignore_notifications_modal.filter_instead": "Filtrar en su lugar",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Aún podrás aceptar, rechazar o reportar usuarios",
|
||||
"ignore_notifications_modal.filter_to_avoid_confusion": "Filtrar ayuda a evitar confusiones potenciales",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Puedes revisar las notificaciones filtradas por separado",
|
||||
|
@ -399,13 +399,13 @@
|
|||
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",
|
||||
"keyboard_shortcuts.back": "volver atrás",
|
||||
"keyboard_shortcuts.blocked": "abrir una lista de usuarios bloqueados",
|
||||
"keyboard_shortcuts.boost": "retootear",
|
||||
"keyboard_shortcuts.boost": "Impulsar publicación",
|
||||
"keyboard_shortcuts.column": "enfocar un estado en una de las columnas",
|
||||
"keyboard_shortcuts.compose": "enfocar el área de texto de redacción",
|
||||
"keyboard_shortcuts.description": "Descripción",
|
||||
"keyboard_shortcuts.direct": "para abrir la columna de menciones privadas",
|
||||
"keyboard_shortcuts.down": "mover hacia abajo en la lista",
|
||||
"keyboard_shortcuts.enter": "abrir estado",
|
||||
"keyboard_shortcuts.enter": "Abrir publicación",
|
||||
"keyboard_shortcuts.favourite": "Marcar como favorita la publicación",
|
||||
"keyboard_shortcuts.favourites": "Abrir lista de favoritos",
|
||||
"keyboard_shortcuts.federated": "abrir el timeline federado",
|
||||
|
@ -419,23 +419,23 @@
|
|||
"keyboard_shortcuts.my_profile": "abrir tu perfil",
|
||||
"keyboard_shortcuts.notifications": "abrir la columna de notificaciones",
|
||||
"keyboard_shortcuts.open_media": "para abrir archivos multimedia",
|
||||
"keyboard_shortcuts.pinned": "abrir la lista de toots destacados",
|
||||
"keyboard_shortcuts.pinned": "Abrir la lista de publicaciones fijadas",
|
||||
"keyboard_shortcuts.profile": "abrir el perfil del autor",
|
||||
"keyboard_shortcuts.reply": "para responder",
|
||||
"keyboard_shortcuts.reply": "Responder a la publicación",
|
||||
"keyboard_shortcuts.requests": "abrir la lista de peticiones de seguidores",
|
||||
"keyboard_shortcuts.search": "para poner el foco en la búsqueda",
|
||||
"keyboard_shortcuts.spoilers": "para mostrar/ocultar el campo CW",
|
||||
"keyboard_shortcuts.start": "abrir la columna \"comenzar\"",
|
||||
"keyboard_shortcuts.toggle_hidden": "mostrar/ocultar texto tras aviso de contenido (CW)",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "mostrar/ocultar medios",
|
||||
"keyboard_shortcuts.toot": "para comenzar un nuevo toot",
|
||||
"keyboard_shortcuts.toot": "Comenzar una nueva publicación",
|
||||
"keyboard_shortcuts.unfocus": "para retirar el foco de la caja de redacción/búsqueda",
|
||||
"keyboard_shortcuts.up": "para ir hacia arriba en la lista",
|
||||
"lightbox.close": "Cerrar",
|
||||
"lightbox.compress": "Comprimir cuadro de visualización de imagen",
|
||||
"lightbox.expand": "Expandir cuadro de visualización de imagen",
|
||||
"lightbox.next": "Siguiente",
|
||||
"lightbox.previous": "Anterior",
|
||||
"lightbox.zoom_in": "Ampliar al tamaño real",
|
||||
"lightbox.zoom_out": "Ampliar para ajustar",
|
||||
"limited_account_hint.action": "Mostrar perfil de todos modos",
|
||||
"limited_account_hint.title": "Este perfil ha sido ocultado por los moderadores de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
|
@ -474,7 +474,7 @@
|
|||
"navigation_bar.blocks": "Usuarios bloqueados",
|
||||
"navigation_bar.bookmarks": "Marcadores",
|
||||
"navigation_bar.community_timeline": "Historia local",
|
||||
"navigation_bar.compose": "Escribir un nuevo toot",
|
||||
"navigation_bar.compose": "Redactar una nueva publicación",
|
||||
"navigation_bar.direct": "Menciones privadas",
|
||||
"navigation_bar.discover": "Descubrir",
|
||||
"navigation_bar.domain_blocks": "Dominios ocultos",
|
||||
|
@ -482,7 +482,7 @@
|
|||
"navigation_bar.favourites": "Favoritos",
|
||||
"navigation_bar.filters": "Palabras silenciadas",
|
||||
"navigation_bar.follow_requests": "Solicitudes para seguirte",
|
||||
"navigation_bar.followed_tags": "Hashtags seguidos",
|
||||
"navigation_bar.followed_tags": "Etiquetas seguidas",
|
||||
"navigation_bar.follows_and_followers": "Siguiendo y seguidores",
|
||||
"navigation_bar.lists": "Listas",
|
||||
"navigation_bar.logout": "Cerrar sesión",
|
||||
|
@ -490,25 +490,25 @@
|
|||
"navigation_bar.mutes": "Usuarios silenciados",
|
||||
"navigation_bar.opened_in_classic_interface": "Publicaciones, cuentas y otras páginas específicas se abren por defecto en la interfaz web clásica.",
|
||||
"navigation_bar.personal": "Personal",
|
||||
"navigation_bar.pins": "Toots fijados",
|
||||
"navigation_bar.pins": "Publicaciones fijadas",
|
||||
"navigation_bar.preferences": "Preferencias",
|
||||
"navigation_bar.public_timeline": "Historia federada",
|
||||
"navigation_bar.search": "Buscar",
|
||||
"navigation_bar.security": "Seguridad",
|
||||
"not_signed_in_indicator.not_signed_in": "Necesitas iniciar sesión para acceder a este recurso.",
|
||||
"notification.admin.report": "{name} denunció a {target}",
|
||||
"notification.admin.report_account": "{name} informó de {count, plural, one {una publicación} other {# publicaciones}} de {target} por {category}",
|
||||
"notification.admin.report_account_other": "{name} informó de {count, plural, one {una publicación} other {# publicaciones}} de {target}",
|
||||
"notification.admin.report_statuses": "{name} informó de {target} por {category}",
|
||||
"notification.admin.report_statuses_other": "{name} informó de {target}",
|
||||
"notification.admin.report_account": "{name} reportó {count, plural, one {una publicación} other {# publicaciones}} de {target} por {category}",
|
||||
"notification.admin.report_account_other": "{name} reportó {count, plural, one {una publicación} other {# publicaciones}} de {target}",
|
||||
"notification.admin.report_statuses": "{name} reportó {target} por {category}",
|
||||
"notification.admin.report_statuses_other": "{name} reportó {target}",
|
||||
"notification.admin.sign_up": "{name} se unio",
|
||||
"notification.admin.sign_up.name_and_others": "{name} y {count, plural, one {# más} other {# más}} se registraron",
|
||||
"notification.admin.sign_up.name_and_others": "{name} y {count, plural, one {# otro} other {# otros}} se registraron",
|
||||
"notification.favourite": "{name} marcó como favorita tu publicación",
|
||||
"notification.favourite.name_and_others_with_link": "{name} y <a>{count, plural, one {# más} other {# más}}</a> marcaron tu publicación como favorita",
|
||||
"notification.favourite.name_and_others_with_link": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> marcaron tu publicación como favorita",
|
||||
"notification.follow": "{name} te empezó a seguir",
|
||||
"notification.follow.name_and_others": "{name} y {count, plural, one {# más} other {# más}} te siguieron",
|
||||
"notification.follow.name_and_others": "{name} y {count, plural, one {# otro} other {# otros}} te siguieron",
|
||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# más} other {# más}} han solicitado seguirte",
|
||||
"notification.follow_request.name_and_others": "{name} y {count, plural, one {# otro} other {# otros}} han solicitado seguirte",
|
||||
"notification.label.mention": "Mención",
|
||||
"notification.label.private_mention": "Mención privada",
|
||||
"notification.label.private_reply": "Respuesta privada",
|
||||
|
@ -519,14 +519,14 @@
|
|||
"notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.",
|
||||
"notification.moderation_warning.action_disable": "Tu cuenta ha sido desactivada.",
|
||||
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Se han marcado como sensibles algunas de tus publicaciones.",
|
||||
"notification.moderation_warning.action_none": "Tu cuenta ha recibido un aviso de moderación.",
|
||||
"notification.moderation_warning.action_none": "Tu cuenta ha recibido una advertencia de moderación.",
|
||||
"notification.moderation_warning.action_sensitive": "De ahora en adelante, todas tus publicaciones se marcarán como sensibles.",
|
||||
"notification.moderation_warning.action_silence": "Tu cuenta ha sido limitada.",
|
||||
"notification.moderation_warning.action_suspend": "Tu cuenta ha sido suspendida.",
|
||||
"notification.own_poll": "Tu encuesta ha terminado",
|
||||
"notification.poll": "Una encuesta ha terminado",
|
||||
"notification.reblog": "{name} ha retooteado tu estado",
|
||||
"notification.reblog.name_and_others_with_link": "{name} y <a>{count, plural, one {# más} other {# más}}</a> impulsaron tu publicación",
|
||||
"notification.poll": "Una encuesta en la que has votado ha terminado",
|
||||
"notification.reblog": "{name} ha impulsado tu publicación",
|
||||
"notification.reblog.name_and_others_with_link": "{name} y <a>{count, plural, one {# otro} other {# otros}}</a> impulsaron tu publicación",
|
||||
"notification.relationships_severance_event": "Conexiones perdidas con {name}",
|
||||
"notification.relationships_severance_event.account_suspension": "Un administrador de {from} ha suspendido {target}, lo que significa que ya no puedes recibir actualizaciones de sus cuentas o interactuar con ellas.",
|
||||
"notification.relationships_severance_event.domain_block": "Un administrador de {from} ha bloqueado {target}, incluyendo {followersCount} de tus seguidores y {followingCount, plural, one {# cuenta} other {# cuentas}} que sigues.",
|
||||
|
@ -536,18 +536,18 @@
|
|||
"notification.update": "{name} editó una publicación",
|
||||
"notification_requests.accept": "Aceptar",
|
||||
"notification_requests.accept_multiple": "{count, plural, one {Aceptar # solicitud…} other {Aceptar # solicitudes…}}",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Aceptar solicitud} other {Aceptar solicitudes}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Vas a aceptar {count, plural, one {una solicitud} other {# solicitudes}}. ¿Quieres continuar?",
|
||||
"notification_requests.confirm_accept_multiple.title": "¿Aceptar las solicitudes?",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Descartar solicitud} other {Descartar solicitudes}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "Vas a descartar {count, plural, one {una solicitud} other {# solicitudes}}. No podrás volver a acceder fácilmente a {count, plural, one {ella} other {ellas}} de nuevo. ¿Seguro que quieres continuar?",
|
||||
"notification_requests.confirm_dismiss_multiple.title": "¿Descartar las solicitudes?",
|
||||
"notification_requests.confirm_accept_multiple.button": "{count, plural, one {Solicitud aceptada} other {Solicitudes aceptadas}}",
|
||||
"notification_requests.confirm_accept_multiple.message": "Estás por aceptar {count, plural, one {una solicitud de notificación} other {# solicitudes de notificación}}. ¿Estás seguro de que quieres continuar?",
|
||||
"notification_requests.confirm_accept_multiple.title": "¿Deseas aceptar las solicitudes de notificación?",
|
||||
"notification_requests.confirm_dismiss_multiple.button": "{count, plural, one {Solicitud descartada} other {Solicitudes descartadas}}",
|
||||
"notification_requests.confirm_dismiss_multiple.message": "Estás por descartar {count, plural, one {una solicitud de notificación} other {# solicitudes de notificación}}. No serás capaz de acceder fácilmente a {count, plural, one {ella} other {ellas}} de nuevo. ¿Estás seguro de que quieres continuar?",
|
||||
"notification_requests.confirm_dismiss_multiple.title": "¿Deseas descartar las solicitudes de notificación?",
|
||||
"notification_requests.dismiss": "Descartar",
|
||||
"notification_requests.dismiss_multiple": "{count, plural, one {Descartar # solicitud…} other {Descartar # solicitudes…}}",
|
||||
"notification_requests.edit_selection": "Editar",
|
||||
"notification_requests.exit_selection": "Hecho",
|
||||
"notification_requests.explainer_for_limited_account": "Las notificaciones de esta cuenta han sido filtradas porque la cuenta ha sido limitada por un moderador.",
|
||||
"notification_requests.explainer_for_limited_remote_account": "Las notificaciones de esta cuenta han sido filtradas porque la cuenta o su servidor ha sido limitada por un moderador.",
|
||||
"notification_requests.explainer_for_limited_account": "Las notificaciones de esta cuenta han sido filtradas, ya que la cuenta ha sido limitada por un moderador.",
|
||||
"notification_requests.explainer_for_limited_remote_account": "Las notificaciones de esta cuenta han sido filtradas, ya que la cuenta o su servidor ha sido limitada por un moderador.",
|
||||
"notification_requests.maximize": "Maximizar",
|
||||
"notification_requests.minimize_banner": "Minimizar banner de notificaciones filtradas",
|
||||
"notification_requests.notifications_from": "Notificaciones de {name}",
|
||||
|
@ -555,7 +555,7 @@
|
|||
"notification_requests.view": "Ver notificaciones",
|
||||
"notifications.clear": "Limpiar notificaciones",
|
||||
"notifications.clear_confirmation": "¿Seguro de querer borrar permanentemente todas tus notificaciones?",
|
||||
"notifications.clear_title": "¿Borrar notificaciones?",
|
||||
"notifications.clear_title": "¿Limpiar notificaciones?",
|
||||
"notifications.column_settings.admin.report": "Nuevas denuncias:",
|
||||
"notifications.column_settings.admin.sign_up": "Registros nuevos:",
|
||||
"notifications.column_settings.alert": "Notificaciones de escritorio",
|
||||
|
@ -567,7 +567,7 @@
|
|||
"notifications.column_settings.mention": "Menciones:",
|
||||
"notifications.column_settings.poll": "Resultados de la votación:",
|
||||
"notifications.column_settings.push": "Notificaciones push",
|
||||
"notifications.column_settings.reblog": "Retoots:",
|
||||
"notifications.column_settings.reblog": "Impulsos:",
|
||||
"notifications.column_settings.show": "Mostrar en columna",
|
||||
"notifications.column_settings.sound": "Reproducir sonido",
|
||||
"notifications.column_settings.status": "Nuevas publicaciones:",
|
||||
|
@ -575,7 +575,7 @@
|
|||
"notifications.column_settings.unread_notifications.highlight": "Destacar notificaciones no leídas",
|
||||
"notifications.column_settings.update": "Ediciones:",
|
||||
"notifications.filter.all": "Todos",
|
||||
"notifications.filter.boosts": "Retoots",
|
||||
"notifications.filter.boosts": "Impulsos",
|
||||
"notifications.filter.favourites": "Favoritos",
|
||||
"notifications.filter.follows": "Seguidores",
|
||||
"notifications.filter.mentions": "Menciones",
|
||||
|
@ -621,7 +621,7 @@
|
|||
"onboarding.profile.display_name_hint": "Tu nombre completo o tu apodo…",
|
||||
"onboarding.profile.lead": "Siempre puedes completar esto más tarde en los ajustes, donde hay aún más opciones de personalización disponibles.",
|
||||
"onboarding.profile.note": "Biografía",
|
||||
"onboarding.profile.note_hint": "Puedes @mencionar a otras personas o #hashtags…",
|
||||
"onboarding.profile.note_hint": "Puedes @mencionar a otras personas o #etiquetas…",
|
||||
"onboarding.profile.save_and_continue": "Guardar y continuar",
|
||||
"onboarding.profile.title": "Configuración del perfil",
|
||||
"onboarding.profile.upload_avatar": "Subir foto de perfil",
|
||||
|
@ -639,7 +639,7 @@
|
|||
"onboarding.steps.publish_status.title": "Escribe tu primera publicación",
|
||||
"onboarding.steps.setup_profile.body": "Si rellenas tu perfil tendrás más posibilidades de que otros interactúen contigo.",
|
||||
"onboarding.steps.setup_profile.title": "Personaliza tu perfil",
|
||||
"onboarding.steps.share_profile.body": "¡Dile a tus amigos cómo encontrarte en Mastodon!",
|
||||
"onboarding.steps.share_profile.body": "Dile a tus amigos cómo encontrarte en Mastodon",
|
||||
"onboarding.steps.share_profile.title": "Comparte tu perfil",
|
||||
"onboarding.tips.2fa": "<strong>¿Sabías que?</strong> Puedes proteger tu cuenta configurando la autenticación de dos factores en la configuración de su cuenta. Funciona con cualquier aplicación TOTP de su elección, ¡no necesitas número de teléfono!",
|
||||
"onboarding.tips.accounts_from_other_servers": "<strong>¿Sabías que?</strong> Como Mastodon es descentralizado, algunos perfiles que encuentras están alojados en servidores distintos del tuyo. Y sin embargo, ¡puedes interactuar con ellos! ¡Su servidor corresponde a la segunda mitad de su nombre de usuario!",
|
||||
|
@ -665,7 +665,7 @@
|
|||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Cualquiera dentro y fuera de Mastodon",
|
||||
"privacy.public.short": "Público",
|
||||
"privacy.unlisted.additional": "Esto se comporta exactamente igual que el público, excepto que el post no aparecerá en las cronologías en directo o en los hashtags, la exploración o busquedas en Mastodon, incluso si está optado por activar la cuenta de usuario.",
|
||||
"privacy.unlisted.additional": "Esto se comporta exactamente igual que el público, excepto que el post no aparecerá en las cronologías en directo o en las etiquetas, la exploración o busquedas en Mastodon, incluso si está optado por activar la cuenta de usuario.",
|
||||
"privacy.unlisted.long": "Menos fanfares algorítmicos",
|
||||
"privacy.unlisted.short": "Público silencioso",
|
||||
"privacy_policy.last_updated": "Actualizado por última vez {date}",
|
||||
|
@ -699,7 +699,7 @@
|
|||
"report.category.title_account": "perfil",
|
||||
"report.category.title_status": "publicación",
|
||||
"report.close": "Realizado",
|
||||
"report.comment.title": "¿Hay algo más que usted cree que debamos saber?",
|
||||
"report.comment.title": "¿Hay algo más que creas que deberíamos saber?",
|
||||
"report.forward": "Reenviar a {target}",
|
||||
"report.forward_hint": "Esta cuenta es de otro servidor. ¿Enviar una copia anonimizada del informe allí también?",
|
||||
"report.mute": "Silenciar",
|
||||
|
@ -776,9 +776,9 @@
|
|||
"status.admin_status": "Abrir este estado en la interfaz de moderación",
|
||||
"status.block": "Bloquear a @{name}",
|
||||
"status.bookmark": "Añadir marcador",
|
||||
"status.cancel_reblog_private": "Eliminar retoot",
|
||||
"status.cannot_reblog": "Este toot no puede retootearse",
|
||||
"status.continued_thread": "Continuó el hilo",
|
||||
"status.cancel_reblog_private": "Deshacer impulso",
|
||||
"status.cannot_reblog": "Esta publicación no puede ser impulsada",
|
||||
"status.continued_thread": "Hilo continuado",
|
||||
"status.copy": "Copiar enlace al estado",
|
||||
"status.delete": "Borrar",
|
||||
"status.detailed_status": "Vista de conversación detallada",
|
||||
|
@ -803,16 +803,16 @@
|
|||
"status.mute_conversation": "Silenciar conversación",
|
||||
"status.open": "Expandir estado",
|
||||
"status.pin": "Fijar",
|
||||
"status.pinned": "Toot fijado",
|
||||
"status.pinned": "Publicación fijada",
|
||||
"status.read_more": "Leer más",
|
||||
"status.reblog": "Retootear",
|
||||
"status.reblog": "Impulsar",
|
||||
"status.reblog_private": "Implusar a la audiencia original",
|
||||
"status.reblogged_by": "Retooteado por {name}",
|
||||
"status.reblogged_by": "Impulsado por {name}",
|
||||
"status.reblogs": "{count, plural, one {impulso} other {impulsos}}",
|
||||
"status.reblogs.empty": "Nadie retooteó este toot todavía. Cuando alguien lo haga, aparecerá aquí.",
|
||||
"status.reblogs.empty": "Nadie impulsó esta publicación todavía. Cuando alguien lo haga, aparecerá aquí.",
|
||||
"status.redraft": "Borrar y volver a borrador",
|
||||
"status.remove_bookmark": "Eliminar marcador",
|
||||
"status.replied_in_thread": "Respondió en el hilo",
|
||||
"status.replied_in_thread": "Respondido en el hilo",
|
||||
"status.replied_to": "Respondió a {name}",
|
||||
"status.reply": "Responder",
|
||||
"status.replyAll": "Responder al hilo",
|
||||
|
|
|
@ -267,7 +267,7 @@
|
|||
"empty_column.favourites": "Todavía nadie marcó esta publicación como favorita. Cuando alguien lo haga, se mostrarán aquí.",
|
||||
"empty_column.follow_requests": "No tienes ninguna petición de seguidor. Cuando recibas una, se mostrará aquí.",
|
||||
"empty_column.followed_tags": "No has seguido ninguna etiqueta todavía. Cuando lo hagas, se mostrarán aquí.",
|
||||
"empty_column.hashtag": "No hay nada en este hashtag aún.",
|
||||
"empty_column.hashtag": "No hay nada en esta etiqueta todavía.",
|
||||
"empty_column.home": "¡Tu línea temporal está vacía! Sigue a más personas para rellenarla.",
|
||||
"empty_column.list": "Aún no hay nada en esta lista. Cuando los miembros de esta lista publiquen nuevos estados, estos aparecerán aquí.",
|
||||
"empty_column.lists": "No tienes ninguna lista. Cuando crees una, se mostrará aquí.",
|
||||
|
@ -342,7 +342,7 @@
|
|||
"hashtag.column_header.tag_mode.any": "o {additional}",
|
||||
"hashtag.column_header.tag_mode.none": "sin {additional}",
|
||||
"hashtag.column_settings.select.no_options_message": "No se encontraron sugerencias",
|
||||
"hashtag.column_settings.select.placeholder": "Introduzca hashtags…",
|
||||
"hashtag.column_settings.select.placeholder": "Introduce etiquetas…",
|
||||
"hashtag.column_settings.tag_mode.all": "Todos estos",
|
||||
"hashtag.column_settings.tag_mode.any": "Cualquiera de estos",
|
||||
"hashtag.column_settings.tag_mode.none": "Ninguno de estos",
|
||||
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "para retirar el foco de la caja de redacción/búsqueda",
|
||||
"keyboard_shortcuts.up": "para ir hacia arriba en la lista",
|
||||
"lightbox.close": "Cerrar",
|
||||
"lightbox.compress": "Comprimir cuadro de visualización de imagen",
|
||||
"lightbox.expand": "Expandir cuadro de visualización de imagen",
|
||||
"lightbox.next": "Siguiente",
|
||||
"lightbox.previous": "Anterior",
|
||||
"lightbox.zoom_in": "Ampliar al tamaño real",
|
||||
"lightbox.zoom_out": "Ampliar para ajustar",
|
||||
"limited_account_hint.action": "Mostrar perfil de todos modos",
|
||||
"limited_account_hint.title": "Este perfil ha sido ocultado por los moderadores de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
|
@ -637,7 +637,7 @@
|
|||
"onboarding.steps.follow_people.title": "Personaliza tu línea de inicio",
|
||||
"onboarding.steps.publish_status.body": "Di hola al mundo con texto, fotos, vídeos o encuestas {emoji}",
|
||||
"onboarding.steps.publish_status.title": "Escribe tu primera publicación",
|
||||
"onboarding.steps.setup_profile.body": "Aumenta tus interacciones tcompletando tu perfil.",
|
||||
"onboarding.steps.setup_profile.body": "Aumenta tus interacciones con un perfil completo.",
|
||||
"onboarding.steps.setup_profile.title": "Personaliza tu perfil",
|
||||
"onboarding.steps.share_profile.body": "¡Dile a tus amigos cómo encontrarte en Mastodon!",
|
||||
"onboarding.steps.share_profile.title": "Comparte tu perfil de Mastodon",
|
||||
|
|
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Fookus tekstialalt/otsingult ära",
|
||||
"keyboard_shortcuts.up": "Liigu loetelus üles",
|
||||
"lightbox.close": "Sulge",
|
||||
"lightbox.compress": "Suru kokku pildi vaatamise kast",
|
||||
"lightbox.expand": "Laienda pildi vaatamise kast",
|
||||
"lightbox.next": "Järgmine",
|
||||
"lightbox.previous": "Eelmine",
|
||||
"limited_account_hint.action": "Näita profilli sellegipoolest",
|
||||
|
|
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "testua konposatzeko area / bilaketatik fokua kentzea",
|
||||
"keyboard_shortcuts.up": "zerrendan gora mugitzea",
|
||||
"lightbox.close": "Itxi",
|
||||
"lightbox.compress": "Konprimatu irudia ikusteko kaxa",
|
||||
"lightbox.expand": "Zabaldu irudia ikusteko kaxa",
|
||||
"lightbox.next": "Hurrengoa",
|
||||
"lightbox.previous": "Aurrekoa",
|
||||
"limited_account_hint.action": "Erakutsi profila hala ere",
|
||||
|
|
|
@ -422,8 +422,6 @@
|
|||
"keyboard_shortcuts.unfocus": "برداشتن تمرکز از ناحیهٔ نوشتن یا جستوجو",
|
||||
"keyboard_shortcuts.up": "بالا بردن در سیاهه",
|
||||
"lightbox.close": "بستن",
|
||||
"lightbox.compress": "فشردهسازی جعبهٔ نمایش تصویر",
|
||||
"lightbox.expand": "گسترش جعبهٔ نمایش تصویر",
|
||||
"lightbox.next": "بعدی",
|
||||
"lightbox.previous": "قبلی",
|
||||
"limited_account_hint.action": "به هر روی نمایه نشان داده شود",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Poistu kirjoitus- tai hakukentästä",
|
||||
"keyboard_shortcuts.up": "Siirry luettelossa taaksepäin",
|
||||
"lightbox.close": "Sulje",
|
||||
"lightbox.compress": "Tiivis kuvankatselunäkymä",
|
||||
"lightbox.expand": "Laajennettu kuvankatselunäkymä",
|
||||
"lightbox.next": "Seuraava",
|
||||
"lightbox.previous": "Edellinen",
|
||||
"lightbox.zoom_in": "Zoomaa todelliseen kokoon",
|
||||
"lightbox.zoom_out": "Zoomaa mahtumaan",
|
||||
"limited_account_hint.action": "Näytä profiili joka tapauksessa",
|
||||
"limited_account_hint.title": "Palvelimen {domain} moderaattorit ovat piilottaneet tämän profiilin.",
|
||||
"link_preview.author": "Tehnyt {name}",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Tak skrivi-/leiti-økið úr miðdeplinum",
|
||||
"keyboard_shortcuts.up": "Flyt upp á listanum",
|
||||
"lightbox.close": "Lat aftur",
|
||||
"lightbox.compress": "Kroyst myndavísikassa saman",
|
||||
"lightbox.expand": "Víðka myndavísikassa",
|
||||
"lightbox.next": "Fram",
|
||||
"lightbox.previous": "Aftur",
|
||||
"lightbox.zoom_in": "Suma til veruliga stødd",
|
||||
"lightbox.zoom_out": "Suma, so tað passar",
|
||||
"limited_account_hint.action": "Vís vangamynd kortini",
|
||||
"limited_account_hint.title": "Hesin vangin er fjaldur av kjakleiðarunum á {domain}.",
|
||||
"link_preview.author": "Av {name}",
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
"compose_form.publish": "Publier",
|
||||
"compose_form.publish_form": "Publier",
|
||||
"compose_form.reply": "Répondre",
|
||||
"compose_form.save_changes": "Mis à jour",
|
||||
"compose_form.save_changes": "Mettre à jour",
|
||||
"compose_form.spoiler.marked": "Enlever l'avertissement de contenu",
|
||||
"compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu",
|
||||
"compose_form.spoiler_placeholder": "Avertissement de contenu (optionnel)",
|
||||
|
@ -312,7 +312,7 @@
|
|||
"follow_request.authorize": "Autoriser",
|
||||
"follow_request.reject": "Rejeter",
|
||||
"follow_requests.unlocked_explanation": "Même si votre compte n’est pas privé, l’équipe de {domain} a pensé que vous pourriez vouloir peut-être consulter manuellement les demandes d'abonnement de ces comptes.",
|
||||
"follow_suggestions.curated_suggestion": "Choix du staff",
|
||||
"follow_suggestions.curated_suggestion": "Sélectionné par l'équipe",
|
||||
"follow_suggestions.dismiss": "Ne plus afficher",
|
||||
"follow_suggestions.featured_longer": "Sélectionné par l'équipe de {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "Populaire dans le cercle des personnes que vous suivez",
|
||||
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Ne plus se concentrer sur la zone de rédaction/barre de recherche",
|
||||
"keyboard_shortcuts.up": "Monter dans la liste",
|
||||
"lightbox.close": "Fermer",
|
||||
"lightbox.compress": "Compresser la fenêtre de visualisation d'images",
|
||||
"lightbox.expand": "Agrandir la fenêtre de visualisation d'images",
|
||||
"lightbox.next": "Suivant",
|
||||
"lightbox.previous": "Précédent",
|
||||
"limited_account_hint.action": "Afficher le profil quand même",
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
"compose_form.publish": "Publier",
|
||||
"compose_form.publish_form": "Nouvelle publication",
|
||||
"compose_form.reply": "Répondre",
|
||||
"compose_form.save_changes": "Mis à jour",
|
||||
"compose_form.save_changes": "Mettre à jour",
|
||||
"compose_form.spoiler.marked": "Enlever l’avertissement de contenu",
|
||||
"compose_form.spoiler.unmarked": "Ajouter un avertissement de contenu",
|
||||
"compose_form.spoiler_placeholder": "Avertissement de contenu (optionnel)",
|
||||
|
@ -312,7 +312,7 @@
|
|||
"follow_request.authorize": "Accepter",
|
||||
"follow_request.reject": "Rejeter",
|
||||
"follow_requests.unlocked_explanation": "Même si votre compte n’est pas privé, l’équipe de {domain} a pensé que vous pourriez vouloir consulter manuellement les demandes de suivi de ces comptes.",
|
||||
"follow_suggestions.curated_suggestion": "Choix du staff",
|
||||
"follow_suggestions.curated_suggestion": "Sélectionné par l'équipe",
|
||||
"follow_suggestions.dismiss": "Ne plus afficher",
|
||||
"follow_suggestions.featured_longer": "Sélectionné par l'équipe de {domain}",
|
||||
"follow_suggestions.friends_of_friends_longer": "Populaire dans le cercle des personnes que vous suivez",
|
||||
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Quitter la zone de rédaction/barre de recherche",
|
||||
"keyboard_shortcuts.up": "Monter dans la liste",
|
||||
"lightbox.close": "Fermer",
|
||||
"lightbox.compress": "Compresser la fenêtre de visualisation des images",
|
||||
"lightbox.expand": "Agrandir la fenêtre de visualisation des images",
|
||||
"lightbox.next": "Suivant",
|
||||
"lightbox.previous": "Précédent",
|
||||
"limited_account_hint.action": "Afficher le profil quand même",
|
||||
|
|
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Nei boppe yn list ferpleatse",
|
||||
"lightbox.close": "Slute",
|
||||
"lightbox.compress": "Ofbylding passend werjaan",
|
||||
"lightbox.expand": "Ofbylding grut werjaan",
|
||||
"lightbox.next": "Folgjende",
|
||||
"lightbox.previous": "Foarige",
|
||||
"limited_account_hint.action": "Profyl dochs besjen",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Unfocus cum textarea/search",
|
||||
"keyboard_shortcuts.up": "Bog suas ar an liosta",
|
||||
"lightbox.close": "Dún",
|
||||
"lightbox.compress": "Comhbhrúigh an bosca amhairc íomhá",
|
||||
"lightbox.expand": "Leathnaigh an bosca amhairc íomhá",
|
||||
"lightbox.next": "An céad eile",
|
||||
"lightbox.previous": "Roimhe seo",
|
||||
"lightbox.zoom_in": "Súmáil chuig an méid iarbhír",
|
||||
"lightbox.zoom_out": "Súmáil a d'oirfeadh",
|
||||
"limited_account_hint.action": "Taispeáin an phróifíl ar aon nós",
|
||||
"limited_account_hint.title": "Tá an phróifíl seo curtha i bhfolach ag na modhnóra {domain}.",
|
||||
"link_preview.author": "Le {name}",
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
"account.followers.empty": "Chan eil neach sam bith a’ leantainn air a’ chleachdaiche seo fhathast.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} neach-leantainn} other {{counter} luchd-leantainn}}",
|
||||
"account.following": "A’ leantainn",
|
||||
"account.following_counter": "{count, plural, one {Tha {counter} a’ leantainn} other {Tha {counter} a’ leantainn}}",
|
||||
"account.following_counter": "{count, plural, one {A’ leantainn {counter}} other {A’ leantainn {counter}}}",
|
||||
"account.follows.empty": "Chan eil an cleachdaiche seo a’ leantainn neach sam bith fhathast.",
|
||||
"account.go_to_profile": "Tadhail air a’ phròifil",
|
||||
"account.hide_reblogs": "Falaich na brosnachaidhean o @{name}",
|
||||
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Thoir am fòcas far raon teacsa an sgrìobhaidh/an luirg",
|
||||
"keyboard_shortcuts.up": "Gluais suas air an liosta",
|
||||
"lightbox.close": "Dùin",
|
||||
"lightbox.compress": "Co-theannaich bogsa sealladh an deilbh",
|
||||
"lightbox.expand": "Leudaich bogsa sealladh an deilbh",
|
||||
"lightbox.next": "Air adhart",
|
||||
"lightbox.previous": "Air ais",
|
||||
"lightbox.zoom_in": "Sùm dhan fhìor-mheud",
|
||||
"lightbox.zoom_out": "Sùm fèin-obrachail",
|
||||
"limited_account_hint.action": "Seall a’ phròifil co-dhiù",
|
||||
"limited_account_hint.title": "Chaidh a’ phròifil seo fhalach le maoir {domain}.",
|
||||
"link_preview.author": "Le {name}",
|
||||
|
|
|
@ -368,13 +368,13 @@
|
|||
"home.pending_critical_update.link": "Mira as actualizacións",
|
||||
"home.pending_critical_update.title": "Hai una actualización crítica de seguridade!",
|
||||
"home.show_announcements": "Amosar anuncios",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon non pode informar ás usuarias se ignoraches as súas notificacións. Ao ignorar as notificacións non evitarás que as mensaxes sexan enviadas igualmente.",
|
||||
"ignore_notifications_modal.disclaimer": "Mastodon non pode informar ás usuarias de que ignoraches as súas notificacións. Ao ignorar as notificacións non evitarás que as mensaxes sexan enviadas igualmente.",
|
||||
"ignore_notifications_modal.filter_instead": "Filtrar igualmente",
|
||||
"ignore_notifications_modal.filter_to_act_users": "Poderás seguir aceptando, rexeitando e denunciando usuarias",
|
||||
"ignore_notifications_modal.filter_to_avoid_confusion": "Ao filtrar axudas a evitar posibles confusións",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Podes revisar as notificacións filtradas por separado",
|
||||
"ignore_notifications_modal.filter_to_review_separately": "Podes revisar por separado as notificacións filtradas",
|
||||
"ignore_notifications_modal.ignore": "Ignorar notificacións",
|
||||
"ignore_notifications_modal.limited_accounts_title": "Ignorar notificacións desde contas moderadas?",
|
||||
"ignore_notifications_modal.limited_accounts_title": "Ignorar notificacións desde contas limitadas?",
|
||||
"ignore_notifications_modal.new_accounts_title": "Ignorar notificacións desde novas contas?",
|
||||
"ignore_notifications_modal.not_followers_title": "Ignorar notificacións de persoas que non te seguen?",
|
||||
"ignore_notifications_modal.not_following_title": "Ignorar notificacións de persoas que non segues?",
|
||||
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Para deixar de destacar a área de escritura/procura",
|
||||
"keyboard_shortcuts.up": "Para mover cara arriba na listaxe",
|
||||
"lightbox.close": "Fechar",
|
||||
"lightbox.compress": "Comprimir a caixa de vista da imaxe",
|
||||
"lightbox.expand": "Estender a caixa de vista da imaxe",
|
||||
"lightbox.next": "Seguinte",
|
||||
"lightbox.previous": "Anterior",
|
||||
"lightbox.zoom_in": "Ver tamaño real",
|
||||
"lightbox.zoom_out": "Ver tamaño axustado",
|
||||
"limited_account_hint.action": "Mostrar perfil igualmente",
|
||||
"limited_account_hint.title": "Este perfil foi agochado pola moderación de {domain}.",
|
||||
"link_preview.author": "Por {name}",
|
||||
|
@ -463,7 +463,7 @@
|
|||
"mute_modal.hide_options": "Opcións ao ocultar",
|
||||
"mute_modal.indefinite": "Ata que as reactive",
|
||||
"mute_modal.show_options": "Mostrar opcións",
|
||||
"mute_modal.they_can_mention_and_follow": "Pódete mencionar e seguirte, pero non o verás.",
|
||||
"mute_modal.they_can_mention_and_follow": "Pódete mencionar e seguirte, pero non a verás.",
|
||||
"mute_modal.they_wont_know": "Non saberá que a acalaches.",
|
||||
"mute_modal.title": "Acalar usuaria?",
|
||||
"mute_modal.you_wont_see_mentions": "Non verás as publicacións que a mencionen.",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "לצאת מתיבת חיבור/חיפוש",
|
||||
"keyboard_shortcuts.up": "לנוע במעלה הרשימה",
|
||||
"lightbox.close": "סגירה",
|
||||
"lightbox.compress": "דחיסת קופסת צפייה בתמונה",
|
||||
"lightbox.expand": "הרחבת קופסת צפייה בתמונה",
|
||||
"lightbox.next": "הבא",
|
||||
"lightbox.previous": "הקודם",
|
||||
"lightbox.zoom_in": "הגדלה לגודל מלא",
|
||||
"lightbox.zoom_out": "התאמה לגודל המסך",
|
||||
"limited_account_hint.action": "הצג חשבון בכל זאת",
|
||||
"limited_account_hint.title": "פרופיל המשתמש הזה הוסתר על ידי המנחים של {domain}.",
|
||||
"link_preview.author": "מאת {name}",
|
||||
|
@ -787,6 +787,7 @@
|
|||
"status.edit": "עריכה",
|
||||
"status.edited": "נערך לאחרונה {date}",
|
||||
"status.edited_x_times": "נערך {count, plural, one {פעם {count}} other {{count} פעמים}}",
|
||||
"status.embed": "העתקת קוד להטמעה",
|
||||
"status.favourite": "חיבוב",
|
||||
"status.favourites": "{count, plural, one {חיבוב אחד} two {זוג חיבובים} other {# חיבובים}}",
|
||||
"status.filter": "סנן הודעה זו",
|
||||
|
|
|
@ -349,8 +349,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "बंद करें",
|
||||
"lightbox.compress": "कंप्रेस इमेज व्यू बॉक्स",
|
||||
"lightbox.expand": "एक्सपैंड इमेज व्यू बॉक्स",
|
||||
"lightbox.next": "अगला",
|
||||
"lightbox.previous": "पिछला",
|
||||
"limited_account_hint.action": "फिर भी प्रोफाइल दिखाओ",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Szerkesztés/keresés fókuszból való kivétele",
|
||||
"keyboard_shortcuts.up": "Mozgás felfelé a listában",
|
||||
"lightbox.close": "Bezárás",
|
||||
"lightbox.compress": "Képnéző doboz összezárása",
|
||||
"lightbox.expand": "Képnéző doboz kinyitása",
|
||||
"lightbox.next": "Következő",
|
||||
"lightbox.previous": "Előző",
|
||||
"lightbox.zoom_in": "Nagyítás a tényleges méretre",
|
||||
"lightbox.zoom_out": "Méretre igazítás",
|
||||
"limited_account_hint.action": "Profil megjelenítése mindenképpen",
|
||||
"limited_account_hint.title": "Ezt a profilt {domain} moderátorai elrejtették.",
|
||||
"link_preview.author": "{name} szerint",
|
||||
|
|
|
@ -271,8 +271,6 @@
|
|||
"keyboard_shortcuts.unfocus": "տեքստի/որոնման տիրոյթից ապասեւեռուելու համար",
|
||||
"keyboard_shortcuts.up": "ցանկով վերեւ շարժուելու համար",
|
||||
"lightbox.close": "Փակել",
|
||||
"lightbox.compress": "Փակել պատկերի դիտման պատուհանը",
|
||||
"lightbox.expand": "Բացել պատկերի դիտման պատուհանը",
|
||||
"lightbox.next": "Յաջորդ",
|
||||
"lightbox.previous": "Նախորդ",
|
||||
"lists.account.add": "Աւելացնել ցանկին",
|
||||
|
|
|
@ -423,8 +423,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Disfocalisar le area de composition de texto/de recerca",
|
||||
"keyboard_shortcuts.up": "Displaciar in alto in le lista",
|
||||
"lightbox.close": "Clauder",
|
||||
"lightbox.compress": "Comprimer le quadro de visualisation de imagine",
|
||||
"lightbox.expand": "Expander le quadro de visualisation de imagine",
|
||||
"lightbox.next": "Sequente",
|
||||
"lightbox.previous": "Precedente",
|
||||
"limited_account_hint.action": "Monstrar profilo in omne caso",
|
||||
|
|
|
@ -381,8 +381,6 @@
|
|||
"keyboard_shortcuts.unfocus": "untuk tidak fokus pada area teks/pencarian",
|
||||
"keyboard_shortcuts.up": "untuk memindah ke atas pada daftar",
|
||||
"lightbox.close": "Tutup",
|
||||
"lightbox.compress": "Kompres kotak tampilan gambar",
|
||||
"lightbox.expand": "Besarkan kotak tampilan gambar",
|
||||
"lightbox.next": "Selanjutnya",
|
||||
"lightbox.previous": "Sebelumnya",
|
||||
"limited_account_hint.action": "Tetap tampilkan profil",
|
||||
|
|
|
@ -396,8 +396,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Desinfocar text-area de composition/serchar",
|
||||
"keyboard_shortcuts.up": "Mover ad-supra in li liste",
|
||||
"lightbox.close": "Cluder",
|
||||
"lightbox.compress": "Compresser vise-buxe de image",
|
||||
"lightbox.expand": "Expander vise-buxe de image",
|
||||
"lightbox.next": "Sequent",
|
||||
"lightbox.previous": "Precedent",
|
||||
"limited_account_hint.action": "Monstrar profil totvez",
|
||||
|
|
|
@ -339,8 +339,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "Klozar",
|
||||
"lightbox.compress": "Kompresez imajvidbuxo",
|
||||
"lightbox.expand": "Expansez imajvidbuxo",
|
||||
"lightbox.next": "Nexta",
|
||||
"lightbox.previous": "Antea",
|
||||
"limited_account_hint.action": "Jus montrez profilo",
|
||||
|
|
|
@ -432,8 +432,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Taka virkni úr textainnsetningarreit eða leit",
|
||||
"keyboard_shortcuts.up": "Fara ofar í listanum",
|
||||
"lightbox.close": "Loka",
|
||||
"lightbox.compress": "Þjappa myndskoðunarreit",
|
||||
"lightbox.expand": "Fletta út myndskoðunarreit",
|
||||
"lightbox.next": "Næsta",
|
||||
"lightbox.previous": "Fyrra",
|
||||
"limited_account_hint.action": "Birta notandasniðið samt",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Rimuove il focus sull'area di composizione testuale/ricerca",
|
||||
"keyboard_shortcuts.up": "Scorre in su nell'elenco",
|
||||
"lightbox.close": "Chiudi",
|
||||
"lightbox.compress": "Comprimi casella di visualizzazione immagine",
|
||||
"lightbox.expand": "Espandi casella di visualizzazione immagine",
|
||||
"lightbox.next": "Successivo",
|
||||
"lightbox.previous": "Precedente",
|
||||
"lightbox.zoom_in": "Ingrandisci alla dimensione attuale",
|
||||
"lightbox.zoom_out": "Ingrandisci per adattarsi",
|
||||
"limited_account_hint.action": "Mostra comunque il profilo",
|
||||
"limited_account_hint.title": "Questo profilo è stato nascosto dai moderatori di {domain}.",
|
||||
"link_preview.author": "Di {name}",
|
||||
|
|
|
@ -528,10 +528,10 @@
|
|||
"keyboard_shortcuts.unfocus": "投稿の入力欄・検索欄から離れる",
|
||||
"keyboard_shortcuts.up": "カラム内一つ上に移動",
|
||||
"lightbox.close": "閉じる",
|
||||
"lightbox.compress": "画像ビューボックスを閉じる",
|
||||
"lightbox.expand": "画像ビューボックスを開く",
|
||||
"lightbox.next": "次",
|
||||
"lightbox.previous": "前",
|
||||
"lightbox.zoom_in": "実際のサイズにする",
|
||||
"lightbox.zoom_out": "表示範囲に合わせる",
|
||||
"limited_account_hint.action": "構わず表示する",
|
||||
"limited_account_hint.title": "このプロフィールは{domain}のモデレーターによって非表示にされています。",
|
||||
"link_preview.author": "{name}",
|
||||
|
@ -555,6 +555,7 @@
|
|||
"lists.subheading": "あなたのリスト",
|
||||
"load_pending": "{count}件の新着",
|
||||
"loading_indicator.label": "読み込み中…",
|
||||
"media_gallery.hide": "隠す",
|
||||
"moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。",
|
||||
"mute_modal.hide_from_notifications": "通知をオフにする",
|
||||
"mute_modal.hide_options": "オプションを閉じる",
|
||||
|
@ -928,6 +929,7 @@
|
|||
"status.edit": "編集",
|
||||
"status.edited": "最終更新日 {date}",
|
||||
"status.edited_x_times": "{count}回編集",
|
||||
"status.embed": "埋め込みコードを取得",
|
||||
"status.emoji_reaction": "絵文字リアクション",
|
||||
"status.emoji_reaction.pick": "絵文字を追加する",
|
||||
"status.emoji_reactions": "{count, plural, one {絵文字} other {絵文字}}",
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
"about.blocks": "Ulac agbur",
|
||||
"about.contact": "Anermis:",
|
||||
"about.disclaimer": "Mastodon d aseɣẓan ilelli, d aseɣẓan n uɣbalu yeldin, d tnezzut n Mastodon gGmbH.",
|
||||
"about.domain_blocks.no_reason_available": "Ulac taɣẓint",
|
||||
"about.domain_blocks.preamble": "Maṣṭudun s umata yeḍmen-ak ad teẓreḍ agbur, ad tesdemreḍ akked yimseqdacen-nniḍen seg yal aqeddac deg fedivers. Ha-tent-an ɣur-k tsuraf i yellan deg uqeddac-agi.",
|
||||
"about.domain_blocks.silenced.title": "Ɣur-s talast",
|
||||
"about.domain_blocks.suspended.title": "Yeḥbes",
|
||||
"about.not_available": "Talɣut-a ur tettwabder ara deg uqeddac-a.",
|
||||
"about.powered_by": "Azeṭṭa inmetti yettwasɣelsen sɣur {mastodon}",
|
||||
"about.rules": "Ilugan n uqeddac",
|
||||
"account.account_note_header": "Tamawt tudmawant",
|
||||
"account.add_or_remove_from_list": "Rnu neɣ kkes seg tebdarin",
|
||||
"account.badges.bot": "Aṛubut",
|
||||
"account.badges.group": "Agraw",
|
||||
|
@ -46,6 +48,7 @@
|
|||
"account.mute_notifications_short": "Susem alɣuten",
|
||||
"account.mute_short": "Sgugem",
|
||||
"account.muted": "Yettwasgugem",
|
||||
"account.mutual": "Temṭafarem",
|
||||
"account.no_bio": "Ulac aglam i d-yettunefken.",
|
||||
"account.open_original_page": "Ldi asebter anasli",
|
||||
"account.posts": "Tisuffaɣ",
|
||||
|
@ -62,6 +65,7 @@
|
|||
"account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
|
||||
"account.unfollow": "Ur ṭṭafaṛ ara",
|
||||
"account.unmute": "Kkes asgugem ɣef @{name}",
|
||||
"account.unmute_notifications_short": "Serreḥ i yilɣa",
|
||||
"account.unmute_short": "Kkes asgugem",
|
||||
"account_note.placeholder": "Ulac iwenniten",
|
||||
"admin.dashboard.retention.cohort_size": "Iseqdacen imaynuten",
|
||||
|
@ -78,6 +82,7 @@
|
|||
"block_modal.title": "Sewḥel aseqdac ?",
|
||||
"block_modal.you_wont_see_mentions": "Ur tezmireḍ ara ad twaliḍ tisuffaɣ anda d-yettwabdar.",
|
||||
"boost_modal.combo": "Tzemreḍ ad tsiteḍ ɣef {combo} akken ad tzegleḍ aya tikelt i d-iteddun",
|
||||
"boost_modal.reblog": "Zuzer tasuffeɣt?",
|
||||
"bundle_column_error.copy_stacktrace": "Nɣel tuccḍa n uneqqis",
|
||||
"bundle_column_error.error.title": "Uh, ala !",
|
||||
"bundle_column_error.network.title": "Tuccḍa deg uẓeṭṭa",
|
||||
|
@ -152,6 +157,7 @@
|
|||
"confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreḍ akka tura. Tetḥeqqeḍ tebɣiḍ ad tkemmleḍ?",
|
||||
"confirmations.logout.confirm": "Ffeɣ",
|
||||
"confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?",
|
||||
"confirmations.logout.title": "Tebɣiḍ ad teffɣeḍ ssya?",
|
||||
"confirmations.mute.confirm": "Sgugem",
|
||||
"confirmations.redraft.confirm": "Kkes sakin ɛiwed tira",
|
||||
"confirmations.reply.confirm": "Err",
|
||||
|
@ -185,7 +191,7 @@
|
|||
"domain_pill.server": "Aqeddac",
|
||||
"domain_pill.username": "Isem n useqdac",
|
||||
"domain_pill.your_server": "D axxam-inek·inem umḍin, anda i zedɣent akk tsuffaɣ-ik·im. Ur k·m-yeεǧib ara wa? Ssenfel-d iqeddacen melmi i ak·m-yehwa, awi-d daɣen ineḍfaren-ik·im yid-k·m.",
|
||||
"embed.instructions": "Ẓẓu addad-agi deg usmel-inek s wenγal n tangalt yellan sdaw-agi.",
|
||||
"embed.instructions": "Ẓẓu addad-agi deg usmel-inek·inem s wenɣal n tangalt yellan sdaw-agi.",
|
||||
"embed.preview": "Akka ara d-iban:",
|
||||
"emoji_button.activity": "Aqeddic",
|
||||
"emoji_button.clear": "Sfeḍ",
|
||||
|
@ -327,8 +333,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "i tulin ɣer d asawen n tebdart",
|
||||
"lightbox.close": "Mdel",
|
||||
"lightbox.compress": "Ḥemmeẓ tamnaḍt n uskan n tugna",
|
||||
"lightbox.expand": "Simeɣer tamnaḍt n uskan n tugna",
|
||||
"lightbox.next": "Ɣer zdat",
|
||||
"lightbox.previous": "Ɣer deffir",
|
||||
"limited_account_hint.action": "Wali amaɣnu akken yebɣu yili",
|
||||
|
@ -351,6 +355,7 @@
|
|||
"lists.subheading": "Tibdarin-ik·im",
|
||||
"load_pending": "{count, plural, one {# n uferdis amaynut} other {# n yiferdisen imaynuten}}",
|
||||
"loading_indicator.label": "Yessalay-d …",
|
||||
"media_gallery.hide": "Seggelmes",
|
||||
"mute_modal.hide_from_notifications": "Ffer-it deg ulɣuten",
|
||||
"mute_modal.hide_options": "Ffer tinefrunin",
|
||||
"mute_modal.indefinite": "Alamma ssnesreɣ asgugem fell-as",
|
||||
|
@ -405,6 +410,7 @@
|
|||
"notification.status": "{name} akken i d-yessufeɣ",
|
||||
"notification_requests.accept": "Qbel",
|
||||
"notification_requests.dismiss": "Agi",
|
||||
"notification_requests.edit_selection": "Ẓreg",
|
||||
"notification_requests.exit_selection": "Immed",
|
||||
"notification_requests.notifications_from": "Alɣuten sɣur {name}",
|
||||
"notifications.clear": "Sfeḍ alɣuten",
|
||||
|
@ -583,6 +589,7 @@
|
|||
"status.direct_indicator": "Abdar uslig",
|
||||
"status.edit": "Ẓreg",
|
||||
"status.edited_x_times": "Tettwaẓreg {count, plural, one {{count} n tikkelt} other {{count} n tikkal}}",
|
||||
"status.embed": "Awi-d tangalt n weslaɣ",
|
||||
"status.favourite": "Amenyaf",
|
||||
"status.favourites": "{count, plural, one {n usmenyaf} other {n ismenyafen}}",
|
||||
"status.filter": "Sizdeg tassufeɣt-a",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "작성창에서 포커스 해제",
|
||||
"keyboard_shortcuts.up": "리스트에서 위로 이동",
|
||||
"lightbox.close": "닫기",
|
||||
"lightbox.compress": "이미지 박스 압축",
|
||||
"lightbox.expand": "이미지 박스 확장",
|
||||
"lightbox.next": "다음",
|
||||
"lightbox.previous": "이전",
|
||||
"lightbox.zoom_in": "실제 크기에 맞춰 보기",
|
||||
"lightbox.zoom_out": "화면 크기에 맞춰 보기",
|
||||
"limited_account_hint.action": "그래도 프로필 보기",
|
||||
"limited_account_hint.title": "이 프로필은 {domain}의 중재자에 의해 숨겨진 상태입니다.",
|
||||
"link_preview.author": "{name}",
|
||||
|
@ -778,6 +778,7 @@
|
|||
"status.bookmark": "북마크",
|
||||
"status.cancel_reblog_private": "부스트 취소",
|
||||
"status.cannot_reblog": "이 게시물은 부스트 할 수 없습니다",
|
||||
"status.continued_thread": "이어지는 글타래",
|
||||
"status.copy": "게시물 링크 복사",
|
||||
"status.delete": "삭제",
|
||||
"status.detailed_status": "대화 자세히 보기",
|
||||
|
@ -786,6 +787,7 @@
|
|||
"status.edit": "수정",
|
||||
"status.edited": "{date}에 마지막으로 편집됨",
|
||||
"status.edited_x_times": "{count, plural, other {{count}}} 번 수정됨",
|
||||
"status.embed": "임베드 코드 받기",
|
||||
"status.favourite": "좋아요",
|
||||
"status.favourites": "{count, plural, other {좋아요}}",
|
||||
"status.filter": "이 게시물을 필터",
|
||||
|
@ -810,6 +812,7 @@
|
|||
"status.reblogs.empty": "아직 아무도 이 게시물을 부스트하지 않았습니다. 부스트 한 사람들이 여기에 표시 됩니다.",
|
||||
"status.redraft": "지우고 다시 쓰기",
|
||||
"status.remove_bookmark": "북마크 삭제",
|
||||
"status.replied_in_thread": "글타래에 답장",
|
||||
"status.replied_to": "{name} 님에게",
|
||||
"status.reply": "답장",
|
||||
"status.replyAll": "글타래에 답장",
|
||||
|
|
|
@ -293,8 +293,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Bal nede cîhê nivîsê /lêgerînê",
|
||||
"keyboard_shortcuts.up": "Di lîsteyê de rake jor",
|
||||
"lightbox.close": "Bigire",
|
||||
"lightbox.compress": "Qutîya wêneya nîşan dike bitepisîne",
|
||||
"lightbox.expand": "Qutîya wêneya nîşan dike fireh bike",
|
||||
"lightbox.next": "Pêş",
|
||||
"lightbox.previous": "Paş",
|
||||
"limited_account_hint.action": "Bi heman awayî profîlê nîşan bide",
|
||||
|
|
|
@ -195,8 +195,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Anfogella tekstva gomposya/hwilas",
|
||||
"keyboard_shortcuts.up": "Movya war-vann y'n rol",
|
||||
"lightbox.close": "Degea",
|
||||
"lightbox.compress": "Kula kist a weles aven",
|
||||
"lightbox.expand": "Efani kist a weles aven",
|
||||
"lightbox.next": "Nessa",
|
||||
"lightbox.previous": "Kynsa",
|
||||
"lists.account.add": "Keworra dhe rol",
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
"account.follow_back": "Sige tamyen",
|
||||
"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 dingun.",
|
||||
"account.go_to_profile": "Va al profil",
|
||||
"account.hide_reblogs": "Eskonde repartajasyones de @{name}",
|
||||
|
@ -60,6 +62,7 @@
|
|||
"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 a @{name}",
|
||||
"account.unblock_domain": "Dezbloka domeno {domain}",
|
||||
"account.unblock_short": "Dezbloka",
|
||||
|
@ -393,8 +396,6 @@
|
|||
"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",
|
||||
|
@ -418,6 +419,7 @@
|
|||
"lists.subheading": "Tus listas",
|
||||
"load_pending": "{count, plural, one {# muevo elemento} other {# muevos elementos}}",
|
||||
"loading_indicator.label": "Eskargando…",
|
||||
"media_gallery.hide": "Eskonde",
|
||||
"moved_to_account_banner.text": "Tu kuento {disabledAccount} esta aktualmente inkapasitado porke transferates a {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Eskonde de avizos",
|
||||
"mute_modal.hide_options": "Eskonde opsyones",
|
||||
|
|
|
@ -432,10 +432,10 @@
|
|||
"keyboard_shortcuts.unfocus": "Nebefokusuoti rengykles teksto sritį / paiešką",
|
||||
"keyboard_shortcuts.up": "Perkelti į viršų sąraše",
|
||||
"lightbox.close": "Uždaryti",
|
||||
"lightbox.compress": "Suspausti vaizdo peržiūros langelį",
|
||||
"lightbox.expand": "Išplėsti vaizdo peržiūros langelį",
|
||||
"lightbox.next": "Kitas",
|
||||
"lightbox.previous": "Ankstesnis",
|
||||
"lightbox.zoom_in": "Padidink iki tikrojo dydžio",
|
||||
"lightbox.zoom_out": "Padidink, kad tilptų",
|
||||
"limited_account_hint.action": "Vis tiek rodyti profilį",
|
||||
"limited_account_hint.title": "Šį profilį paslėpė {domain} prižiūrėtojai.",
|
||||
"link_preview.author": "Sukūrė {name}",
|
||||
|
|
|
@ -385,8 +385,6 @@
|
|||
"keyboard_shortcuts.unfocus": "Atfokusēt veidojamā teksta/meklēšanas lauku",
|
||||
"keyboard_shortcuts.up": "Pārvietoties augšup sarakstā",
|
||||
"lightbox.close": "Aizvērt",
|
||||
"lightbox.compress": "Saspiest attēla skata lodziņu",
|
||||
"lightbox.expand": "Izvērst attēla skata lodziņu",
|
||||
"lightbox.next": "Tālāk",
|
||||
"lightbox.previous": "Iepriekšējais",
|
||||
"limited_account_hint.action": "Tik un tā rādīt profilu",
|
||||
|
@ -409,6 +407,7 @@
|
|||
"lists.subheading": "Tavi saraksti",
|
||||
"load_pending": "{count, plural, one {# jauna lieta} other {# jaunas lietas}}",
|
||||
"loading_indicator.label": "Ielādē…",
|
||||
"media_gallery.hide": "Paslēpt",
|
||||
"moved_to_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots, jo Tu pārcēlies uz kontu {movedToAccount}.",
|
||||
"mute_modal.hide_from_notifications": "Paslēpt paziņojumos",
|
||||
"mute_modal.hide_options": "Paslēpt iespējas",
|
||||
|
|
|
@ -169,8 +169,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "बंद करा",
|
||||
"lightbox.compress": "प्रतिमा दृश्य बॉक्स कॉम्प्रेस करा",
|
||||
"lightbox.expand": "प्रतिमा दृश्य बॉक्स विस्तृत करा",
|
||||
"lightbox.next": "पुढे",
|
||||
"lightbox.previous": "मागील",
|
||||
"limited_account_hint.action": "तरीही प्रोफाइल दाखवा",
|
||||
|
|
|
@ -360,8 +360,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "Pindah ke atas dalam senarai",
|
||||
"lightbox.close": "Tutup",
|
||||
"lightbox.compress": "Kecilkan kotak paparan imej",
|
||||
"lightbox.expand": "Besarkan kotak paparan imej",
|
||||
"lightbox.next": "Seterusnya",
|
||||
"lightbox.previous": "Sebelumnya",
|
||||
"limited_account_hint.action": "Paparkan profil",
|
||||
|
|
|
@ -339,8 +339,6 @@
|
|||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "ပိတ်ပါ",
|
||||
"lightbox.compress": "ရုပ်ပုံမြင်ကွင်းအကွက်ကို ချုံ့ပါ",
|
||||
"lightbox.expand": "ပုံကိုဖွင့်ပါ",
|
||||
"lightbox.next": "ရှေ့သို့",
|
||||
"lightbox.previous": "ရှေ့သို့",
|
||||
"limited_account_hint.action": "ဘာပဲဖြစ်ဖြစ် ပရိုဖိုင်ကို ပြပါ",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue