Compare commits
98 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
35b84985a8 | ||
|
d41f0b66cc | ||
|
921b781909 | ||
|
6f5c0afe93 | ||
|
eec6095e02 | ||
|
9f04b0d4b1 | ||
|
628358aeea | ||
|
c235711ffe | ||
|
ff6ca8bdc6 | ||
|
dbda87c31f | ||
|
e4a241abef | ||
|
93555182c3 | ||
|
0eff42d688 | ||
|
1d92b90be9 | ||
|
da809f9eec | ||
|
c4d36d024c | ||
|
9e97fbf0af | ||
|
10f6793fd0 | ||
|
a594139115 | ||
|
95bd85d9e8 | ||
|
8d51ce4290 | ||
|
06636c6eca | ||
|
e9822a4e4e | ||
|
9a61b0ef22 | ||
|
d872902997 | ||
|
5ec25ff3e1 | ||
|
49e296e1b0 | ||
|
7347d4f8bb | ||
|
7571c37c99 | ||
|
3c18964256 | ||
|
c61dd918a2 | ||
|
02ba03d6db | ||
|
3bee0996c5 | ||
|
89daeb43a8 | ||
|
7d4f4f9aab | ||
|
256c2b1de0 | ||
|
02e3e1ec09 | ||
|
ff924f95bb | ||
|
c10f4bdb03 | ||
|
d907d4352e | ||
|
a8b51124ba | ||
|
161c72d66d | ||
|
53d99ebf4f | ||
|
1001922156 | ||
|
99f962ba73 | ||
|
2471796d75 | ||
|
545095b3ce | ||
|
d319b3dbe4 | ||
|
d60fd87e01 | ||
|
94230fe565 | ||
|
04ecf44c2f | ||
|
b6af88192f | ||
|
1419f656e2 | ||
|
3ba7cde38d | ||
|
ce854ed506 | ||
|
21b9da6418 | ||
|
764f876953 | ||
|
2c1ed5f872 | ||
|
7d376e41be | ||
|
f4b80e6511 | ||
|
a56c4742d3 | ||
|
38fc1b498d | ||
|
511c6f9625 | ||
|
868568d1c1 | ||
|
65f30f65a2 | ||
|
e0ef7f9d79 | ||
|
127bfda521 | ||
|
1494509468 | ||
|
1e5d1fa5c8 | ||
|
a3b369337f | ||
|
43c37a4768 | ||
|
cafe27fb29 | ||
|
7e6214b869 | ||
|
a8eb0bf44f | ||
|
35fdf561be | ||
|
081956742c | ||
|
8528fd89d2 | ||
|
9592b5e31e | ||
|
cea98e0c12 | ||
|
6eb60260b1 | ||
|
81d29e4126 | ||
|
c11a52d888 | ||
|
e52293482e | ||
|
f38e6a14f2 | ||
|
a434d9c0cc | ||
|
a29432f0cd | ||
|
098c7d27fe | ||
|
3d3b403359 | ||
|
25b0d7538e | ||
|
a3b2ea599d | ||
|
573414f728 | ||
|
aa273a2718 | ||
|
0d3ffa691e | ||
|
5ad45552b3 | ||
|
dc313f27bb | ||
|
7cad926401 | ||
|
3487460f00 | ||
|
72314d26ae |
@@ -11,10 +11,11 @@ DB_PASS=
|
||||
DB_PORT=5432
|
||||
|
||||
# Federation
|
||||
# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects.
|
||||
# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation.
|
||||
# LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com.
|
||||
LOCAL_DOMAIN=example.com
|
||||
LOCAL_HTTPS=true
|
||||
|
||||
# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links)
|
||||
|
||||
# Use this only if you need to run mastodon on a different domain than the one used for federation.
|
||||
# You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md
|
||||
|
3
Gemfile
3
Gemfile
@@ -28,7 +28,7 @@ gem 'browser'
|
||||
gem 'charlock_holmes', '~> 0.7.5'
|
||||
gem 'iso-639'
|
||||
gem 'cld3', '~> 3.2.0'
|
||||
gem 'devise', '~> 4.2'
|
||||
gem 'devise', '~> 4.3'
|
||||
gem 'devise-two-factor', '~> 3.0'
|
||||
gem 'doorkeeper', '~> 4.2'
|
||||
gem 'fast_blank', '~> 1.0'
|
||||
@@ -58,6 +58,7 @@ gem 'redis', '~> 3.3', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||
gem 'rqrcode', '~> 0.10'
|
||||
gem 'ruby-oembed', '~> 0.12', require: 'oembed'
|
||||
gem 'ruby-progressbar', '~> 1.4'
|
||||
gem 'sanitize', '~> 4.4'
|
||||
gem 'sidekiq', '~> 5.0'
|
||||
gem 'sidekiq-scheduler', '~> 2.1'
|
||||
|
@@ -299,13 +299,11 @@ GEM
|
||||
sidekiq (>= 3.5.0)
|
||||
statsd-ruby (~> 1.2.0)
|
||||
oj (3.3.9)
|
||||
openssl (2.0.6)
|
||||
orm_adapter (0.5.0)
|
||||
ostatus2 (2.0.1)
|
||||
ostatus2 (2.0.2)
|
||||
addressable (~> 2.4)
|
||||
http (~> 2.0)
|
||||
nokogiri (~> 1.6)
|
||||
openssl (~> 2.0)
|
||||
ox (2.8.2)
|
||||
paperclip (5.1.0)
|
||||
activemodel (>= 4.2.0)
|
||||
@@ -561,7 +559,7 @@ DEPENDENCIES
|
||||
charlock_holmes (~> 0.7.5)
|
||||
cld3 (~> 3.2.0)
|
||||
climate_control (~> 0.2)
|
||||
devise (~> 4.2)
|
||||
devise (~> 4.3)
|
||||
devise-two-factor (~> 3.0)
|
||||
doorkeeper (~> 4.2)
|
||||
dotenv-rails (~> 2.2)
|
||||
@@ -621,6 +619,7 @@ DEPENDENCIES
|
||||
rspec-sidekiq (~> 3.0)
|
||||
rubocop
|
||||
ruby-oembed (~> 0.12)
|
||||
ruby-progressbar (~> 1.4)
|
||||
sanitize (~> 4.4)
|
||||
scss_lint (~> 0.55)
|
||||
sidekiq (~> 5.0)
|
||||
@@ -643,4 +642,4 @@ RUBY VERSION
|
||||
ruby 2.4.2p198
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.0
|
||||
1.16.1
|
||||
|
@@ -2,7 +2,8 @@
|
||||
|
||||
class AccountsController < ApplicationController
|
||||
include AccountControllerConcern
|
||||
include SignatureVerification
|
||||
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
@@ -26,10 +27,11 @@ class AccountsController < ApplicationController
|
||||
end
|
||||
|
||||
format.json do
|
||||
render json: @account,
|
||||
serializer: ActivityPub::ActorSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
skip_session!
|
||||
|
||||
render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do
|
||||
ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -3,6 +3,7 @@
|
||||
module Admin
|
||||
class CustomEmojisController < BaseController
|
||||
before_action :set_custom_emoji, except: [:index, :new, :create]
|
||||
before_action :set_filter_params
|
||||
|
||||
def index
|
||||
authorize :custom_emoji, :index?
|
||||
@@ -32,23 +33,26 @@ module Admin
|
||||
|
||||
if @custom_emoji.update(resource_params)
|
||||
log_action :update, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.updated_msg')
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.updated_msg')
|
||||
else
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.update_failed_msg')
|
||||
flash[:alert] = I18n.t('admin.custom_emojis.update_failed_msg')
|
||||
end
|
||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @custom_emoji, :destroy?
|
||||
@custom_emoji.destroy!
|
||||
log_action :destroy, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.destroyed_msg')
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.destroyed_msg')
|
||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
||||
end
|
||||
|
||||
def copy
|
||||
authorize @custom_emoji, :copy?
|
||||
|
||||
emoji = CustomEmoji.find_or_initialize_by(domain: nil, shortcode: @custom_emoji.shortcode)
|
||||
emoji = CustomEmoji.find_or_initialize_by(domain: nil,
|
||||
shortcode: @custom_emoji.shortcode)
|
||||
emoji.image = @custom_emoji.image
|
||||
|
||||
if emoji.save
|
||||
@@ -58,21 +62,23 @@ module Admin
|
||||
flash[:alert] = I18n.t('admin.custom_emojis.copy_failed_msg')
|
||||
end
|
||||
|
||||
redirect_to admin_custom_emojis_path(page: params[:page])
|
||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
||||
end
|
||||
|
||||
def enable
|
||||
authorize @custom_emoji, :enable?
|
||||
@custom_emoji.update!(disabled: false)
|
||||
log_action :enable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.enabled_msg')
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.enabled_msg')
|
||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
||||
end
|
||||
|
||||
def disable
|
||||
authorize @custom_emoji, :disable?
|
||||
@custom_emoji.update!(disabled: true)
|
||||
log_action :disable, @custom_emoji
|
||||
redirect_to admin_custom_emojis_path, notice: I18n.t('admin.custom_emojis.disabled_msg')
|
||||
flash[:notice] = I18n.t('admin.custom_emojis.disabled_msg')
|
||||
redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params)
|
||||
end
|
||||
|
||||
private
|
||||
@@ -81,6 +87,10 @@ module Admin
|
||||
@custom_emoji = CustomEmoji.find(params[:id])
|
||||
end
|
||||
|
||||
def set_filter_params
|
||||
@filter_params = filter_params.to_hash.symbolize_keys
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params.require(:custom_emoji).permit(:shortcode, :image, :visible_in_picker)
|
||||
end
|
||||
|
@@ -17,6 +17,8 @@ module Admin
|
||||
bootstrap_timeline_accounts
|
||||
thumbnail
|
||||
min_invite_role
|
||||
activity_api_enabled
|
||||
peers_api_enabled
|
||||
).freeze
|
||||
|
||||
BOOLEAN_SETTINGS = %w(
|
||||
@@ -24,6 +26,8 @@ module Admin
|
||||
open_deletion
|
||||
timeline_preview
|
||||
show_staff_badge
|
||||
activity_api_enabled
|
||||
peers_api_enabled
|
||||
).freeze
|
||||
|
||||
UPLOAD_SETTINGS = %w(
|
||||
|
@@ -6,8 +6,8 @@ class Api::BaseController < ApplicationController
|
||||
|
||||
include RateLimitHeaders
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
skip_before_action :store_current_location
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
|
||||
render json: { error: e.to_s }, status: 422
|
||||
|
36
app/controllers/api/v1/instances/activity_controller.rb
Normal file
36
app/controllers/api/v1/instances/activity_controller.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Instances::ActivityController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
respond_to :json
|
||||
|
||||
def show
|
||||
render_cached_json('api:v1:instances:activity:show', expires_in: 1.day) { activity }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def activity
|
||||
weeks = []
|
||||
|
||||
12.times do |i|
|
||||
day = i.weeks.ago.to_date
|
||||
week_id = day.cweek
|
||||
week = Date.commercial(day.cwyear, week_id)
|
||||
|
||||
weeks << {
|
||||
week: week.to_time.to_i.to_s,
|
||||
statuses: Redis.current.get("activity:statuses:local:#{week_id}") || '0',
|
||||
logins: Redis.current.pfcount("activity:logins:#{week_id}").to_s,
|
||||
registrations: Redis.current.get("activity:accounts:local:#{week_id}") || '0',
|
||||
}
|
||||
end
|
||||
|
||||
weeks
|
||||
end
|
||||
|
||||
def require_enabled_api!
|
||||
head 404 unless Setting.activity_api_enabled
|
||||
end
|
||||
end
|
17
app/controllers/api/v1/instances/peers_controller.rb
Normal file
17
app/controllers/api/v1/instances/peers_controller.rb
Normal file
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Instances::PeersController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
render_cached_json('api:v1:instances:peers:index', expires_in: 1.day) { Account.remote.domains }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_enabled_api!
|
||||
head 404 unless Setting.peers_api_enabled
|
||||
end
|
||||
end
|
@@ -30,7 +30,7 @@ class ApplicationController < ActionController::Base
|
||||
private
|
||||
|
||||
def https_enabled?
|
||||
Rails.env.production? && ENV['LOCAL_HTTPS'] == 'true'
|
||||
Rails.env.production?
|
||||
end
|
||||
|
||||
def store_current_location
|
||||
@@ -121,4 +121,26 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_cached_json(cache_key, **options)
|
||||
options[:expires_in] ||= 3.minutes
|
||||
cache_key = cache_key.join(':') if cache_key.is_a?(Enumerable)
|
||||
cache_public = options.key?(:public) ? options.delete(:public) : true
|
||||
content_type = options.delete(:content_type) || 'application/json'
|
||||
|
||||
data = Rails.cache.fetch(cache_key, { raw: true }.merge(options)) do
|
||||
yield.to_json
|
||||
end
|
||||
|
||||
expires_in options[:expires_in], public: cache_public
|
||||
render json: data, content_type: content_type
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = 'Accept'
|
||||
end
|
||||
|
||||
def skip_session!
|
||||
request.session_options[:skip] = true
|
||||
end
|
||||
end
|
||||
|
@@ -2,10 +2,4 @@
|
||||
|
||||
class Auth::ConfirmationsController < Devise::ConfirmationsController
|
||||
layout 'auth'
|
||||
|
||||
def show
|
||||
super do |user|
|
||||
BootstrapTimelineWorker.perform_async(user.account_id) if user.errors.empty?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -37,6 +37,10 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||
new_user_session_path
|
||||
end
|
||||
|
||||
def after_update_path_for(_resource)
|
||||
edit_user_registration_path
|
||||
end
|
||||
|
||||
def check_enabled_registrations
|
||||
redirect_to root_path if single_user_mode? || !allowed_registrations?
|
||||
end
|
||||
|
@@ -4,6 +4,7 @@ class AuthorizeFollowsController < ApplicationController
|
||||
layout 'modal'
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_body_classes
|
||||
|
||||
def show
|
||||
@account = located_account || render(:error)
|
||||
@@ -58,4 +59,8 @@ class AuthorizeFollowsController < ApplicationController
|
||||
def acct_params
|
||||
params.fetch(:acct, '')
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'modal-layout'
|
||||
end
|
||||
end
|
||||
|
@@ -17,6 +17,7 @@ module UserTrackingConcern
|
||||
|
||||
# Mark as signed-in today
|
||||
current_user.update_tracked_fields!(request)
|
||||
ActivityTracker.record('activity:logins', current_user.id)
|
||||
|
||||
# Regenerate feed if needed
|
||||
regenerate_feed! if user_needs_feed_update?
|
||||
|
@@ -2,14 +2,16 @@
|
||||
|
||||
class EmojisController < ApplicationController
|
||||
before_action :set_emoji
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render json: @emoji,
|
||||
serializer: ActivityPub::EmojiSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
skip_session!
|
||||
|
||||
render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do
|
||||
ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -38,4 +38,8 @@ class RemoteFollowController < ApplicationController
|
||||
def suspended_account?
|
||||
@account.suspended?
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'modal-layout'
|
||||
end
|
||||
end
|
||||
|
@@ -28,6 +28,7 @@ class Settings::MigrationsController < ApplicationController
|
||||
end
|
||||
|
||||
def migration_account_changed?
|
||||
current_account.moved_to_account_id != @migration.account&.id
|
||||
current_account.moved_to_account_id != @migration.account&.id &&
|
||||
current_account.id != @migration.account&.id
|
||||
end
|
||||
end
|
||||
|
@@ -25,6 +25,6 @@ class SharesController < ApplicationController
|
||||
end
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'compose-standalone'
|
||||
@body_classes = 'modal-layout compose-standalone'
|
||||
end
|
||||
end
|
||||
|
@@ -10,6 +10,7 @@ class StatusesController < ApplicationController
|
||||
before_action :set_link_headers
|
||||
before_action :check_account_suspension
|
||||
before_action :redirect_to_original, only: [:show]
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
@@ -21,19 +22,21 @@ class StatusesController < ApplicationController
|
||||
end
|
||||
|
||||
format.json do
|
||||
render json: @status,
|
||||
serializer: ActivityPub::NoteSerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
skip_session! unless @stream_entry.hidden?
|
||||
|
||||
render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def activity
|
||||
render json: @status,
|
||||
serializer: ActivityPub::ActivitySerializer,
|
||||
adapter: ActivityPub::Adapter,
|
||||
content_type: 'application/activity+json'
|
||||
skip_session!
|
||||
|
||||
render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json', public: !@stream_entry.hidden?) do
|
||||
ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter)
|
||||
end
|
||||
end
|
||||
|
||||
def embed
|
||||
|
@@ -1,15 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WellKnown
|
||||
class HostMetaController < ApplicationController
|
||||
class HostMetaController < ActionController::Base
|
||||
include RoutingHelper
|
||||
|
||||
before_action { response.headers['Vary'] = 'Accept' }
|
||||
|
||||
def show
|
||||
@webfinger_template = "#{webfinger_url}?resource={uri}"
|
||||
|
||||
respond_to do |format|
|
||||
format.xml { render content_type: 'application/xrd+xml' }
|
||||
end
|
||||
|
||||
expires_in(3.days, public: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -1,9 +1,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module WellKnown
|
||||
class WebfingerController < ApplicationController
|
||||
class WebfingerController < ActionController::Base
|
||||
include RoutingHelper
|
||||
|
||||
before_action { response.headers['Vary'] = 'Accept' }
|
||||
|
||||
def show
|
||||
@account = Account.find_local!(username_from_resource)
|
||||
|
||||
@@ -16,6 +18,8 @@ module WellKnown
|
||||
render content_type: 'application/xrd+xml'
|
||||
end
|
||||
end
|
||||
|
||||
expires_in(3.days, public: true)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
head 404
|
||||
end
|
||||
|
@@ -34,7 +34,7 @@ module Admin::ActionLogsHelper
|
||||
link_to attributes['domain'], "https://#{attributes['domain']}"
|
||||
when 'Status'
|
||||
tmp_status = Status.new(attributes)
|
||||
link_to tmp_status.account.acct, TagManager.instance.url_for(tmp_status)
|
||||
link_to tmp_status.account&.acct || "##{tmp_status.account_id}", TagManager.instance.url_for(tmp_status)
|
||||
end
|
||||
end
|
||||
|
||||
|
@@ -39,6 +39,10 @@ module JsonLdHelper
|
||||
!json.nil? && equals_or_includes?(json['@context'], ActivityPub::TagManager::CONTEXT)
|
||||
end
|
||||
|
||||
def unsupported_uri_scheme?(uri)
|
||||
!uri.start_with?('http://', 'https://')
|
||||
end
|
||||
|
||||
def canonicalize(json)
|
||||
graph = RDF::Graph.new << JSON::LD::API.toRdf(json)
|
||||
graph.dump(:normalize)
|
||||
|
@@ -4,6 +4,7 @@ module RoutingHelper
|
||||
extend ActiveSupport::Concern
|
||||
include Rails.application.routes.url_helpers
|
||||
include ActionView::Helpers::AssetTagHelper
|
||||
include Webpacker::Helper
|
||||
|
||||
included do
|
||||
def default_url_options
|
||||
@@ -17,6 +18,10 @@ module RoutingHelper
|
||||
URI.join(root_url, source).to_s
|
||||
end
|
||||
|
||||
def full_pack_url(source, **options)
|
||||
full_asset_url(asset_pack_path(source, options))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def use_storage?
|
||||
|
@@ -28,6 +28,9 @@ module SettingsHelper
|
||||
pt: 'Português',
|
||||
'pt-BR': 'Português do Brasil',
|
||||
ru: 'Русский',
|
||||
sk: 'Slovensky',
|
||||
sr: 'Српски',
|
||||
'sr-Latn': 'Srpski (latinica)',
|
||||
sv: 'Svenska',
|
||||
th: 'ภาษาไทย',
|
||||
tr: 'Türkçe',
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 32 KiB |
BIN
app/javascript/images/wave-compose-standalone.png
Normal file
BIN
app/javascript/images/wave-compose-standalone.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
app/javascript/images/wave-drawer.png
Normal file
BIN
app/javascript/images/wave-drawer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
app/javascript/images/wave-modal.png
Normal file
BIN
app/javascript/images/wave-modal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
@@ -31,7 +31,7 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
|
||||
|
||||
const unescapeHTML = (html) => {
|
||||
const wrapper = document.createElement('div');
|
||||
html = html.replace(/<br \/>|<br>|\n/, ' ');
|
||||
html = html.replace(/<br \/>|<br>|\n/g, ' ');
|
||||
wrapper.innerHTML = html;
|
||||
return wrapper.textContent;
|
||||
};
|
||||
|
@@ -1,57 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { pushNotificationsSetting } from '../settings';
|
||||
|
||||
export const SET_BROWSER_SUPPORT = 'PUSH_NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||
export const SET_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_SET_SUBSCRIPTION';
|
||||
export const CLEAR_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_CLEAR_SUBSCRIPTION';
|
||||
export const ALERTS_CHANGE = 'PUSH_NOTIFICATIONS_ALERTS_CHANGE';
|
||||
|
||||
export function setBrowserSupport (value) {
|
||||
return {
|
||||
type: SET_BROWSER_SUPPORT,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSubscription (subscription) {
|
||||
return {
|
||||
type: SET_SUBSCRIPTION,
|
||||
subscription,
|
||||
};
|
||||
}
|
||||
|
||||
export function clearSubscription () {
|
||||
return {
|
||||
type: CLEAR_SUBSCRIPTION,
|
||||
};
|
||||
}
|
||||
|
||||
export function changeAlerts(key, value) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: ALERTS_CHANGE,
|
||||
key,
|
||||
value,
|
||||
});
|
||||
|
||||
dispatch(saveSettings());
|
||||
};
|
||||
}
|
||||
|
||||
export function saveSettings() {
|
||||
return (_, getState) => {
|
||||
const state = getState().get('push_notifications');
|
||||
const subscription = state.get('subscription');
|
||||
const alerts = state.get('alerts');
|
||||
const data = { alerts };
|
||||
|
||||
axios.put(`/api/web/push_subscriptions/${subscription.get('id')}`, {
|
||||
data,
|
||||
}).then(() => {
|
||||
const me = getState().getIn(['meta', 'me']);
|
||||
if (me) {
|
||||
pushNotificationsSetting.set(me, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
23
app/javascript/mastodon/actions/push_notifications/index.js
Normal file
23
app/javascript/mastodon/actions/push_notifications/index.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import {
|
||||
SET_BROWSER_SUPPORT,
|
||||
SET_SUBSCRIPTION,
|
||||
CLEAR_SUBSCRIPTION,
|
||||
SET_ALERTS,
|
||||
setAlerts,
|
||||
} from './setter';
|
||||
import { register, saveSettings } from './registerer';
|
||||
|
||||
export {
|
||||
SET_BROWSER_SUPPORT,
|
||||
SET_SUBSCRIPTION,
|
||||
CLEAR_SUBSCRIPTION,
|
||||
SET_ALERTS,
|
||||
register,
|
||||
};
|
||||
|
||||
export function changeAlerts(path, value) {
|
||||
return dispatch => {
|
||||
dispatch(setAlerts(path, value));
|
||||
dispatch(saveSettings());
|
||||
};
|
||||
}
|
149
app/javascript/mastodon/actions/push_notifications/registerer.js
Normal file
149
app/javascript/mastodon/actions/push_notifications/registerer.js
Normal file
@@ -0,0 +1,149 @@
|
||||
import api from '../../api';
|
||||
import { pushNotificationsSetting } from '../../settings';
|
||||
import { setBrowserSupport, setSubscription, clearSubscription } from './setter';
|
||||
|
||||
// Taken from https://www.npmjs.com/package/web-push
|
||||
const urlBase64ToUint8Array = (base64String) => {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
};
|
||||
|
||||
const getApplicationServerKey = () => document.querySelector('[name="applicationServerKey"]').getAttribute('content');
|
||||
|
||||
const getRegistration = () => navigator.serviceWorker.ready;
|
||||
|
||||
const getPushSubscription = (registration) =>
|
||||
registration.pushManager.getSubscription()
|
||||
.then(subscription => ({ registration, subscription }));
|
||||
|
||||
const subscribe = (registration) =>
|
||||
registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(getApplicationServerKey()),
|
||||
});
|
||||
|
||||
const unsubscribe = ({ registration, subscription }) =>
|
||||
subscription ? subscription.unsubscribe().then(() => registration) : registration;
|
||||
|
||||
const sendSubscriptionToBackend = (getState, subscription, me) => {
|
||||
const params = { subscription };
|
||||
|
||||
if (me) {
|
||||
const data = pushNotificationsSetting.get(me);
|
||||
if (data) {
|
||||
params.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
return api(getState).post('/api/web/push_subscriptions', params).then(response => response.data);
|
||||
};
|
||||
|
||||
// Last one checks for payload support: https://web-push-book.gauntface.com/chapter-06/01-non-standards-browsers/#no-payload
|
||||
const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype);
|
||||
|
||||
export function register () {
|
||||
return (dispatch, getState) => {
|
||||
dispatch(setBrowserSupport(supportsPushNotifications));
|
||||
const me = getState().getIn(['meta', 'me']);
|
||||
|
||||
if (me && !pushNotificationsSetting.get(me)) {
|
||||
const alerts = getState().getIn(['push_notifications', 'alerts']);
|
||||
if (alerts) {
|
||||
pushNotificationsSetting.set(me, { alerts: alerts });
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsPushNotifications) {
|
||||
if (!getApplicationServerKey()) {
|
||||
console.error('The VAPID public key is not set. You will not be able to receive Web Push Notifications.');
|
||||
return;
|
||||
}
|
||||
|
||||
getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(({ registration, subscription }) => {
|
||||
if (subscription !== null) {
|
||||
// We have a subscription, check if it is still valid
|
||||
const currentServerKey = (new Uint8Array(subscription.options.applicationServerKey)).toString();
|
||||
const subscriptionServerKey = urlBase64ToUint8Array(getApplicationServerKey()).toString();
|
||||
const serverEndpoint = getState().getIn(['push_notifications', 'subscription', 'endpoint']);
|
||||
|
||||
// If the VAPID public key did not change and the endpoint corresponds
|
||||
// to the endpoint saved in the backend, the subscription is valid
|
||||
if (subscriptionServerKey === currentServerKey && subscription.endpoint === serverEndpoint) {
|
||||
return subscription;
|
||||
} else {
|
||||
// Something went wrong, try to subscribe again
|
||||
return unsubscribe({ registration, subscription }).then(subscribe).then(
|
||||
subscription => sendSubscriptionToBackend(getState, subscription, me));
|
||||
}
|
||||
}
|
||||
|
||||
// No subscription, try to subscribe
|
||||
return subscribe(registration).then(
|
||||
subscription => sendSubscriptionToBackend(getState, subscription, me));
|
||||
})
|
||||
.then(subscription => {
|
||||
// If we got a PushSubscription (and not a subscription object from the backend)
|
||||
// it means that the backend subscription is valid (and was set during hydration)
|
||||
if (!(subscription instanceof PushSubscription)) {
|
||||
dispatch(setSubscription(subscription));
|
||||
if (me) {
|
||||
pushNotificationsSetting.set(me, { alerts: subscription.alerts });
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.code === 20 && error.name === 'AbortError') {
|
||||
console.warn('Your browser supports Web Push Notifications, but does not seem to implement the VAPID protocol.');
|
||||
} else if (error.code === 5 && error.name === 'InvalidCharacterError') {
|
||||
console.error('The VAPID public key seems to be invalid:', getApplicationServerKey());
|
||||
}
|
||||
|
||||
// Clear alerts and hide UI settings
|
||||
dispatch(clearSubscription());
|
||||
if (me) {
|
||||
pushNotificationsSetting.remove(me);
|
||||
}
|
||||
|
||||
try {
|
||||
getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(unsubscribe);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('Your browser does not support Web Push Notifications.');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function saveSettings() {
|
||||
return (_, getState) => {
|
||||
const state = getState().get('push_notifications');
|
||||
const subscription = state.get('subscription');
|
||||
const alerts = state.get('alerts');
|
||||
const data = { alerts };
|
||||
|
||||
api(getState).put(`/api/web/push_subscriptions/${subscription.get('id')}`, {
|
||||
data,
|
||||
}).then(() => {
|
||||
const me = getState().getIn(['meta', 'me']);
|
||||
if (me) {
|
||||
pushNotificationsSetting.set(me, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
34
app/javascript/mastodon/actions/push_notifications/setter.js
Normal file
34
app/javascript/mastodon/actions/push_notifications/setter.js
Normal file
@@ -0,0 +1,34 @@
|
||||
export const SET_BROWSER_SUPPORT = 'PUSH_NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||
export const SET_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_SET_SUBSCRIPTION';
|
||||
export const CLEAR_SUBSCRIPTION = 'PUSH_NOTIFICATIONS_CLEAR_SUBSCRIPTION';
|
||||
export const SET_ALERTS = 'PUSH_NOTIFICATIONS_SET_ALERTS';
|
||||
|
||||
export function setBrowserSupport (value) {
|
||||
return {
|
||||
type: SET_BROWSER_SUPPORT,
|
||||
value,
|
||||
};
|
||||
}
|
||||
|
||||
export function setSubscription (subscription) {
|
||||
return {
|
||||
type: SET_SUBSCRIPTION,
|
||||
subscription,
|
||||
};
|
||||
}
|
||||
|
||||
export function clearSubscription () {
|
||||
return {
|
||||
type: CLEAR_SUBSCRIPTION,
|
||||
};
|
||||
}
|
||||
|
||||
export function setAlerts (path, value) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: SET_ALERTS,
|
||||
path,
|
||||
value,
|
||||
});
|
||||
};
|
||||
}
|
@@ -1,14 +1,14 @@
|
||||
import axios from 'axios';
|
||||
import api from '../api';
|
||||
import { debounce } from 'lodash';
|
||||
|
||||
export const SETTING_CHANGE = 'SETTING_CHANGE';
|
||||
export const SETTING_SAVE = 'SETTING_SAVE';
|
||||
|
||||
export function changeSetting(key, value) {
|
||||
export function changeSetting(path, value) {
|
||||
return dispatch => {
|
||||
dispatch({
|
||||
type: SETTING_CHANGE,
|
||||
key,
|
||||
path,
|
||||
value,
|
||||
});
|
||||
|
||||
@@ -21,9 +21,9 @@ const debouncedSave = debounce((dispatch, getState) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = getState().get('settings').filter((_, key) => key !== 'saved').toJS();
|
||||
const data = getState().get('settings').filter((_, path) => path !== 'saved').toJS();
|
||||
|
||||
axios.put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE }));
|
||||
api(getState).put('/api/web/settings', { data }).then(() => dispatch({ type: SETTING_SAVE }));
|
||||
}, 5000, { trailing: true });
|
||||
|
||||
export function saveSettings() {
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import axios from 'axios';
|
||||
import ready from './ready';
|
||||
import LinkHeader from './link_header';
|
||||
|
||||
export const getLinks = response => {
|
||||
@@ -11,10 +12,17 @@ export const getLinks = response => {
|
||||
return LinkHeader.parse(value);
|
||||
};
|
||||
|
||||
let csrfHeader = {};
|
||||
function setCSRFHeader() {
|
||||
const csrfToken = document.querySelector('meta[name=csrf-token]').content;
|
||||
csrfHeader['X-CSRF-Token'] = csrfToken;
|
||||
}
|
||||
ready(setCSRFHeader);
|
||||
|
||||
export default getState => axios.create({
|
||||
headers: {
|
||||
headers: Object.assign(csrfHeader, getState ? {
|
||||
'Authorization': `Bearer ${getState().getIn(['meta', 'access_token'], '')}`,
|
||||
},
|
||||
} : {}),
|
||||
|
||||
transformResponse: [function (data) {
|
||||
try {
|
||||
|
@@ -27,6 +27,7 @@ export default class Account extends ImmutablePureComponent {
|
||||
onFollow: PropTypes.func.isRequired,
|
||||
onBlock: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func.isRequired,
|
||||
onMuteNotifications: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
hidden: PropTypes.bool,
|
||||
};
|
||||
|
@@ -5,20 +5,27 @@ import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { me } from '../../../initial_state';
|
||||
|
||||
const APPROX_HASHTAG_RE = /(?:^|[^\/\)\w])#(\S+)/i;
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
needsLockWarning: state.getIn(['compose', 'privacy']) === 'private' && !state.getIn(['accounts', me, 'locked']),
|
||||
hashtagWarning: state.getIn(['compose', 'privacy']) !== 'public' && APPROX_HASHTAG_RE.test(state.getIn(['compose', 'text'])),
|
||||
});
|
||||
|
||||
const WarningWrapper = ({ needsLockWarning }) => {
|
||||
const WarningWrapper = ({ needsLockWarning, hashtagWarning }) => {
|
||||
if (needsLockWarning) {
|
||||
return <Warning message={<FormattedMessage id='compose_form.lock_disclaimer' defaultMessage='Your account is not {locked}. Anyone can follow you to view your follower-only posts.' values={{ locked: <a href='/settings/profile'><FormattedMessage id='compose_form.lock_disclaimer.lock' defaultMessage='locked' /></a> }} />} />;
|
||||
}
|
||||
if (hashtagWarning) {
|
||||
return <Warning message={<FormattedMessage id='compose_form.hashtag_warning' defaultMessage="This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag." />} />;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
WarningWrapper.propTypes = {
|
||||
needsLockWarning: PropTypes.bool,
|
||||
hashtagWarning: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default connect(mapStateToProps)(WarningWrapper);
|
||||
|
@@ -94,6 +94,7 @@ export default class Compose extends React.PureComponent {
|
||||
<div className='drawer__inner' onFocus={this.onFocus}>
|
||||
<NavigationContainer onClose={this.onBlur} />
|
||||
<ComposeFormContainer />
|
||||
{multiColumn && <div className='mastodon' />}
|
||||
</div>
|
||||
|
||||
<Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
||||
|
@@ -48,7 +48,7 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||
render () {
|
||||
const { intl, myAccount, columns, multiColumn } = this.props;
|
||||
|
||||
let navItems = [];
|
||||
const navItems = [];
|
||||
|
||||
if (multiColumn) {
|
||||
if (!columns.find(item => item.get('id') === 'HOME')) {
|
||||
@@ -68,21 +68,20 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
navItems = navItems.concat([
|
||||
navItems.push(
|
||||
<ColumnLink key='4' icon='star' text={intl.formatMessage(messages.favourites)} to='/favourites' />,
|
||||
<ColumnLink key='5' icon='thumb-tack' text={intl.formatMessage(messages.pins)} to='/pinned' />,
|
||||
<ColumnLink key='9' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />,
|
||||
]);
|
||||
<ColumnLink key='5' icon='bars' text={intl.formatMessage(messages.lists)} to='/lists' />
|
||||
);
|
||||
|
||||
if (myAccount.get('locked')) {
|
||||
navItems.push(<ColumnLink key='6' icon='users' text={intl.formatMessage(messages.follow_requests)} to='/follow_requests' />);
|
||||
}
|
||||
|
||||
navItems = navItems.concat([
|
||||
<ColumnLink key='7' icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />,
|
||||
<ColumnLink key='8' icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />,
|
||||
<ColumnLink key='10' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' hideOnMobile />,
|
||||
]);
|
||||
if (multiColumn) {
|
||||
navItems.push(<ColumnLink key='7' icon='question' text={intl.formatMessage(messages.keyboard_shortcuts)} to='/keyboard-shortcuts' />);
|
||||
}
|
||||
|
||||
navItems.push(<ColumnLink key='8' icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />);
|
||||
|
||||
return (
|
||||
<Column icon='asterisk' heading={intl.formatMessage(messages.heading)} hideHeadingOnMobile>
|
||||
@@ -90,24 +89,24 @@ export default class GettingStarted extends ImmutablePureComponent {
|
||||
<ColumnSubheading text={intl.formatMessage(messages.navigation_subheading)} />
|
||||
{navItems}
|
||||
<ColumnSubheading text={intl.formatMessage(messages.settings_subheading)} />
|
||||
<ColumnLink icon='book' text={intl.formatMessage(messages.info)} href='/about/more' />
|
||||
<ColumnLink icon='thumb-tack' text={intl.formatMessage(messages.pins)} to='/pinned' />
|
||||
<ColumnLink icon='volume-off' text={intl.formatMessage(messages.mutes)} to='/mutes' />
|
||||
<ColumnLink icon='ban' text={intl.formatMessage(messages.blocks)} to='/blocks' />
|
||||
<ColumnLink icon='cog' text={intl.formatMessage(messages.preferences)} href='/settings/preferences' />
|
||||
<ColumnLink icon='sign-out' text={intl.formatMessage(messages.sign_out)} href='/auth/sign_out' method='delete' />
|
||||
</div>
|
||||
|
||||
<div className='getting-started__footer scrollable optionally-scrollable'>
|
||||
<div className='static-content getting-started'>
|
||||
<p>
|
||||
<a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.faq' defaultMessage='FAQ' /></a> • <a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/User-guide.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.userguide' defaultMessage='User Guide' /></a> • <a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.appsshort' defaultMessage='Apps' /></a>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='getting_started.open_source_notice'
|
||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
||||
values={{ github: <a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div className='static-content getting-started'>
|
||||
<p>
|
||||
<a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/FAQ.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.faq' defaultMessage='FAQ' /></a> • <a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/User-guide.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.userguide' defaultMessage='User Guide' /></a> • <a href='https://github.com/tootsuite/documentation/blob/master/Using-Mastodon/Apps.md' rel='noopener' target='_blank'><FormattedMessage id='getting_started.appsshort' defaultMessage='Apps' /></a>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='getting_started.open_source_notice'
|
||||
defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
|
||||
values={{ github: <a href='https://github.com/tootsuite/mastodon' rel='noopener' target='_blank'>tootsuite/mastodon</a> }}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</Column>
|
||||
);
|
||||
|
@@ -27,11 +27,11 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.basic' defaultMessage='Basic' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='home_timeline' settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} />
|
||||
<SettingToggle prefix='home_timeline' settings={settings} settingPath={['shows', 'reblog']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_reblogs' defaultMessage='Show boosts' />} />
|
||||
</div>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='home_timeline' settings={settings} settingKey={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
|
||||
<SettingToggle prefix='home_timeline' settings={settings} settingPath={['shows', 'reply']} onChange={onChange} label={<FormattedMessage id='home.column_settings.show_replies' defaultMessage='Show replies' />} />
|
||||
</div>
|
||||
|
||||
<span className='column-settings__section'><FormattedMessage id='home.column_settings.advanced' defaultMessage='Advanced' /></span>
|
||||
|
@@ -33,59 +33,59 @@ export default class KeyboardShortcuts extends ImmutablePureComponent {
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><code>r</code></td>
|
||||
<td><kbd>r</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.reply' defaultMessage='to reply' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>m</code></td>
|
||||
<td><kbd>m</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.mention' defaultMessage='to mention author' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>f</code></td>
|
||||
<td><kbd>f</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.favourite' defaultMessage='to favourite' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>b</code></td>
|
||||
<td><kbd>b</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.boost' defaultMessage='to boost' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>enter</code></td>
|
||||
<td><kbd>enter</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>up</code></td>
|
||||
<td><kbd>up</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.up' defaultMessage='to move up in the list' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>down</code></td>
|
||||
<td><kbd>down</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.down' defaultMessage='to move down in the list' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>1</code>-<code>9</code></td>
|
||||
<td><kbd>1</kbd>-<kbd>9</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.column' defaultMessage='to focus a status in one of the columns' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>n</code></td>
|
||||
<td><kbd>n</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.compose' defaultMessage='to focus the compose textarea' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>alt</code>+<code>n</code></td>
|
||||
<td><kbd>alt</kbd>+<kbd>n</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.toot' defaultMessage='to start a brand new toot' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>backspace</code></td>
|
||||
<td><kbd>backspace</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.back' defaultMessage='to navigate back' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>s</code></td>
|
||||
<td><kbd>s</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.search' defaultMessage='to focus search' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>esc</code></td>
|
||||
<td><kbd>esc</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.unfocus' defaultMessage='to un-focus compose textarea/search' /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>?</code></td>
|
||||
<td><kbd>?</kbd></td>
|
||||
<td><FormattedMessage id='keyboard_shortcuts.legend' defaultMessage='to display this legend' /></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@@ -11,12 +11,11 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
settings: ImmutablePropTypes.map.isRequired,
|
||||
pushSettings: ImmutablePropTypes.map.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
onClear: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
onPushChange = (key, checked) => {
|
||||
this.props.onChange(['push', ...key], checked);
|
||||
onPushChange = (path, checked) => {
|
||||
this.props.onChange(['push', ...path], checked);
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -40,10 +39,10 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
<span id='notifications-follow' className='column-settings__section'><FormattedMessage id='notifications.column_settings.follow' defaultMessage='New followers:' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'follow']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'follow']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'follow']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'follow']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'follow']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'follow']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'follow']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,10 +50,10 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
<span id='notifications-favourite' className='column-settings__section'><FormattedMessage id='notifications.column_settings.favourite' defaultMessage='Favourites:' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'favourite']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'favourite']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'favourite']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'favourite']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'favourite']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'favourite']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -62,10 +61,10 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
<span id='notifications-mention' className='column-settings__section'><FormattedMessage id='notifications.column_settings.mention' defaultMessage='Mentions:' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'mention']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'mention']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'mention']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'mention']} onChange={onChange} label={soundStr} />
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'mention']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'mention']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'mention']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'mention']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -73,10 +72,10 @@ export default class ColumnSettings extends React.PureComponent {
|
||||
<span id='notifications-reblog' className='column-settings__section'><FormattedMessage id='notifications.column_settings.reblog' defaultMessage='Boosts:' /></span>
|
||||
|
||||
<div className='column-settings__row'>
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingKey={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingKey={['alerts', 'reblog']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['shows', 'reblog']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingKey={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
|
||||
<SettingToggle prefix='notifications_desktop' settings={settings} settingPath={['alerts', 'reblog']} onChange={onChange} label={alertStr} />
|
||||
{showPushSettings && <SettingToggle prefix='notifications_push' settings={pushSettings} settingPath={['alerts', 'reblog']} meta={pushMeta} onChange={this.onPushChange} label={pushStr} />}
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['shows', 'reblog']} onChange={onChange} label={showStr} />
|
||||
<SettingToggle prefix='notifications' settings={settings} settingPath={['sounds', 'reblog']} onChange={onChange} label={soundStr} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -8,23 +8,23 @@ export default class SettingToggle extends React.PureComponent {
|
||||
static propTypes = {
|
||||
prefix: PropTypes.string,
|
||||
settings: ImmutablePropTypes.map.isRequired,
|
||||
settingKey: PropTypes.array.isRequired,
|
||||
settingPath: PropTypes.array.isRequired,
|
||||
label: PropTypes.node.isRequired,
|
||||
meta: PropTypes.node,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
onChange = ({ target }) => {
|
||||
this.props.onChange(this.props.settingKey, target.checked);
|
||||
this.props.onChange(this.props.settingPath, target.checked);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { prefix, settings, settingKey, label, meta } = this.props;
|
||||
const id = ['setting-toggle', prefix, ...settingKey].filter(Boolean).join('-');
|
||||
const { prefix, settings, settingPath, label, meta } = this.props;
|
||||
const id = ['setting-toggle', prefix, ...settingPath].filter(Boolean).join('-');
|
||||
|
||||
return (
|
||||
<div className='setting-toggle'>
|
||||
<Toggle id={id} checked={settings.getIn(settingKey)} onChange={this.onChange} onKeyDown={this.onKeyDown} />
|
||||
<Toggle id={id} checked={settings.getIn(settingPath)} onChange={this.onChange} onKeyDown={this.onKeyDown} />
|
||||
<label htmlFor={id} className='setting-toggle__label'>{label}</label>
|
||||
{meta && <span className='setting-meta__label'>{meta}</span>}
|
||||
</div>
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import { connect } from 'react-redux';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import ColumnSettings from '../components/column_settings';
|
||||
import { changeSetting, saveSettings } from '../../../actions/settings';
|
||||
import { changeSetting } from '../../../actions/settings';
|
||||
import { clearNotifications } from '../../../actions/notifications';
|
||||
import { changeAlerts as changePushNotifications, saveSettings as savePushNotificationSettings } from '../../../actions/push_notifications';
|
||||
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
|
||||
import { openModal } from '../../../actions/modal';
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -18,19 +18,14 @@ const mapStateToProps = state => ({
|
||||
|
||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
|
||||
onChange (key, checked) {
|
||||
if (key[0] === 'push') {
|
||||
dispatch(changePushNotifications(key.slice(1), checked));
|
||||
onChange (path, checked) {
|
||||
if (path[0] === 'push') {
|
||||
dispatch(changePushNotifications(path.slice(1), checked));
|
||||
} else {
|
||||
dispatch(changeSetting(['notifications', ...key], checked));
|
||||
dispatch(changeSetting(['notifications', ...path], checked));
|
||||
}
|
||||
},
|
||||
|
||||
onSave () {
|
||||
dispatch(saveSettings());
|
||||
dispatch(savePushNotificationSettings());
|
||||
},
|
||||
|
||||
onClear () {
|
||||
dispatch(openModal('CONFIRM', {
|
||||
message: intl.formatMessage(messages.clearMessage),
|
||||
|
@@ -13,6 +13,10 @@ const messages = defineMessages({
|
||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||
cannot_reblog: { id: 'status.cannot_reblog', defaultMessage: 'This post cannot be boosted' },
|
||||
favourite: { id: 'status.favourite', defaultMessage: 'Favourite' },
|
||||
mute: { id: 'status.mute', defaultMessage: 'Mute @{name}' },
|
||||
muteConversation: { id: 'status.mute_conversation', defaultMessage: 'Mute conversation' },
|
||||
unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
|
||||
block: { id: 'status.block', defaultMessage: 'Block @{name}' },
|
||||
report: { id: 'status.report', defaultMessage: 'Report @{name}' },
|
||||
share: { id: 'status.share', defaultMessage: 'Share' },
|
||||
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
|
||||
@@ -34,6 +38,9 @@ export default class ActionBar extends React.PureComponent {
|
||||
onFavourite: PropTypes.func.isRequired,
|
||||
onDelete: PropTypes.func.isRequired,
|
||||
onMention: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func,
|
||||
onMuteConversation: PropTypes.func,
|
||||
onBlock: PropTypes.func,
|
||||
onReport: PropTypes.func,
|
||||
onPin: PropTypes.func,
|
||||
onEmbed: PropTypes.func,
|
||||
@@ -60,6 +67,18 @@ export default class ActionBar extends React.PureComponent {
|
||||
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
||||
}
|
||||
|
||||
handleMuteClick = () => {
|
||||
this.props.onMute(this.props.status.get('account'));
|
||||
}
|
||||
|
||||
handleConversationMuteClick = () => {
|
||||
this.props.onMuteConversation(this.props.status);
|
||||
}
|
||||
|
||||
handleBlockClick = () => {
|
||||
this.props.onBlock(this.props.status.get('account'));
|
||||
}
|
||||
|
||||
handleReport = () => {
|
||||
this.props.onReport(this.props.status);
|
||||
}
|
||||
@@ -83,6 +102,7 @@ export default class ActionBar extends React.PureComponent {
|
||||
const { status, intl } = this.props;
|
||||
|
||||
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'));
|
||||
const mutingConversation = status.get('muted');
|
||||
|
||||
let menu = [];
|
||||
|
||||
@@ -95,10 +115,15 @@ export default class ActionBar extends React.PureComponent {
|
||||
menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
}
|
||||
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
}
|
||||
|
||||
|
@@ -43,7 +43,7 @@ export default class Card extends React.PureComponent {
|
||||
Immutable.fromJS([
|
||||
{
|
||||
type: 'image',
|
||||
url: card.get('url'),
|
||||
url: card.get('embed_url'),
|
||||
description: card.get('title'),
|
||||
meta: {
|
||||
original: {
|
||||
|
@@ -20,14 +20,16 @@ import {
|
||||
replyCompose,
|
||||
mentionCompose,
|
||||
} from '../../actions/compose';
|
||||
import { deleteStatus } from '../../actions/statuses';
|
||||
import { blockAccount } from '../../actions/accounts';
|
||||
import { muteStatus, unmuteStatus, deleteStatus } from '../../actions/statuses';
|
||||
import { initMuteModal } from '../../actions/mutes';
|
||||
import { initReport } from '../../actions/reports';
|
||||
import { makeGetStatus } from '../../selectors';
|
||||
import { ScrollContainer } from 'react-router-scroll-4';
|
||||
import ColumnBackButton from '../../components/column_back_button';
|
||||
import StatusContainer from '../../containers/status_container';
|
||||
import { openModal } from '../../actions/modal';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { HotKeys } from 'react-hotkeys';
|
||||
import { boostModal, deleteModal } from '../../initial_state';
|
||||
@@ -36,6 +38,7 @@ import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from
|
||||
const messages = defineMessages({
|
||||
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
|
||||
deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' },
|
||||
blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' },
|
||||
});
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
@@ -148,6 +151,28 @@ export default class Status extends ImmutablePureComponent {
|
||||
this.props.dispatch(openModal('VIDEO', { media, time }));
|
||||
}
|
||||
|
||||
handleMuteClick = (account) => {
|
||||
this.props.dispatch(initMuteModal(account));
|
||||
}
|
||||
|
||||
handleConversationMuteClick = (status) => {
|
||||
if (status.get('muted')) {
|
||||
this.props.dispatch(unmuteStatus(status.get('id')));
|
||||
} else {
|
||||
this.props.dispatch(muteStatus(status.get('id')));
|
||||
}
|
||||
}
|
||||
|
||||
handleBlockClick = (account) => {
|
||||
const { dispatch, intl } = this.props;
|
||||
|
||||
dispatch(openModal('CONFIRM', {
|
||||
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
|
||||
confirm: intl.formatMessage(messages.blockConfirm),
|
||||
onConfirm: () => dispatch(blockAccount(account.get('id'))),
|
||||
}));
|
||||
}
|
||||
|
||||
handleReport = (status) => {
|
||||
this.props.dispatch(initReport(status.get('account'), status));
|
||||
}
|
||||
@@ -321,6 +346,9 @@ export default class Status extends ImmutablePureComponent {
|
||||
onReblog={this.handleReblogClick}
|
||||
onDelete={this.handleDeleteClick}
|
||||
onMention={this.handleMentionClick}
|
||||
onMute={this.handleMuteClick}
|
||||
onMuteConversation={this.handleConversationMuteClick}
|
||||
onBlock={this.handleBlockClick}
|
||||
onReport={this.handleReport}
|
||||
onPin={this.handlePin}
|
||||
onEmbed={this.handleEmbed}
|
||||
|
@@ -26,7 +26,6 @@ ColumnLink.propTypes = {
|
||||
to: PropTypes.string,
|
||||
href: PropTypes.string,
|
||||
method: PropTypes.string,
|
||||
hideOnMobile: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default ColumnLink;
|
||||
|
@@ -27,8 +27,6 @@ const componentMap = {
|
||||
'LIST': ListTimeline,
|
||||
};
|
||||
|
||||
const isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl');
|
||||
|
||||
@component => injectIntl(component, { withRef: true })
|
||||
export default class ColumnsArea extends ImmutablePureComponent {
|
||||
|
||||
@@ -55,7 +53,10 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
if (!this.props.singleColumn) {
|
||||
this.node.addEventListener('wheel', this.handleWheel, detectPassiveEvents.hasSupport ? { passive: true } : false);
|
||||
}
|
||||
this.lastIndex = getIndex(this.context.router.history.location.pathname);
|
||||
|
||||
this.lastIndex = getIndex(this.context.router.history.location.pathname);
|
||||
this.isRtlLayout = document.getElementsByTagName('body')[0].classList.contains('rtl');
|
||||
|
||||
this.setState({ shouldAnimate: true });
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
|
||||
|
||||
handleChildrenContentChange() {
|
||||
if (!this.props.singleColumn) {
|
||||
const modifier = isRtlLayout ? -1 : 1;
|
||||
const modifier = this.isRtlLayout ? -1 : 1;
|
||||
this._interruptScrollAnimation = scrollRight(this.node, (this.node.scrollWidth - window.innerWidth) * modifier);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import axios from 'axios';
|
||||
import api from '../../../api';
|
||||
|
||||
@injectIntl
|
||||
export default class EmbedModal extends ImmutablePureComponent {
|
||||
@@ -23,7 +23,7 @@ export default class EmbedModal extends ImmutablePureComponent {
|
||||
|
||||
this.setState({ loading: true });
|
||||
|
||||
axios.post('/api/web/embed', { url }).then(res => {
|
||||
api().post('/api/web/embed', { url }).then(res => {
|
||||
this.setState({ loading: false, oembed: res.data });
|
||||
|
||||
const iframeDocument = this.iframe.contentWindow.document;
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "فك التدبيس",
|
||||
"column_subheading.navigation": "التصفح",
|
||||
"column_subheading.settings": "الإعدادات",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "حسابك ليس {locked}. يمكن لأي شخص متابعتك و عرض المنشورات.",
|
||||
"compose_form.lock_disclaimer.lock": "مقفل",
|
||||
"compose_form.placeholder": "فيمَ تفكّر؟",
|
||||
@@ -66,7 +67,7 @@
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "هل تود حقا حذف هذه القائمة ؟",
|
||||
"confirmations.domain_block.confirm": "إخفاء إسم النطاق كاملا",
|
||||
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",
|
||||
"confirmations.domain_block.message": "متأكد من أنك تود حظر إسم النطاق {domain} بالكامل ؟ في غالب الأحيان يُستَحسَن كتم أو حظر بعض الحسابات بدلا من حظر نطاق بالكامل.",
|
||||
"confirmations.mute.confirm": "أكتم",
|
||||
"confirmations.mute.message": "هل أنت متأكد أنك تريد كتم {name} ؟",
|
||||
"confirmations.unfollow.confirm": "إلغاء المتابعة",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "ليس هناك بعدُ أي محتوى ذو علاقة بهذا الوسم.",
|
||||
"empty_column.home": "إنك لا تتبع بعد أي شخص إلى حد الآن. زر {public} أو استخدام حقل البحث لكي تبدأ على التعرف على مستخدمين آخرين.",
|
||||
"empty_column.home.public_timeline": "الخيط العام",
|
||||
"empty_column.list": "هذه القائمة فارغة.",
|
||||
"empty_column.list": "هذه القائمة فارغة مؤقتا و لكن سوف تمتلئ تدريجيا عندما يبدأ الأعضاء المُنتَمين إليها بنشر تبويقات.",
|
||||
"empty_column.notifications": "لم تتلق أي إشعار بعدُ. تفاعل مع المستخدمين الآخرين لإنشاء محادثة.",
|
||||
"empty_column.public": "لا يوجد أي شيء هنا ! قم بنشر شيء ما للعامة، أو إتبع مستخدمين آخرين في الخوادم المثيلة الأخرى لملء خيط المحادثات العام",
|
||||
"follow_request.authorize": "ترخيص",
|
||||
@@ -122,7 +123,7 @@
|
||||
"keyboard_shortcuts.reply": "للردّ",
|
||||
"keyboard_shortcuts.search": "للتركيز على البحث",
|
||||
"keyboard_shortcuts.toot": "لتحرير تبويق جديد",
|
||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.unfocus": "لإلغاء التركيز على حقل النص أو نافذة البحث",
|
||||
"keyboard_shortcuts.up": "للإنتقال إلى أعلى القائمة",
|
||||
"lightbox.close": "إغلاق",
|
||||
"lightbox.next": "التالي",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "مستخدِم",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} و {results}}",
|
||||
"standalone.public_title": "نظرة على ...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "تعذرت ترقية هذا المنشور",
|
||||
"status.delete": "إحذف",
|
||||
"status.embed": "إدماج",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "الصورة مستترة",
|
||||
"status.mention": "أذكُر @{name}",
|
||||
"status.more": "المزيد",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "كتم المحادثة",
|
||||
"status.open": "وسع هذه المشاركة",
|
||||
"status.pin": "تدبيس على الملف الشخصي",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "Какво си мислиш?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Изтриване",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Споменаване",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Deslligar",
|
||||
"column_subheading.navigation": "Navegació",
|
||||
"column_subheading.settings": "Configuració",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "El teu compte no està bloquejat {locked}. Tothom pot seguir-te i veure els teus missatges a seguidors.",
|
||||
"compose_form.lock_disclaimer.lock": "bloquejat",
|
||||
"compose_form.placeholder": "En què estàs pensant?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Encara no hi ha res amb aquesta etiqueta.",
|
||||
"empty_column.home": "Encara no segueixes ningú. Visita {public} o fes cerca per començar i conèixer altres usuaris.",
|
||||
"empty_column.home.public_timeline": "la línia de temps pública",
|
||||
"empty_column.list": "Encara no hi ha res en aquesta llista.",
|
||||
"empty_column.list": "Encara no hi ha res en aquesta llista. Quan els membres d'aquesta llista publiquin nous estats, apareixeran aquí.",
|
||||
"empty_column.notifications": "Encara no tens notificacions. Interactua amb altres per iniciar la conversa.",
|
||||
"empty_column.public": "No hi ha res aquí! Escriu alguna cosa públicament o segueix manualment usuaris d'altres instàncies per omplir-ho",
|
||||
"follow_request.authorize": "Autoritzar",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "usuari",
|
||||
"search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
|
||||
"standalone.public_title": "Una mirada a l'interior ...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Aquesta publicació no pot ser retootejada",
|
||||
"status.delete": "Esborrar",
|
||||
"status.embed": "Incrustar",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Multimèdia amagat",
|
||||
"status.mention": "Esmentar @{name}",
|
||||
"status.more": "Més",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Silenciar conversació",
|
||||
"status.open": "Ampliar aquest estat",
|
||||
"status.pin": "Fixat en el perfil",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Lösen",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Einstellungen",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Wer dir folgen will, kann das jederzeit tun und dann auch deine privaten Beiträge sehen.",
|
||||
"compose_form.lock_disclaimer.lock": "gesperrt",
|
||||
"compose_form.placeholder": "Worüber möchtest du schreiben?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
|
||||
"standalone.public_title": "Ein kleiner Einblick …",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
|
||||
"status.delete": "Löschen",
|
||||
"status.embed": "Einbetten",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Medien versteckt",
|
||||
"status.mention": "@{name} erwähnen",
|
||||
"status.more": "Mehr",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Thread stummschalten",
|
||||
"status.open": "Diesen Beitrag öffnen",
|
||||
"status.pin": "Im Profil anheften",
|
||||
|
@@ -727,6 +727,10 @@
|
||||
{
|
||||
"defaultMessage": "locked",
|
||||
"id": "compose_form.lock_disclaimer.lock"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"id": "compose_form.hashtag_warning"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/compose/containers/warning_container.json"
|
||||
@@ -1053,7 +1057,7 @@
|
||||
"id": "lists.delete"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "There is nothing in this list yet.",
|
||||
"defaultMessage": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
||||
"id": "empty_column.list"
|
||||
}
|
||||
],
|
||||
@@ -1244,6 +1248,22 @@
|
||||
"defaultMessage": "Favourite",
|
||||
"id": "status.favourite"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Mute @{name}",
|
||||
"id": "status.mute"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Mute conversation",
|
||||
"id": "status.mute_conversation"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Unmute conversation",
|
||||
"id": "status.unmute_conversation"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Block @{name}",
|
||||
"id": "status.block"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Report @{name}",
|
||||
"id": "status.report"
|
||||
@@ -1276,6 +1296,14 @@
|
||||
{
|
||||
"defaultMessage": "Are you sure you want to delete this status?",
|
||||
"id": "confirmations.delete.message"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Block",
|
||||
"id": "confirmations.block.confirm"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Are you sure you want to block {name}?",
|
||||
"id": "confirmations.block.message"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/status/index.json"
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "What is on your mind?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Delete",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Mention @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Depingli",
|
||||
"column_subheading.navigation": "Navigado",
|
||||
"column_subheading.settings": "Agordoj",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Via konta ne estas ŝlosita. Iu ajn povas sekvi vin por vidi viajn privatajn pepojn.",
|
||||
"compose_form.lock_disclaimer.lock": "ŝlosita",
|
||||
"compose_form.placeholder": "Pri kio vi pensas?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "uzanto",
|
||||
"search_results.total": "{count, number} {count, plural, one {rezultato} other {rezultatoj}}",
|
||||
"standalone.public_title": "Rigardeti…",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Tiun publikaĵon oni ne povas diskonigi",
|
||||
"status.delete": "Forigi",
|
||||
"status.embed": "Enmeti",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Sonbildaĵo kaŝita",
|
||||
"status.mention": "Mencii @{name}",
|
||||
"status.more": "Pli",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Silentigi konversacion",
|
||||
"status.open": "Disfaldi statkonigon",
|
||||
"status.pin": "Pingli al la profilo",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Dejar de fijar",
|
||||
"column_subheading.navigation": "Navegación",
|
||||
"column_subheading.settings": "Ajustes",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
|
||||
"compose_form.lock_disclaimer.lock": "bloqueado",
|
||||
"compose_form.placeholder": "¿En qué estás pensando?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "usuario",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
|
||||
"standalone.public_title": "Un pequeño vistazo...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Este toot no puede retootearse",
|
||||
"status.delete": "Borrar",
|
||||
"status.embed": "Incrustado",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Contenido multimedia oculto",
|
||||
"status.mention": "Mencionar",
|
||||
"status.more": "Más",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Silenciar conversación",
|
||||
"status.open": "Expandir estado",
|
||||
"status.pin": "Fijar",
|
||||
|
@@ -7,22 +7,22 @@
|
||||
"account.followers": "پیگیران",
|
||||
"account.follows": "پی میگیرد",
|
||||
"account.follows_you": "پیگیر شماست",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.hide_reblogs": "پنهان کردن بازبوقهای @{name}",
|
||||
"account.media": "رسانه",
|
||||
"account.mention": "نامبردن از @{name}",
|
||||
"account.moved_to": "{name} has moved to:",
|
||||
"account.moved_to": "{name} منتقل شده است به:",
|
||||
"account.mute": "بیصدا کردن @{name}",
|
||||
"account.mute_notifications": "Mute notifications from @{name}",
|
||||
"account.mute_notifications": "بیصداکردن اعلانها از طرف @{name}",
|
||||
"account.posts": "نوشتهها",
|
||||
"account.report": "گزارش @{name}",
|
||||
"account.requested": "در انتظار پذیرش",
|
||||
"account.share": "همرسانی نمایهٔ @{name}",
|
||||
"account.show_reblogs": "Show boosts from @{name}",
|
||||
"account.show_reblogs": "نشاندادن بازبوقهای @{name}",
|
||||
"account.unblock": "رفع انسداد @{name}",
|
||||
"account.unblock_domain": "رفع پنهانسازی از {domain}",
|
||||
"account.unfollow": "پایان پیگیری",
|
||||
"account.unmute": "باصدا کردن @{name}",
|
||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||
"account.unmute_notifications": "باصداکردن اعلانها از طرف @{name}",
|
||||
"account.view_full_profile": "نمایش نمایهٔ کامل",
|
||||
"boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید",
|
||||
"bundle_column_error.body": "هنگام بازکردن این بخش خطایی رخ داد.",
|
||||
@@ -36,7 +36,7 @@
|
||||
"column.favourites": "پسندیدهها",
|
||||
"column.follow_requests": "درخواستهای پیگیری",
|
||||
"column.home": "خانه",
|
||||
"column.lists": "Lists",
|
||||
"column.lists": "فهرستها",
|
||||
"column.mutes": "کاربران بیصداشده",
|
||||
"column.notifications": "اعلانها",
|
||||
"column.pins": "نوشتههای ثابت",
|
||||
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "رهاکردن",
|
||||
"column_subheading.navigation": "گشت و گذار",
|
||||
"column_subheading.settings": "تنظیمات",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "حساب شما {locked} نیست. هر کسی میتواند پیگیر شما شود و نوشتههای ویژهٔ پیگیران شما را ببیند.",
|
||||
"compose_form.lock_disclaimer.lock": "قفل",
|
||||
"compose_form.placeholder": "تازه چه خبر؟",
|
||||
@@ -64,7 +65,7 @@
|
||||
"confirmations.delete.confirm": "پاک کن",
|
||||
"confirmations.delete.message": "آیا واقعاً میخواهید این نوشته را پاک کنید؟",
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||
"confirmations.delete_list.message": "آیا واقعاً میخواهید این فهرست را برای همیشه پاک کنید؟",
|
||||
"confirmations.domain_block.confirm": "پنهانسازی کل دامین",
|
||||
"confirmations.domain_block.message": "آیا جدی جدی میخواهید کل دامین {domain} را مسدود کنید؟ بیشتر وقتها مسدودکردن یا بیصداکردن چند حساب کاربری خاص کافی است و توصیه میشود.",
|
||||
"confirmations.mute.confirm": "بیصدا کن",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "هنوز هیچ چیزی با این هشتگ نیست.",
|
||||
"empty_column.home": "شما هنوز پیگیر کسی نیستید. {public} را ببینید یا چیزی را جستجو کنید تا کاربران دیگر را ببینید.",
|
||||
"empty_column.home.public_timeline": "فهرست نوشتههای همهجا",
|
||||
"empty_column.list": "There is nothing in this list yet.",
|
||||
"empty_column.list": "در این فهرست هنوز چیزی نیست. وقتی اعضای این فهرست چیزی بنویسند، اینجا ظاهر خواهد شد.",
|
||||
"empty_column.notifications": "هنوز هیچ اعلانی ندارید. به نوشتههای دیگران واکنش نشان دهید تا گفتگو آغاز شود.",
|
||||
"empty_column.public": "اینجا هنوز چیزی نیست! خودتان چیزی بنویسید یا کاربران دیگر را پی بگیرید تا اینجا پر شود",
|
||||
"follow_request.authorize": "اجازه دهید",
|
||||
@@ -107,46 +108,46 @@
|
||||
"home.column_settings.show_reblogs": "نمایش بازبوقها",
|
||||
"home.column_settings.show_replies": "نمایش پاسخها",
|
||||
"home.settings": "تنظیمات ستون",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
||||
"keyboard_shortcuts.back": "برای بازگشت",
|
||||
"keyboard_shortcuts.boost": "برای بازبوقیدن",
|
||||
"keyboard_shortcuts.column": "برای برجستهکردن یک نوشته در یکی از ستونها",
|
||||
"keyboard_shortcuts.compose": "برای فعالکردن کادر نوشتهٔ تازه",
|
||||
"keyboard_shortcuts.description": "Description",
|
||||
"keyboard_shortcuts.down": "to move down in the list",
|
||||
"keyboard_shortcuts.down": "برای پایینرفتن در فهرست",
|
||||
"keyboard_shortcuts.enter": "to open status",
|
||||
"keyboard_shortcuts.favourite": "to favourite",
|
||||
"keyboard_shortcuts.favourite": "برای پسندیدن",
|
||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
||||
"keyboard_shortcuts.hotkey": "Hotkey",
|
||||
"keyboard_shortcuts.legend": "to display this legend",
|
||||
"keyboard_shortcuts.mention": "to mention author",
|
||||
"keyboard_shortcuts.reply": "to reply",
|
||||
"keyboard_shortcuts.search": "to focus search",
|
||||
"keyboard_shortcuts.toot": "to start a brand new toot",
|
||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"keyboard_shortcuts.hotkey": "میانبر",
|
||||
"keyboard_shortcuts.legend": "برای نمایش این راهنما",
|
||||
"keyboard_shortcuts.mention": "برای نامبردن از نویسنده",
|
||||
"keyboard_shortcuts.reply": "برای پاسخدادن",
|
||||
"keyboard_shortcuts.search": "برای فعالکردن جستجو",
|
||||
"keyboard_shortcuts.toot": "برای آغاز یک بوق تازه",
|
||||
"keyboard_shortcuts.unfocus": "برای برداشتن توجه از نوشتن/جستجو",
|
||||
"keyboard_shortcuts.up": "برای بالا رفتن در فهرست",
|
||||
"lightbox.close": "بستن",
|
||||
"lightbox.next": "بعدی",
|
||||
"lightbox.previous": "قبلی",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
"lists.edit": "Edit list",
|
||||
"lists.new.create": "Add list",
|
||||
"lists.new.title_placeholder": "New list title",
|
||||
"lists.search": "Search among people you follow",
|
||||
"lists.subheading": "Your lists",
|
||||
"lists.account.add": "افزودن به فهرست",
|
||||
"lists.account.remove": "پاککردن از فهرست",
|
||||
"lists.delete": "حذف فهرست",
|
||||
"lists.edit": "ویرایش فهرست",
|
||||
"lists.new.create": "افزودن فهرست",
|
||||
"lists.new.title_placeholder": "نام فهرست تازه",
|
||||
"lists.search": "بین کسانی که پی میگیرید بگردید",
|
||||
"lists.subheading": "فهرستهای شما",
|
||||
"loading_indicator.label": "بارگیری...",
|
||||
"media_gallery.toggle_visible": "تغییر پیدایی",
|
||||
"missing_indicator.label": "پیدا نشد",
|
||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||
"mute_modal.hide_notifications": "اعلانهای این کاربر پنهان شود؟",
|
||||
"navigation_bar.blocks": "کاربران مسدودشده",
|
||||
"navigation_bar.community_timeline": "نوشتههای محلی",
|
||||
"navigation_bar.edit_profile": "ویرایش نمایه",
|
||||
"navigation_bar.favourites": "پسندیدهها",
|
||||
"navigation_bar.follow_requests": "درخواستهای پیگیری",
|
||||
"navigation_bar.info": "اطلاعات تکمیلی",
|
||||
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
|
||||
"navigation_bar.lists": "Lists",
|
||||
"navigation_bar.keyboard_shortcuts": "میانبرهای صفحهکلید",
|
||||
"navigation_bar.lists": "فهرستها",
|
||||
"navigation_bar.logout": "خروج",
|
||||
"navigation_bar.mutes": "کاربران بیصداشده",
|
||||
"navigation_bar.pins": "نوشتههای ثابت",
|
||||
@@ -173,7 +174,7 @@
|
||||
"onboarding.page_four.home": "ستون «خانه» نوشتههای کسانی را نشان میدهد که شما پی میگیرید.",
|
||||
"onboarding.page_four.notifications": "ستون «اعلانها» ارتباطهای شما با دیگران را نشان میدهد.",
|
||||
"onboarding.page_one.federation": "ماستدون شبکهای از سرورهای مستقل است که با پیوستن به یکدیگر یک شبکهٔ اجتماعی بزرگ را تشکیل میدهند.",
|
||||
"onboarding.page_one.handle": "شما روی سرور {domain} هستید، بنابراین شناسهٔ کامل شما {handle} است.",
|
||||
"onboarding.page_one.handle": "شما روی سرور {domain} هستید، بنابراین شناسهٔ کامل شما {handle} است",
|
||||
"onboarding.page_one.welcome": "به ماستدون خوش آمدید!",
|
||||
"onboarding.page_six.admin": "نشانی مسئول سرور شما {admin} است.",
|
||||
"onboarding.page_six.almost_done": "الان تقریباً آمادهاید...",
|
||||
@@ -198,7 +199,7 @@
|
||||
"privacy.unlisted.short": "فهرستنشده",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.hours": "{number}h",
|
||||
"relative_time.just_now": "now",
|
||||
"relative_time.just_now": "الان",
|
||||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"reply_indicator.cancel": "لغو",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "کاربر",
|
||||
"search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}",
|
||||
"standalone.public_title": "نگاهی به کاربران این سرور...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "این نوشته را نمیشود بازبوقید",
|
||||
"status.delete": "پاککردن",
|
||||
"status.embed": "جاگذاری",
|
||||
@@ -220,7 +222,8 @@
|
||||
"status.load_more": "بیشتر نشان بده",
|
||||
"status.media_hidden": "تصویر پنهان شده",
|
||||
"status.mention": "نامبردن از @{name}",
|
||||
"status.more": "More",
|
||||
"status.more": "بیشتر",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "بیصداکردن گفتگو",
|
||||
"status.open": "این نوشته را باز کن",
|
||||
"status.pin": "نوشتهٔ ثابت نمایه",
|
||||
@@ -241,7 +244,7 @@
|
||||
"tabs_bar.home": "خانه",
|
||||
"tabs_bar.local_timeline": "محلی",
|
||||
"tabs_bar.notifications": "اعلانها",
|
||||
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
|
||||
"ui.beforeunload": "اگر از ماستدون خارج شوید پیشنویس شما پاک خواهد شد.",
|
||||
"upload_area.title": "برای بارگذاری به اینجا بکشید",
|
||||
"upload_button.label": "افزودن تصویر",
|
||||
"upload_form.description": "نوشتهٔ توضیحی برای کمبینایان و نابینایان",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "Mitä sinulla on mielessä?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Poista",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Mainitse @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Retirer",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Paramètres",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Votre compte n’est pas {locked}. Tout le monde peut vous suivre et voir vos pouets privés.",
|
||||
"compose_form.lock_disclaimer.lock": "verrouillé",
|
||||
"compose_form.placeholder": "Qu’avez-vous en tête ?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Il n’y a encore aucun contenu associé à ce hashtag",
|
||||
"empty_column.home": "Vous ne suivez encore personne. Visitez {public} ou bien utilisez la recherche pour vous connecter à d’autres utilisateur⋅ice⋅s.",
|
||||
"empty_column.home.public_timeline": "le fil public",
|
||||
"empty_column.list": "Il n'y a rien dans cette liste pour l'instant.",
|
||||
"empty_column.list": "Il n'y a rien dans cette liste pour l'instant. Dès que des personnes de cette liste publierons de nouveaux statuts, ils apparaîtront ici.",
|
||||
"empty_column.notifications": "Vous n’avez pas encore de notification. Interagissez avec d’autres utilisateur⋅ice⋅s pour débuter la conversation.",
|
||||
"empty_column.public": "Il n’y a rien ici ! Écrivez quelque chose publiquement, ou bien suivez manuellement des utilisateur⋅ice⋅s d’autres instances pour remplir le fil public.",
|
||||
"follow_request.authorize": "Accepter",
|
||||
@@ -113,7 +114,7 @@
|
||||
"keyboard_shortcuts.compose": "pour centrer la zone de redaction",
|
||||
"keyboard_shortcuts.description": "Description",
|
||||
"keyboard_shortcuts.down": "descendre dans la liste",
|
||||
"keyboard_shortcuts.enter": "to open status",
|
||||
"keyboard_shortcuts.enter": "pour ouvrir le statut",
|
||||
"keyboard_shortcuts.favourite": "vers les favoris",
|
||||
"keyboard_shortcuts.heading": "Raccourcis clavier",
|
||||
"keyboard_shortcuts.hotkey": "Raccourci",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "utilisateur⋅ice",
|
||||
"search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
|
||||
"standalone.public_title": "Jeter un coup d’œil…",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Cette publication ne peut être boostée",
|
||||
"status.delete": "Effacer",
|
||||
"status.embed": "Intégrer",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Média caché",
|
||||
"status.mention": "Mentionner",
|
||||
"status.more": "Plus",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Masquer la conversation",
|
||||
"status.open": "Déplier ce statut",
|
||||
"status.pin": "Épingler sur le profil",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Soltar",
|
||||
"column_subheading.navigation": "Navegación",
|
||||
"column_subheading.settings": "Axustes",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "A súa conta non está {locked}. Calquera pode seguila para ver as súas mensaxes só-para-seguidoras.",
|
||||
"compose_form.lock_disclaimer.lock": "bloqueado",
|
||||
"compose_form.placeholder": "A qué andas?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Aínda non hai nada con esta etiqueta.",
|
||||
"empty_column.home": "A súa liña temporal de inicio está baldeira! Visite {public} ou utilice a busca para atopar outras usuarias.",
|
||||
"empty_column.home.public_timeline": "a liña temporal pública",
|
||||
"empty_column.list": "Aínda non hai nada en esta lista.",
|
||||
"empty_column.list": "Aínda non hai nada en esta lista. Cando as usuarias incluídas na lista publiquen mensaxes, aparecerán aquí.",
|
||||
"empty_column.notifications": "Aínda non ten notificacións. Interactúe con outras para iniciar unha conversa.",
|
||||
"empty_column.public": "Nada por aquí! Escriba algo de xeito público, ou siga manualmente usuarias de outras instancias para ir enchéndoa",
|
||||
"follow_request.authorize": "Autorizar",
|
||||
@@ -108,7 +109,7 @@
|
||||
"home.column_settings.show_replies": "Mostrar respostas",
|
||||
"home.settings": "Axustes da columna",
|
||||
"keyboard_shortcuts.back": "voltar atrás",
|
||||
"keyboard_shortcuts.boost": "repetir",
|
||||
"keyboard_shortcuts.boost": "promover",
|
||||
"keyboard_shortcuts.column": "destacar un estado en unha das columnas",
|
||||
"keyboard_shortcuts.compose": "Foco no área de escritura",
|
||||
"keyboard_shortcuts.description": "Descrición",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "usuaria",
|
||||
"search_results.total": "{count, number} {count,plural,one {result} outros {results}}",
|
||||
"standalone.public_title": "Ollada dentro...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Esta mensaxe non pode ser promocionada",
|
||||
"status.delete": "Eliminar",
|
||||
"status.embed": "Incrustar",
|
||||
@@ -221,11 +223,12 @@
|
||||
"status.media_hidden": "Medios ocultos",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
"status.more": "Máis",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Acalar conversa",
|
||||
"status.open": "Expandir este estado",
|
||||
"status.pin": "Fixar no perfil",
|
||||
"status.reblog": "Promocionar",
|
||||
"status.reblogged_by": "{name} promocionado",
|
||||
"status.reblog": "Promover",
|
||||
"status.reblogged_by": "{name} promoveu",
|
||||
"status.reply": "Resposta",
|
||||
"status.replyAll": "Resposta a conversa",
|
||||
"status.report": "Informar @{name}",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "שחרור קיבוע",
|
||||
"column_subheading.navigation": "ניווט",
|
||||
"column_subheading.settings": "אפשרויות",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "חשבונך אינו {locked}. כל אחד יוכל לעקוב אחריך כדי לקרוא את הודעותיך המיועדות לעוקבים בלבד.",
|
||||
"compose_form.lock_disclaimer.lock": "נעול",
|
||||
"compose_form.placeholder": "מה עובר לך בראש?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "משתמש(ת)",
|
||||
"search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}",
|
||||
"standalone.public_title": "הצצה פנימה...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "לא ניתן להדהד הודעה זו",
|
||||
"status.delete": "מחיקה",
|
||||
"status.embed": "הטמעה",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "מדיה מוסתרת",
|
||||
"status.mention": "פניה אל @{name}",
|
||||
"status.more": "עוד",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "השתקת שיחה",
|
||||
"status.open": "הרחבת הודעה",
|
||||
"status.pin": "לקבע באודות",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigacija",
|
||||
"column_subheading.settings": "Postavke",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Tvoj račun nije {locked}. Svatko te može slijediti kako bi vidio postove namijenjene samo tvojim sljedbenicima.",
|
||||
"compose_form.lock_disclaimer.lock": "zaključan",
|
||||
"compose_form.placeholder": "Što ti je na umu?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Ovaj post ne može biti boostan",
|
||||
"status.delete": "Obriši",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Sakriven media sadržaj",
|
||||
"status.mention": "Spomeni @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Utišaj razgovor",
|
||||
"status.open": "Proširi ovaj status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "Mire gondolsz?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Törlés",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Említés",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigasi",
|
||||
"column_subheading.settings": "Pengaturan",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Akun anda tidak {locked}. Semua orang dapat mengikuti anda untuk melihat postingan khusus untuk pengikut anda.",
|
||||
"compose_form.lock_disclaimer.lock": "dikunci",
|
||||
"compose_form.placeholder": "Apa yang ada di pikiran anda?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count} {count, plural, one {hasil} other {hasil}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Hapus",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media disembunyikan",
|
||||
"status.mention": "Balasan @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Tampilkan status ini",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "Quo esas en tua spirito?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {rezulto} other {rezulti}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Efacar",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Kontenajo celita",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Detaligar ca mesajo",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "A cosa stai pensando?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count} {count, plural, one {risultato} other {risultati}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Elimina",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Allegato nascosto",
|
||||
"status.mention": "Nomina @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Espandi questo post",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "ピン留めを外す",
|
||||
"column_subheading.navigation": "ナビゲーション",
|
||||
"column_subheading.settings": "設定",
|
||||
"compose_form.hashtag_warning": "このトゥートは未収載なのでハッシュタグの一覧に表示されません。公開トゥートだけがハッシュタグで検索できます。",
|
||||
"compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
|
||||
"compose_form.lock_disclaimer.lock": "非公開",
|
||||
"compose_form.placeholder": "今なにしてる?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "このハッシュタグはまだ使われていません。",
|
||||
"empty_column.home": "まだ誰もフォローしていません。{public}を見に行くか、検索を使って他のユーザーを見つけましょう。",
|
||||
"empty_column.home.public_timeline": "連合タイムライン",
|
||||
"empty_column.list": "このリストにはまだなにもありません。",
|
||||
"empty_column.list": "このリストにはまだなにもありません。このリストのメンバーが新しいトゥートをするとここに表示されます。",
|
||||
"empty_column.notifications": "まだ通知がありません。他の人とふれ合って会話を始めましょう。",
|
||||
"empty_column.public": "ここにはまだ何もありません! 公開で何かを投稿したり、他のインスタンスのユーザーをフォローしたりしていっぱいにしましょう",
|
||||
"follow_request.authorize": "許可",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "ユーザー",
|
||||
"search_results.total": "{count, number}件の結果",
|
||||
"standalone.public_title": "今こんな話をしています...",
|
||||
"status.block": "@{name}をブロック",
|
||||
"status.cannot_reblog": "この投稿はブーストできません",
|
||||
"status.delete": "削除",
|
||||
"status.embed": "埋め込み",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "非表示のメディア",
|
||||
"status.mention": "返信",
|
||||
"status.more": "もっと見る",
|
||||
"status.mute": "@{name}をミュート",
|
||||
"status.mute_conversation": "会話をミュート",
|
||||
"status.open": "詳細を表示",
|
||||
"status.pin": "プロフィールに固定表示",
|
||||
|
@@ -1,55 +1,56 @@
|
||||
{
|
||||
"account.block": "차단",
|
||||
"account.block_domain": "{domain} 전체를 숨김",
|
||||
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
|
||||
"account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.",
|
||||
"account.edit_profile": "프로필 편집",
|
||||
"account.follow": "팔로우",
|
||||
"account.followers": "팔로워",
|
||||
"account.follows": "팔로우",
|
||||
"account.follows_you": "날 팔로우합니다",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.hide_reblogs": "@{name}의 부스트를 숨기기",
|
||||
"account.media": "미디어",
|
||||
"account.mention": "답장",
|
||||
"account.moved_to": "{name} has moved to:",
|
||||
"account.moved_to": "{name}는 계정을 이동했습니다:",
|
||||
"account.mute": "뮤트",
|
||||
"account.mute_notifications": "Mute notifications from @{name}",
|
||||
"account.mute_notifications": "@{name}의 알림을 뮤트",
|
||||
"account.posts": "포스트",
|
||||
"account.report": "신고",
|
||||
"account.requested": "승인 대기 중",
|
||||
"account.share": "Share @{name}'s profile",
|
||||
"account.show_reblogs": "Show boosts from @{name}",
|
||||
"account.share": "@{name}의 프로파일 공유",
|
||||
"account.show_reblogs": "@{name}의 부스트 보기",
|
||||
"account.unblock": "차단 해제",
|
||||
"account.unblock_domain": "{domain} 숨김 해제",
|
||||
"account.unfollow": "팔로우 해제",
|
||||
"account.unmute": "뮤트 해제",
|
||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||
"account.unmute_notifications": "@{name}의 알림 뮤트 해제",
|
||||
"account.view_full_profile": "전체 프로필 보기",
|
||||
"boost_modal.combo": "다음부터 {combo}를 누르면 이 과정을 건너뛸 수 있습니다.",
|
||||
"bundle_column_error.body": "Something went wrong while loading this component.",
|
||||
"bundle_column_error.retry": "Try again",
|
||||
"bundle_column_error.title": "Network error",
|
||||
"bundle_modal_error.close": "Close",
|
||||
"bundle_modal_error.message": "Something went wrong while loading this component.",
|
||||
"bundle_modal_error.retry": "Try again",
|
||||
"bundle_column_error.body": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.",
|
||||
"bundle_column_error.retry": "다시 시도",
|
||||
"bundle_column_error.title": "네트워크 에러",
|
||||
"bundle_modal_error.close": "닫기",
|
||||
"bundle_modal_error.message": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.",
|
||||
"bundle_modal_error.retry": "다시 시도",
|
||||
"column.blocks": "차단 중인 사용자",
|
||||
"column.community": "로컬 타임라인",
|
||||
"column.favourites": "즐겨찾기",
|
||||
"column.follow_requests": "팔로우 요청",
|
||||
"column.home": "홈",
|
||||
"column.lists": "Lists",
|
||||
"column.lists": "리스트",
|
||||
"column.mutes": "뮤트 중인 사용자",
|
||||
"column.notifications": "알림",
|
||||
"column.pins": "고정된 툿",
|
||||
"column.public": "연합 타임라인",
|
||||
"column_back_button.label": "돌아가기",
|
||||
"column_header.hide_settings": "Hide settings",
|
||||
"column_header.moveLeft_settings": "Move column to the left",
|
||||
"column_header.moveRight_settings": "Move column to the right",
|
||||
"column_header.hide_settings": "설정 숨기기",
|
||||
"column_header.moveLeft_settings": "왼쪽으로 이동",
|
||||
"column_header.moveRight_settings": "오른쪽으로 이동",
|
||||
"column_header.pin": "고정하기",
|
||||
"column_header.show_settings": "Show settings",
|
||||
"column_header.show_settings": "설정 보이기",
|
||||
"column_header.unpin": "고정 해제",
|
||||
"column_subheading.navigation": "내비게이션",
|
||||
"column_subheading.settings": "설정",
|
||||
"compose_form.hashtag_warning": "이 툿은 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 툿만이 해시태그로 검색 될 수 있습니다.",
|
||||
"compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.",
|
||||
"compose_form.lock_disclaimer.lock": "비공개",
|
||||
"compose_form.placeholder": "지금 무엇을 하고 있나요?",
|
||||
@@ -63,35 +64,35 @@
|
||||
"confirmations.block.message": "정말로 {name}를 차단하시겠습니까?",
|
||||
"confirmations.delete.confirm": "삭제",
|
||||
"confirmations.delete.message": "정말로 삭제하시겠습니까?",
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||
"confirmations.delete_list.confirm": "삭제",
|
||||
"confirmations.delete_list.message": "정말로 이 리스트를 삭제하시겠습니까?",
|
||||
"confirmations.domain_block.confirm": "도메인 전체를 숨김",
|
||||
"confirmations.domain_block.message": "정말로 {domain} 전체를 숨기시겠습니까? 대부분의 경우 개별 차단이나 뮤트로 충분합니다.",
|
||||
"confirmations.mute.confirm": "뮤트",
|
||||
"confirmations.mute.message": "정말로 {name}를 뮤트하시겠습니까?",
|
||||
"confirmations.unfollow.confirm": "Unfollow",
|
||||
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
|
||||
"confirmations.unfollow.confirm": "언팔로우",
|
||||
"confirmations.unfollow.message": "정말로 {name}를 언팔로우하시겠습니까?",
|
||||
"embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 공유하세요.",
|
||||
"embed.preview": "다음과 같이 표시됩니다:",
|
||||
"emoji_button.activity": "활동",
|
||||
"emoji_button.custom": "Custom",
|
||||
"emoji_button.custom": "커스텀",
|
||||
"emoji_button.flags": "국기",
|
||||
"emoji_button.food": "음식",
|
||||
"emoji_button.label": "emoji를 추가",
|
||||
"emoji_button.nature": "자연",
|
||||
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.not_found": "없어!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.objects": "물건",
|
||||
"emoji_button.people": "사람들",
|
||||
"emoji_button.recent": "Frequently used",
|
||||
"emoji_button.recent": "자주 사용 됨",
|
||||
"emoji_button.search": "검색...",
|
||||
"emoji_button.search_results": "Search results",
|
||||
"emoji_button.search_results": "검색 결과",
|
||||
"emoji_button.symbols": "기호",
|
||||
"emoji_button.travel": "여행과 장소",
|
||||
"empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!",
|
||||
"empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.",
|
||||
"empty_column.home": "아직 아무도 팔로우 하고 있지 않습니다. {public}를 보러 가거나, 검색하여 다른 사용자를 찾아 보세요.",
|
||||
"empty_column.home.public_timeline": "연합 타임라인",
|
||||
"empty_column.list": "There is nothing in this list yet.",
|
||||
"empty_column.list": "리스트에 아직 아무 것도 없습니다.",
|
||||
"empty_column.notifications": "아직 알림이 없습니다. 다른 사람과 대화를 시작해 보세요!",
|
||||
"empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 인스턴스 유저를 팔로우 해서 가득 채워보세요!",
|
||||
"follow_request.authorize": "허가",
|
||||
@@ -107,46 +108,46 @@
|
||||
"home.column_settings.show_reblogs": "부스트 표시",
|
||||
"home.column_settings.show_replies": "답글 표시",
|
||||
"home.settings": "컬럼 설정",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
||||
"keyboard_shortcuts.description": "Description",
|
||||
"keyboard_shortcuts.down": "to move down in the list",
|
||||
"keyboard_shortcuts.enter": "to open status",
|
||||
"keyboard_shortcuts.favourite": "to favourite",
|
||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
||||
"keyboard_shortcuts.hotkey": "Hotkey",
|
||||
"keyboard_shortcuts.legend": "to display this legend",
|
||||
"keyboard_shortcuts.mention": "to mention author",
|
||||
"keyboard_shortcuts.reply": "to reply",
|
||||
"keyboard_shortcuts.search": "to focus search",
|
||||
"keyboard_shortcuts.toot": "to start a brand new toot",
|
||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"keyboard_shortcuts.back": "뒤로가기",
|
||||
"keyboard_shortcuts.boost": "부스트",
|
||||
"keyboard_shortcuts.column": "해당 열에 포커스",
|
||||
"keyboard_shortcuts.compose": "작성창으로 포커스",
|
||||
"keyboard_shortcuts.description": "설명",
|
||||
"keyboard_shortcuts.down": "리스트에서 아래로 이동",
|
||||
"keyboard_shortcuts.enter": "열기",
|
||||
"keyboard_shortcuts.favourite": "관심글 지정",
|
||||
"keyboard_shortcuts.heading": "키보드 단축키",
|
||||
"keyboard_shortcuts.hotkey": "핫키",
|
||||
"keyboard_shortcuts.legend": "이 도움말 표시",
|
||||
"keyboard_shortcuts.mention": "멘션",
|
||||
"keyboard_shortcuts.reply": "답장",
|
||||
"keyboard_shortcuts.search": "검색창에 포커스",
|
||||
"keyboard_shortcuts.toot": "새 툿 작성",
|
||||
"keyboard_shortcuts.unfocus": "작성창에서 포커스 해제",
|
||||
"keyboard_shortcuts.up": "리스트에서 위로 이동",
|
||||
"lightbox.close": "닫기",
|
||||
"lightbox.next": "Next",
|
||||
"lightbox.previous": "Previous",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
"lists.edit": "Edit list",
|
||||
"lists.new.create": "Add list",
|
||||
"lists.new.title_placeholder": "New list title",
|
||||
"lists.search": "Search among people you follow",
|
||||
"lists.subheading": "Your lists",
|
||||
"lightbox.next": "다음",
|
||||
"lightbox.previous": "이전",
|
||||
"lists.account.add": "리스트에 추가",
|
||||
"lists.account.remove": "리스트에서 제거",
|
||||
"lists.delete": "리스트 삭제",
|
||||
"lists.edit": "리스트 편집",
|
||||
"lists.new.create": "리스트 추가",
|
||||
"lists.new.title_placeholder": "새 리스트의 이름",
|
||||
"lists.search": "팔로우 중인 사람들 중에서 찾기",
|
||||
"lists.subheading": "당신의 리스트",
|
||||
"loading_indicator.label": "불러오는 중...",
|
||||
"media_gallery.toggle_visible": "표시 전환",
|
||||
"missing_indicator.label": "찾을 수 없습니다",
|
||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||
"mute_modal.hide_notifications": "이 사용자로부터의 알림을 뮤트하시겠습니까?",
|
||||
"navigation_bar.blocks": "차단한 사용자",
|
||||
"navigation_bar.community_timeline": "로컬 타임라인",
|
||||
"navigation_bar.edit_profile": "프로필 편집",
|
||||
"navigation_bar.favourites": "즐겨찾기",
|
||||
"navigation_bar.follow_requests": "팔로우 요청",
|
||||
"navigation_bar.info": "이 인스턴스에 대해서",
|
||||
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
|
||||
"navigation_bar.lists": "Lists",
|
||||
"navigation_bar.keyboard_shortcuts": "키보드 단축키",
|
||||
"navigation_bar.lists": "리스트",
|
||||
"navigation_bar.logout": "로그아웃",
|
||||
"navigation_bar.mutes": "뮤트 중인 사용자",
|
||||
"navigation_bar.pins": "고정된 툿",
|
||||
@@ -162,8 +163,8 @@
|
||||
"notifications.column_settings.favourite": "즐겨찾기",
|
||||
"notifications.column_settings.follow": "새 팔로워",
|
||||
"notifications.column_settings.mention": "답글",
|
||||
"notifications.column_settings.push": "Push notifications",
|
||||
"notifications.column_settings.push_meta": "This device",
|
||||
"notifications.column_settings.push": "푸시 알림",
|
||||
"notifications.column_settings.push_meta": "이 장치",
|
||||
"notifications.column_settings.reblog": "부스트",
|
||||
"notifications.column_settings.show": "컬럼에 표시",
|
||||
"notifications.column_settings.sound": "효과음 재생",
|
||||
@@ -177,7 +178,7 @@
|
||||
"onboarding.page_one.welcome": "Mastodon에 어서 오세요!",
|
||||
"onboarding.page_six.admin": "이 인스턴스의 관리자는 {admin}입니다.",
|
||||
"onboarding.page_six.almost_done": "이상입니다.",
|
||||
"onboarding.page_six.appetoot": "Bon Appetoot!",
|
||||
"onboarding.page_six.appetoot": "본 아페툿!",
|
||||
"onboarding.page_six.apps_available": "iOS、Android 또는 다른 플랫폼에서 사용할 수 있는 {apps}이 있습니다.",
|
||||
"onboarding.page_six.github": "Mastodon는 오픈 소스 소프트웨어입니다. 버그 보고나 기능 추가 요청, 기여는 {github}에서 할 수 있습니다.",
|
||||
"onboarding.page_six.guidelines": "커뮤니티 가이드라인",
|
||||
@@ -212,7 +213,8 @@
|
||||
"search_popout.tips.text": "단순한 텍스트 검색은 관계된 프로필 이름, 유저 이름 그리고 해시태그를 표시합니다",
|
||||
"search_popout.tips.user": "유저",
|
||||
"search_results.total": "{count, number}건의 결과",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"standalone.public_title": "지금 이런 이야기를 하고 있습니다…",
|
||||
"status.block": "@{name} 차단",
|
||||
"status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
|
||||
"status.delete": "삭제",
|
||||
"status.embed": "공유하기",
|
||||
@@ -220,7 +222,8 @@
|
||||
"status.load_more": "더 보기",
|
||||
"status.media_hidden": "미디어 숨겨짐",
|
||||
"status.mention": "답장",
|
||||
"status.more": "More",
|
||||
"status.more": "자세히",
|
||||
"status.mute": "@{name} 뮤트",
|
||||
"status.mute_conversation": "이 대화를 뮤트",
|
||||
"status.open": "상세 정보 표시",
|
||||
"status.pin": "고정",
|
||||
@@ -231,7 +234,7 @@
|
||||
"status.report": "신고",
|
||||
"status.sensitive_toggle": "클릭해서 표시하기",
|
||||
"status.sensitive_warning": "민감한 미디어",
|
||||
"status.share": "Share",
|
||||
"status.share": "공유",
|
||||
"status.show_less": "숨기기",
|
||||
"status.show_more": "더 보기",
|
||||
"status.unmute_conversation": "이 대화의 뮤트 해제하기",
|
||||
@@ -241,19 +244,19 @@
|
||||
"tabs_bar.home": "홈",
|
||||
"tabs_bar.local_timeline": "로컬",
|
||||
"tabs_bar.notifications": "알림",
|
||||
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
|
||||
"ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.",
|
||||
"upload_area.title": "드래그 & 드롭으로 업로드",
|
||||
"upload_button.label": "미디어 추가",
|
||||
"upload_form.description": "Describe for the visually impaired",
|
||||
"upload_form.description": "시각장애인을 위한 설명",
|
||||
"upload_form.undo": "재시도",
|
||||
"upload_progress.label": "업로드 중...",
|
||||
"video.close": "Close video",
|
||||
"video.exit_fullscreen": "Exit full screen",
|
||||
"video.expand": "Expand video",
|
||||
"video.fullscreen": "Full screen",
|
||||
"video.hide": "Hide video",
|
||||
"video.mute": "Mute sound",
|
||||
"video.pause": "Pause",
|
||||
"video.play": "Play",
|
||||
"video.unmute": "Unmute sound"
|
||||
"video.close": "동영상 닫기",
|
||||
"video.exit_fullscreen": "전체화면 나가기",
|
||||
"video.expand": "동영상 확장",
|
||||
"video.fullscreen": "전체화면",
|
||||
"video.hide": "동영상 숨기기",
|
||||
"video.mute": "음소거",
|
||||
"video.pause": "일시정지",
|
||||
"video.play": "재생",
|
||||
"video.unmute": "음소거 해제"
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Losmaken",
|
||||
"column_subheading.navigation": "Navigatie",
|
||||
"column_subheading.settings": "Instellingen",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en toots zien die je alleen aan volgers hebt gericht.",
|
||||
"compose_form.lock_disclaimer.lock": "besloten",
|
||||
"compose_form.placeholder": "Wat wil je kwijt?",
|
||||
@@ -64,7 +65,7 @@
|
||||
"confirmations.delete.confirm": "Verwijderen",
|
||||
"confirmations.delete.message": "Weet je het zeker dat je deze toot wilt verwijderen?",
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "Weet je zeker dat je deze lijst permanent wilt verwijderen?",
|
||||
"confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?",
|
||||
"confirmations.domain_block.confirm": "Negeer alles van deze server",
|
||||
"confirmations.domain_block.message": "Weet je het echt, echt zeker dat je alles van {domain} wil negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en gewenst.",
|
||||
"confirmations.mute.confirm": "Negeren",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Er is nog niks te vinden onder deze hashtag.",
|
||||
"empty_column.home": "Jij volgt nog niemand. Bezoek {public} of gebruik het zoekvenster om andere mensen te ontmoeten.",
|
||||
"empty_column.home.public_timeline": "de globale tijdlijn",
|
||||
"empty_column.list": "Er is nog niks in deze lijst.",
|
||||
"empty_column.list": "Er is nog niks in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.",
|
||||
"empty_column.notifications": "Je hebt nog geen meldingen. Heb interactie met andere mensen om het gesprek aan te gaan.",
|
||||
"empty_column.public": "Er is hier helemaal niks! Toot iets in het openbaar of volg mensen van andere servers om het te vullen",
|
||||
"follow_request.authorize": "Goedkeuren",
|
||||
@@ -99,10 +100,10 @@
|
||||
"getting_started.appsshort": "Apps",
|
||||
"getting_started.faq": "FAQ",
|
||||
"getting_started.heading": "Beginnen",
|
||||
"getting_started.open_source_notice": "Mastodon is open-sourcesoftware. Je kunt bijdragen of problemen melden op GitHub via {github}.",
|
||||
"getting_started.open_source_notice": "Mastodon is vrije software. Je kunt bijdragen of problemen melden op GitHub via {github}.",
|
||||
"getting_started.userguide": "Gebruikersgids",
|
||||
"home.column_settings.advanced": "Geavanceerd",
|
||||
"home.column_settings.basic": "Basis",
|
||||
"home.column_settings.basic": "Algemeen",
|
||||
"home.column_settings.filter_regex": "Wegfilteren met reguliere expressies",
|
||||
"home.column_settings.show_reblogs": "Boosts tonen",
|
||||
"home.column_settings.show_replies": "Reacties tonen",
|
||||
@@ -129,7 +130,7 @@
|
||||
"lightbox.previous": "Vorige",
|
||||
"lists.account.add": "Aan lijst toevoegen",
|
||||
"lists.account.remove": "Uit lijst verwijderen",
|
||||
"lists.delete": "Delete list",
|
||||
"lists.delete": "Lijst verwijderen",
|
||||
"lists.edit": "Lijst bewerken",
|
||||
"lists.new.create": "Lijst toevoegen",
|
||||
"lists.new.title_placeholder": "Naam nieuwe lijst",
|
||||
@@ -145,7 +146,7 @@
|
||||
"navigation_bar.favourites": "Favorieten",
|
||||
"navigation_bar.follow_requests": "Volgverzoeken",
|
||||
"navigation_bar.info": "Uitgebreide informatie",
|
||||
"navigation_bar.keyboard_shortcuts": "Toetsenbord sneltoetsen",
|
||||
"navigation_bar.keyboard_shortcuts": "Sneltoetsen",
|
||||
"navigation_bar.lists": "Lijsten",
|
||||
"navigation_bar.logout": "Afmelden",
|
||||
"navigation_bar.mutes": "Genegeerde gebruikers",
|
||||
@@ -179,7 +180,7 @@
|
||||
"onboarding.page_six.almost_done": "Bijna klaar...",
|
||||
"onboarding.page_six.appetoot": "Veel succes!",
|
||||
"onboarding.page_six.apps_available": "Er zijn {apps} beschikbaar voor iOS, Android en andere platformen.",
|
||||
"onboarding.page_six.github": "Mastodon kost niets, en is open-source- en vrije software. Je kan bugs melden, nieuwe mogelijkheden aanvragen en als ontwikkelaar meewerken op {github}.",
|
||||
"onboarding.page_six.github": "Mastodon kost niets en is vrije software. Je kan bugs melden, nieuwe mogelijkheden aanvragen en als ontwikkelaar meewerken op {github}.",
|
||||
"onboarding.page_six.guidelines": "communityrichtlijnen",
|
||||
"onboarding.page_six.read_guidelines": "Vergeet niet de {guidelines} van {domain} te lezen!",
|
||||
"onboarding.page_six.various_app": "mobiele apps",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "gebruiker",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}",
|
||||
"standalone.public_title": "Een kijkje binnenin...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Deze toot kan niet geboost worden",
|
||||
"status.delete": "Verwijderen",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media verborgen",
|
||||
"status.mention": "Vermeld @{name}",
|
||||
"status.more": "Meer",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Negeer conversatie",
|
||||
"status.open": "Toot volledig tonen",
|
||||
"status.pin": "Aan profielpagina vastmaken",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Løsne",
|
||||
"column_subheading.navigation": "Navigasjon",
|
||||
"column_subheading.settings": "Innstillinger",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Hvem som helst kan følge deg og se dine private poster.",
|
||||
"compose_form.lock_disclaimer.lock": "låst",
|
||||
"compose_form.placeholder": "Hva har du på hjertet?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Denne posten kan ikke fremheves",
|
||||
"status.delete": "Slett",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media skjult",
|
||||
"status.mention": "Nevn @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Demp samtale",
|
||||
"status.open": "Utvid denne statusen",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Despenjar",
|
||||
"column_subheading.navigation": "Navigacion",
|
||||
"column_subheading.settings": "Paramètres",
|
||||
"compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap etiqueta estant qu’es pas listat. Òm pas cercar que los tuts publics per etiqueta.",
|
||||
"compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo mond pòt vos sègre e veire los estatuts reservats als seguidors.",
|
||||
"compose_form.lock_disclaimer.lock": "clavat",
|
||||
"compose_form.placeholder": "A de qué pensatz ?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "I a pas encara de contengut ligat a aquesta etiqueta.",
|
||||
"empty_column.home": "Vòstre flux d’acuèlh es void. Visitatz {public} o utilizatz la recèrca per vos connectar a d’autras personas.",
|
||||
"empty_column.home.public_timeline": "lo flux public",
|
||||
"empty_column.list": "I a pas res dins la lista pel moment.",
|
||||
"empty_column.list": "I a pas res dins la lista pel moment. Quand de membres d’aquesta lista publiquen de novèls estatuts los veiretz aquí.",
|
||||
"empty_column.notifications": "Avètz pas encara de notificacions. Respondètz a qualqu’un per començar una conversacion.",
|
||||
"empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autras instàncias per garnir lo flux public",
|
||||
"follow_request.authorize": "Autorizar",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "utilizaire",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
|
||||
"standalone.public_title": "Una ulhada dedins…",
|
||||
"status.block": "Blocar @{name}",
|
||||
"status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat",
|
||||
"status.delete": "Escafar",
|
||||
"status.embed": "Embarcar",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Mèdia rescondut",
|
||||
"status.mention": "Mencionar",
|
||||
"status.more": "Mai",
|
||||
"status.mute": "Rescondre @{name}",
|
||||
"status.mute_conversation": "Rescondre la conversacion",
|
||||
"status.open": "Desplegar aqueste estatut",
|
||||
"status.pin": "Penjar al perfil",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Cofnij przypięcie",
|
||||
"column_subheading.navigation": "Nawigacja",
|
||||
"column_subheading.settings": "Ustawienia",
|
||||
"compose_form.hashtag_warning": "Ten wpis nie będzie widoczny pod podanymi hashtagami, ponieważ jest oznaczony jako niewidoczny. Tylko publiczne wpisy mogą zostać znalezione z użyciem hashtagów.",
|
||||
"compose_form.lock_disclaimer": "Twoje konto nie jest {locked}. Każdy, kto Cię śledzi, może wyświetlać Twoje wpisy przeznaczone tylko dla śledzących.",
|
||||
"compose_form.lock_disclaimer.lock": "zablokowane",
|
||||
"compose_form.placeholder": "Co Ci chodzi po głowie?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Nie ma wpisów oznaczonych tym hashtagiem. Możesz napisać pierwszy!",
|
||||
"empty_column.home": "Nie śledzisz nikogo. Odwiedź publiczną oś czasu lub użyj wyszukiwarki, aby znaleźć interesujące Cię profile.",
|
||||
"empty_column.home.public_timeline": "publiczna oś czasu",
|
||||
"empty_column.list": "Nie ma nic na tej liście.",
|
||||
"empty_column.list": "Nie ma nic na tej liście. Kiedy członkowie listy dodadzą nowe wpisy, pojawia się one tutaj.",
|
||||
"empty_column.notifications": "Nie masz żadnych powiadomień. Rozpocznij interakcje z innymi użytkownikami.",
|
||||
"empty_column.public": "Tu nic nie ma! Napisz coś publicznie, lub dodaj ludzi z innych instancji, aby to wyświetlić.",
|
||||
"follow_request.authorize": "Autoryzuj",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "użytkownik",
|
||||
"search_results.total": "{count, number} {count, plural, one {wynik} few {wyniki} many {wyników} more {wyników}}",
|
||||
"standalone.public_title": "Spojrzenie w głąb…",
|
||||
"status.block": "Zablokuj @{name}",
|
||||
"status.cannot_reblog": "Ten wpis nie może zostać podbity",
|
||||
"status.delete": "Usuń",
|
||||
"status.embed": "Osadź",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Zawartość multimedialna ukryta",
|
||||
"status.mention": "Wspomnij o @{name}",
|
||||
"status.more": "Więcej",
|
||||
"status.mute": "Wycisz @{name}",
|
||||
"status.mute_conversation": "Wycisz konwersację",
|
||||
"status.open": "Rozszerz ten wpis",
|
||||
"status.pin": "Przypnij do profilu",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Desafixar",
|
||||
"column_subheading.navigation": "Navegação",
|
||||
"column_subheading.settings": "Configurações",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "A sua conta não está {locked}. Qualquer pessoa pode te seguir e visualizar postagens direcionadas a apenas seguidores.",
|
||||
"compose_form.lock_disclaimer.lock": "trancada",
|
||||
"compose_form.placeholder": "No que você está pensando?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Ainda não há qualquer conteúdo com essa hashtag.",
|
||||
"empty_column.home": "Você ainda não segue usuário algo. Visite a timeline {public} ou use o buscador para procurar e conhecer outros usuários.",
|
||||
"empty_column.home.public_timeline": "global",
|
||||
"empty_column.list": "Ainda não há nada nesta lista.",
|
||||
"empty_column.list": "Ainda não há nada nesta lista. Quando membros dessa lista fizerem novas postagens, elas aparecerão aqui.",
|
||||
"empty_column.notifications": "Você ainda não possui notificações. Interaja com outros usuários para começar a conversar.",
|
||||
"empty_column.public": "Não há nada aqui! Escreva algo publicamente ou siga manualmente usuários de outras instâncias",
|
||||
"follow_request.authorize": "Autorizar",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "usuário",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
|
||||
"standalone.public_title": "Dê uma espiada...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Esta postagem não pode ser compartilhada",
|
||||
"status.delete": "Excluir",
|
||||
"status.embed": "Incorporar",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Mídia escondida",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
"status.more": "Mais",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Silenciar conversa",
|
||||
"status.open": "Expandir",
|
||||
"status.pin": "Fixar no perfil",
|
||||
|
@@ -35,11 +35,11 @@
|
||||
"column.community": "Local",
|
||||
"column.favourites": "Favoritos",
|
||||
"column.follow_requests": "Seguidores Pendentes",
|
||||
"column.home": "Home",
|
||||
"column.home": "Início",
|
||||
"column.lists": "Listas",
|
||||
"column.mutes": "Utilizadores silenciados",
|
||||
"column.notifications": "Notificações",
|
||||
"column.pins": "Pinned toot",
|
||||
"column.pins": "Posts fixos",
|
||||
"column.public": "Global",
|
||||
"column_back_button.label": "Voltar",
|
||||
"column_header.hide_settings": "Esconder preferências",
|
||||
@@ -47,9 +47,10 @@
|
||||
"column_header.moveRight_settings": "Mover coluna para a direita",
|
||||
"column_header.pin": "Fixar",
|
||||
"column_header.show_settings": "Mostrar preferências",
|
||||
"column_header.unpin": "Remover fixar",
|
||||
"column_header.unpin": "Desafixar",
|
||||
"column_subheading.navigation": "Navegação",
|
||||
"column_subheading.settings": "Preferências",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "A tua conta não está {locked}. Qualquer pessoa pode seguir-te e ver as publicações direcionadas apenas a seguidores.",
|
||||
"compose_form.lock_disclaimer.lock": "bloqueada",
|
||||
"compose_form.placeholder": "Em que estás a pensar?",
|
||||
@@ -91,7 +92,7 @@
|
||||
"empty_column.hashtag": "Não foram encontradas publicações com essa hashtag.",
|
||||
"empty_column.home": "Ainda não segues qualquer utilizador. Visita {public} ou utiliza a pesquisa para procurar outros utilizadores.",
|
||||
"empty_column.home.public_timeline": "global",
|
||||
"empty_column.list": "Ainda não existem publicações nesta lista.",
|
||||
"empty_column.list": "Ainda não existem publicações nesta lista. Quando membros desta lista fizerem novas publicações, elas aparecerão aqui.",
|
||||
"empty_column.notifications": "Não tens notificações. Interage com outros utilizadores para iniciar uma conversa.",
|
||||
"empty_column.public": "Não há nada aqui! Escreve algo publicamente ou segue outros utilizadores para ver aqui os conteúdos públicos",
|
||||
"follow_request.authorize": "Autorizar",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "utilizador",
|
||||
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
|
||||
"standalone.public_title": "Espreitar lá dentro...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Este post não pode ser partilhado",
|
||||
"status.delete": "Eliminar",
|
||||
"status.embed": "Incorporar",
|
||||
@@ -221,9 +223,10 @@
|
||||
"status.media_hidden": "Media escondida",
|
||||
"status.mention": "Mencionar @{name}",
|
||||
"status.more": "Mais",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Silenciar conversa",
|
||||
"status.open": "Expandir",
|
||||
"status.pin": "Pin on profile",
|
||||
"status.pin": "Fixar no perfil",
|
||||
"status.reblog": "Partilhar",
|
||||
"status.reblogged_by": "{name} partilhou",
|
||||
"status.reply": "Responder",
|
||||
@@ -231,7 +234,7 @@
|
||||
"status.report": "Denunciar @{name}",
|
||||
"status.sensitive_toggle": "Clique para ver",
|
||||
"status.sensitive_warning": "Conteúdo sensível",
|
||||
"status.share": "Share",
|
||||
"status.share": "Compartilhar",
|
||||
"status.show_less": "Mostrar menos",
|
||||
"status.show_more": "Mostrar mais",
|
||||
"status.unmute_conversation": "Deixar de silenciar esta conversa",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Открепить",
|
||||
"column_subheading.navigation": "Навигация",
|
||||
"column_subheading.settings": "Настройки",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ваш аккаунт не {locked}. Любой человек может подписаться на Вас и просматривать посты для подписчиков.",
|
||||
"compose_form.lock_disclaimer.lock": "закрыт",
|
||||
"compose_form.placeholder": "О чем Вы думаете?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "пользователь",
|
||||
"search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
|
||||
"standalone.public_title": "Прямо сейчас",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Этот статус не может быть продвинут",
|
||||
"status.delete": "Удалить",
|
||||
"status.embed": "Встроить",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Медиаконтент скрыт",
|
||||
"status.mention": "Упомянуть @{name}",
|
||||
"status.more": "Больше",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Заглушить тред",
|
||||
"status.open": "Развернуть статус",
|
||||
"status.pin": "Закрепить в профиле",
|
||||
|
262
app/javascript/mastodon/locales/sk.json
Normal file
262
app/javascript/mastodon/locales/sk.json
Normal file
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"account.block": "Blokovať @{name}",
|
||||
"account.block_domain": "Blokovať všetko z {domain}",
|
||||
"account.disclaimer_full": "Inofrmácie nižšie nemusia reflektovať použivateľský účet kompletne.",
|
||||
"account.edit_profile": "Upraviť profil",
|
||||
"account.follow": "Sledovať",
|
||||
"account.followers": "Sledujúci",
|
||||
"account.follows": "Sledovaní",
|
||||
"account.follows_you": "Sleduje teba",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.media": "Média",
|
||||
"account.mention": "Napísať @{name}",
|
||||
"account.moved_to": "{name} has moved to:",
|
||||
"account.mute": "Ignorovať @{name}",
|
||||
"account.mute_notifications": "Mute notifications from @{name}",
|
||||
"account.posts": "Správ",
|
||||
"account.report": "Nahlásiť @{name}",
|
||||
"account.requested": "Čaká na schválenie. Klikni na zrušenie žiadosti",
|
||||
"account.share": "Zdieľať @{name} profil",
|
||||
"account.show_reblogs": "Show boosts from @{name}",
|
||||
"account.unblock": "Odblokovať @{name}",
|
||||
"account.unblock_domain": "Prestať blokovať {domain}",
|
||||
"account.unfollow": "Prestať nasledovať",
|
||||
"account.unmute": "Prestať ignorovať @{name}",
|
||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||
"account.view_full_profile": "Pozri celý profil",
|
||||
"boost_modal.combo": "Nabudúce môžeš kliknúť {combo} a preskočiť",
|
||||
"bundle_column_error.body": "Nastala chyba pri načítaní tohto komponentu.",
|
||||
"bundle_column_error.retry": "Skús znova",
|
||||
"bundle_column_error.title": "Chyba siete",
|
||||
"bundle_modal_error.close": "Zatvoriť",
|
||||
"bundle_modal_error.message": "Nastala chyba pri načítaní tohto komponentu.",
|
||||
"bundle_modal_error.retry": "Skúsiť znova",
|
||||
"column.blocks": "Blokovaní používatelia",
|
||||
"column.community": "Lokálna časová os",
|
||||
"column.favourites": "Obľúbené",
|
||||
"column.follow_requests": "Žiadosti",
|
||||
"column.home": "Moja časová os",
|
||||
"column.lists": "Lists",
|
||||
"column.mutes": "Ignorovaní používatelia",
|
||||
"column.notifications": "Notifikácie",
|
||||
"column.pins": "Pripnuté toots",
|
||||
"column.public": "Federovaná časová os",
|
||||
"column_back_button.label": "Späť",
|
||||
"column_header.hide_settings": "Skryť nastavenia",
|
||||
"column_header.moveLeft_settings": "Presunúť stĺpec doľava",
|
||||
"column_header.moveRight_settings": "Presunúť stĺpec doprava",
|
||||
"column_header.pin": "Pripnúť",
|
||||
"column_header.show_settings": "Ukázať nastavenia",
|
||||
"column_header.unpin": "Odopnúť",
|
||||
"column_subheading.navigation": "Navigácia",
|
||||
"column_subheading.settings": "Nastavenia",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Tvoj účet nie je zamknutý. Ktokoľvek ťa môže nasledovať a vidieť tvoje správy pre sledujúcich.",
|
||||
"compose_form.lock_disclaimer.lock": "zamknutý",
|
||||
"compose_form.placeholder": "Čo máš na mysli?",
|
||||
"compose_form.publish": "Toot",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive": "Označ súbor ako chúlostivý",
|
||||
"compose_form.spoiler": "Skryť text za varovanie",
|
||||
"compose_form.spoiler_placeholder": "Napíš sem tvoje varovanie",
|
||||
"confirmation_modal.cancel": "Zrušiť",
|
||||
"confirmations.block.confirm": "Blokovať",
|
||||
"confirmations.block.message": "Naozaj chceš blokovať {name}?",
|
||||
"confirmations.delete.confirm": "Zmazať",
|
||||
"confirmations.delete.message": "Naozaj chceš zmazať túto správu?",
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||
"confirmations.domain_block.confirm": "Skryť celú doménu",
|
||||
"confirmations.domain_block.message": "Si si naozaj istý, že chceš blokovať celú {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať daných používateľov.",
|
||||
"confirmations.mute.confirm": "Ignoruj",
|
||||
"confirmations.mute.message": "Naozaj chceš ignorovať {name}?",
|
||||
"confirmations.unfollow.confirm": "Nesledovať",
|
||||
"confirmations.unfollow.message": "Naozaj chceš prestať sledovať {name}?",
|
||||
"embed.instructions": "Skopíruj kód nižšie a ridaj tento status na tvoju web stránku.",
|
||||
"embed.preview": "Tu je ukážka ako to bude vyzerať:",
|
||||
"emoji_button.activity": "Aktivity",
|
||||
"emoji_button.custom": "Vlastné",
|
||||
"emoji_button.flags": "Vlajky",
|
||||
"emoji_button.food": "Jedlá a nápoje",
|
||||
"emoji_button.label": "Vlož emoji",
|
||||
"emoji_button.nature": "Zvieratká",
|
||||
"emoji_button.not_found": "Nenájdené",
|
||||
"emoji_button.objects": "Predmety",
|
||||
"emoji_button.people": "Ľudia",
|
||||
"emoji_button.recent": "Často používané",
|
||||
"emoji_button.search": "Hľadaj...",
|
||||
"emoji_button.search_results": "Nájdené",
|
||||
"emoji_button.symbols": "Symboly",
|
||||
"emoji_button.travel": "Cestovanie a miesta",
|
||||
"empty_column.community": "Lokálna časová os je prázdna. Napíš niečo aby sa to začalo hýbať!",
|
||||
"empty_column.hashtag": "Ešte nič nie je v tomto hashtag-u.",
|
||||
"empty_column.home": "Ešte nesleduješ nikoho. Pre začiatok pozri {public} alebo použi vyhľadávanie aby si našiel ostatných používateľov.",
|
||||
"empty_column.home.public_timeline": "verejnú časovú os",
|
||||
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
||||
"empty_column.notifications": "Nemáš žiadne notifikácie. Napíš niekomu, nasleduj niekoho alebo komunikuj s ostatnými.",
|
||||
"empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne alebo začni sledovať používateľov z iných Mastodon serverov aby tu niečo bolo",
|
||||
"follow_request.authorize": "Potvrdiť",
|
||||
"follow_request.reject": "Odmietnúť",
|
||||
"getting_started.appsshort": "Aplikácie",
|
||||
"getting_started.faq": "FAQ",
|
||||
"getting_started.heading": "Začíname",
|
||||
"getting_started.open_source_notice": "Mastodon má otvorený kód. Reportovať chyby alebo prispievať vlastným kódom môžeš na GitHube v {github}.",
|
||||
"getting_started.userguide": "Používateľská príručka",
|
||||
"home.column_settings.advanced": "Rozšírené",
|
||||
"home.column_settings.basic": "Základné",
|
||||
"home.column_settings.filter_regex": "Filtrovať použitím regulárnych výrazov",
|
||||
"home.column_settings.show_reblogs": "Zobraziť boosts",
|
||||
"home.column_settings.show_replies": "Zobraziť odpovede",
|
||||
"home.settings": "Nastavenia stĺpcov",
|
||||
"keyboard_shortcuts.back": "to navigate back",
|
||||
"keyboard_shortcuts.boost": "to boost",
|
||||
"keyboard_shortcuts.column": "to focus a status in one of the columns",
|
||||
"keyboard_shortcuts.compose": "to focus the compose textarea",
|
||||
"keyboard_shortcuts.description": "Description",
|
||||
"keyboard_shortcuts.down": "to move down in the list",
|
||||
"keyboard_shortcuts.enter": "to open status",
|
||||
"keyboard_shortcuts.favourite": "to favourite",
|
||||
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
|
||||
"keyboard_shortcuts.hotkey": "Hotkey",
|
||||
"keyboard_shortcuts.legend": "to display this legend",
|
||||
"keyboard_shortcuts.mention": "to mention author",
|
||||
"keyboard_shortcuts.reply": "to reply",
|
||||
"keyboard_shortcuts.search": "to focus search",
|
||||
"keyboard_shortcuts.toot": "to start a brand new toot",
|
||||
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "Zavrieť",
|
||||
"lightbox.next": "Ďalší",
|
||||
"lightbox.previous": "Predchádzajúci",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
"lists.edit": "Edit list",
|
||||
"lists.new.create": "Add list",
|
||||
"lists.new.title_placeholder": "New list title",
|
||||
"lists.search": "Search among people you follow",
|
||||
"lists.subheading": "Your lists",
|
||||
"loading_indicator.label": "Nahrávam...",
|
||||
"media_gallery.toggle_visible": "Zapnúť/Vypnúť viditeľnosť",
|
||||
"missing_indicator.label": "Nenájdené",
|
||||
"mute_modal.hide_notifications": "Hide notifications from this user?",
|
||||
"navigation_bar.blocks": "Blokovaní používatelia",
|
||||
"navigation_bar.community_timeline": "Lokálna časová os",
|
||||
"navigation_bar.edit_profile": "Upraviť profil",
|
||||
"navigation_bar.favourites": "Obľúbené",
|
||||
"navigation_bar.follow_requests": "Žiadosti",
|
||||
"navigation_bar.info": "O tomto Mastodon serveri",
|
||||
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
|
||||
"navigation_bar.lists": "Lists",
|
||||
"navigation_bar.logout": "Odhlásiť",
|
||||
"navigation_bar.mutes": "Ignorovaní používatelia",
|
||||
"navigation_bar.pins": "Pripnuté toots",
|
||||
"navigation_bar.preferences": "Možnosti",
|
||||
"navigation_bar.public_timeline": "Federovaná časová os",
|
||||
"notification.favourite": "{name} sa páči tvoj status",
|
||||
"notification.follow": "{name} ťa začal(a) sledovať",
|
||||
"notification.mention": "{name} ťa zmienil",
|
||||
"notification.reblog": "{name} re-tootol tvoj status",
|
||||
"notifications.clear": "Vymazať notifikácie",
|
||||
"notifications.clear_confirmation": "Naozaj chceš vymazať všetky tvoje notifikácie?",
|
||||
"notifications.column_settings.alert": "Bublinové notifikácie",
|
||||
"notifications.column_settings.favourite": "Obľúbené:",
|
||||
"notifications.column_settings.follow": "Nový nasledujúci:",
|
||||
"notifications.column_settings.mention": "Zmienenia:",
|
||||
"notifications.column_settings.push": "Push notifikácie",
|
||||
"notifications.column_settings.push_meta": "Toto zariadenie",
|
||||
"notifications.column_settings.reblog": "Re-toots:",
|
||||
"notifications.column_settings.show": "Zobraziť v stĺpci",
|
||||
"notifications.column_settings.sound": "Prehrať zvuk",
|
||||
"onboarding.done": "Koniec",
|
||||
"onboarding.next": "Ďalej",
|
||||
"onboarding.page_five.public_timelines": "Lokálna časová os zobrazuje verejné správy od všetkých na {domain}. Federovaná časová os zobrazuje verejné správy od všetkých ľudí ktoré {domain} nasleduje. Tieto sú takzvané Verejné Časové Osi, výborná možnosť ako nájsť a spoznať nových ľudí.",
|
||||
"onboarding.page_four.home": "Domovská časová os zobrazí správy od ľudí ktorých sleduješ.",
|
||||
"onboarding.page_four.notifications": "Stĺpec s notifikáciami zobrazí keď budeš s niekým komunikovať.",
|
||||
"onboarding.page_one.federation": "Mastodon je sieť nezávislých serverov spojením ktorých vzniká jedna veľká federovaná sociálna sieť.",
|
||||
"onboarding.page_one.handle": "Ty si na {domain}, takže tvoje celý nickname je {handle}",
|
||||
"onboarding.page_one.welcome": "Vitajte v Mastodon!",
|
||||
"onboarding.page_six.admin": "Správca tohto servera je {admin}.",
|
||||
"onboarding.page_six.almost_done": "Takmer hotovo...",
|
||||
"onboarding.page_six.appetoot": "Bon Appetoot!",
|
||||
"onboarding.page_six.apps_available": "Aplikácie {apps} sú dostupné na pre iOS, Android and ďalšie platformy.",
|
||||
"onboarding.page_six.github": "Mastodon je free open-source software. Chyby, nové funkcie alebo prispievať svojím kódom mǒžeš na {github}.",
|
||||
"onboarding.page_six.guidelines": "pravidlá komunity",
|
||||
"onboarding.page_six.read_guidelines": "Prosím prečítajte si {domain} pravidlá {guidelines}!",
|
||||
"onboarding.page_six.various_app": "mobilné applikácie",
|
||||
"onboarding.page_three.profile": "Uprav svoj profile a zmeň svoj avatar, bio a meno ktoré bude zobrazené. V nastaveniach nájdeš ďalšie možnosti.",
|
||||
"onboarding.page_three.search": "Použi vyhľadávacie políčko na nájdenie ľudí a hashtagov, ako napríklad {slovensko}, {slovakia} alebo {pivo}. Na nájdenie človeka ktorý je registrovaný na inom Mastodon serveri použi jeho celý nickname.",
|
||||
"onboarding.page_two.compose": "Správy píš zo stĺpca na komponovanie. Môžeš nahrávať obrázky, meniť nastavenia súkromia správ a pridávať varovania ikonkami nižšie.",
|
||||
"onboarding.skip": "Preskočiť",
|
||||
"privacy.change": "Zmeň viditeľnosť statusu",
|
||||
"privacy.direct.long": "Pošli priamo iba spomenutým používateľom",
|
||||
"privacy.direct.short": "Súkromne",
|
||||
"privacy.private.long": "Pošli iba sledujúcim",
|
||||
"privacy.private.short": "Iba sledujúci",
|
||||
"privacy.public.long": "Pošli všetkým",
|
||||
"privacy.public.short": "Verejne",
|
||||
"privacy.unlisted.long": "Neposielať verejne",
|
||||
"privacy.unlisted.short": "Nie je v zozname",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.hours": "{number}h",
|
||||
"relative_time.just_now": "now",
|
||||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"reply_indicator.cancel": "Zrušiť",
|
||||
"report.placeholder": "Ďalšie komentáre",
|
||||
"report.submit": "Poslať",
|
||||
"report.target": "Reportovať {target}",
|
||||
"search.placeholder": "Hľadaj",
|
||||
"search_popout.search_format": "Advanced search format",
|
||||
"search_popout.tips.hashtag": "hashtag",
|
||||
"search_popout.tips.status": "status",
|
||||
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} nájdených",
|
||||
"standalone.public_title": "Čo tam nájdeš...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
|
||||
"status.delete": "Zmazať",
|
||||
"status.embed": "Embed",
|
||||
"status.favourite": "Páči sa mi",
|
||||
"status.load_more": "Zobraziť viac",
|
||||
"status.media_hidden": "Skryté médiá",
|
||||
"status.mention": "Napísať @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Ignorovať konverzáciu",
|
||||
"status.open": "Otvoriť",
|
||||
"status.pin": "Pripnúť na profil",
|
||||
"status.reblog": "Re-toot",
|
||||
"status.reblogged_by": "{name} re-tootol",
|
||||
"status.reply": "Odpovedať",
|
||||
"status.replyAll": "Odpovedať všetkým",
|
||||
"status.report": "Nahlásiť @{name}",
|
||||
"status.sensitive_toggle": "Klikni pre zobrazenie",
|
||||
"status.sensitive_warning": "Chúlostivý obsah",
|
||||
"status.share": "Zdieľať",
|
||||
"status.show_less": "Zobraziť menej",
|
||||
"status.show_more": "Zobraziť viac",
|
||||
"status.unmute_conversation": "Prestať ignorovať konverzáciu",
|
||||
"status.unpin": "Odopnúť z profilu",
|
||||
"tabs_bar.compose": "Napísať",
|
||||
"tabs_bar.federated_timeline": "Federovaná",
|
||||
"tabs_bar.home": "Domov",
|
||||
"tabs_bar.local_timeline": "Local",
|
||||
"tabs_bar.notifications": "Notifikácie",
|
||||
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
|
||||
"upload_area.title": "Ťahaj a pusti pre nahratie",
|
||||
"upload_button.label": "Pridať",
|
||||
"upload_form.description": "Describe for the visually impaired",
|
||||
"upload_form.undo": "Späť",
|
||||
"upload_progress.label": "Nahrávam...",
|
||||
"video.close": "Zavrieť video",
|
||||
"video.exit_fullscreen": "Vpnúť zobrazenie na celú obrazovku",
|
||||
"video.expand": "Zväčšiť video",
|
||||
"video.fullscreen": "Zapnúť zobrazenie na celú obrazovku",
|
||||
"video.hide": "Skryť video",
|
||||
"video.mute": "Vypnúť zvuk",
|
||||
"video.pause": "Pauza",
|
||||
"video.play": "Prehrať",
|
||||
"video.unmute": "Zapnúť zvuk"
|
||||
}
|
262
app/javascript/mastodon/locales/sr-Latn.json
Normal file
262
app/javascript/mastodon/locales/sr-Latn.json
Normal file
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"account.block": "Blokiraj korisnika @{name}",
|
||||
"account.block_domain": "Sakrij sve sa domena {domain}",
|
||||
"account.disclaimer_full": "Navedene informacije možda ne odslikavaju korisnički profil u potpunosti.",
|
||||
"account.edit_profile": "Izmeni profil",
|
||||
"account.follow": "Zaprati",
|
||||
"account.followers": "Pratioca",
|
||||
"account.follows": "Prati",
|
||||
"account.follows_you": "Prati Vas",
|
||||
"account.hide_reblogs": "Sakrij podrške koje daje korisnika @{name}",
|
||||
"account.media": "Mediji",
|
||||
"account.mention": "Pomeni korisnika @{name}",
|
||||
"account.moved_to": "{name} se pomerio na:",
|
||||
"account.mute": "Ućutkaj korisnika @{name}",
|
||||
"account.mute_notifications": "Isključi obaveštenja od korisnika @{name}",
|
||||
"account.posts": "Statusa",
|
||||
"account.report": "Prijavi @{name}",
|
||||
"account.requested": "Čekam odobrenje. Kliknite da poništite zahtev za praćenje",
|
||||
"account.share": "Podeli profil korisnika @{name}",
|
||||
"account.show_reblogs": "Prikaži podrške od korisnika @{name}",
|
||||
"account.unblock": "Odblokiraj korisnika @{name}",
|
||||
"account.unblock_domain": "Odblokiraj domen {domain}",
|
||||
"account.unfollow": "Otprati",
|
||||
"account.unmute": "Ukloni ućutkavanje korisniku @{name}",
|
||||
"account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}",
|
||||
"account.view_full_profile": "Vidi ceo profil",
|
||||
"boost_modal.combo": "Možete pritisnuti {combo} da preskočite ovo sledeći put",
|
||||
"bundle_column_error.body": "Nešto je pošlo po zlu prilikom učitavanja ove komponente.",
|
||||
"bundle_column_error.retry": "Pokušajte ponovo",
|
||||
"bundle_column_error.title": "Mrežna greška",
|
||||
"bundle_modal_error.close": "Zatvori",
|
||||
"bundle_modal_error.message": "Nešto nije bilo u redu pri učitavanju ove komponente.",
|
||||
"bundle_modal_error.retry": "Pokušajte ponovo",
|
||||
"column.blocks": "Blokirani korisnici",
|
||||
"column.community": "Lokalna lajna",
|
||||
"column.favourites": "Omiljeni",
|
||||
"column.follow_requests": "Zahtevi za praćenje",
|
||||
"column.home": "Početna",
|
||||
"column.lists": "Liste",
|
||||
"column.mutes": "Ućutkani korisnici",
|
||||
"column.notifications": "Obaveštenja",
|
||||
"column.pins": "Prikačeni tutovi",
|
||||
"column.public": "Federisana lajna",
|
||||
"column_back_button.label": "Nazad",
|
||||
"column_header.hide_settings": "Sakrij postavke",
|
||||
"column_header.moveLeft_settings": "Pomeri kolonu ulevo",
|
||||
"column_header.moveRight_settings": "Pomeri kolonu udesno",
|
||||
"column_header.pin": "Prikači",
|
||||
"column_header.show_settings": "Prikaži postavke",
|
||||
"column_header.unpin": "Otkači",
|
||||
"column_subheading.navigation": "Navigacija",
|
||||
"column_subheading.settings": "Postavke",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Vaš nalog nije {locked}. Svako može da Vas zaprati i da vidi objave namenjene samo Vašim pratiocima.",
|
||||
"compose_form.lock_disclaimer.lock": "zaključan",
|
||||
"compose_form.placeholder": "Šta Vam je na umu?",
|
||||
"compose_form.publish": "Tutni",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive": "Obeleži multimediju kao osetljivu",
|
||||
"compose_form.spoiler": "Sakrij tekst ispod upozorenja",
|
||||
"compose_form.spoiler_placeholder": "Ovde upišite upozorenje",
|
||||
"confirmation_modal.cancel": "Poništi",
|
||||
"confirmations.block.confirm": "Blokiraj",
|
||||
"confirmations.block.message": "Da li ste sigurni da želite da blokirate korisnika {name}?",
|
||||
"confirmations.delete.confirm": "Obriši",
|
||||
"confirmations.delete.message": "Da li ste sigurni da želite obrišete ovaj status?",
|
||||
"confirmations.delete_list.confirm": "Obriši",
|
||||
"confirmations.delete_list.message": "Da li ste sigurni da želite da bespovratno obrišete ovu listu?",
|
||||
"confirmations.domain_block.confirm": "Sakrij ceo domen",
|
||||
"confirmations.domain_block.message": "Da li ste stvarno, stvarno sigurno da želite da blokirate ceo domen {domain}? U većini slučajeva, par dobrih blokiranja ili ućutkavanja su dovoljna i preporučljiva.",
|
||||
"confirmations.mute.confirm": "Ućutkaj",
|
||||
"confirmations.mute.message": "Da li stvarno želite da ućutkate korisnika {name}?",
|
||||
"confirmations.unfollow.confirm": "Otprati",
|
||||
"confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?",
|
||||
"embed.instructions": "Ugradi ovaj status na Vaš veb sajt kopiranjem koda ispod.",
|
||||
"embed.preview": "Ovako će da izgleda:",
|
||||
"emoji_button.activity": "Aktivnost",
|
||||
"emoji_button.custom": "Proizvoljno",
|
||||
"emoji_button.flags": "Zastave",
|
||||
"emoji_button.food": "Hrana & piće",
|
||||
"emoji_button.label": "Ubaci smajli",
|
||||
"emoji_button.nature": "Priroda",
|
||||
"emoji_button.not_found": "Nema smajlija!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.objects": "Objekti",
|
||||
"emoji_button.people": "Ljudi",
|
||||
"emoji_button.recent": "Najčešće korišćeni",
|
||||
"emoji_button.search": "Pretraga...",
|
||||
"emoji_button.search_results": "Rezultati pretrage",
|
||||
"emoji_button.symbols": "Simboli",
|
||||
"emoji_button.travel": "Putovanja & mesta",
|
||||
"empty_column.community": "Lokalna lajna je prazna. Napišite nešto javno da lajna produva!",
|
||||
"empty_column.hashtag": "Trenutno nema ništa na ovom heštegu.",
|
||||
"empty_column.home": "Vaša lajna je prazna! Posetite {public} ili koristite pretragu da počnete i upoznajete nove ljude.",
|
||||
"empty_column.home.public_timeline": "javna lajna",
|
||||
"empty_column.list": "U ovoj listi još nema ničega. Kada članovi liste objave nove statuse, oni će se pojavljivati ovde.",
|
||||
"empty_column.notifications": "Trenutno nemate obaveštenja. Družite se malo da započnete razgovore.",
|
||||
"empty_column.public": "Ovde nema ničega! Napišite nešto javno, ili nađite korisnike sa drugih instanci koje ćete zapratiti da popunite ovu prazninu",
|
||||
"follow_request.authorize": "Odobri",
|
||||
"follow_request.reject": "Odbij",
|
||||
"getting_started.appsshort": "Aplikacije",
|
||||
"getting_started.faq": "ČPP",
|
||||
"getting_started.heading": "Da počnete",
|
||||
"getting_started.open_source_notice": "Mastodont je softver otvorenog koda. Možete mu doprineti ili prijaviti probleme preko GitHub-a na {github}.",
|
||||
"getting_started.userguide": "Korisničko uputstvo",
|
||||
"home.column_settings.advanced": "Napredno",
|
||||
"home.column_settings.basic": "Osnovno",
|
||||
"home.column_settings.filter_regex": "Filtriraj regularnim izrazima",
|
||||
"home.column_settings.show_reblogs": "Prikaži i podržavanja",
|
||||
"home.column_settings.show_replies": "Prikaži odgovore",
|
||||
"home.settings": "Postavke kolone",
|
||||
"keyboard_shortcuts.back": "da odete nazad",
|
||||
"keyboard_shortcuts.boost": "da podržite",
|
||||
"keyboard_shortcuts.column": "da se prebacite na status u jednoj od kolona",
|
||||
"keyboard_shortcuts.compose": "da se prebacite na pisanje novog tuta",
|
||||
"keyboard_shortcuts.description": "Opis",
|
||||
"keyboard_shortcuts.down": "da se pomerite na dole u listi",
|
||||
"keyboard_shortcuts.enter": "da otvorite status",
|
||||
"keyboard_shortcuts.favourite": "da označite kao omiljeno",
|
||||
"keyboard_shortcuts.heading": "Prečice na tastaturi",
|
||||
"keyboard_shortcuts.hotkey": "Prečica",
|
||||
"keyboard_shortcuts.legend": "da prikažete ovaj podsetnik",
|
||||
"keyboard_shortcuts.mention": "da pomenete autora",
|
||||
"keyboard_shortcuts.reply": "da odgovorite",
|
||||
"keyboard_shortcuts.search": "da se prebacite na pretragu",
|
||||
"keyboard_shortcuts.toot": "da započnete skroz novi tut",
|
||||
"keyboard_shortcuts.unfocus": "da ne budete više na pretrazi/pravljenju novog tuta",
|
||||
"keyboard_shortcuts.up": "da se pomerite na gore u listi",
|
||||
"lightbox.close": "Zatvori",
|
||||
"lightbox.next": "Sledeći",
|
||||
"lightbox.previous": "Prethodni",
|
||||
"lists.account.add": "Dodaj na listu",
|
||||
"lists.account.remove": "Ukloni sa liste",
|
||||
"lists.delete": "Obriši listu",
|
||||
"lists.edit": "Izmeni listu",
|
||||
"lists.new.create": "Dodaj listu",
|
||||
"lists.new.title_placeholder": "Naslov nove liste",
|
||||
"lists.search": "Pretraži među ljudima koje pratite",
|
||||
"lists.subheading": "Vaše liste",
|
||||
"loading_indicator.label": "Učitavam...",
|
||||
"media_gallery.toggle_visible": "Uključi/isključi vidljivost",
|
||||
"missing_indicator.label": "Nije pronađeno",
|
||||
"mute_modal.hide_notifications": "Sakrij obaveštenja od ovog korisnika?",
|
||||
"navigation_bar.blocks": "Blokirani korisnici",
|
||||
"navigation_bar.community_timeline": "Lokalna lajna",
|
||||
"navigation_bar.edit_profile": "Izmeni profil",
|
||||
"navigation_bar.favourites": "Omiljeni",
|
||||
"navigation_bar.follow_requests": "Zahtevi za praćenje",
|
||||
"navigation_bar.info": "O ovoj instanci",
|
||||
"navigation_bar.keyboard_shortcuts": "Prečice na tastaturi",
|
||||
"navigation_bar.lists": "Liste",
|
||||
"navigation_bar.logout": "Odjava",
|
||||
"navigation_bar.mutes": "Ućutkani korisnici",
|
||||
"navigation_bar.pins": "Prikačeni tutovi",
|
||||
"navigation_bar.preferences": "Podešavanja",
|
||||
"navigation_bar.public_timeline": "Federisana lajna",
|
||||
"notification.favourite": "{name} je stavio Vaš status kao omiljeni",
|
||||
"notification.follow": "{name} Vas je zapratio",
|
||||
"notification.mention": "{name} Vas je pomenuo",
|
||||
"notification.reblog": "{name} je podržao(la) Vaš status",
|
||||
"notifications.clear": "Očisti obaveštenja",
|
||||
"notifications.clear_confirmation": "Da li ste sigurno da trajno želite da očistite Vaša obaveštenja?",
|
||||
"notifications.column_settings.alert": "Obaveštenja na radnoj površini",
|
||||
"notifications.column_settings.favourite": "Omiljeni:",
|
||||
"notifications.column_settings.follow": "Novi pratioci:",
|
||||
"notifications.column_settings.mention": "Pominjanja:",
|
||||
"notifications.column_settings.push": "Guraj obaveštenja",
|
||||
"notifications.column_settings.push_meta": "Ovaj uređaj",
|
||||
"notifications.column_settings.reblog": "Podrški:",
|
||||
"notifications.column_settings.show": "Prikaži u koloni",
|
||||
"notifications.column_settings.sound": "Puštaj zvuk",
|
||||
"onboarding.done": "Gotovo",
|
||||
"onboarding.next": "Sledeće",
|
||||
"onboarding.page_five.public_timelines": "Lokalna lajna prikazuje sve javne statuse od svih na domenu {domain}. Federisana lajna prikazuje javne statuse od svih ljudi koje prate korisnici sa domena {domain}. Ovo su javne lajne, sjajan način da otkrijete nove ljude.",
|
||||
"onboarding.page_four.home": "Početna lajna prikazuje statuse ljudi koje Vi pratite.",
|
||||
"onboarding.page_four.notifications": "Kolona sa obaveštenjima Vam prikazuje kada neko priča sa Vama.",
|
||||
"onboarding.page_one.federation": "Mastodont je mreža nezavisnih servera koji se uvezuju da naprave jednu veću društvenu mrežu. Ove servere zovemo instancama.",
|
||||
"onboarding.page_one.handle": "Vi ste na domenu {domain}, pa je Vaša puna identifikacija {handle}",
|
||||
"onboarding.page_one.welcome": "Dobrodošli na Mastodont!",
|
||||
"onboarding.page_six.admin": "Administrator Vaše instance je {admin}.",
|
||||
"onboarding.page_six.almost_done": "Još malo, pa gotovo...",
|
||||
"onboarding.page_six.appetoot": "Prijatutno!",
|
||||
"onboarding.page_six.apps_available": "Postoje {apps} dostupne za iOS, Android i druge platforme.",
|
||||
"onboarding.page_six.github": "Mastodont je slobodan softver otvorenog koda. Možete prijavljivati greške, potraživati nove funckionalnosti, ili učestvujući u programiranju. Naš izvorni kod je ovde: {github}.",
|
||||
"onboarding.page_six.guidelines": "smernice zajednice",
|
||||
"onboarding.page_six.read_guidelines": "Pročitejte {guidelines} domena {domain}!",
|
||||
"onboarding.page_six.various_app": "mobilne aplikacije",
|
||||
"onboarding.page_three.profile": "Izmenite profil da promenite avatar, biografiju i ime za prikaz. Tamo ćete naći i ostala podešavanja.",
|
||||
"onboarding.page_three.search": "Korisite pretragu da nađete ljude i gledate heštegove, kao što su {illustration} i {introductions}. Da nađete osobu koja nije na ovoj instanci, koristite njenu punu identifikaciju.",
|
||||
"onboarding.page_two.compose": "Pišite statuse iz prve kolone. Možete otpremati slike, menjati podešavanja privatnosti, i dodavati upozorenja za osetljiv sadržaj preko ikonica ispod.",
|
||||
"onboarding.skip": "Preskoči",
|
||||
"privacy.change": "Podesi status privatnosti",
|
||||
"privacy.direct.long": "Objavi samo korisnicima koji su pomenuti",
|
||||
"privacy.direct.short": "Direktno",
|
||||
"privacy.private.long": "Objavi samo pratiocima",
|
||||
"privacy.private.short": "Samo za pratioce",
|
||||
"privacy.public.long": "Objavi na javnoj lajni",
|
||||
"privacy.public.short": "Javno",
|
||||
"privacy.unlisted.long": "Ne objavljuj na javnim lajnama",
|
||||
"privacy.unlisted.short": "Neizlistano",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.hours": "{number}h",
|
||||
"relative_time.just_now": "sada",
|
||||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"reply_indicator.cancel": "Poništi",
|
||||
"report.placeholder": "Dodatni komentari",
|
||||
"report.submit": "Pošalji",
|
||||
"report.target": "Prijavljujem {target}",
|
||||
"search.placeholder": "Pretraga",
|
||||
"search_popout.search_format": "Napredni format pretrage",
|
||||
"search_popout.tips.hashtag": "hešteg",
|
||||
"search_popout.tips.status": "status",
|
||||
"search_popout.tips.text": "Traženjem običnog teksta ćete dobiti sva pronađena imena, sva korisnička imena i sve nađene heštegove",
|
||||
"search_popout.tips.user": "korisnik",
|
||||
"search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}",
|
||||
"standalone.public_title": "Pogled iznutra...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Ovaj status ne može da se podrži",
|
||||
"status.delete": "Obriši",
|
||||
"status.embed": "Ugradi na sajt",
|
||||
"status.favourite": "Omiljeno",
|
||||
"status.load_more": "Učitaj još",
|
||||
"status.media_hidden": "Multimedija sakrivena",
|
||||
"status.mention": "Pomeni korisnika @{name}",
|
||||
"status.more": "Još",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Ućutkaj prepisku",
|
||||
"status.open": "Proširi ovaj status",
|
||||
"status.pin": "Prikači na profil",
|
||||
"status.reblog": "Podrži",
|
||||
"status.reblogged_by": "{name} podržao(la)",
|
||||
"status.reply": "Odgovori",
|
||||
"status.replyAll": "Odgovori na diskusiju",
|
||||
"status.report": "Prijavi korisnika @{name}",
|
||||
"status.sensitive_toggle": "Kliknite da vidite",
|
||||
"status.sensitive_warning": "Osetljiv sadržaj",
|
||||
"status.share": "Podeli",
|
||||
"status.show_less": "Prikaži manje",
|
||||
"status.show_more": "Prikaži više",
|
||||
"status.unmute_conversation": "Uključi prepisku",
|
||||
"status.unpin": "Otkači sa profila",
|
||||
"tabs_bar.compose": "Napiši",
|
||||
"tabs_bar.federated_timeline": "Federisano",
|
||||
"tabs_bar.home": "Početna",
|
||||
"tabs_bar.local_timeline": "Lokalno",
|
||||
"tabs_bar.notifications": "Obaveštenja",
|
||||
"ui.beforeunload": "Ako napustite Mastodont, izgubićete napisani nacrt.",
|
||||
"upload_area.title": "Prevucite ovde da otpremite",
|
||||
"upload_button.label": "Dodaj multimediju",
|
||||
"upload_form.description": "Opiši za slabovide osobe",
|
||||
"upload_form.undo": "Opozovi",
|
||||
"upload_progress.label": "Otpremam...",
|
||||
"video.close": "Zatvori video",
|
||||
"video.exit_fullscreen": "Napusti ceo ekran",
|
||||
"video.expand": "Proširi video",
|
||||
"video.fullscreen": "Ceo ekran",
|
||||
"video.hide": "Sakrij video",
|
||||
"video.mute": "Ugasi zvuk",
|
||||
"video.pause": "Pauziraj",
|
||||
"video.play": "Pusti",
|
||||
"video.unmute": "Vrati zvuk"
|
||||
}
|
262
app/javascript/mastodon/locales/sr.json
Normal file
262
app/javascript/mastodon/locales/sr.json
Normal file
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"account.block": "Блокирај корисника @{name}",
|
||||
"account.block_domain": "Сакриј све са домена {domain}",
|
||||
"account.disclaimer_full": "Наведене информације можда не одсликавају кориснички профил у потпуности.",
|
||||
"account.edit_profile": "Измени профил",
|
||||
"account.follow": "Запрати",
|
||||
"account.followers": "Пратиоца",
|
||||
"account.follows": "Прати",
|
||||
"account.follows_you": "Прати Вас",
|
||||
"account.hide_reblogs": "Сакриј подршке које даје корисника @{name}",
|
||||
"account.media": "Медији",
|
||||
"account.mention": "Помени корисника @{name}",
|
||||
"account.moved_to": "{name} се померио на:",
|
||||
"account.mute": "Ућуткај корисника @{name}",
|
||||
"account.mute_notifications": "Искључи обавештења од корисника @{name}",
|
||||
"account.posts": "Статуса",
|
||||
"account.report": "Пријави @{name}",
|
||||
"account.requested": "Чекам одобрење. Кликните да поништите захтев за праћење",
|
||||
"account.share": "Подели профил корисника @{name}",
|
||||
"account.show_reblogs": "Прикажи подршке од корисника @{name}",
|
||||
"account.unblock": "Одблокирај корисника @{name}",
|
||||
"account.unblock_domain": "Одблокирај домен {domain}",
|
||||
"account.unfollow": "Отпрати",
|
||||
"account.unmute": "Уклони ућуткавање кориснику @{name}",
|
||||
"account.unmute_notifications": "Укључи назад обавештења од корисника @{name}",
|
||||
"account.view_full_profile": "Види цео профил",
|
||||
"boost_modal.combo": "Можете притиснути {combo} да прескочите ово следећи пут",
|
||||
"bundle_column_error.body": "Нешто је пошло по злу приликом учитавања ове компоненте.",
|
||||
"bundle_column_error.retry": "Покушајте поново",
|
||||
"bundle_column_error.title": "Мрежна грешка",
|
||||
"bundle_modal_error.close": "Затвори",
|
||||
"bundle_modal_error.message": "Нешто није било у реду при учитавању ове компоненте.",
|
||||
"bundle_modal_error.retry": "Покушајте поново",
|
||||
"column.blocks": "Блокирани корисници",
|
||||
"column.community": "Локална лајна",
|
||||
"column.favourites": "Омиљени",
|
||||
"column.follow_requests": "Захтеви за праћење",
|
||||
"column.home": "Почетна",
|
||||
"column.lists": "Листе",
|
||||
"column.mutes": "Ућуткани корисници",
|
||||
"column.notifications": "Обавештења",
|
||||
"column.pins": "Прикачени тутови",
|
||||
"column.public": "Федерисана лајна",
|
||||
"column_back_button.label": "Назад",
|
||||
"column_header.hide_settings": "Сакриј поставке",
|
||||
"column_header.moveLeft_settings": "Помери колону улево",
|
||||
"column_header.moveRight_settings": "Помери колону удесно",
|
||||
"column_header.pin": "Прикачи",
|
||||
"column_header.show_settings": "Прикажи поставке",
|
||||
"column_header.unpin": "Откачи",
|
||||
"column_subheading.navigation": "Навигација",
|
||||
"column_subheading.settings": "Поставке",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ваш налог није {locked}. Свако може да Вас запрати и да види објаве намењене само Вашим пратиоцима.",
|
||||
"compose_form.lock_disclaimer.lock": "закључан",
|
||||
"compose_form.placeholder": "Шта Вам је на уму?",
|
||||
"compose_form.publish": "Тутни",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
"compose_form.sensitive": "Обележи мултимедију као осетљиву",
|
||||
"compose_form.spoiler": "Сакриј текст испод упозорења",
|
||||
"compose_form.spoiler_placeholder": "Овде упишите упозорење",
|
||||
"confirmation_modal.cancel": "Поништи",
|
||||
"confirmations.block.confirm": "Блокирај",
|
||||
"confirmations.block.message": "Да ли сте сигурни да желите да блокирате корисника {name}?",
|
||||
"confirmations.delete.confirm": "Обриши",
|
||||
"confirmations.delete.message": "Да ли сте сигурни да желите обришете овај статус?",
|
||||
"confirmations.delete_list.confirm": "Обриши",
|
||||
"confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?",
|
||||
"confirmations.domain_block.confirm": "Сакриј цео домен",
|
||||
"confirmations.domain_block.message": "Да ли сте стварно, стварно сигурно да желите да блокирате цео домен {domain}? У већини случајева, пар добрих блокирања или ућуткавања су довољна и препоручљива.",
|
||||
"confirmations.mute.confirm": "Ућуткај",
|
||||
"confirmations.mute.message": "Да ли стварно желите да ућуткате корисника {name}?",
|
||||
"confirmations.unfollow.confirm": "Отпрати",
|
||||
"confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?",
|
||||
"embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.",
|
||||
"embed.preview": "Овако ће да изгледа:",
|
||||
"emoji_button.activity": "Активност",
|
||||
"emoji_button.custom": "Произвољно",
|
||||
"emoji_button.flags": "Заставе",
|
||||
"emoji_button.food": "Храна & пиће",
|
||||
"emoji_button.label": "Убаци смајли",
|
||||
"emoji_button.nature": "Природа",
|
||||
"emoji_button.not_found": "Нема смајлија!! (╯°□°)╯︵ ┻━┻",
|
||||
"emoji_button.objects": "Објекти",
|
||||
"emoji_button.people": "Људи",
|
||||
"emoji_button.recent": "Најчешће коришћени",
|
||||
"emoji_button.search": "Претрага...",
|
||||
"emoji_button.search_results": "Резултати претраге",
|
||||
"emoji_button.symbols": "Симболи",
|
||||
"emoji_button.travel": "Путовања & места",
|
||||
"empty_column.community": "Локална лајна је празна. Напишите нешто јавно да лајна продува!",
|
||||
"empty_column.hashtag": "Тренутно нема ништа на овом хештегу.",
|
||||
"empty_column.home": "Ваша лајна је празна! Посетите {public} или користите претрагу да почнете и упознајете нове људе.",
|
||||
"empty_column.home.public_timeline": "јавна лајна",
|
||||
"empty_column.list": "У овој листи још нема ничега. Када чланови листе објаве нове статусе, они ће се појављивати овде.",
|
||||
"empty_column.notifications": "Тренутно немате обавештења. Дружите се мало да започнете разговоре.",
|
||||
"empty_column.public": "Овде нема ничега! Напишите нешто јавно, или нађите кориснике са других инстанци које ћете запратити да попуните ову празнину",
|
||||
"follow_request.authorize": "Одобри",
|
||||
"follow_request.reject": "Одбиј",
|
||||
"getting_started.appsshort": "Апликације",
|
||||
"getting_started.faq": "ЧПП",
|
||||
"getting_started.heading": "Да почнете",
|
||||
"getting_started.open_source_notice": "Мастoдонт је софтвер отвореног кода. Можете му допринети или пријавити проблеме преко GitHub-а на {github}.",
|
||||
"getting_started.userguide": "Корисничко упутство",
|
||||
"home.column_settings.advanced": "Напредно",
|
||||
"home.column_settings.basic": "Основно",
|
||||
"home.column_settings.filter_regex": "Филтрирај регуларним изразима",
|
||||
"home.column_settings.show_reblogs": "Прикажи и подржавања",
|
||||
"home.column_settings.show_replies": "Прикажи одговоре",
|
||||
"home.settings": "Поставке колоне",
|
||||
"keyboard_shortcuts.back": "да одете назад",
|
||||
"keyboard_shortcuts.boost": "да подржите",
|
||||
"keyboard_shortcuts.column": "да се пребаците на статус у једној од колона",
|
||||
"keyboard_shortcuts.compose": "да се пребаците на писање новог тута",
|
||||
"keyboard_shortcuts.description": "Опис",
|
||||
"keyboard_shortcuts.down": "да се померите на доле у листи",
|
||||
"keyboard_shortcuts.enter": "да отворите статус",
|
||||
"keyboard_shortcuts.favourite": "да означите као омиљено",
|
||||
"keyboard_shortcuts.heading": "Пречице на тастатури",
|
||||
"keyboard_shortcuts.hotkey": "Пречица",
|
||||
"keyboard_shortcuts.legend": "да прикажете овај подсетник",
|
||||
"keyboard_shortcuts.mention": "да поменете аутора",
|
||||
"keyboard_shortcuts.reply": "да одговорите",
|
||||
"keyboard_shortcuts.search": "да се пребаците на претрагу",
|
||||
"keyboard_shortcuts.toot": "да започнете скроз нови тут",
|
||||
"keyboard_shortcuts.unfocus": "да не будете више на претрази/прављењу новог тута",
|
||||
"keyboard_shortcuts.up": "да се померите на горе у листи",
|
||||
"lightbox.close": "Затвори",
|
||||
"lightbox.next": "Следећи",
|
||||
"lightbox.previous": "Претходни",
|
||||
"lists.account.add": "Додај на листу",
|
||||
"lists.account.remove": "Уклони са листе",
|
||||
"lists.delete": "Обриши листу",
|
||||
"lists.edit": "Измени листу",
|
||||
"lists.new.create": "Додај листу",
|
||||
"lists.new.title_placeholder": "Наслов нове листе",
|
||||
"lists.search": "Претражи међу људима које пратите",
|
||||
"lists.subheading": "Ваше листе",
|
||||
"loading_indicator.label": "Учитавам...",
|
||||
"media_gallery.toggle_visible": "Укључи/искључи видљивост",
|
||||
"missing_indicator.label": "Није пронађено",
|
||||
"mute_modal.hide_notifications": "Сакриј обавештења од овог корисника?",
|
||||
"navigation_bar.blocks": "Блокирани корисници",
|
||||
"navigation_bar.community_timeline": "Локална лајна",
|
||||
"navigation_bar.edit_profile": "Измени профил",
|
||||
"navigation_bar.favourites": "Омиљени",
|
||||
"navigation_bar.follow_requests": "Захтеви за праћење",
|
||||
"navigation_bar.info": "О овој инстанци",
|
||||
"navigation_bar.keyboard_shortcuts": "Пречице на тастатури",
|
||||
"navigation_bar.lists": "Листе",
|
||||
"navigation_bar.logout": "Одјава",
|
||||
"navigation_bar.mutes": "Ућуткани корисници",
|
||||
"navigation_bar.pins": "Прикачени тутови",
|
||||
"navigation_bar.preferences": "Подешавања",
|
||||
"navigation_bar.public_timeline": "Федерисана лајна",
|
||||
"notification.favourite": "{name} је ставио Ваш статус као омиљени",
|
||||
"notification.follow": "{name} Вас је запратио",
|
||||
"notification.mention": "{name} Вас је поменуо",
|
||||
"notification.reblog": "{name} је подржао(ла) Ваш статус",
|
||||
"notifications.clear": "Очисти обавештења",
|
||||
"notifications.clear_confirmation": "Да ли сте сигурно да трајно желите да очистите Ваша обавештења?",
|
||||
"notifications.column_settings.alert": "Обавештења на радној површини",
|
||||
"notifications.column_settings.favourite": "Омиљени:",
|
||||
"notifications.column_settings.follow": "Нови пратиоци:",
|
||||
"notifications.column_settings.mention": "Помињања:",
|
||||
"notifications.column_settings.push": "Гурај обавештења",
|
||||
"notifications.column_settings.push_meta": "Овај уређај",
|
||||
"notifications.column_settings.reblog": "Подршки:",
|
||||
"notifications.column_settings.show": "Прикажи у колони",
|
||||
"notifications.column_settings.sound": "Пуштај звук",
|
||||
"onboarding.done": "Готово",
|
||||
"onboarding.next": "Следеће",
|
||||
"onboarding.page_five.public_timelines": "Локална лајна приказује све јавне статусе од свих на домену {domain}. Федерисана лајна приказује јавне статусе од свих људи које прате корисници са домена {domain}. Ово су јавне лајне, сјајан начин да откријете нове људе.",
|
||||
"onboarding.page_four.home": "Почетна лајна приказује статусе људи које Ви пратите.",
|
||||
"onboarding.page_four.notifications": "Колона са обавештењима Вам приказује када неко прича са Вама.",
|
||||
"onboarding.page_one.federation": "Мастодонт је мрежа независних сервера који се увезују да направе једну већу друштвену мрежу. Ове сервере зовемо инстанцама.",
|
||||
"onboarding.page_one.handle": "Ви сте на домену {domain}, па је Ваша пуна идентификација {handle}",
|
||||
"onboarding.page_one.welcome": "Добродошли на Мастодонт!",
|
||||
"onboarding.page_six.admin": "Администратор Ваше инстанце је {admin}.",
|
||||
"onboarding.page_six.almost_done": "Још мало, па готово...",
|
||||
"onboarding.page_six.appetoot": "Пријатутно!",
|
||||
"onboarding.page_six.apps_available": "Постоје {apps} доступне за iOS, Андроид и друге платформе.",
|
||||
"onboarding.page_six.github": "Мастодонт је слободан софтвер отвореног кода. Можете пријављивати грешке, потраживати нове фунцкионалности, или учествујући у програмирању. Наш изворни код је овде: {github}.",
|
||||
"onboarding.page_six.guidelines": "смернице заједнице",
|
||||
"onboarding.page_six.read_guidelines": "Прочитејте {guidelines} домена {domain}!",
|
||||
"onboarding.page_six.various_app": "мобилне апликације",
|
||||
"onboarding.page_three.profile": "Измените профил да промените аватар, биографију и име за приказ. Тамо ћете наћи и остала подешавања.",
|
||||
"onboarding.page_three.search": "Корисите претрагу да нађете људе и гледате хештегове, као што су {illustration} и {introductions}. Да нађете особу која није на овој инстанци, користите њену пуну идентификацију.",
|
||||
"onboarding.page_two.compose": "Пишите статусе из прве колоне. Можете отпремати слике, мењати подешавања приватности, и додавати упозорења за осетљив садржај преко иконица испод.",
|
||||
"onboarding.skip": "Прескочи",
|
||||
"privacy.change": "Подеси статус приватности",
|
||||
"privacy.direct.long": "Објави само корисницима који су поменути",
|
||||
"privacy.direct.short": "Директно",
|
||||
"privacy.private.long": "Објави само пратиоцима",
|
||||
"privacy.private.short": "Само за пратиоце",
|
||||
"privacy.public.long": "Објави на јавној лајни",
|
||||
"privacy.public.short": "Јавно",
|
||||
"privacy.unlisted.long": "Не објављуј на јавним лајнама",
|
||||
"privacy.unlisted.short": "Неизлистано",
|
||||
"relative_time.days": "{number}d",
|
||||
"relative_time.hours": "{number}h",
|
||||
"relative_time.just_now": "сада",
|
||||
"relative_time.minutes": "{number}m",
|
||||
"relative_time.seconds": "{number}s",
|
||||
"reply_indicator.cancel": "Поништи",
|
||||
"report.placeholder": "Додатни коментари",
|
||||
"report.submit": "Пошаљи",
|
||||
"report.target": "Пријављујем {target}",
|
||||
"search.placeholder": "Претрага",
|
||||
"search_popout.search_format": "Напредни формат претраге",
|
||||
"search_popout.tips.hashtag": "хештег",
|
||||
"search_popout.tips.status": "статус",
|
||||
"search_popout.tips.text": "Тражењем обичног текста ћете добити сва пронађена имена, сва корисничка имена и све нађене хештегове",
|
||||
"search_popout.tips.user": "корисник",
|
||||
"search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}",
|
||||
"standalone.public_title": "Поглед изнутра...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Овај статус не може да се подржи",
|
||||
"status.delete": "Обриши",
|
||||
"status.embed": "Угради на сајт",
|
||||
"status.favourite": "Омиљено",
|
||||
"status.load_more": "Учитај још",
|
||||
"status.media_hidden": "Мултимедија сакривена",
|
||||
"status.mention": "Помени корисника @{name}",
|
||||
"status.more": "Још",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Ућуткај преписку",
|
||||
"status.open": "Прошири овај статус",
|
||||
"status.pin": "Прикачи на профил",
|
||||
"status.reblog": "Подржи",
|
||||
"status.reblogged_by": "{name} подржао(ла)",
|
||||
"status.reply": "Одговори",
|
||||
"status.replyAll": "Одговори на дискусију",
|
||||
"status.report": "Пријави корисника @{name}",
|
||||
"status.sensitive_toggle": "Кликните да видите",
|
||||
"status.sensitive_warning": "Осетљив садржај",
|
||||
"status.share": "Подели",
|
||||
"status.show_less": "Прикажи мање",
|
||||
"status.show_more": "Прикажи више",
|
||||
"status.unmute_conversation": "Укључи преписку",
|
||||
"status.unpin": "Откачи са профила",
|
||||
"tabs_bar.compose": "Напиши",
|
||||
"tabs_bar.federated_timeline": "Федерисано",
|
||||
"tabs_bar.home": "Почетна",
|
||||
"tabs_bar.local_timeline": "Локално",
|
||||
"tabs_bar.notifications": "Обавештења",
|
||||
"ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.",
|
||||
"upload_area.title": "Превуците овде да отпремите",
|
||||
"upload_button.label": "Додај мултимедију",
|
||||
"upload_form.description": "Опиши за слабовиде особе",
|
||||
"upload_form.undo": "Опозови",
|
||||
"upload_progress.label": "Отпремам...",
|
||||
"video.close": "Затвори видео",
|
||||
"video.exit_fullscreen": "Напусти цео екран",
|
||||
"video.expand": "Прошири видео",
|
||||
"video.fullscreen": "Цео екран",
|
||||
"video.hide": "Сакриј видео",
|
||||
"video.mute": "Угаси звук",
|
||||
"video.pause": "Паузирај",
|
||||
"video.play": "Пусти",
|
||||
"video.unmute": "Врати звук"
|
||||
}
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Ångra fäst",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Inställningar",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vemsomhelst kan följa dig och även se dina inlägg skrivna för endast dina följare.",
|
||||
"compose_form.lock_disclaimer.lock": "låst",
|
||||
"compose_form.placeholder": "Vad funderar du på?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "användare",
|
||||
"search_results.total": "{count, number} {count, plural, ett {result} andra {results}}",
|
||||
"standalone.public_title": "En titt inuti...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Detta inlägg kan inte knuffas",
|
||||
"status.delete": "Ta bort",
|
||||
"status.embed": "Bädda in",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media dold",
|
||||
"status.mention": "Omnämn @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Tysta konversation",
|
||||
"status.open": "Utvidga denna status",
|
||||
"status.pin": "Fäst i profil",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigation",
|
||||
"column_subheading.settings": "Settings",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
|
||||
"compose_form.lock_disclaimer.lock": "locked",
|
||||
"compose_form.placeholder": "What is on your mind?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "This post cannot be boosted",
|
||||
"status.delete": "Delete",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Media hidden",
|
||||
"status.mention": "Mention @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this status",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Navigasyon",
|
||||
"column_subheading.settings": "Ayarlar",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Hesabınız {locked} değil. Sadece takipçilerle paylaştığınız gönderileri görebilmek için sizi herhangi bir kullanıcı takip edebilir.",
|
||||
"compose_form.lock_disclaimer.lock": "kilitli",
|
||||
"compose_form.placeholder": "Ne düşünüyorsun?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Bu gönderi boost edilemez",
|
||||
"status.delete": "Sil",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Gizli görsel",
|
||||
"status.mention": "Bahset @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Bu gönderiyi genişlet",
|
||||
"status.pin": "Pin on profile",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "Unpin",
|
||||
"column_subheading.navigation": "Навігація",
|
||||
"column_subheading.settings": "Налаштування",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "Ваш акаунт не {locked}. Кожен може підписатися на Вас та бачити Ваші приватні пости.",
|
||||
"compose_form.lock_disclaimer.lock": "приватний",
|
||||
"compose_form.placeholder": "Що у Вас на думці?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} {count, plural, one {результат} few {результати} many {результатів} other {результатів}}",
|
||||
"standalone.public_title": "A look inside...",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "Цей допис не може бути передмухнутий",
|
||||
"status.delete": "Видалити",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "Медіаконтент приховано",
|
||||
"status.mention": "Згадати",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Заглушити діалог",
|
||||
"status.open": "Розгорнути допис",
|
||||
"status.pin": "Pin on profile",
|
||||
|
2
app/javascript/mastodon/locales/whitelist_sk.json
Normal file
2
app/javascript/mastodon/locales/whitelist_sk.json
Normal file
@@ -0,0 +1,2 @@
|
||||
[
|
||||
]
|
2
app/javascript/mastodon/locales/whitelist_sr-Latn.json
Normal file
2
app/javascript/mastodon/locales/whitelist_sr-Latn.json
Normal file
@@ -0,0 +1,2 @@
|
||||
[
|
||||
]
|
2
app/javascript/mastodon/locales/whitelist_sr.json
Normal file
2
app/javascript/mastodon/locales/whitelist_sr.json
Normal file
@@ -0,0 +1,2 @@
|
||||
[
|
||||
]
|
@@ -25,11 +25,11 @@
|
||||
"account.unmute_notifications": "不再隐藏来自 @{name} 的通知",
|
||||
"account.view_full_profile": "查看完整资料",
|
||||
"boost_modal.combo": "下次按住 {combo} 即可跳过此提示",
|
||||
"bundle_column_error.body": "载入组件出错。",
|
||||
"bundle_column_error.body": "载入这个组件时发生了错误。",
|
||||
"bundle_column_error.retry": "重试",
|
||||
"bundle_column_error.title": "网络错误",
|
||||
"bundle_modal_error.close": "关闭",
|
||||
"bundle_modal_error.message": "载入组件出错。",
|
||||
"bundle_modal_error.message": "载入这个组件时发生了错误。",
|
||||
"bundle_modal_error.retry": "重试",
|
||||
"column.blocks": "屏蔽用户",
|
||||
"column.community": "本站时间轴",
|
||||
@@ -50,8 +50,9 @@
|
||||
"column_header.unpin": "取消固定",
|
||||
"column_subheading.navigation": "导航",
|
||||
"column_subheading.settings": "设置",
|
||||
"compose_form.lock_disclaimer": "你的帐户没有{locked}。任何人都可以通过关注你来查看仅关注者可见的嘟文。",
|
||||
"compose_form.lock_disclaimer.lock": "被保护",
|
||||
"compose_form.hashtag_warning": "这条嘟文被设置为“不公开”,因此它不会出现在任何话题标签的列表下。只有公开的嘟文才能通过话题标签进行搜索。",
|
||||
"compose_form.lock_disclaimer": "你的帐户没有{locked}。任何人都可以在关注你后立即查看仅关注者可见的嘟文。",
|
||||
"compose_form.lock_disclaimer.lock": "开启保护",
|
||||
"compose_form.placeholder": "在想啥?",
|
||||
"compose_form.publish": "嘟嘟",
|
||||
"compose_form.publish_loud": "{publish}!",
|
||||
@@ -60,17 +61,17 @@
|
||||
"compose_form.spoiler_placeholder": "折叠部分的警告消息",
|
||||
"confirmation_modal.cancel": "取消",
|
||||
"confirmations.block.confirm": "屏蔽",
|
||||
"confirmations.block.message": "想好了,真的要屏蔽 {name}?",
|
||||
"confirmations.block.message": "你确定要屏蔽 {name} 吗?",
|
||||
"confirmations.delete.confirm": "删除",
|
||||
"confirmations.delete.message": "想好了,真的要删除这条嘟文?",
|
||||
"confirmations.delete.message": "你确定要删除这条嘟文吗?",
|
||||
"confirmations.delete_list.confirm": "删除",
|
||||
"confirmations.delete_list.message": "你确定要永久删除这个列表吗?",
|
||||
"confirmations.domain_block.confirm": "隐藏整个网站的内容",
|
||||
"confirmations.domain_block.message": "你真的真的确定要隐藏所有来自 {domain} 的内容吗?多数情况下,屏蔽或隐藏几个特定的用户就应该能满足你的需要了。",
|
||||
"confirmations.domain_block.message": "你真的确定要隐藏所有来自 {domain} 的内容吗?多数情况下,屏蔽或隐藏几个特定的用户应该就能满足你的需要了。",
|
||||
"confirmations.mute.confirm": "隐藏",
|
||||
"confirmations.mute.message": "想好了,真的要隐藏 {name}?",
|
||||
"confirmations.mute.message": "你确定要隐藏 {name} 吗?",
|
||||
"confirmations.unfollow.confirm": "取消关注",
|
||||
"confirmations.unfollow.message": "确定要取消关注 {name} 吗?",
|
||||
"confirmations.unfollow.message": "你确定要取消关注 {name} 吗?",
|
||||
"embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。",
|
||||
"embed.preview": "它会像这样显示出来:",
|
||||
"emoji_button.activity": "活动",
|
||||
@@ -92,8 +93,8 @@
|
||||
"empty_column.home": "你还没有关注任何用户。快看看{public},向其他用户搭讪吧。",
|
||||
"empty_column.home.public_timeline": "公共时间轴",
|
||||
"empty_column.list": "这个列表中暂时没有内容。列表中用户所发送的的新嘟文将会在这里显示。",
|
||||
"empty_column.notifications": "你还没有收到过通知信息,快向其他用户搭讪吧。",
|
||||
"empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户,这里就会有嘟文出现了哦!",
|
||||
"empty_column.notifications": "你还没有收到过任何通知,快向其他用户搭讪吧。",
|
||||
"empty_column.public": "这里神马都没有!写一些公开的嘟文,或者关注其他实例的用户后,这里就会有嘟文出现了哦!",
|
||||
"follow_request.authorize": "同意",
|
||||
"follow_request.reject": "拒绝",
|
||||
"getting_started.appsshort": "应用",
|
||||
@@ -138,7 +139,7 @@
|
||||
"loading_indicator.label": "加载中……",
|
||||
"media_gallery.toggle_visible": "切换显示/隐藏",
|
||||
"missing_indicator.label": "找不到内容",
|
||||
"mute_modal.hide_notifications": "隐藏来自这个用户的通知",
|
||||
"mute_modal.hide_notifications": "同时隐藏来自这个用户的通知",
|
||||
"navigation_bar.blocks": "被屏蔽的用户",
|
||||
"navigation_bar.community_timeline": "本站时间轴",
|
||||
"navigation_bar.edit_profile": "修改个人资料",
|
||||
@@ -157,25 +158,25 @@
|
||||
"notification.mention": "{name} 提及你",
|
||||
"notification.reblog": "{name} 转嘟了你的嘟文",
|
||||
"notifications.clear": "清空通知列表",
|
||||
"notifications.clear_confirmation": "你确定要清空通知列表吗?",
|
||||
"notifications.clear_confirmation": "你确定要永久清空通知列表吗?",
|
||||
"notifications.column_settings.alert": "桌面通知",
|
||||
"notifications.column_settings.favourite": "你的嘟文被收藏:",
|
||||
"notifications.column_settings.follow": "关注你:",
|
||||
"notifications.column_settings.mention": "提及你:",
|
||||
"notifications.column_settings.favourite": "当你的嘟文被收藏时:",
|
||||
"notifications.column_settings.follow": "当有人关注你时:",
|
||||
"notifications.column_settings.mention": "当有人在嘟文中提及你时:",
|
||||
"notifications.column_settings.push": "推送通知",
|
||||
"notifications.column_settings.push_meta": "此设备",
|
||||
"notifications.column_settings.reblog": "你的嘟文被转嘟:",
|
||||
"notifications.column_settings.reblog": "当有人转嘟了你的嘟文时:",
|
||||
"notifications.column_settings.show": "在通知栏显示",
|
||||
"notifications.column_settings.sound": "播放音效",
|
||||
"onboarding.done": "出发!",
|
||||
"onboarding.next": "下一步",
|
||||
"onboarding.page_five.public_timelines": "本站时间轴显示的是由本站({domain})用户发布的所有公开嘟文。跨站公共时间轴显示的的是由本站用户关注对象所发布的所有公开嘟文。这些就是寻人好去处的公共时间轴啦。",
|
||||
"onboarding.page_four.home": "你的主页上的时间轴上显示的是你关注对象的嘟文。",
|
||||
"onboarding.page_four.notifications": "如果有人与你互动,便会出现在通知栏中哦~",
|
||||
"onboarding.page_one.federation": "Mastodon 是由一系列独立的服务器共同打造的强大的社交网络,我们将这些各自独立但又相互连接的服务器叫做实例。",
|
||||
"onboarding.page_one.handle": "你在 {domain},{handle} 就是你的完整帐户名称。",
|
||||
"onboarding.page_four.home": "你的主页时间轴上显示的是你的关注对象所发布的嘟文。",
|
||||
"onboarding.page_four.notifications": "如果有人与你互动了,他们就会出现在通知栏中哦~",
|
||||
"onboarding.page_one.federation": "Mastodon 是由一系列独立的服务器共同打造的强大的社交网络,我们将这些各自独立而又相互连接的服务器叫做实例。",
|
||||
"onboarding.page_one.handle": "你是在 {domain} 上注册的,所以你的完整用户地址是 {handle}。",
|
||||
"onboarding.page_one.welcome": "欢迎来到 Mastodon!",
|
||||
"onboarding.page_six.admin": "{admin} 是你所在服务器实例的管理员.",
|
||||
"onboarding.page_six.admin": "{admin} 是你所在服务器实例的管理员。",
|
||||
"onboarding.page_six.almost_done": "差不多了……",
|
||||
"onboarding.page_six.appetoot": "嗷呜~",
|
||||
"onboarding.page_six.apps_available": "我们还有适用于 iOS、Android 和其它平台的{apps}哦~",
|
||||
@@ -184,8 +185,8 @@
|
||||
"onboarding.page_six.read_guidelines": "别忘了看看 {domain} 的{guidelines}!",
|
||||
"onboarding.page_six.various_app": "移动设备应用",
|
||||
"onboarding.page_three.profile": "你可以修改你的个人资料,比如头像、简介和昵称等偏好设置。",
|
||||
"onboarding.page_three.search": "你可以通过搜索功能寻找用户和话题标签,比如{illustration}或者{introductions}。如果你想搜索其他实例上的用户,就需要输入完整帐户名称(用户名@域名)哦。",
|
||||
"onboarding.page_two.compose": "在撰写栏中开始嘟嘟吧!下方的按钮分别用来上传图片,修改嘟文可见范围,以及添加警告信息。",
|
||||
"onboarding.page_three.search": "你可以通过搜索功能寻找用户和话题标签,比如{illustration}或者{introductions}。如果你想搜索其他实例上的用户,就需要输入完整用户地址(@用户名@域名)哦。",
|
||||
"onboarding.page_two.compose": "在撰写栏中开始嘟嘟吧!下方的按钮分别可以用来上传图片、修改嘟文可见范围,以及添加警告信息。",
|
||||
"onboarding.skip": "跳过",
|
||||
"privacy.change": "设置嘟文可见范围",
|
||||
"privacy.direct.long": "只有被提及的用户能看到",
|
||||
@@ -196,11 +197,11 @@
|
||||
"privacy.public.short": "公开",
|
||||
"privacy.unlisted.long": "所有人可见,但不会出现在公共时间轴上",
|
||||
"privacy.unlisted.short": "不公开",
|
||||
"relative_time.days": "{number} 天",
|
||||
"relative_time.hours": "{number} 时",
|
||||
"relative_time.days": "{number}天",
|
||||
"relative_time.hours": "{number}时",
|
||||
"relative_time.just_now": "刚刚",
|
||||
"relative_time.minutes": "{number} 分",
|
||||
"relative_time.seconds": "{number} 秒",
|
||||
"relative_time.minutes": "{number}分",
|
||||
"relative_time.seconds": "{number}秒",
|
||||
"reply_indicator.cancel": "取消",
|
||||
"report.placeholder": "附言",
|
||||
"report.submit": "提交",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "用户",
|
||||
"search_results.total": "共 {count, number} 个结果",
|
||||
"standalone.public_title": "大家都在干啥?",
|
||||
"status.block": "屏蔽 @{name}",
|
||||
"status.cannot_reblog": "无法转嘟这条嘟文",
|
||||
"status.delete": "删除",
|
||||
"status.embed": "嵌入",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "隐藏媒体内容",
|
||||
"status.mention": "提及 @{name}",
|
||||
"status.more": "更多",
|
||||
"status.mute": "隐藏 @{name}",
|
||||
"status.mute_conversation": "隐藏此对话",
|
||||
"status.open": "展开嘟文",
|
||||
"status.pin": "在个人资料页面置顶",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "取下",
|
||||
"column_subheading.navigation": "瀏覽",
|
||||
"column_subheading.settings": "設定",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "你的用戶狀態為「{locked}」,任何人都能立即關注你,然後看到「只有關注者能看」的文章。",
|
||||
"compose_form.lock_disclaimer.lock": "公共",
|
||||
"compose_form.placeholder": "你在想甚麼?",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} 項結果",
|
||||
"standalone.public_title": "站點一瞥…",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "這篇文章無法被轉推",
|
||||
"status.delete": "刪除",
|
||||
"status.embed": "鑲嵌",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "隱藏媒體內容",
|
||||
"status.mention": "提及 @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "靜音對話",
|
||||
"status.open": "展開文章",
|
||||
"status.pin": "置頂到資料頁",
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"column_header.unpin": "取下",
|
||||
"column_subheading.navigation": "瀏覽",
|
||||
"column_subheading.settings": "設定",
|
||||
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
|
||||
"compose_form.lock_disclaimer": "你的帳號沒有{locked}。任何人都可以關注你,看到發給關注者的貼文。",
|
||||
"compose_form.lock_disclaimer.lock": "上鎖",
|
||||
"compose_form.placeholder": "在想些什麼?",
|
||||
@@ -63,8 +64,8 @@
|
||||
"confirmations.block.message": "你確定要封鎖 {name} ?",
|
||||
"confirmations.delete.confirm": "刪除",
|
||||
"confirmations.delete.message": "你確定要刪除這個狀態?",
|
||||
"confirmations.delete_list.confirm": "Delete",
|
||||
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
|
||||
"confirmations.delete_list.confirm": "刪除",
|
||||
"confirmations.delete_list.message": "確定要永久性地刪除這個名單嗎?",
|
||||
"confirmations.domain_block.confirm": "隱藏整個網域",
|
||||
"confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或消音幾個特定目標就好。",
|
||||
"confirmations.mute.confirm": "消音",
|
||||
@@ -127,14 +128,14 @@
|
||||
"lightbox.close": "關閉",
|
||||
"lightbox.next": "繼續",
|
||||
"lightbox.previous": "回退",
|
||||
"lists.account.add": "Add to list",
|
||||
"lists.account.remove": "Remove from list",
|
||||
"lists.delete": "Delete list",
|
||||
"lists.edit": "Edit list",
|
||||
"lists.new.create": "Add list",
|
||||
"lists.new.title_placeholder": "New list title",
|
||||
"lists.search": "Search among people you follow",
|
||||
"lists.subheading": "Your lists",
|
||||
"lists.account.add": "加到名單裡",
|
||||
"lists.account.remove": "從名單中移除",
|
||||
"lists.delete": "刪除名單",
|
||||
"lists.edit": "修改名單",
|
||||
"lists.new.create": "新增名單",
|
||||
"lists.new.title_placeholder": "名單名稱",
|
||||
"lists.search": "搜尋您關注的使用者",
|
||||
"lists.subheading": "您的名單",
|
||||
"loading_indicator.label": "讀取中...",
|
||||
"media_gallery.toggle_visible": "切換可見性",
|
||||
"missing_indicator.label": "找不到",
|
||||
@@ -145,8 +146,8 @@
|
||||
"navigation_bar.favourites": "最愛",
|
||||
"navigation_bar.follow_requests": "關注請求",
|
||||
"navigation_bar.info": "關於本站",
|
||||
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
|
||||
"navigation_bar.lists": "Lists",
|
||||
"navigation_bar.keyboard_shortcuts": "快速鍵",
|
||||
"navigation_bar.lists": "名單",
|
||||
"navigation_bar.logout": "登出",
|
||||
"navigation_bar.mutes": "消音的使用者",
|
||||
"navigation_bar.pins": "置頂貼文",
|
||||
@@ -213,6 +214,7 @@
|
||||
"search_popout.tips.user": "user",
|
||||
"search_results.total": "{count, number} 項結果",
|
||||
"standalone.public_title": "站點一瞥…",
|
||||
"status.block": "Block @{name}",
|
||||
"status.cannot_reblog": "此貼文無法轉推",
|
||||
"status.delete": "刪除",
|
||||
"status.embed": "Embed",
|
||||
@@ -221,6 +223,7 @@
|
||||
"status.media_hidden": "媒體已隱藏",
|
||||
"status.mention": "提到 @{name}",
|
||||
"status.more": "More",
|
||||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "消音對話",
|
||||
"status.open": "展開這個狀態",
|
||||
"status.pin": "置頂到個人資訊頁",
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import * as WebPushSubscription from './web_push_subscription';
|
||||
import Mastodon from './containers/mastodon';
|
||||
import * as registerPushNotifications from './actions/push_notifications';
|
||||
import { default as Mastodon, store } from './containers/mastodon';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ready from './ready';
|
||||
@@ -25,7 +25,7 @@ function main() {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// avoid offline in dev mode because it's harder to debug
|
||||
require('offline-plugin/runtime').install();
|
||||
WebPushSubscription.register();
|
||||
store.dispatch(registerPushNotifications.register());
|
||||
}
|
||||
perf.stop('main()');
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { STORE_HYDRATE } from '../actions/store';
|
||||
import { SET_BROWSER_SUPPORT, SET_SUBSCRIPTION, CLEAR_SUBSCRIPTION, ALERTS_CHANGE } from '../actions/push_notifications';
|
||||
import { SET_BROWSER_SUPPORT, SET_SUBSCRIPTION, CLEAR_SUBSCRIPTION, SET_ALERTS } from '../actions/push_notifications';
|
||||
import Immutable from 'immutable';
|
||||
|
||||
const initialState = Immutable.Map({
|
||||
@@ -43,8 +43,8 @@ export default function push_subscriptions(state = initialState, action) {
|
||||
return state.set('browserSupport', action.value);
|
||||
case CLEAR_SUBSCRIPTION:
|
||||
return initialState;
|
||||
case ALERTS_CHANGE:
|
||||
return state.setIn(action.key, action.value);
|
||||
case SET_ALERTS:
|
||||
return state.setIn(action.path, action.value);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@@ -93,7 +93,7 @@ export default function settings(state = initialState, action) {
|
||||
return hydrate(state, action.state.get('settings'));
|
||||
case SETTING_CHANGE:
|
||||
return state
|
||||
.setIn(action.key, action.value)
|
||||
.setIn(action.path, action.value)
|
||||
.set('saved', false);
|
||||
case COLUMN_ADD:
|
||||
return state
|
||||
|
@@ -1,129 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import { store } from './containers/mastodon';
|
||||
import { setBrowserSupport, setSubscription, clearSubscription } from './actions/push_notifications';
|
||||
import { pushNotificationsSetting } from './settings';
|
||||
|
||||
// Taken from https://www.npmjs.com/package/web-push
|
||||
const urlBase64ToUint8Array = (base64String) => {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
};
|
||||
|
||||
const getApplicationServerKey = () => document.querySelector('[name="applicationServerKey"]').getAttribute('content');
|
||||
|
||||
const getRegistration = () => navigator.serviceWorker.ready;
|
||||
|
||||
const getPushSubscription = (registration) =>
|
||||
registration.pushManager.getSubscription()
|
||||
.then(subscription => ({ registration, subscription }));
|
||||
|
||||
const subscribe = (registration) =>
|
||||
registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(getApplicationServerKey()),
|
||||
});
|
||||
|
||||
const unsubscribe = ({ registration, subscription }) =>
|
||||
subscription ? subscription.unsubscribe().then(() => registration) : registration;
|
||||
|
||||
const sendSubscriptionToBackend = (subscription) => {
|
||||
const params = { subscription };
|
||||
|
||||
const me = store.getState().getIn(['meta', 'me']);
|
||||
if (me) {
|
||||
const data = pushNotificationsSetting.get(me);
|
||||
if (data) {
|
||||
params.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
return axios.post('/api/web/push_subscriptions', params).then(response => response.data);
|
||||
};
|
||||
|
||||
// Last one checks for payload support: https://web-push-book.gauntface.com/chapter-06/01-non-standards-browsers/#no-payload
|
||||
const supportsPushNotifications = ('serviceWorker' in navigator && 'PushManager' in window && 'getKey' in PushSubscription.prototype);
|
||||
|
||||
export function register () {
|
||||
store.dispatch(setBrowserSupport(supportsPushNotifications));
|
||||
const me = store.getState().getIn(['meta', 'me']);
|
||||
|
||||
if (me && !pushNotificationsSetting.get(me)) {
|
||||
const alerts = store.getState().getIn(['push_notifications', 'alerts']);
|
||||
if (alerts) {
|
||||
pushNotificationsSetting.set(me, { alerts: alerts });
|
||||
}
|
||||
}
|
||||
|
||||
if (supportsPushNotifications) {
|
||||
if (!getApplicationServerKey()) {
|
||||
console.error('The VAPID public key is not set. You will not be able to receive Web Push Notifications.');
|
||||
return;
|
||||
}
|
||||
|
||||
getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(({ registration, subscription }) => {
|
||||
if (subscription !== null) {
|
||||
// We have a subscription, check if it is still valid
|
||||
const currentServerKey = (new Uint8Array(subscription.options.applicationServerKey)).toString();
|
||||
const subscriptionServerKey = urlBase64ToUint8Array(getApplicationServerKey()).toString();
|
||||
const serverEndpoint = store.getState().getIn(['push_notifications', 'subscription', 'endpoint']);
|
||||
|
||||
// If the VAPID public key did not change and the endpoint corresponds
|
||||
// to the endpoint saved in the backend, the subscription is valid
|
||||
if (subscriptionServerKey === currentServerKey && subscription.endpoint === serverEndpoint) {
|
||||
return subscription;
|
||||
} else {
|
||||
// Something went wrong, try to subscribe again
|
||||
return unsubscribe({ registration, subscription }).then(subscribe).then(sendSubscriptionToBackend);
|
||||
}
|
||||
}
|
||||
|
||||
// No subscription, try to subscribe
|
||||
return subscribe(registration).then(sendSubscriptionToBackend);
|
||||
})
|
||||
.then(subscription => {
|
||||
// If we got a PushSubscription (and not a subscription object from the backend)
|
||||
// it means that the backend subscription is valid (and was set during hydration)
|
||||
if (!(subscription instanceof PushSubscription)) {
|
||||
store.dispatch(setSubscription(subscription));
|
||||
if (me) {
|
||||
pushNotificationsSetting.set(me, { alerts: subscription.alerts });
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.code === 20 && error.name === 'AbortError') {
|
||||
console.warn('Your browser supports Web Push Notifications, but does not seem to implement the VAPID protocol.');
|
||||
} else if (error.code === 5 && error.name === 'InvalidCharacterError') {
|
||||
console.error('The VAPID public key seems to be invalid:', getApplicationServerKey());
|
||||
}
|
||||
|
||||
// Clear alerts and hide UI settings
|
||||
store.dispatch(clearSubscription());
|
||||
if (me) {
|
||||
pushNotificationsSetting.remove(me);
|
||||
}
|
||||
|
||||
try {
|
||||
getRegistration()
|
||||
.then(getPushSubscription)
|
||||
.then(unsubscribe);
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.warn('Your browser does not support Web Push Notifications.');
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@
|
||||
|
||||
@import 'mastodon/reset';
|
||||
@import 'mastodon/basics';
|
||||
@import 'mastodon/modal';
|
||||
@import 'mastodon/containers';
|
||||
@import 'mastodon/lists';
|
||||
@import 'mastodon/footer';
|
||||
|
@@ -398,10 +398,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
&__content {
|
||||
max-width: calc(100% - 90px);
|
||||
}
|
||||
|
||||
&__title {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
&__timestamp {
|
||||
@@ -415,7 +417,7 @@
|
||||
color: $ui-primary-color;
|
||||
font-family: 'mastodon-font-monospace', monospace;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
word-wrap: break-word;
|
||||
min-height: 20px;
|
||||
}
|
||||
|
||||
|
@@ -214,6 +214,7 @@
|
||||
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
transform-origin: 50% 0;
|
||||
}
|
||||
|
||||
.dropdown--active .icon-button {
|
||||
@@ -606,6 +607,7 @@
|
||||
font-weight: 400;
|
||||
overflow: hidden;
|
||||
white-space: pre-wrap;
|
||||
padding-top: 2px;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
@@ -704,6 +706,10 @@
|
||||
|
||||
.status.status-direct {
|
||||
background: lighten($ui-base-color, 12%);
|
||||
|
||||
&.muted {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.detailed-status,
|
||||
@@ -858,7 +864,7 @@
|
||||
.status__action-bar {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.status__action-bar-button {
|
||||
@@ -1752,7 +1758,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: lighten($ui-base-color, 13%);
|
||||
background: lighten($ui-base-color, 13%) url('../images/wave-drawer.png') no-repeat bottom / 100% auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
@@ -1765,6 +1771,11 @@
|
||||
&.darker {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
> .mastodon {
|
||||
background: url('../images/mastodon-ui.png') no-repeat left bottom / contain;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.pseudo-drawer {
|
||||
@@ -2061,20 +2072,18 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.getting-started__wrapper,
|
||||
.getting_started {
|
||||
background: $ui-base-color;
|
||||
}
|
||||
|
||||
.getting-started__wrapper {
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.getting-started__footer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.getting-started {
|
||||
box-sizing: border-box;
|
||||
padding-bottom: 235px;
|
||||
background: url('../images/mastodon-getting-started.png') no-repeat 0 100%;
|
||||
background: $ui-base-color;
|
||||
flex: 1 0 auto;
|
||||
|
||||
p {
|
||||
@@ -2099,7 +2108,7 @@
|
||||
padding: 0 10px 8px;
|
||||
}
|
||||
|
||||
code {
|
||||
kbd {
|
||||
display: inline-block;
|
||||
padding: 3px 5px;
|
||||
background-color: lighten($ui-base-color, 8%);
|
||||
@@ -2143,7 +2152,8 @@
|
||||
|
||||
@import 'boost';
|
||||
|
||||
button.icon-button i.fa-retweet {
|
||||
.no-reduce-motion button.icon-button i.fa-retweet {
|
||||
|
||||
background-position: 0 0;
|
||||
height: 19px;
|
||||
transition: background-position 0.9s steps(10);
|
||||
@@ -2154,13 +2164,23 @@ button.icon-button i.fa-retweet {
|
||||
&::before {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
button.icon-button.active i.fa-retweet {
|
||||
.no-reduce-motion button.icon-button.active i.fa-retweet {
|
||||
transition-duration: 0.9s;
|
||||
background-position: 0 100%;
|
||||
}
|
||||
|
||||
.reduce-motion button.icon-button i.fa-retweet {
|
||||
color: $ui-base-lighter-color;
|
||||
transition: color 100ms ease-in;
|
||||
}
|
||||
|
||||
.reduce-motion button.icon-button.active i.fa-retweet {
|
||||
color: $ui-highlight-color;
|
||||
}
|
||||
|
||||
.status-card {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
@@ -2938,6 +2958,7 @@ button.icon-button.active i.fa-retweet {
|
||||
border-radius: 4px;
|
||||
margin-left: 40px;
|
||||
overflow: hidden;
|
||||
transform-origin: 50% 0;
|
||||
}
|
||||
|
||||
.privacy-dropdown__option {
|
||||
|
20
app/javascript/styles/mastodon/modal.scss
Normal file
20
app/javascript/styles/mastodon/modal.scss
Normal file
@@ -0,0 +1,20 @@
|
||||
.modal-layout {
|
||||
background: $ui-base-color url('../images/wave-modal.png') repeat-x bottom fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.modal-layout__mastodon {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: flex-end;
|
||||
|
||||
> * {
|
||||
flex: 1;
|
||||
max-height: 235px;
|
||||
background: url('../images/mastodon-ui.png') no-repeat left bottom / contain;
|
||||
}
|
||||
}
|
31
app/lib/activity_tracker.rb
Normal file
31
app/lib/activity_tracker.rb
Normal file
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityTracker
|
||||
EXPIRE_AFTER = 90.days.seconds
|
||||
|
||||
class << self
|
||||
def increment(prefix)
|
||||
key = [prefix, current_week].join(':')
|
||||
|
||||
redis.incrby(key, 1)
|
||||
redis.expire(key, EXPIRE_AFTER)
|
||||
end
|
||||
|
||||
def record(prefix, value)
|
||||
key = [prefix, current_week].join(':')
|
||||
|
||||
redis.pfadd(key, value)
|
||||
redis.expire(key, EXPIRE_AFTER)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redis
|
||||
Redis.current
|
||||
end
|
||||
|
||||
def current_week
|
||||
Time.zone.today.cweek
|
||||
end
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user