diff options
Diffstat (limited to 'app')
195 files changed, 3462 insertions, 1020 deletions
diff --git a/app/controllers/admin/accounts_controller.rb b/app/controllers/admin/accounts_controller.rb index 2fa1dfe5f..68b6352f8 100644 --- a/app/controllers/admin/accounts_controller.rb +++ b/app/controllers/admin/accounts_controller.rb @@ -41,7 +41,7 @@ module Admin def reject authorize @account.user, :reject? - SuspendAccountService.new.call(@account, including_user: true, destroy: true, skip_distribution: true) + SuspendAccountService.new.call(@account, reserve_email: false, reserve_username: false) redirect_to admin_pending_accounts_path end diff --git a/app/controllers/admin/custom_emojis_controller.rb b/app/controllers/admin/custom_emojis_controller.rb index f77699166..2af90f051 100644 --- a/app/controllers/admin/custom_emojis_controller.rb +++ b/app/controllers/admin/custom_emojis_controller.rb @@ -2,19 +2,20 @@ module Admin class CustomEmojisController < BaseController - before_action :set_custom_emoji, except: [:index, :new, :create] - before_action :set_filter_params - include ObfuscateFilename + obfuscate_filename [:custom_emoji, :image] def index authorize :custom_emoji, :index? + @custom_emojis = filtered_custom_emojis.eager_load(:local_counterpart).page(params[:page]) + @form = Form::CustomEmojiBatch.new end def new authorize :custom_emoji, :create? + @custom_emoji = CustomEmoji.new end @@ -31,69 +32,17 @@ module Admin end end - def update - authorize @custom_emoji, :update? - - if @custom_emoji.update(resource_params) - log_action :update, @custom_emoji - flash[:notice] = I18n.t('admin.custom_emojis.updated_msg') - else - 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 - 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.image = @custom_emoji.image - - if emoji.save - log_action :create, emoji - flash[:notice] = I18n.t('admin.custom_emojis.copied_msg') - else - flash[:alert] = I18n.t('admin.custom_emojis.copy_failed_msg') - end - - 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 - 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 - flash[:notice] = I18n.t('admin.custom_emojis.disabled_msg') - redirect_to admin_custom_emojis_path(page: params[:page], **@filter_params) + def batch + @form = Form::CustomEmojiBatch.new(form_custom_emoji_batch_params.merge(current_account: current_account, action: action_from_button)) + @form.save + rescue ActionController::ParameterMissing + flash[:alert] = I18n.t('admin.accounts.no_account_selected') + ensure + redirect_to admin_custom_emojis_path(filter_params) end private - def set_custom_emoji - @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 @@ -103,12 +52,29 @@ module Admin end def filter_params - params.permit( - :local, - :remote, - :by_domain, - :shortcode - ) + params.slice(:local, :remote, :by_domain, :shortcode, :page).permit(:local, :remote, :by_domain, :shortcode, :page) + end + + def action_from_button + if params[:update] + 'update' + elsif params[:list] + 'list' + elsif params[:unlist] + 'unlist' + elsif params[:enable] + 'enable' + elsif params[:disable] + 'disable' + elsif params[:copy] + 'copy' + elsif params[:delete] + 'delete' + end + end + + def form_custom_emoji_batch_params + params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: []) end end end diff --git a/app/controllers/admin/report_notes_controller.rb b/app/controllers/admin/report_notes_controller.rb index bcb3f2026..b816c5b5d 100644 --- a/app/controllers/admin/report_notes_controller.rb +++ b/app/controllers/admin/report_notes_controller.rb @@ -5,10 +5,10 @@ module Admin before_action :set_report_note, only: [:destroy] def create - authorize ReportNote, :create? + authorize :report_note, :create? @report_note = current_account.report_notes.new(resource_params) - @report = @report_note.report + @report = @report_note.report if @report_note.save if params[:create_and_resolve] @@ -26,9 +26,8 @@ module Admin redirect_to admin_report_path(@report), notice: I18n.t('admin.report_notes.created_msg') else - @report_notes = @report.notes.latest - @report_history = @report.history - @form = Form::StatusBatch.new + @report_notes = (@report.notes.latest + @report.history + @report.target_account.targeted_account_warnings.latest.custom).sort_by(&:created_at) + @form = Form::StatusBatch.new render template: 'admin/reports/show' end diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb index 8bd4e5f8b..65341bbfb 100644 --- a/app/controllers/admin/tags_controller.rb +++ b/app/controllers/admin/tags_controller.rb @@ -2,13 +2,34 @@ module Admin class TagsController < BaseController - before_action :set_tags, only: :index - before_action :set_tag, except: :index - before_action :set_usage_by_domain, except: :index - before_action :set_counters, except: :index + before_action :set_tag, except: [:index, :batch, :approve_all, :reject_all] + before_action :set_usage_by_domain, except: [:index, :batch, :approve_all, :reject_all] + before_action :set_counters, except: [:index, :batch, :approve_all, :reject_all] def index authorize :tag, :index? + + @tags = filtered_tags.page(params[:page]) + @form = Form::TagBatch.new + end + + def batch + @form = Form::TagBatch.new(form_tag_batch_params.merge(current_account: current_account, action: action_from_button)) + @form.save + rescue ActionController::ParameterMissing + flash[:alert] = I18n.t('admin.accounts.no_account_selected') + ensure + redirect_to admin_tags_path(filter_params) + end + + def approve_all + Form::TagBatch.new(current_account: current_account, tag_ids: Tag.pending_review.pluck(:id), action: 'approve').save + redirect_to admin_tags_path(filter_params) + end + + def reject_all + Form::TagBatch.new(current_account: current_account, tag_ids: Tag.pending_review.pluck(:id), action: 'reject').save + redirect_to admin_tags_path(filter_params) end def show @@ -27,10 +48,6 @@ module Admin private - def set_tags - @tags = filtered_tags.page(params[:page]) - end - def set_tag @tag = Tag.find(params[:id]) end @@ -52,16 +69,11 @@ module Admin end def filtered_tags - scope = Tag - scope = scope.discoverable if filter_params[:context] == 'directory' - scope = scope.unreviewed if filter_params[:review] == 'unreviewed' - scope = scope.reviewed.order(reviewed_at: :desc) if filter_params[:review] == 'reviewed' - scope = scope.pending_review.order(requested_review_at: :desc) if filter_params[:review] == 'pending_review' - scope.order(max_score: :desc) + TagFilter.new(filter_params).results end def filter_params - params.slice(:context, :review).permit(:context, :review) + params.slice(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name).permit(:directory, :reviewed, :unreviewed, :pending_review, :page, :popular, :active, :name) end def tag_params @@ -75,5 +87,17 @@ module Admin date.to_time(:utc).beginning_of_day.to_i end end + + def form_tag_batch_params + params.require(:form_tag_batch).permit(:action, tag_ids: []) + end + + def action_from_button + if params[:approve] + 'approve' + elsif params[:reject] + 'reject' + end + end end end diff --git a/app/controllers/api/v1/admin/accounts_controller.rb b/app/controllers/api/v1/admin/accounts_controller.rb index c306180ca..c35ea5ab2 100644 --- a/app/controllers/api/v1/admin/accounts_controller.rb +++ b/app/controllers/api/v1/admin/accounts_controller.rb @@ -58,7 +58,7 @@ class Api::V1::Admin::AccountsController < Api::BaseController def reject authorize @account.user, :reject? - SuspendAccountService.new.call(@account, including_user: true, destroy: true, skip_distribution: true) + SuspendAccountService.new.call(@account, reserve_email: false, reserve_username: false) render json: @account, serializer: REST::Admin::AccountSerializer end diff --git a/app/controllers/api/v1/custom_emojis_controller.rb b/app/controllers/api/v1/custom_emojis_controller.rb index 252f667dd..4e6d5d7c6 100644 --- a/app/controllers/api/v1/custom_emojis_controller.rb +++ b/app/controllers/api/v1/custom_emojis_controller.rb @@ -7,6 +7,6 @@ class Api::V1::CustomEmojisController < Api::BaseController def index expires_in 3.minutes, public: true - render_with_cache(each_serializer: REST::CustomEmojiSerializer) { CustomEmoji.local.where(disabled: false).includes(:category) } + render_with_cache(each_serializer: REST::CustomEmojiSerializer) { CustomEmoji.listed.includes(:category) } end end diff --git a/app/controllers/api/v1/featured_tags/suggestions_controller.rb b/app/controllers/api/v1/featured_tags/suggestions_controller.rb new file mode 100644 index 000000000..fb27ef88b --- /dev/null +++ b/app/controllers/api/v1/featured_tags/suggestions_controller.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class Api::V1::FeaturedTags::SuggestionsController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index + + before_action :require_user! + before_action :set_most_used_tags, only: :index + + respond_to :json + + def index + render json: @most_used_tags, each_serializer: REST::TagSerializer + end + + private + + def set_most_used_tags + @most_used_tags = Tag.most_used(current_account).where.not(id: current_account.featured_tags).limit(10) + end +end diff --git a/app/controllers/api/v1/featured_tags_controller.rb b/app/controllers/api/v1/featured_tags_controller.rb new file mode 100644 index 000000000..e4e836c97 --- /dev/null +++ b/app/controllers/api/v1/featured_tags_controller.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +class Api::V1::FeaturedTagsController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:accounts' }, only: :index + before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index + + before_action :require_user! + before_action :set_featured_tags, only: :index + before_action :set_featured_tag, except: [:index, :create] + + def index + render json: @featured_tags, each_serializer: REST::FeaturedTagSerializer + end + + def create + @featured_tag = current_account.featured_tags.new(featured_tag_params) + @featured_tag.reset_data + @featured_tag.save! + render json: @featured_tag, serializer: REST::FeaturedTagSerializer + end + + def destroy + @featured_tag.destroy! + render_empty + end + + private + + def set_featured_tag + @featured_tag = current_account.featured_tags.find(params[:id]) + end + + def set_featured_tags + @featured_tags = current_account.featured_tags.order(statuses_count: :desc) + end + + def featured_tag_params + params.permit(:name) + end +end diff --git a/app/controllers/api/v1/follow_requests_controller.rb b/app/controllers/api/v1/follow_requests_controller.rb index e6888154e..0ee6e531f 100644 --- a/app/controllers/api/v1/follow_requests_controller.rb +++ b/app/controllers/api/v1/follow_requests_controller.rb @@ -14,12 +14,12 @@ class Api::V1::FollowRequestsController < Api::BaseController def authorize AuthorizeFollowService.new.call(account, current_account) NotifyService.new.call(current_account, Follow.find_by(account: account, target_account: current_account)) - render_empty + render json: account, serializer: REST::RelationshipSerializer, relationships: relationships end def reject RejectFollowService.new.call(account, current_account) - render_empty + render json: account, serializer: REST::RelationshipSerializer, relationships: relationships end private @@ -28,6 +28,10 @@ class Api::V1::FollowRequestsController < Api::BaseController Account.find(params[:id]) end + def relationships(**options) + AccountRelationshipsPresenter.new([params[:id]], current_user.account_id, options) + end + def load_accounts default_accounts.merge(paginated_follow_requests).to_a end diff --git a/app/controllers/api/v1/markers_controller.rb b/app/controllers/api/v1/markers_controller.rb new file mode 100644 index 000000000..28c2ec791 --- /dev/null +++ b/app/controllers/api/v1/markers_controller.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class Api::V1::MarkersController < Api::BaseController + before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, only: [:index] + before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, except: [:index] + + before_action :require_user! + + def index + @markers = current_user.markers.where(timeline: Array(params[:timeline])).each_with_object({}) { |marker, h| h[marker.timeline] = marker } + render json: serialize_map(@markers) + end + + def create + Marker.transaction do + @markers = {} + + resource_params.each_pair do |timeline, timeline_params| + @markers[timeline] = current_user.markers.find_or_initialize_by(timeline: timeline) + @markers[timeline].update!(timeline_params) + end + end + + render json: serialize_map(@markers) + rescue ActiveRecord::StaleObjectError + render json: { error: 'Conflict during update, please try again' }, status: 409 + end + + private + + def serialize_map(map) + serialized = {} + + map.each_pair do |key, value| + serialized[key] = ActiveModelSerializers::SerializableResource.new(value, serializer: REST::MarkerSerializer).as_json + end + + Oj.dump(serialized) + end + + def resource_params + params.slice(*Marker::TIMELINES).permit(*Marker::TIMELINES.map { |timeline| { timeline.to_sym => [:last_read_id] } }) + end +end diff --git a/app/controllers/api/v1/search_controller.rb b/app/controllers/api/v1/search_controller.rb deleted file mode 100644 index 4fb869bb9..000000000 --- a/app/controllers/api/v1/search_controller.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::SearchController < Api::BaseController - include Authorization - - RESULTS_LIMIT = (ENV['MAX_SEARCH_RESULTS'] || 20).to_i - - before_action -> { doorkeeper_authorize! :read, :'read:search' } - before_action :require_user! - - respond_to :json - - def index - @search = Search.new(search_results) - render json: @search, serializer: REST::SearchSerializer - end - - private - - def search_results - SearchService.new.call( - params[:q], - current_account, - limit_param(RESULTS_LIMIT), - search_params.merge(resolve: truthy_param?(:resolve)) - ) - end - - def search_params - params.permit(:type, :offset, :min_id, :max_id, :account_id) - end -end diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index aabe24324..ccc10f966 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true class Api::V1::Timelines::PublicController < Api::BaseController + before_action :require_user!, only: [:show], if: :require_auth? after_action :insert_pagination_headers, unless: -> { @statuses.empty? } respond_to :json @@ -12,6 +13,10 @@ class Api::V1::Timelines::PublicController < Api::BaseController private + def require_auth? + !Setting.timeline_preview + end + def load_statuses cached_public_statuses end diff --git a/app/controllers/api/v2/search_controller.rb b/app/controllers/api/v2/search_controller.rb index 9aa6edc69..7fdc030e5 100644 --- a/app/controllers/api/v2/search_controller.rb +++ b/app/controllers/api/v2/search_controller.rb @@ -1,8 +1,32 @@ # frozen_string_literal: true -class Api::V2::SearchController < Api::V1::SearchController +class Api::V2::SearchController < Api::BaseController + include Authorization + + RESULTS_LIMIT = (ENV['MAX_SEARCH_RESULTS'] || 20).to_i + + before_action -> { doorkeeper_authorize! :read, :'read:search' } + before_action :require_user! + + respond_to :json + def index @search = Search.new(search_results) - render json: @search, serializer: REST::V2::SearchSerializer + render json: @search, serializer: REST::SearchSerializer + end + + private + + def search_results + SearchService.new.call( + params[:q], + current_account, + limit_param(RESULTS_LIMIT), + search_params.merge(resolve: truthy_param?(:resolve)) + ) + end + + def search_params + params.permit(:type, :offset, :min_id, :max_id, :account_id) end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 59624cad5..92339ce2f 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -42,7 +42,7 @@ class ApplicationController < ActionController::Base private def https_enabled? - Rails.env.production? + Rails.env.production? && !request.path.start_with?('/health') end def authorized_fetch_mode? diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index 7ecbaf193..c2b38883b 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -8,7 +8,6 @@ class Auth::SessionsController < Devise::SessionsController skip_before_action :require_no_authentication, only: [:create] skip_before_action :require_functional! - prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create] prepend_before_action :set_pack before_action :set_instance_presenter, only: [:new] @@ -23,9 +22,22 @@ class Auth::SessionsController < Devise::SessionsController end def create - super do |resource| - remember_me(resource) - flash.delete(:notice) + self.resource = begin + if user_params[:email].blank? && session[:otp_user_id].present? + User.find(session[:otp_user_id]) + else + warden.authenticate!(auth_options) + end + end + + if resource.otp_required_for_login? + if user_params[:otp_attempt].present? && session[:otp_user_id].present? + authenticate_with_two_factor_via_otp(resource) + else + prompt_for_two_factor(resource) + end + else + authenticate_and_respond(resource) end end @@ -38,18 +50,6 @@ class Auth::SessionsController < Devise::SessionsController protected - def find_user - if session[:otp_user_id] - User.find(session[:otp_user_id]) - elsif user_params[:email] - if use_seamless_external_login? && Devise.check_at_sign && user_params[:email].index('@').nil? - User.joins(:account).find_by(accounts: { username: user_params[:email] }) - else - User.find_for_authentication(email: user_params[:email]) - end - end - end - def user_params params.require(:user).permit(:email, :password, :otp_attempt) end @@ -72,32 +72,17 @@ class Auth::SessionsController < Devise::SessionsController super end - def two_factor_enabled? - find_user.try(:otp_required_for_login?) - end - def valid_otp_attempt?(user) user.validate_and_consume_otp!(user_params[:otp_attempt]) || user.invalidate_otp_backup_code!(user_params[:otp_attempt]) - rescue OpenSSL::Cipher::CipherError => _error + rescue OpenSSL::Cipher::CipherError false end - def authenticate_with_two_factor - user = self.resource = find_user - - if user_params[:otp_attempt].present? && session[:otp_user_id] - authenticate_with_two_factor_via_otp(user) - elsif user&.valid_password?(user_params[:password]) - prompt_for_two_factor(user) - end - end - def authenticate_with_two_factor_via_otp(user) if valid_otp_attempt?(user) session.delete(:otp_user_id) - remember_me(user) - sign_in(user) + authenticate_and_respond(user) else flash.now[:alert] = I18n.t('users.invalid_otp_token') prompt_for_two_factor(user) @@ -109,6 +94,13 @@ class Auth::SessionsController < Devise::SessionsController render :two_factor end + def authenticate_and_respond(user) + sign_in(user) + remember_me(user) + + respond_with user, location: after_sign_in_path_for(user) + end + private def set_pack @@ -125,9 +117,11 @@ class Auth::SessionsController < Devise::SessionsController def home_paths(resource) paths = [about_path] + if single_user_mode? && resource.is_a?(User) paths << short_account_path(username: resource.account) end + paths end diff --git a/app/controllers/media_proxy_controller.rb b/app/controllers/media_proxy_controller.rb index 558cd6e30..47544f21c 100644 --- a/app/controllers/media_proxy_controller.rb +++ b/app/controllers/media_proxy_controller.rb @@ -8,6 +8,8 @@ class MediaProxyController < ApplicationController before_action :authenticate_user!, if: :whitelist_mode? rescue_from ActiveRecord::RecordInvalid, with: :not_found + rescue_from Mastodon::UnexpectedResponseError, with: :not_found + rescue_from HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, with: :internal_server_error def show RedisLock.acquire(lock_options) do |lock| diff --git a/app/controllers/settings/deletes_controller.rb b/app/controllers/settings/deletes_controller.rb index 97fe4d328..15a59c999 100644 --- a/app/controllers/settings/deletes_controller.rb +++ b/app/controllers/settings/deletes_controller.rb @@ -14,12 +14,11 @@ class Settings::DeletesController < Settings::BaseController end def destroy - if current_user.valid_password?(delete_params[:password]) - Admin::SuspensionWorker.perform_async(current_user.account_id, true) - sign_out + if challenge_passed? + destroy_account! redirect_to new_user_session_path, notice: I18n.t('deletes.success_msg') else - redirect_to settings_delete_path, alert: I18n.t('deletes.bad_password_msg') + redirect_to settings_delete_path, alert: I18n.t('deletes.challenge_not_passed') end end @@ -29,11 +28,25 @@ class Settings::DeletesController < Settings::BaseController redirect_to root_path unless Setting.open_deletion end - def delete_params - params.require(:form_delete_confirmation).permit(:password) + def resource_params + params.require(:form_delete_confirmation).permit(:password, :username) end def require_not_suspended! forbidden if current_account.suspended? end + + def challenge_passed? + if current_user.encrypted_password.blank? + current_account.username == resource_params[:username] + else + current_user.valid_password?(resource_params[:password]) + end + end + + def destroy_account! + current_account.suspend! + Admin::SuspensionWorker.perform_async(current_user.account_id, true) + sign_out + end end diff --git a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb index 3145e092d..46c90bf74 100644 --- a/app/controllers/settings/two_factor_authentication/confirmations_controller.rb +++ b/app/controllers/settings/two_factor_authentication/confirmations_controller.rb @@ -15,7 +15,7 @@ module Settings end def create - if current_user.validate_and_consume_otp!(confirmation_params[:code]) + if current_user.validate_and_consume_otp!(confirmation_params[:otp_attempt]) flash.now[:notice] = I18n.t('two_factor_authentication.enabled_success') current_user.otp_required_for_login = true @@ -33,7 +33,7 @@ module Settings private def confirmation_params - params.require(:form_two_factor_confirmation).permit(:code) + params.require(:form_two_factor_confirmation).permit(:otp_attempt) end def prepare_two_factor_form diff --git a/app/controllers/settings/two_factor_authentications_controller.rb b/app/controllers/settings/two_factor_authentications_controller.rb index 6904076e4..c93b17577 100644 --- a/app/controllers/settings/two_factor_authentications_controller.rb +++ b/app/controllers/settings/two_factor_authentications_controller.rb @@ -34,7 +34,7 @@ module Settings private def confirmation_params - params.require(:form_two_factor_confirmation).permit(:code) + params.require(:form_two_factor_confirmation).permit(:otp_attempt) end def verify_otp_required @@ -42,8 +42,8 @@ module Settings end def acceptable_code? - current_user.validate_and_consume_otp!(confirmation_params[:code]) || - current_user.invalidate_otp_backup_code!(confirmation_params[:code]) + current_user.validate_and_consume_otp!(confirmation_params[:otp_attempt]) || + current_user.invalidate_otp_backup_code!(confirmation_params[:otp_attempt]) end end end diff --git a/app/controllers/well_known/webfinger_controller.rb b/app/controllers/well_known/webfinger_controller.rb index d60bf98ab..480e58f3f 100644 --- a/app/controllers/well_known/webfinger_controller.rb +++ b/app/controllers/well_known/webfinger_controller.rb @@ -5,18 +5,22 @@ module WellKnown include RoutingHelper before_action { response.headers['Vary'] = 'Accept' } + before_action :set_account + before_action :check_account_suspension - def show - @account = Account.find_local!(username_from_resource) + rescue_from ActiveRecord::RecordNotFound, ActionController::ParameterMissing, with: :not_found + def show expires_in 3.days, public: true render json: @account, serializer: WebfingerSerializer, content_type: 'application/jrd+json' - rescue ActiveRecord::RecordNotFound, ActionController::ParameterMissing - head 404 end private + def set_account + @account = Account.find_local!(username_from_resource) + end + def username_from_resource resource_user = resource_param username, domain = resource_user.split('@') @@ -28,5 +32,17 @@ module WellKnown def resource_param params.require(:resource) end + + def check_account_suspension + expires_in(3.minutes, public: true) && gone if @account.suspended? + end + + def not_found + head 404 + end + + def gone + head 410 + end end end diff --git a/app/helpers/admin/filter_helper.rb b/app/helpers/admin/filter_helper.rb index 506429e10..8af1683e7 100644 --- a/app/helpers/admin/filter_helper.rb +++ b/app/helpers/admin/filter_helper.rb @@ -5,7 +5,7 @@ module Admin::FilterHelper REPORT_FILTERS = %i(resolved account_id target_account_id).freeze INVITE_FILTER = %i(available expired).freeze CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze - TAGS_FILTERS = %i(context review).freeze + TAGS_FILTERS = %i(directory reviewed unreviewed pending_review popular active name).freeze INSTANCES_FILTERS = %i(limited by_domain).freeze FOLLOWERS_FILTERS = %i(relationship status by_domain activity order).freeze diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6940c8535..40f914f1e 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -77,8 +77,12 @@ module ApplicationHelper content_tag(:i, nil, attributes.merge(class: class_names.join(' '))) end - def custom_emoji_tag(custom_emoji) - image_tag(custom_emoji.image.url, class: 'emojione', alt: ":#{custom_emoji.shortcode}:") + def custom_emoji_tag(custom_emoji, animate = true) + if animate + image_tag(custom_emoji.image.url, class: 'emojione', alt: ":#{custom_emoji.shortcode}:") + else + image_tag(custom_emoji.image.url(:static), class: 'emojione custom-emoji', alt: ":#{custom_emoji.shortcode}", 'data-original' => full_asset_url(custom_emoji.image.url), 'data-static' => full_asset_url(custom_emoji.image.url(:static))) + end end def opengraph(property, content) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index 92bc222ea..2b3fd1263 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -43,7 +43,8 @@ module SettingsHelper oc: 'Occitan', pl: 'Polski', pt: 'Português', - 'pt-BR': 'Português do Brasil', + 'pt-PT': 'Português (Portugal)', + 'pt-BR': 'Português (Brasil)', ro: 'Română', ru: 'Русский', sk: 'Slovenčina', diff --git a/app/javascript/flavours/glitch/actions/markers.js b/app/javascript/flavours/glitch/actions/markers.js new file mode 100644 index 000000000..c3a5fe86f --- /dev/null +++ b/app/javascript/flavours/glitch/actions/markers.js @@ -0,0 +1,30 @@ +export const submitMarkers = () => (dispatch, getState) => { + const accessToken = getState().getIn(['meta', 'access_token'], ''); + const params = {}; + + const lastHomeId = getState().getIn(['timelines', 'home', 'items', 0]); + const lastNotificationId = getState().getIn(['notifications', 'items', 0, 'id']); + + if (lastHomeId) { + params.home = { + last_read_id: lastHomeId, + }; + } + + if (lastNotificationId) { + params.notifications = { + last_read_id: lastNotificationId, + }; + } + + if (Object.keys(params).length === 0) { + return; + } + + const client = new XMLHttpRequest(); + + client.open('POST', '/api/v1/markers', false); + client.setRequestHeader('Content-Type', 'application/json'); + client.setRequestHeader('Authorization', `Bearer ${accessToken}`); + client.send(JSON.stringify(params)); +}; diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index 0c2331374..be48b1c77 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -165,7 +165,7 @@ export function expandNotifications({ maxId } = {}, done = noOp) { dispatch(importFetchedAccounts(response.data.map(item => item.account))); dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status))); - dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent && preferPendingItems)); + dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems)); fetchRelatedRelationships(dispatch, response.data); done(); }).catch(error => { @@ -182,11 +182,12 @@ export function expandNotificationsRequest(isLoadingMore) { }; }; -export function expandNotificationsSuccess(notifications, next, isLoadingMore, usePendingItems) { +export function expandNotificationsSuccess(notifications, next, isLoadingMore, isLoadingRecent, usePendingItems) { return { type: NOTIFICATIONS_EXPAND_SUCCESS, notifications, next, + isLoadingRecent: isLoadingRecent, usePendingItems, skipLoading: !isLoadingMore, }; diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 36c4b236c..905aa54c1 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent { state = { selected: {}, + expired: null, }; + static getDerivedStateFromProps (props, state) { + const { poll, intl } = props; + const expired = poll.get('expired') || (new Date(poll.get('expires_at'))).getTime() < intl.now(); + return (expired === state.expired) ? null : { expired }; + } + + componentDidMount () { + this._setupTimer(); + } + + componentDidUpdate () { + this._setupTimer(); + } + + componentWillUnmount () { + clearTimeout(this._timer); + } + + _setupTimer () { + const { poll, intl } = this.props; + clearTimeout(this._timer); + if (!this.state.expired) { + const delay = (new Date(poll.get('expires_at'))).getTime() - intl.now(); + this._timer = setTimeout(() => { + this.setState({ expired: true }); + }, delay); + } + } + handleOptionChange = e => { const { target: { value } } = e; @@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent { this.props.dispatch(fetchPoll(this.props.poll.get('id'))); }; - renderOption (option, optionIndex) { + renderOption (option, optionIndex, showResults) { const { poll, disabled } = this.props; const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100; const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count')); const active = !!this.state.selected[`${optionIndex}`]; - const showResults = poll.get('voted') || poll.get('expired'); let titleEmojified = option.get('title_emojified'); if (!titleEmojified) { @@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent { render () { const { poll, intl } = this.props; + const { expired } = this.state; if (!poll) { return null; } - const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; - const showResults = poll.get('voted') || poll.get('expired'); + const timeRemaining = expired ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; + const showResults = poll.get('voted') || expired; const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); return ( <div className='poll'> <ul> - {poll.get('options').map((option, i) => this.renderOption(option, i))} + {poll.get('options').map((option, i) => this.renderOption(option, i, showResults))} </ul> <div className='poll__footer'> diff --git a/app/javascript/flavours/glitch/components/scrollable_list.js b/app/javascript/flavours/glitch/components/scrollable_list.js index 5f42bdd8b..7c0b6d082 100644 --- a/app/javascript/flavours/glitch/components/scrollable_list.js +++ b/app/javascript/flavours/glitch/components/scrollable_list.js @@ -153,7 +153,9 @@ export default class ScrollableList extends PureComponent { const someItemInserted = React.Children.count(prevProps.children) > 0 && React.Children.count(prevProps.children) < React.Children.count(this.props.children) && this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props); - if (someItemInserted && (this.node.scrollTop > 0 || this.mouseMovedRecently)) { + const pendingChanged = (prevProps.numPending > 0) !== (this.props.numPending > 0); + + if (pendingChanged || someItemInserted && (this.node.scrollTop > 0 || this.mouseMovedRecently)) { return this.node.scrollHeight - this.node.scrollTop; } else { return null; @@ -228,6 +230,13 @@ export default class ScrollableList extends PureComponent { handleLoadPending = e => { e.preventDefault(); this.props.onLoadPending(); + // Prevent the weird scroll-jumping behavior, as we explicitly don't want to + // scroll to top, and we know the scroll height is going to change + this.scrollToTopOnMouseIdle = false; + this.lastScrollWasSynthetic = false; + this.clearMouseIdleTimer(); + this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY); + this.mouseMovedRecently = true; } render () { diff --git a/app/javascript/flavours/glitch/components/status_icons.js b/app/javascript/flavours/glitch/components/status_icons.js index af86010f0..d99b25e25 100644 --- a/app/javascript/flavours/glitch/components/status_icons.js +++ b/app/javascript/flavours/glitch/components/status_icons.js @@ -93,7 +93,7 @@ class StatusIcons extends React.PureComponent { {mediaIcon ? ( <Icon fixedWidth - className='status__media-icon`' + className='status__media-icon' id={mediaIcon} aria-hidden='true' title={this.mediaIconTitleText()} diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index bded66d09..15eb4f85f 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -108,7 +108,7 @@ const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ dispatch((_, getState) => { let state = getState(); if (state.getIn(['local_settings', 'confirm_boost_missing_media_description']) && status.get('media_attachments').some(item => !item.get('description')) && !status.get('reblogged')) { - dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog, missingMediaDescription: true })); + dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog, missingMediaDescription: true })); } else if (e.shiftKey || !boostModal) { this.onModalReblog(status); } else { diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index fc0202129..0d131bd35 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -256,7 +256,7 @@ class Header extends ImmutablePureComponent { <div className='account__header__tabs__buttons'> {actionBtn} - <DropdownMenuContainer items={menu} id='ellipsis-v' size={24} direction='right' /> + <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' /> </div> </div> diff --git a/app/javascript/flavours/glitch/features/community_timeline/index.js b/app/javascript/flavours/glitch/features/community_timeline/index.js index cb7d72c53..5585edc9c 100644 --- a/app/javascript/flavours/glitch/features/community_timeline/index.js +++ b/app/javascript/flavours/glitch/features/community_timeline/index.js @@ -18,9 +18,10 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => { const uuid = columnId; const columns = state.getIn(['settings', 'columns']); const index = columns.findIndex(c => c.get('uuid') === uuid); + const timelineState = state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`]); return { - hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0, + hasUnread: !!timelineState && (timelineState.get('unread') > 0 || timelineState.get('pendingItems').size > 0), onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']), }; }; diff --git a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js index 60fee9b7f..404504e84 100644 --- a/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js +++ b/app/javascript/flavours/glitch/features/compose/components/dropdown_menu.js @@ -77,9 +77,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent document.removeEventListener('touchend', this.handleDocumentClick, withPassive); } - handleClick = (e) => { - const name = e.currentTarget.getAttribute('data-index'); - + handleClick = (name, e) => { const { onChange, onClose, @@ -103,9 +101,8 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent } } - handleKeyDown = e => { + handleKeyDown = (name, e) => { const { items } = this.props; - const name = e.currentTarget.getAttribute('data-index'); const index = items.findIndex(item => { return (item.name === name); }); @@ -183,7 +180,7 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent let prefix = null; if (on !== null && typeof on !== 'undefined') { - prefix = <Toggle checked={on} onChange={this.handleClick} />; + prefix = <Toggle checked={on} onChange={this.handleClick.bind(this, name)} />; } else if (icon) { prefix = <Icon className='icon' fixedWidth id={icon} /> } @@ -191,8 +188,8 @@ export default class ComposerOptionsDropdownContent extends React.PureComponent return ( <div className={computedClass} - onClick={this.handleClick} - onKeyDown={this.handleKeyDown} + onClick={this.handleClick.bind(this, name)} + onKeyDown={this.handleKeyDown.bind(this, name)} role='option' tabIndex='0' key={name} diff --git a/app/javascript/flavours/glitch/features/compose/components/poll_form.js b/app/javascript/flavours/glitch/features/compose/components/poll_form.js index d0678f2f0..3d818ea20 100644 --- a/app/javascript/flavours/glitch/features/compose/components/poll_form.js +++ b/app/javascript/flavours/glitch/features/compose/components/poll_form.js @@ -79,7 +79,7 @@ class Option extends React.PureComponent { </label> <div className='poll__cancel'> - <IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} id='times' onClick={this.handleOptionRemove} /> + <IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' onClick={this.handleOptionRemove} /> </div> </li> ); diff --git a/app/javascript/flavours/glitch/features/notifications/index.js b/app/javascript/flavours/glitch/features/notifications/index.js index bd1af97a9..99b2391c7 100644 --- a/app/javascript/flavours/glitch/features/notifications/index.js +++ b/app/javascript/flavours/glitch/features/notifications/index.js @@ -47,7 +47,7 @@ const mapStateToProps = state => ({ notifications: getNotifications(state), localSettings: state.get('local_settings'), isLoading: state.getIn(['notifications', 'isLoading'], true), - isUnread: state.getIn(['notifications', 'unread']) > 0, + isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0, hasMore: state.getIn(['notifications', 'hasMore']), numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, notifCleaningActive: state.getIn(['notifications', 'cleaningMode']), diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js index 7d1deb4ce..8bded391a 100644 --- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js @@ -223,10 +223,10 @@ class FocalPointModal extends ImmutablePureComponent { <div className='setting-text__toolbar'> <button disabled={detecting || media.get('type') !== 'image'} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button> - <CharacterCounter max={420} text={detecting ? '' : description} /> + <CharacterCounter max={1500} text={detecting ? '' : description} /> </div> - <Button disabled={!dirty || detecting || length(description) > 420} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> + <Button disabled={!dirty || detecting || length(description) > 1500} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> </div> <div className='focal-point-modal__content'> diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js index 1feda0b97..6cc1b1cde 100644 --- a/app/javascript/flavours/glitch/features/ui/index.js +++ b/app/javascript/flavours/glitch/features/ui/index.js @@ -12,6 +12,7 @@ import { expandHomeTimeline } from 'flavours/glitch/actions/timelines'; import { expandNotifications, notificationsSetVisibility } from 'flavours/glitch/actions/notifications'; import { fetchFilters } from 'flavours/glitch/actions/filters'; import { clearHeight } from 'flavours/glitch/actions/height_cache'; +import { submitMarkers } from 'flavours/glitch/actions/markers'; import { WrappedSwitch, WrappedRoute } from 'flavours/glitch/util/react_router_helpers'; import UploadArea from './components/upload_area'; import ColumnsAreaContainer from './containers/columns_area_container'; @@ -63,6 +64,7 @@ const messages = defineMessages({ const mapStateToProps = state => ({ hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, + canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, layout: state.getIn(['local_settings', 'layout']), isWide: state.getIn(['local_settings', 'stretch']), navbarUnder: state.getIn(['local_settings', 'navbar_under']), @@ -229,6 +231,7 @@ class UI extends React.Component { isComposing: PropTypes.bool, hasComposingText: PropTypes.bool, hasMediaAttachments: PropTypes.bool, + canUploadMore: PropTypes.bool, match: PropTypes.object.isRequired, location: PropTypes.object.isRequired, history: PropTypes.object.isRequired, @@ -243,7 +246,9 @@ class UI extends React.Component { }; handleBeforeUnload = (e) => { - const { intl, hasComposingText, hasMediaAttachments } = this.props; + const { intl, dispatch, hasComposingText, hasMediaAttachments } = this.props; + + dispatch(submitMarkers()); if (hasComposingText || hasMediaAttachments) { // Setting returnValue to any string causes confirmation dialog. @@ -269,7 +274,7 @@ class UI extends React.Component { this.dragTargets.push(e.target); } - if (e.dataTransfer && e.dataTransfer.types.includes('Files')) { + if (e.dataTransfer && e.dataTransfer.types.includes('Files') && this.props.canUploadMore) { this.setState({ draggingOver: true }); } } @@ -290,12 +295,13 @@ class UI extends React.Component { handleDrop = (e) => { if (this.dataTransferIsText(e.dataTransfer)) return; + e.preventDefault(); this.setState({ draggingOver: false }); this.dragTargets = []; - if (e.dataTransfer && e.dataTransfer.files.length >= 1) { + if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore) { this.props.dispatch(uploadCompose(e.dataTransfer.files)); } } diff --git a/app/javascript/flavours/glitch/locales/pt.js b/app/javascript/flavours/glitch/locales/pt-PT.js index 0156f55ff..cf7afd17a 100644 --- a/app/javascript/flavours/glitch/locales/pt.js +++ b/app/javascript/flavours/glitch/locales/pt-PT.js @@ -1,4 +1,4 @@ -import inherited from 'mastodon/locales/pt.json'; +import inherited from 'mastodon/locales/pt-PT.json'; const messages = { // No translations available. diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js index 72725d20b..019de2167 100644 --- a/app/javascript/flavours/glitch/packs/public.js +++ b/app/javascript/flavours/glitch/packs/public.js @@ -11,10 +11,10 @@ function main() { const React = require('react'); const ReactDOM = require('react-dom'); const Rellax = require('rellax'); - const createHistory = require('history').createBrowserHistory; + const { createBrowserHistory } = require('history'); const scrollToDetailedStatus = () => { - const history = createHistory(); + const history = createBrowserHistory(); const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status'); const location = history.location; diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index 135995da6..8dc7a4aba 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -50,12 +50,12 @@ const notificationToMap = (state, notification) => ImmutableMap({ }); const normalizeNotification = (state, notification, usePendingItems) => { - if (usePendingItems) { - return state.update('pendingItems', list => list.unshift(notificationToMap(state, notification))); - } - const top = !shouldCountUnreadNotifications(state); + if (usePendingItems || !top || !state.get('pendingItems').isEmpty()) { + return state.update('pendingItems', list => list.unshift(notificationToMap(state, notification))).update('unread', unread => unread + 1); + } + if (top) { state = state.set('lastReadId', notification.id); } else { @@ -71,7 +71,7 @@ const normalizeNotification = (state, notification, usePendingItems) => { }); }; -const expandNormalizedNotifications = (state, notifications, next, usePendingItems) => { +const expandNormalizedNotifications = (state, notifications, next, isLoadingRecent, usePendingItems) => { const top = !(shouldCountUnreadNotifications(state)); const lastReadId = state.get('lastReadId'); let items = ImmutableList(); @@ -82,6 +82,8 @@ const expandNormalizedNotifications = (state, notifications, next, usePendingIte return state.withMutations(mutable => { if (!items.isEmpty()) { + usePendingItems = isLoadingRecent && (usePendingItems || !mutable.get('top') || !mutable.get('pendingItems').isEmpty()); + mutable.update(usePendingItems ? 'pendingItems' : 'items', list => { const lastIndex = 1 + list.findLastIndex( item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id')) @@ -117,7 +119,7 @@ const filterNotifications = (state, accountIds) => { }; const clearUnread = (state) => { - state = state.set('unread', 0); + state = state.set('unread', state.get('pendingItems').size); const lastNotification = state.get('items').find(item => item !== null); return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0'); } @@ -140,6 +142,8 @@ const deleteByStatus = (state, statusId) => { state = state.update('unread', unread => unread - deletedUnread.size); } const helper = list => list.filterNot(item => item !== null && item.get('status') === statusId); + const deletedUnread = state.get('pendingItems').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0); + state = state.update('unread', unread => unread - deletedUnread.size); return state.update('items', helper).update('pendingItems', helper); }; @@ -216,7 +220,7 @@ export default function notifications(state = initialState, action) { case NOTIFICATIONS_UPDATE: return normalizeNotification(state, action.notification, action.usePendingItems); case NOTIFICATIONS_EXPAND_SUCCESS: - return expandNormalizedNotifications(state, action.notifications, action.next, action.usePendingItems); + return expandNormalizedNotifications(state, action.notifications, action.next, action.isLoadingRecent, action.usePendingItems); case ACCOUNT_BLOCK_SUCCESS: return filterNotifications(state, [action.relationship.id]); case ACCOUNT_MUTE_SUCCESS: diff --git a/app/javascript/flavours/glitch/reducers/timelines.js b/app/javascript/flavours/glitch/reducers/timelines.js index 9b016a4c6..e6bef18e9 100644 --- a/app/javascript/flavours/glitch/reducers/timelines.js +++ b/app/javascript/flavours/glitch/reducers/timelines.js @@ -40,6 +40,7 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is if (timeline.endsWith(':pinned')) { mMap.set('items', statuses.map(status => status.get('id'))); } else if (!statuses.isEmpty()) { + usePendingItems = isLoadingRecent && (usePendingItems || !mMap.get('top') || !mMap.get('pendingItems').isEmpty()); mMap.update(usePendingItems ? 'pendingItems' : 'items', ImmutableList(), oldIds => { const newIds = statuses.map(status => status.get('id')); const lastIndex = oldIds.findLastIndex(id => id !== null && compareId(id, newIds.last()) >= 0) + 1; @@ -59,15 +60,16 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is }; const updateTimeline = (state, timeline, status, usePendingItems) => { - if (usePendingItems) { + const top = state.getIn([timeline, 'top']); + + if (usePendingItems || !top || !state.getIn([timeline, 'pendingItems']).isEmpty()) { if (state.getIn([timeline, 'pendingItems'], ImmutableList()).includes(status.get('id')) || state.getIn([timeline, 'items'], ImmutableList()).includes(status.get('id'))) { return state; } - return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id')))); + return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id'))).update('unread', unread => unread + 1)); } - const top = state.getIn([timeline, 'top']); const ids = state.getIn([timeline, 'items'], ImmutableList()); const includesId = ids.includes(status.get('id')); const unread = state.getIn([timeline, 'unread'], 0); @@ -127,7 +129,7 @@ const filterTimeline = (timeline, state, relationship, statuses) => { const updateTop = (state, timeline, top) => { return state.update(timeline, initialTimeline, map => map.withMutations(mMap => { - if (top) mMap.set('unread', 0); + if (top) mMap.set('unread', mMap.get('pendingItems').size); mMap.set('top', top); })); }; diff --git a/app/javascript/flavours/glitch/styles/accounts.scss b/app/javascript/flavours/glitch/styles/accounts.scss index 0fae137f0..a827d271a 100644 --- a/app/javascript/flavours/glitch/styles/accounts.scss +++ b/app/javascript/flavours/glitch/styles/accounts.scss @@ -226,6 +226,7 @@ } .account__header__fields { + max-width: 100vw; padding: 0; margin: 15px -15px -15px; border: 0 none; diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 74f91599a..089ae68c0 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -720,3 +720,47 @@ a.name-tag, text-overflow: ellipsis; vertical-align: middle; } + +.admin-account-bio { + display: flex; + flex-wrap: wrap; + margin: 0 -5px; + margin-top: 20px; + + > div { + box-sizing: border-box; + padding: 0 5px; + margin-bottom: 10px; + flex: 1 0 50%; + } + + .account__header__fields, + .account__header__content { + background: lighten($ui-base-color, 8%); + border-radius: 4px; + height: 100%; + } + + .account__header__fields { + margin: 0; + border: 0; + + a { + color: lighten($ui-highlight-color, 8%); + } + + dl:first-child .verified { + border-radius: 0 4px 0 0; + } + + .verified a { + color: $valid-value-color; + } + } + + .account__header__content { + box-sizing: border-box; + padding: 20px; + color: $primary-text-color; + } +} diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss index 45eb5a9d0..17455ca58 100644 --- a/app/javascript/flavours/glitch/styles/containers.scss +++ b/app/javascript/flavours/glitch/styles/containers.scss @@ -759,16 +759,6 @@ } } - .static-icon-button { - color: $action-button-color; - font-size: 18px; - - & > span { - font-size: 14px; - font-weight: 500; - } - } - .directory__list { display: grid; grid-gap: 10px; diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 5261f17f4..06f60408d 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -11,7 +11,6 @@ li { margin-bottom: 10px; position: relative; - height: 18px + 12px; } &__chart { @@ -30,13 +29,11 @@ &__text { position: relative; - display: inline-block; + display: flex; padding: 6px 0; line-height: 18px; cursor: default; - white-space: nowrap; overflow: hidden; - text-overflow: ellipsis; input[type=radio], input[type=checkbox] { @@ -89,6 +86,9 @@ top: -1px; border-radius: 50%; vertical-align: middle; + margin-top: auto; + margin-bottom: auto; + flex: 0 0 18px; &.checkbox { border-radius: 4px; @@ -106,6 +106,9 @@ font-weight: 700; padding: 0 10px; text-align: right; + margin-top: auto; + margin-bottom: auto; + flex: 0 0 36px; } &__footer { diff --git a/app/javascript/flavours/glitch/styles/tables.scss b/app/javascript/flavours/glitch/styles/tables.scss index bf67388f0..669f72787 100644 --- a/app/javascript/flavours/glitch/styles/tables.scss +++ b/app/javascript/flavours/glitch/styles/tables.scss @@ -180,6 +180,18 @@ a.table-action-link { } } + &__form { + padding: 16px; + border: 1px solid darken($ui-base-color, 8%); + border-top: 0; + background: $ui-base-color; + + .fields-row { + padding-top: 0; + margin-bottom: 0; + } + } + &__row { border: 1px solid darken($ui-base-color, 8%); border-top: 0; @@ -210,6 +222,45 @@ a.table-action-link { &--unpadded { padding: 0; } + + &--with-image { + display: flex; + align-items: center; + } + + &__image { + flex: 0 0 auto; + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; + + .emojione { + width: 32px; + height: 32px; + } + } + + &__text { + flex: 1 1 auto; + } + + &__extra { + flex: 0 0 auto; + text-align: right; + color: $darker-text-color; + font-weight: 500; + } + } + + .directory__tag { + margin: 0; + width: 100%; + + a { + background: transparent; + border-radius: 0; + } } } diff --git a/app/javascript/mastodon/actions/markers.js b/app/javascript/mastodon/actions/markers.js new file mode 100644 index 000000000..c3a5fe86f --- /dev/null +++ b/app/javascript/mastodon/actions/markers.js @@ -0,0 +1,30 @@ +export const submitMarkers = () => (dispatch, getState) => { + const accessToken = getState().getIn(['meta', 'access_token'], ''); + const params = {}; + + const lastHomeId = getState().getIn(['timelines', 'home', 'items', 0]); + const lastNotificationId = getState().getIn(['notifications', 'items', 0, 'id']); + + if (lastHomeId) { + params.home = { + last_read_id: lastHomeId, + }; + } + + if (lastNotificationId) { + params.notifications = { + last_read_id: lastNotificationId, + }; + } + + if (Object.keys(params).length === 0) { + return; + } + + const client = new XMLHttpRequest(); + + client.open('POST', '/api/v1/markers', false); + client.setRequestHeader('Content-Type', 'application/json'); + client.setRequestHeader('Authorization', `Bearer ${accessToken}`); + client.send(JSON.stringify(params)); +}; diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index d92d972bc..ea76255e3 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -151,7 +151,7 @@ export function expandNotifications({ maxId } = {}, done = noOp) { dispatch(importFetchedAccounts(response.data.map(item => item.account))); dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status))); - dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent && preferPendingItems)); + dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems)); fetchRelatedRelationships(dispatch, response.data); done(); }).catch(error => { @@ -168,11 +168,12 @@ export function expandNotificationsRequest(isLoadingMore) { }; }; -export function expandNotificationsSuccess(notifications, next, isLoadingMore, usePendingItems) { +export function expandNotificationsSuccess(notifications, next, isLoadingMore, isLoadingRecent, usePendingItems) { return { type: NOTIFICATIONS_EXPAND_SUCCESS, notifications, next, + isLoadingRecent: isLoadingRecent, usePendingItems, skipLoading: !isLoadingMore, }; diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.js index 690f9ae5a..373f710d3 100644 --- a/app/javascript/mastodon/components/poll.js +++ b/app/javascript/mastodon/components/poll.js @@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent { state = { selected: {}, + expired: null, }; + static getDerivedStateFromProps (props, state) { + const { poll, intl } = props; + const expired = poll.get('expired') || (new Date(poll.get('expires_at'))).getTime() < intl.now(); + return (expired === state.expired) ? null : { expired }; + } + + componentDidMount () { + this._setupTimer(); + } + + componentDidUpdate () { + this._setupTimer(); + } + + componentWillUnmount () { + clearTimeout(this._timer); + } + + _setupTimer () { + const { poll, intl } = this.props; + clearTimeout(this._timer); + if (!this.state.expired) { + const delay = (new Date(poll.get('expires_at'))).getTime() - intl.now(); + this._timer = setTimeout(() => { + this.setState({ expired: true }); + }, delay); + } + } + handleOptionChange = e => { const { target: { value } } = e; @@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent { this.props.dispatch(fetchPoll(this.props.poll.get('id'))); }; - renderOption (option, optionIndex) { + renderOption (option, optionIndex, showResults) { const { poll, disabled } = this.props; const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100; const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count')); const active = !!this.state.selected[`${optionIndex}`]; - const showResults = poll.get('voted') || poll.get('expired'); let titleEmojified = option.get('title_emojified'); if (!titleEmojified) { @@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent { render () { const { poll, intl } = this.props; + const { expired } = this.state; if (!poll) { return null; } - const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; - const showResults = poll.get('voted') || poll.get('expired'); + const timeRemaining = expired ? intl.formatMessage(messages.closed) : <RelativeTimestamp timestamp={poll.get('expires_at')} futureDate />; + const showResults = poll.get('voted') || expired; const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); return ( <div className='poll'> <ul> - {poll.get('options').map((option, i) => this.renderOption(option, i))} + {poll.get('options').map((option, i) => this.renderOption(option, i, showResults))} </ul> <div className='poll__footer'> diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 0bf817923..253646ed0 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -172,8 +172,9 @@ export default class ScrollableList extends PureComponent { const someItemInserted = React.Children.count(prevProps.children) > 0 && React.Children.count(prevProps.children) < React.Children.count(this.props.children) && this.getFirstChildKey(prevProps) !== this.getFirstChildKey(this.props); + const pendingChanged = (prevProps.numPending > 0) !== (this.props.numPending > 0); - if (someItemInserted && (this.getScrollTop() > 0 || this.mouseMovedRecently)) { + if (pendingChanged || someItemInserted && (this.getScrollTop() > 0 || this.mouseMovedRecently)) { return this.getScrollHeight() - this.getScrollTop(); } else { return null; @@ -261,6 +262,13 @@ export default class ScrollableList extends PureComponent { handleLoadPending = e => { e.preventDefault(); this.props.onLoadPending(); + // Prevent the weird scroll-jumping behavior, as we explicitly don't want to + // scroll to top, and we know the scroll height is going to change + this.scrollToTopOnMouseIdle = false; + this.lastScrollWasSynthetic = false; + this.clearMouseIdleTimer(); + this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY); + this.mouseMovedRecently = true; } render () { diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js index 542b68282..3ac58cf7c 100644 --- a/app/javascript/mastodon/containers/mastodon.js +++ b/app/javascript/mastodon/containers/mastodon.js @@ -12,6 +12,8 @@ import { hydrateStore } from '../actions/store'; import { connectUserStream } from '../actions/streaming'; import { IntlProvider, addLocaleData } from 'react-intl'; import { getLocale } from '../locales'; +import { previewState as previewMediaState } from 'mastodon/features/ui/components/media_modal'; +import { previewState as previewVideoState } from 'mastodon/features/ui/components/video_modal'; import initialState from '../initial_state'; import ErrorBoundary from '../components/error_boundary'; @@ -35,6 +37,10 @@ class MastodonMount extends React.PureComponent { showIntroduction: PropTypes.bool, }; + shouldUpdateScroll (_, { location }) { + return location.state !== previewMediaState && location.state !== previewVideoState; + } + render () { const { showIntroduction } = this.props; @@ -44,7 +50,7 @@ class MastodonMount extends React.PureComponent { return ( <BrowserRouter basename='/web'> - <ScrollContext> + <ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}> <Route path='/' component={UI} /> </ScrollContext> </BrowserRouter> diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js index f95fa4970..30153cc15 100644 --- a/app/javascript/mastodon/features/community_timeline/index.js +++ b/app/javascript/mastodon/features/community_timeline/index.js @@ -18,9 +18,10 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => { const uuid = columnId; const columns = state.getIn(['settings', 'columns']); const index = columns.findIndex(c => c.get('uuid') === uuid); + const timelineState = state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`]); return { - hasUnread: state.getIn(['timelines', `community${onlyMedia ? ':media' : ''}`, 'unread']) > 0, + hasUnread: !!timelineState && (timelineState.get('unread') > 0 || timelineState.get('pendingItems').size > 0), onlyMedia: (columnId && index >= 0) ? columns.get(index).getIn(['params', 'other', 'onlyMedia']) : state.getIn(['settings', 'community', 'other', 'onlyMedia']), }; }; diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index f2b239afe..7e5de0613 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -39,7 +39,7 @@ const mapStateToProps = state => ({ showFilterBar: state.getIn(['settings', 'notifications', 'quickFilter', 'show']), notifications: getNotifications(state), isLoading: state.getIn(['notifications', 'isLoading'], true), - isUnread: state.getIn(['notifications', 'unread']) > 0, + isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0, hasMore: state.getIn(['notifications', 'hasMore']), numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, }); diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js index 735e445e8..7891d6690 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js @@ -223,10 +223,10 @@ class FocalPointModal extends ImmutablePureComponent { <div className='setting-text__toolbar'> <button disabled={detecting || media.get('type') !== 'image'} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button> - <CharacterCounter max={420} text={detecting ? '' : description} /> + <CharacterCounter max={1500} text={detecting ? '' : description} /> </div> - <Button disabled={!dirty || detecting || length(description) > 420} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> + <Button disabled={!dirty || detecting || length(description) > 1500} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> </div> <div className='focal-point-modal__content'> diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 49c5c8d0e..f5e48ed31 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -16,6 +16,7 @@ import { expandNotifications } from '../../actions/notifications'; import { fetchFilters } from '../../actions/filters'; import { clearHeight } from '../../actions/height_cache'; import { focusApp, unfocusApp } from 'mastodon/actions/app'; +import { submitMarkers } from 'mastodon/actions/markers'; import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers'; import UploadArea from './components/upload_area'; import ColumnsAreaContainer from './containers/columns_area_container'; @@ -65,6 +66,7 @@ const mapStateToProps = state => ({ isComposing: state.getIn(['compose', 'is_composing']), hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0, hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0, + canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < 4, dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null, }); @@ -231,6 +233,7 @@ class UI extends React.PureComponent { isComposing: PropTypes.bool, hasComposingText: PropTypes.bool, hasMediaAttachments: PropTypes.bool, + canUploadMore: PropTypes.bool, location: PropTypes.object, intl: PropTypes.object.isRequired, dropdownMenuIsOpen: PropTypes.bool, @@ -241,7 +244,9 @@ class UI extends React.PureComponent { }; handleBeforeUnload = e => { - const { intl, isComposing, hasComposingText, hasMediaAttachments } = this.props; + const { intl, dispatch, isComposing, hasComposingText, hasMediaAttachments } = this.props; + + dispatch(submitMarkers()); if (isComposing && (hasComposingText || hasMediaAttachments)) { // Setting returnValue to any string causes confirmation dialog. @@ -275,13 +280,14 @@ class UI extends React.PureComponent { this.dragTargets.push(e.target); } - if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files')) { + if (e.dataTransfer && Array.from(e.dataTransfer.types).includes('Files') && this.props.canUploadMore) { this.setState({ draggingOver: true }); } } handleDragOver = (e) => { if (this.dataTransferIsText(e.dataTransfer)) return false; + e.preventDefault(); e.stopPropagation(); @@ -296,12 +302,13 @@ class UI extends React.PureComponent { handleDrop = (e) => { if (this.dataTransferIsText(e.dataTransfer)) return; + e.preventDefault(); this.setState({ draggingOver: false }); this.dragTargets = []; - if (e.dataTransfer && e.dataTransfer.files.length >= 1) { + if (e.dataTransfer && e.dataTransfer.files.length >= 1 && this.props.canUploadMore) { this.props.dispatch(uploadCompose(e.dataTransfer.files)); } } diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index e7a21523a..ce66a5d1c 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -4,11 +4,11 @@ "account.block": "حظر @{name}", "account.block_domain": "إخفاء كل شيئ قادم من اسم النطاق {domain}", "account.blocked": "محظور", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "إلغاء طلب المتابَعة", "account.direct": "رسالة خاصة إلى @{name}", "account.domain_blocked": "النطاق مخفي", "account.edit_profile": "تعديل الملف الشخصي", - "account.endorse": "خاصّية على الملف الشخصي", + "account.endorse": "أوصِ به على صفحتك", "account.follow": "تابِع", "account.followers": "متابعون", "account.followers.empty": "لا أحد يتبع هذا الحساب بعد.", @@ -16,29 +16,33 @@ "account.follows.empty": "هذا الحساب لا يتبع أحدًا بعد.", "account.follows_you": "يتابعك", "account.hide_reblogs": "إخفاء ترقيات @{name}", + "account.last_status": "آخر نشاط", "account.link_verified_on": "تم التحقق مِن مِلْكية هذا الرابط بتاريخ {date}", "account.locked_info": "تم تأمين خصوصية هذا الحساب عبر قفل. صاحب الحساب يُراجِع يدويا طلبات المتابَعة و الاشتراك بحسابه.", "account.media": "وسائط", - "account.mention": "أُذكُر/ي @{name}", + "account.mention": "أذكُر @{name}", "account.moved_to": "{name} انتقل إلى:", - "account.mute": "كتم @{name}", + "account.mute": "أكتم @{name}", "account.mute_notifications": "كتم الإخطارات من @{name}", "account.muted": "مكتوم", - "account.posts": "التبويقات", + "account.never_active": "أبدا", + "account.posts": "تبويقات", "account.posts_with_replies": "التبويقات و الردود", - "account.report": "أبلغ/ي عن @{name}", + "account.report": "ابلِغ عن @{name}", "account.requested": "في انتظار الموافقة. اضْغَطْ/ي لإلغاء طلب المتابعة", "account.share": "مشاركة حساب @{name}", - "account.show_reblogs": "عرض ترقيات @{name}", + "account.show_reblogs": "اعرض ترقيات @{name}", "account.unblock": "إلغاء الحظر عن @{name}", "account.unblock_domain": "فك الخْفى عن {domain}", - "account.unendorse": "إزالة ترويجه مِن الملف الشخصي", + "account.unendorse": "أزل ترويجه مِن الملف الشخصي", "account.unfollow": "إلغاء المتابعة", "account.unmute": "إلغاء الكتم عن @{name}", "account.unmute_notifications": "إلغاء كتم إخطارات @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "لقد طرأ هناك خطأ غير متوقّع.", "alert.unexpected.title": "المعذرة!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} في الأسبوع", "boost_modal.combo": "يمكنك/ي ضغط {combo} لتخطّي هذه في المرّة القادمة", "bundle_column_error.body": "لقد وقع هناك خطأ أثناء عملية تحميل هذا العنصر.", "bundle_column_error.retry": "إعادة المحاولة", @@ -49,6 +53,7 @@ "column.blocks": "الحسابات المحجوبة", "column.community": "الخيط العام المحلي", "column.direct": "الرسائل المباشرة", + "column.directory": "Browse profiles", "column.domain_blocks": "النطاقات المخفية", "column.favourites": "المفضلة", "column.follow_requests": "طلبات المتابعة", @@ -58,6 +63,7 @@ "column.notifications": "الإخطارات", "column.pins": "التبويقات المثبتة", "column.public": "الخيط العام الموحد", + "column.status": "Toot", "column_back_button.label": "العودة", "column_header.hide_settings": "إخفاء الإعدادات", "column_header.moveLeft_settings": "نقل القائمة إلى اليسار", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "هل تود حقا حذف هذه القائمة ؟", "confirmations.domain_block.confirm": "إخفاء اسم النطاق كاملا", "confirmations.domain_block.message": "متأكد من أنك تود حظر اسم النطاق {domain} بالكامل ؟ في غالب الأحيان يُستَحسَن كتم أو حظر بعض الحسابات بدلا من حظر نطاق بالكامل.\nلن تتمكن مِن رؤية محتوى هذا النطاق لا على خيوطك العمومية و لا في إشعاراتك. سوف يتم كذلك إزالة كافة متابعيك المنتمين إلى هذا النطاق.", + "confirmations.logout.confirm": "خروج", + "confirmations.logout.message": "متأكد من أنك تريد الخروج؟", "confirmations.mute.confirm": "أكتم", "confirmations.mute.message": "هل أنت متأكد أنك تريد كتم {name} ؟", "confirmations.redraft.confirm": "إزالة و إعادة الصياغة", @@ -103,6 +111,10 @@ "confirmations.reply.message": "الرد في الحين سوف يُعيد كتابة الرسالة التي أنت بصدد كتابتها. متأكد من أنك تريد المواصلة؟", "confirmations.unfollow.confirm": "إلغاء المتابعة", "confirmations.unfollow.message": "متأكد من أنك تريد إلغاء متابعة {name} ؟", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "الوافدون الجُدد", + "directory.recently_active": "نشط مؤخرا", "embed.instructions": "يمكنكم إدماج هذا المنشور على موقعكم الإلكتروني عن طريق نسخ الشفرة أدناه.", "embed.preview": "هكذا ما سوف يبدو عليه:", "emoji_button.activity": "الأنشطة", @@ -118,7 +130,7 @@ "emoji_button.search": "ابحث...", "emoji_button.search_results": "نتائج البحث", "emoji_button.symbols": "رموز", - "emoji_button.travel": "أماكن و أسفار", + "emoji_button.travel": "الأماكن والسفر", "empty_column.account_timeline": "ليس هناك تبويقات!", "empty_column.account_unavailable": "الملف الشخصي غير متوفر", "empty_column.blocks": "لم تقم بحظر أي مستخدِم بعد.", @@ -155,10 +167,10 @@ "hashtag.column_settings.tag_mode.any": "أي كان مِن هذه", "hashtag.column_settings.tag_mode.none": "لا شيء مِن هذه", "hashtag.column_settings.tag_toggle": "إدراج الوسوم الإضافية لهذا العمود", - "home.column_settings.basic": "أساسية", + "home.column_settings.basic": "الأساسية", "home.column_settings.show_reblogs": "عرض الترقيات", - "home.column_settings.show_replies": "عرض الردود", - "home.column_settings.update_live": "تحديث في الوقت الحالي", + "home.column_settings.show_replies": "اعرض الردود", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# يوم} other {# أيام}}", "intervals.full.hours": "{number, plural, one {# ساعة} other {# ساعات}}", "intervals.full.minutes": "{number, plural, one {# دقيقة} other {# دقائق}}", @@ -218,7 +230,7 @@ "lists.account.add": "أضف إلى القائمة", "lists.account.remove": "احذف من القائمة", "lists.delete": "احذف القائمة", - "lists.edit": "تعديل القائمة", + "lists.edit": "عدّل القائمة", "lists.edit.submit": "تعديل العنوان", "lists.new.create": "إنشاء قائمة", "lists.new.title_placeholder": "عنوان القائمة الجديدة", @@ -227,7 +239,7 @@ "load_pending": "{count, plural, one {# new item} other {# new items}}", "loading_indicator.label": "تحميل...", "media_gallery.toggle_visible": "عرض / إخفاء", - "missing_indicator.label": "تعذر العثور عليه", + "missing_indicator.label": "غير موجود", "missing_indicator.sublabel": "تعذر العثور على هذا المورد", "mute_modal.hide_notifications": "هل تود إخفاء الإخطارات القادمة من هذا المستخدم ؟", "navigation_bar.apps": "تطبيقات الأجهزة المحمولة", @@ -250,7 +262,6 @@ "navigation_bar.personal": "شخصي", "navigation_bar.pins": "التبويقات المثبتة", "navigation_bar.preferences": "التفضيلات", - "navigation_bar.profile_directory": "دليل المستخدِمين", "navigation_bar.public_timeline": "الخيط العام الموحد", "navigation_bar.security": "الأمان", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -263,9 +274,9 @@ "notifications.clear_confirmation": "أمتأكد من أنك تود مسح جل الإخطارات الخاصة بك و المتلقاة إلى حد الآن ؟", "notifications.column_settings.alert": "إشعارات سطح المكتب", "notifications.column_settings.favourite": "المُفَضَّلة:", - "notifications.column_settings.filter_bar.advanced": "عرض كافة الفئات", + "notifications.column_settings.filter_bar.advanced": "اعرض كافة الفئات", "notifications.column_settings.filter_bar.category": "شريط الفلترة السريعة", - "notifications.column_settings.filter_bar.show": "عرض", + "notifications.column_settings.filter_bar.show": "اعرض", "notifications.column_settings.follow": "متابعُون جُدُد:", "notifications.column_settings.mention": "الإشارات:", "notifications.column_settings.poll": "نتائج استطلاع الرأي:", @@ -358,6 +369,7 @@ "status.show_more": "أظهر المزيد", "status.show_more_all": "توسيع الكل", "status.show_thread": "الكشف عن المحادثة", + "status.uncached_media_warning": "غير متوفر", "status.unmute_conversation": "فك الكتم عن المحادثة", "status.unpin": "فك التدبيس من الملف الشخصي", "suggestions.dismiss": "إلغاء الاقتراح", @@ -373,20 +385,20 @@ "time_remaining.moments": "لحظات متبقية", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} آخرون {people}} يتحدثون", - "trends.refresh": "Refresh", + "trends.trending_now": "المتداولة الآن", "ui.beforeunload": "سوف تفقد مسودتك إن تركت ماستدون.", "upload_area.title": "اسحب ثم أفلت للرفع", "upload_button.label": "إضافة وسائط ({formats})", "upload_error.limit": "لقد تم بلوغ الحد الأقصى المسموح به لإرسال الملفات.", "upload_error.poll": "لا يمكن إدراج ملفات في استطلاعات الرأي.", "upload_form.description": "وصف للمعاقين بصريا", - "upload_form.edit": "Edit", + "upload_form.edit": "تعديل", "upload_form.undo": "حذف", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.analyzing_picture": "جارٍ فحص الصورة…", + "upload_modal.apply": "طبّق", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.edit_media": "تعديل الوسائط", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", "upload_modal.preview_label": "Preview ({ratio})", "upload_progress.label": "يرفع...", diff --git a/app/javascript/mastodon/locales/ast.json b/app/javascript/mastodon/locales/ast.json index c9b5d6061..2ef693fcb 100644 --- a/app/javascript/mastodon/locales/ast.json +++ b/app/javascript/mastodon/locales/ast.json @@ -16,6 +16,7 @@ "account.follows.empty": "Esti usuariu entá nun sigue a naide.", "account.follows_you": "Síguete", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,10 +25,11 @@ "account.mute": "Silenciar a @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots y rempuestes", "account.report": "Report @{name}", - "account.requested": "Awaiting approval. Click to cancel follow request", + "account.requested": "Awaiting approval", "account.share": "Share @{name}'s profile", "account.show_reblogs": "Show boosts from @{name}", "account.unblock": "Desbloquiar a @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Asocedió un fallu inesperáu.", "alert.unexpected.title": "¡Ups!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Usuarios bloquiaos", "column.community": "Llinia temporal llocal", "column.direct": "Mensaxes direutos", + "column.directory": "Browse profiles", "column.domain_blocks": "Dominios anubríos", "column.favourites": "Favoritos", "column.follow_requests": "Solicitúes de siguimientu", @@ -58,6 +63,7 @@ "column.notifications": "Avisos", "column.pins": "Toots fixaos", "column.public": "Llinia temporal federada", + "column.status": "Toot", "column_back_button.label": "Atrás", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Mover la columna a la esquierda", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "¿De xuru que quies desaniciar dafechu esta llista?", "confirmations.domain_block.confirm": "Anubrir tol dominiu", "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "¿De xuru que quies silenciar a {name}?", "confirmations.redraft.confirm": "Desaniciar y reeditar", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Empotra esti estáu nun sitiu web copiando'l códigu d'embaxo.", "embed.preview": "Asina ye como va vese:", "emoji_button.activity": "Actividaes", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Toots fixaos", "navigation_bar.preferences": "Preferencies", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Llinia temporal federada", "navigation_bar.security": "Seguranza", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Amosar más", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Desfixar del perfil", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "El borrador va perdese si coles de Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 3cb5900f4..309f04513 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Твой последовател", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Публикации", "account.posts_with_replies": "Toots with replies", "account.report": "Report @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Не следвай", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blocked users", "column.community": "Local timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", @@ -58,6 +63,7 @@ "column.notifications": "Известия", "column.pins": "Pinned toot", "column.public": "Публичен канал", + "column.status": "Toot", "column_back_button.label": "Назад", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "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.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Предпочитания", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Публичен канал", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Добави медия", diff --git a/app/javascript/mastodon/locales/bn.json b/app/javascript/mastodon/locales/bn.json index ee79b0edd..e4984a118 100644 --- a/app/javascript/mastodon/locales/bn.json +++ b/app/javascript/mastodon/locales/bn.json @@ -16,6 +16,7 @@ "account.follows.empty": "এই ব্যবহারকারী কাওকে এখনো অনুসরণ করেন না।", "account.follows_you": "আপনাকে অনুসরণ করে", "account.hide_reblogs": "@{name}র সমর্থনগুলি সরিয়ে ফেলুন", + "account.last_status": "Last active", "account.link_verified_on": "এই লিংকের মালিকানা চেক করা হয়েছে {date} তারিকে", "account.locked_info": "এই নিবন্ধনের গোপনীয়তার ক্ষেত্র তালা দেওয়া আছে। নিবন্ধনকারী অনুসরণ করার অনুমতি যাদেরকে দেবেন, শুধু তারাই অনুসরণ করতে পারবেন।", "account.media": "ছবি বা ভিডিও", @@ -24,6 +25,7 @@ "account.mute": "@{name} সব কার্যক্রম আপনার সময়রেখা থেকে সরিয়ে ফেলতে", "account.mute_notifications": "@{name}র প্রজ্ঞাপন আপনার কাছ থেকে সরিয়ে ফেলুন", "account.muted": "সরানো আছে", + "account.never_active": "Never", "account.posts": "টুট", "account.posts_with_replies": "টুট এবং মতামত", "account.report": "@{name} কে রিপোর্ট করতে", @@ -36,6 +38,8 @@ "account.unfollow": "অনুসরণ না করতে", "account.unmute": "@{name}র কার্যকলাপ আবার দেখুন", "account.unmute_notifications": "@{name}র প্রজ্ঞাপন দেওয়ার অনুমতি দিন", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "অপ্রত্যাশিত একটি সমস্যা হয়েছে।", "alert.unexpected.title": "ওহো!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "যাদের বন্ধ করে রাখা হয়েছে", "column.community": "স্থানীয় সময়সারি", "column.direct": "সরাসরি লেখা", + "column.directory": "Browse profiles", "column.domain_blocks": "সরিয়ে ফেলা ওয়েবসাইট", "column.favourites": "পছন্দের গুলো", "column.follow_requests": "অনুসরণের অনুমতি চেয়েছে যারা", @@ -58,6 +63,7 @@ "column.notifications": "প্রজ্ঞাপনগুলো", "column.pins": "পিন করা টুট", "column.public": "যুক্ত সময়রেখা", + "column.status": "Toot", "column_back_button.label": "পেছনে", "column_header.hide_settings": "সেটিংগুলো সরান", "column_header.moveLeft_settings": "কলমটা বামে সরান", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "আপনি কি নিশ্চিত যে আপনি এই তালিকাটি স্থায়িভাবে মুছে ফেলতে চান ?", "confirmations.domain_block.confirm": "এই ওয়েবসাইট থেকে সব সরান", "confirmations.domain_block.message": "আপনি কি সত্যি সত্যি নিশ্চিত যে {domain} ওয়েবসাইট থেকে সব সরাতে চান ? সাধারণত কিছু লক্ষ্যবস্তু বন্ধ এবং সরানোযা যথেষ্ট। নিশ্চিত করলে ওই ওয়েবসাইট থেকে কোনোকিছু কোনখানে দেখবেন না। যারা আপনাকে অনুসরণ করে ওই ওয়েবসাইট থেকে তাদেরকেও মুছে ফেলা হবে।", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "সরিয়ে ফেলুন", "confirmations.mute.message": "আপনি কি নিশ্চিত {name} সরিয়ে ফেলতে চান ?", "confirmations.redraft.confirm": "মুছে ফেলুন এবং আবার সম্পাদন করুন", @@ -103,6 +111,10 @@ "confirmations.reply.message": "এখন মতামত লিখতে গেলে আপনার এখন যেটা লিখছেন সেটা মুছে যাবে। আপনি নি নিশ্চিত এটা করতে চান ?", "confirmations.unfollow.confirm": "অনুসরণ করা বাতিল করতে", "confirmations.unfollow.message": "আপনি কি নিশ্চিত {name} কে আর অনুসরণ করতে চান না ?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "এই লেখাটি আপনার ওয়েবসাইটে যুক্ত করতে নিচের কোডটি বেবহার করুন।", "embed.preview": "সেটা দেখতে এরকম হবে:", "emoji_button.activity": "কার্যকলাপ", @@ -250,7 +262,6 @@ "navigation_bar.personal": "নিজস্ব", "navigation_bar.pins": "পিন দেওয়া টুট", "navigation_bar.preferences": "পছন্দসমূহ", - "navigation_bar.profile_directory": "নিজস্ব পাতার তালিকা", "navigation_bar.public_timeline": "যুক্তবিশ্বের সময়রেখা", "navigation_bar.security": "নিরাপত্তা", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "আরো দেখাতে", "status.show_more_all": "সবগুলোতে আরো দেখতে", "status.show_thread": "আলোচনা দেখতে", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "আলোচনার প্রজ্ঞাপন চালু করতে", "status.unpin": "নিজের পাতা থেকে পিন করে রাখাটির পিন খুলতে", "suggestions.dismiss": "সাহায্যের পরামর্শগুলো সরাতে", @@ -373,7 +385,7 @@ "time_remaining.moments": "সময় বাকি আছে", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} বাকি আছে", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} কথা বলছে", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "যে পর্যন্ত এটা লেখা হয়েছে, মাস্টাডন থেকে চলে গেলে এটা মুছে যাবে।", "upload_area.title": "টেনে এখানে ছেড়ে দিলে এখানে যুক্ত করা যাবে", "upload_button.label": "ছবি বা ভিডিও যুক্ত করতে (এসব ধরণের: JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/br.json b/app/javascript/mastodon/locales/br.json new file mode 100644 index 000000000..2de037f16 --- /dev/null +++ b/app/javascript/mastodon/locales/br.json @@ -0,0 +1,414 @@ +{ + "account.add_or_remove_from_list": "Add or Remove from lists", + "account.badges.bot": "Bot", + "account.block": "Block @{name}", + "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", + "account.cancel_follow_request": "Cancel follow request", + "account.direct": "Direct message @{name}", + "account.domain_blocked": "Domain hidden", + "account.edit_profile": "Edit profile", + "account.endorse": "Feature on profile", + "account.follow": "Follow", + "account.followers": "Followers", + "account.followers.empty": "No one follows this user yet.", + "account.follows": "Follows", + "account.follows.empty": "This user doesn't follow anyone yet.", + "account.follows_you": "Follows you", + "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", + "account.link_verified_on": "Ownership of this link was checked on {date}", + "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", + "account.media": "Media", + "account.mention": "Mention @{name}", + "account.moved_to": "{name} has moved to:", + "account.mute": "Mute @{name}", + "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", + "account.never_active": "Never", + "account.posts": "Toots", + "account.posts_with_replies": "Toots and replies", + "account.report": "Report @{name}", + "account.requested": "Awaiting approval", + "account.share": "Share @{name}'s profile", + "account.show_reblogs": "Show boosts from @{name}", + "account.unblock": "Unblock @{name}", + "account.unblock_domain": "Unhide {domain}", + "account.unendorse": "Don't feature on profile", + "account.unfollow": "Unfollow", + "account.unmute": "Unmute @{name}", + "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", + "alert.unexpected.message": "An unexpected error occurred.", + "alert.unexpected.title": "Oops!", + "autosuggest_hashtag.per_week": "{count} per week", + "boost_modal.combo": "You can press {combo} to skip this next time", + "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", + "column.blocks": "Blocked users", + "column.community": "Local timeline", + "column.direct": "Direct messages", + "column.directory": "Browse profiles", + "column.domain_blocks": "Hidden domains", + "column.favourites": "Favourites", + "column.follow_requests": "Follow requests", + "column.home": "Home", + "column.lists": "Lists", + "column.mutes": "Muted users", + "column.notifications": "Notifications", + "column.pins": "Pinned toot", + "column.public": "Federated timeline", + "column.status": "Toot", + "column_back_button.label": "Back", + "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.pin": "Pin", + "column_header.show_settings": "Show settings", + "column_header.unpin": "Unpin", + "column_subheading.settings": "Settings", + "community.column_settings.media_only": "Media only", + "compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.", + "compose_form.direct_message_warning_learn_more": "Learn more", + "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?", + "compose_form.poll.add_option": "Add a choice", + "compose_form.poll.duration": "Poll duration", + "compose_form.poll.option_placeholder": "Choice {number}", + "compose_form.poll.remove_option": "Remove this choice", + "compose_form.publish": "Toot", + "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Mark media as sensitive", + "compose_form.sensitive.marked": "Media is marked as sensitive", + "compose_form.sensitive.unmarked": "Media is not marked as sensitive", + "compose_form.spoiler.marked": "Text is hidden behind warning", + "compose_form.spoiler.unmarked": "Text is not hidden", + "compose_form.spoiler_placeholder": "Write your warning here", + "confirmation_modal.cancel": "Cancel", + "confirmations.block.block_and_report": "Block & Report", + "confirmations.block.confirm": "Block", + "confirmations.block.message": "Are you sure you want to block {name}?", + "confirmations.delete.confirm": "Delete", + "confirmations.delete.message": "Are you sure you want to delete this status?", + "confirmations.delete_list.confirm": "Delete", + "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", + "confirmations.domain_block.confirm": "Hide entire domain", + "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", + "confirmations.mute.confirm": "Mute", + "confirmations.mute.message": "Are you sure you want to mute {name}?", + "confirmations.redraft.confirm": "Delete & redraft", + "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", + "confirmations.reply.confirm": "Reply", + "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", + "confirmations.unfollow.confirm": "Unfollow", + "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", + "embed.instructions": "Embed this status on your website by copying the code below.", + "embed.preview": "Here is what it will look like:", + "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", + "emoji_button.flags": "Flags", + "emoji_button.food": "Food & Drink", + "emoji_button.label": "Insert emoji", + "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", + "emoji_button.objects": "Objects", + "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", + "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", + "emoji_button.symbols": "Symbols", + "emoji_button.travel": "Travel & Places", + "empty_column.account_timeline": "No toots here!", + "empty_column.account_unavailable": "Profile unavailable", + "empty_column.blocks": "You haven't blocked any users yet.", + "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", + "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.domain_blocks": "There are no hidden domains yet.", + "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", + "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", + "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", + "empty_column.hashtag": "There is nothing in this hashtag yet.", + "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", + "empty_column.home.public_timeline": "the public timeline", + "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", + "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", + "empty_column.mutes": "You haven't muted any users yet.", + "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", + "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", + "follow_request.authorize": "Authorize", + "follow_request.reject": "Reject", + "getting_started.developers": "Developers", + "getting_started.directory": "Profile directory", + "getting_started.documentation": "Documentation", + "getting_started.heading": "Getting started", + "getting_started.invite": "Invite people", + "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", + "getting_started.security": "Security", + "getting_started.terms": "Terms of service", + "hashtag.column_header.tag_mode.all": "and {additional}", + "hashtag.column_header.tag_mode.any": "or {additional}", + "hashtag.column_header.tag_mode.none": "without {additional}", + "hashtag.column_settings.select.no_options_message": "No suggestions found", + "hashtag.column_settings.select.placeholder": "Enter hashtags…", + "hashtag.column_settings.tag_mode.all": "All of these", + "hashtag.column_settings.tag_mode.any": "Any of these", + "hashtag.column_settings.tag_mode.none": "None of these", + "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "home.column_settings.basic": "Basic", + "home.column_settings.show_reblogs": "Show boosts", + "home.column_settings.show_replies": "Show replies", + "home.column_settings.update_live": "Update in real-time", + "intervals.full.days": "{number, plural, one {# day} other {# days}}", + "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", + "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", + "introduction.federation.action": "Next", + "introduction.federation.federated.headline": "Federated", + "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", + "introduction.federation.home.headline": "Home", + "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", + "introduction.federation.local.headline": "Local", + "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", + "introduction.interactions.action": "Finish toot-orial!", + "introduction.interactions.favourite.headline": "Favourite", + "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", + "introduction.interactions.reblog.headline": "Boost", + "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reply.headline": "Reply", + "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", + "introduction.welcome.action": "Let's go!", + "introduction.welcome.headline": "First steps", + "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", + "keyboard_shortcuts.back": "to navigate back", + "keyboard_shortcuts.blocked": "to open blocked users list", + "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.direct": "to open direct messages column", + "keyboard_shortcuts.down": "to move down in the list", + "keyboard_shortcuts.enter": "to open status", + "keyboard_shortcuts.favourite": "to favourite", + "keyboard_shortcuts.favourites": "to open favourites list", + "keyboard_shortcuts.federated": "to open federated timeline", + "keyboard_shortcuts.heading": "Keyboard Shortcuts", + "keyboard_shortcuts.home": "to open home timeline", + "keyboard_shortcuts.hotkey": "Hotkey", + "keyboard_shortcuts.legend": "to display this legend", + "keyboard_shortcuts.local": "to open local timeline", + "keyboard_shortcuts.mention": "to mention author", + "keyboard_shortcuts.muted": "to open muted users list", + "keyboard_shortcuts.my_profile": "to open your profile", + "keyboard_shortcuts.notifications": "to open notifications column", + "keyboard_shortcuts.pinned": "to open pinned toots list", + "keyboard_shortcuts.profile": "to open author's profile", + "keyboard_shortcuts.reply": "to reply", + "keyboard_shortcuts.requests": "to open follow requests list", + "keyboard_shortcuts.search": "to focus search", + "keyboard_shortcuts.start": "to open \"get started\" column", + "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", + "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": "Close", + "lightbox.next": "Next", + "lightbox.previous": "Previous", + "lightbox.view_context": "View context", + "lists.account.add": "Add to list", + "lists.account.remove": "Remove from list", + "lists.delete": "Delete list", + "lists.edit": "Edit list", + "lists.edit.submit": "Change title", + "lists.new.create": "Add list", + "lists.new.title_placeholder": "New list title", + "lists.search": "Search among people you follow", + "lists.subheading": "Your lists", + "load_pending": "{count, plural, one {# new item} other {# new items}}", + "loading_indicator.label": "Loading...", + "media_gallery.toggle_visible": "Toggle visibility", + "missing_indicator.label": "Not found", + "missing_indicator.sublabel": "This resource could not be found", + "mute_modal.hide_notifications": "Hide notifications from this user?", + "navigation_bar.apps": "Mobile apps", + "navigation_bar.blocks": "Blocked users", + "navigation_bar.community_timeline": "Local timeline", + "navigation_bar.compose": "Compose new toot", + "navigation_bar.direct": "Direct messages", + "navigation_bar.discover": "Discover", + "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.edit_profile": "Edit profile", + "navigation_bar.favourites": "Favourites", + "navigation_bar.filters": "Muted words", + "navigation_bar.follow_requests": "Follow requests", + "navigation_bar.follows_and_followers": "Follows and followers", + "navigation_bar.info": "About this server", + "navigation_bar.keyboard_shortcuts": "Hotkeys", + "navigation_bar.lists": "Lists", + "navigation_bar.logout": "Logout", + "navigation_bar.mutes": "Muted users", + "navigation_bar.personal": "Personal", + "navigation_bar.pins": "Pinned toots", + "navigation_bar.preferences": "Preferences", + "navigation_bar.public_timeline": "Federated timeline", + "navigation_bar.security": "Security", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", + "notification.favourite": "{name} favourited your status", + "notification.follow": "{name} followed you", + "notification.mention": "{name} mentioned you", + "notification.poll": "A poll you have voted in has ended", + "notification.reblog": "{name} boosted your status", + "notifications.clear": "Clear notifications", + "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", + "notifications.column_settings.alert": "Desktop notifications", + "notifications.column_settings.favourite": "Favourites:", + "notifications.column_settings.filter_bar.advanced": "Display all categories", + "notifications.column_settings.filter_bar.category": "Quick filter bar", + "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.follow": "New followers:", + "notifications.column_settings.mention": "Mentions:", + "notifications.column_settings.poll": "Poll results:", + "notifications.column_settings.push": "Push notifications", + "notifications.column_settings.reblog": "Boosts:", + "notifications.column_settings.show": "Show in column", + "notifications.column_settings.sound": "Play sound", + "notifications.filter.all": "All", + "notifications.filter.boosts": "Boosts", + "notifications.filter.favourites": "Favourites", + "notifications.filter.follows": "Follows", + "notifications.filter.mentions": "Mentions", + "notifications.filter.polls": "Poll results", + "notifications.group": "{count} notifications", + "poll.closed": "Closed", + "poll.refresh": "Refresh", + "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", + "poll.vote": "Vote", + "poll_button.add_poll": "Add a poll", + "poll_button.remove_poll": "Remove poll", + "privacy.change": "Adjust status privacy", + "privacy.direct.long": "Post to mentioned users only", + "privacy.direct.short": "Direct", + "privacy.private.long": "Post to followers only", + "privacy.private.short": "Followers-only", + "privacy.public.long": "Post to public timelines", + "privacy.public.short": "Public", + "privacy.unlisted.long": "Do not show in public timelines", + "privacy.unlisted.short": "Unlisted", + "regeneration_indicator.label": "Loading…", + "regeneration_indicator.sublabel": "Your home feed is being prepared!", + "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": "Cancel", + "report.forward": "Forward to {target}", + "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", + "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", + "report.placeholder": "Additional comments", + "report.submit": "Submit", + "report.target": "Report {target}", + "search.placeholder": "Search", + "search_popout.search_format": "Advanced search format", + "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", + "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.accounts": "People", + "search_results.hashtags": "Hashtags", + "search_results.statuses": "Toots", + "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", + "search_results.total": "{count, number} {count, plural, one {result} other {results}}", + "status.admin_account": "Open moderation interface for @{name}", + "status.admin_status": "Open this status in the moderation interface", + "status.block": "Block @{name}", + "status.cancel_reblog_private": "Unboost", + "status.cannot_reblog": "This post cannot be boosted", + "status.copy": "Copy link to status", + "status.delete": "Delete", + "status.detailed_status": "Detailed conversation view", + "status.direct": "Direct message @{name}", + "status.embed": "Embed", + "status.favourite": "Favourite", + "status.filtered": "Filtered", + "status.load_more": "Load more", + "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", + "status.pinned": "Pinned toot", + "status.read_more": "Read more", + "status.reblog": "Boost", + "status.reblog_private": "Boost to original audience", + "status.reblogged_by": "{name} boosted", + "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", + "status.redraft": "Delete & re-draft", + "status.reply": "Reply", + "status.replyAll": "Reply to thread", + "status.report": "Report @{name}", + "status.sensitive_warning": "Sensitive content", + "status.share": "Share", + "status.show_less": "Show less", + "status.show_less_all": "Show less for all", + "status.show_more": "Show more", + "status.show_more_all": "Show more for all", + "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", + "status.unmute_conversation": "Unmute conversation", + "status.unpin": "Unpin from profile", + "suggestions.dismiss": "Dismiss suggestion", + "suggestions.header": "You might be interested in…", + "tabs_bar.federated_timeline": "Federated", + "tabs_bar.home": "Home", + "tabs_bar.local_timeline": "Local", + "tabs_bar.notifications": "Notifications", + "tabs_bar.search": "Search", + "time_remaining.days": "{number, plural, one {# day} other {# days}} left", + "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left", + "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", + "time_remaining.moments": "Moments remaining", + "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", + "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", + "trends.trending_now": "Trending now", + "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", + "upload_area.title": "Drag & drop to upload", + "upload_button.label": "Add media ({formats})", + "upload_error.limit": "File upload limit exceeded.", + "upload_error.poll": "File upload not allowed with polls.", + "upload_form.description": "Describe for the visually impaired", + "upload_form.edit": "Edit", + "upload_form.undo": "Delete", + "upload_modal.analyzing_picture": "Analyzing picture…", + "upload_modal.apply": "Apply", + "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.detect_text": "Detect text from picture", + "upload_modal.edit_media": "Edit media", + "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", + "upload_modal.preview_label": "Preview ({ratio})", + "upload_progress.label": "Uploading...", + "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" +} diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 4554ff04e..77f84ac7d 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -4,7 +4,7 @@ "account.block": "Bloqueja @{name}", "account.block_domain": "Amaga-ho tot de {domain}", "account.blocked": "Bloquejat", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Anul·la la sol·licitud de seguiment", "account.direct": "Missatge directe @{name}", "account.domain_blocked": "Domini ocult", "account.edit_profile": "Editar el perfil", @@ -16,6 +16,7 @@ "account.follows.empty": "Aquest usuari encara no segueix a ningú.", "account.follows_you": "Et segueix", "account.hide_reblogs": "Amaga els impulsos de @{name}", + "account.last_status": "Last active", "account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}", "account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.", "account.media": "Mèdia", @@ -24,6 +25,7 @@ "account.mute": "Silencia @{name}", "account.mute_notifications": "Notificacions desactivades de @{name}", "account.muted": "Silenciat", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots i respostes", "account.report": "Informe @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Deixa de seguir", "account.unmute": "Treure silenci de @{name}", "account.unmute_notifications": "Activar notificacions de @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "S'ha produït un error inesperat.", "alert.unexpected.title": "Vaja!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} per setmana", "boost_modal.combo": "Pots premer {combo} per saltar-te això el proper cop", "bundle_column_error.body": "S'ha produït un error en carregar aquest component.", "bundle_column_error.retry": "Torna-ho a provar", @@ -49,6 +53,7 @@ "column.blocks": "Usuaris bloquejats", "column.community": "Línia de temps local", "column.direct": "Missatges directes", + "column.directory": "Browse profiles", "column.domain_blocks": "Dominis ocults", "column.favourites": "Favorits", "column.follow_requests": "Peticions per seguir-te", @@ -58,6 +63,7 @@ "column.notifications": "Notificacions", "column.pins": "Toots fixats", "column.public": "Línia de temps federada", + "column.status": "Toot", "column_back_button.label": "Enrere", "column_header.hide_settings": "Amaga la configuració", "column_header.moveLeft_settings": "Mou la columna cap a l'esquerra", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Estàs segur que vols suprimir permanentment aquesta llista?", "confirmations.domain_block.confirm": "Amaga tot el domini", "confirmations.domain_block.message": "Estàs segur, realment segur que vols bloquejar totalment {domain}? En la majoria dels casos bloquejar o silenciar uns pocs objectius és suficient i preferible. No veuràs contingut d’aquest domini en cap de les línies públiques ni en les notificacions. Els teus seguidors d’aquest domini seran eliminats.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Silencia", "confirmations.mute.message": "Estàs segur que vols silenciar {name}?", "confirmations.redraft.confirm": "Esborrar i refer", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Responen ara es sobreescriurà el missatge que estàs editant. Estàs segur que vols continuar?", "confirmations.unfollow.confirm": "Deixa de seguir", "confirmations.unfollow.message": "Estàs segur que vols deixar de seguir {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Incrusta aquest toot al lloc web copiant el codi a continuació.", "embed.preview": "Aquí tenim quin aspecte tindrá:", "emoji_button.activity": "Activitat", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Bàsic", "home.column_settings.show_reblogs": "Mostrar impulsos", "home.column_settings.show_replies": "Mostrar respostes", - "home.column_settings.update_live": "Actualització en temps real", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# dia} other {# dies}}", "intervals.full.hours": "{number, plural, one {# hora} other {# hores}}", "intervals.full.minutes": "{number, plural, one {# minut} other {# minuts}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Toots fixats", "navigation_bar.preferences": "Preferències", - "navigation_bar.profile_directory": "Directori de perfils", "navigation_bar.public_timeline": "Línia de temps federada", "navigation_bar.security": "Seguretat", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostra més", "status.show_more_all": "Mostra més per a tot", "status.show_thread": "Mostra el fil", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Activar conversació", "status.unpin": "Deslliga del perfil", "suggestions.dismiss": "Descartar suggeriment", @@ -373,22 +385,22 @@ "time_remaining.moments": "Moments restants", "time_remaining.seconds": "{number, plural, one {# segon} other {# segons}} restants", "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {gent}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "El teu esborrany es perdrà si surts de Mastodon.", "upload_area.title": "Arrossega i deixa anar per a carregar", "upload_button.label": "Afegir multimèdia (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "S'ha superat el límit de càrrega d'arxius.", "upload_error.poll": "No es permet l'enviament de fitxers en les enquestes.", "upload_form.description": "Descriure els problemes visuals", - "upload_form.edit": "Edit", + "upload_form.edit": "Edita", "upload_form.undo": "Esborra", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Analitzant imatge…", + "upload_modal.apply": "Aplica", + "upload_modal.description_placeholder": "Uns salts ràpids de guineu marró sobre el gos gandul", + "upload_modal.detect_text": "Detecta el text de l'imatge", + "upload_modal.edit_media": "Editar multimèdia", + "upload_modal.hint": "Fes clic o arrossega el cercle en la previsualització per escollir el punt focal que sempre serà visible de totes les miniatures.", + "upload_modal.preview_label": "Previsualitza ({ratio})", "upload_progress.label": "Pujant...", "video.close": "Tancar el vídeo", "video.exit_fullscreen": "Sortir de pantalla completa", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 428c993a6..d95f32b18 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -16,6 +16,7 @@ "account.follows.empty": "St'utilizatore ùn seguita nisunu.", "account.follows_you": "Vi seguita", "account.hide_reblogs": "Piattà spartere da @{name}", + "account.last_status": "Ultima attività", "account.link_verified_on": "A prupietà di stu ligame hè stata verificata u {date}", "account.locked_info": "U statutu di vita privata di u contu hè chjosu. U pruprietariu esamina manualmente e dumande d'abbunamentu.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Piattà @{name}", "account.mute_notifications": "Piattà nutificazione da @{name}", "account.muted": "Piattatu", + "account.never_active": "Mai", "account.posts": "Statuti", "account.posts_with_replies": "Statuti è risposte", "account.report": "Palisà @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Ùn siguità più", "account.unmute": "Ùn piattà più @{name}", "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}", + "alert.rate_limited.message": "Pruvate ancu dop'à {retry_time, time, medium}.", + "alert.rate_limited.title": "Ghjettu limitatu", "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.", "alert.unexpected.title": "Uups!", "autosuggest_hashtag.per_week": "{count} per settimana", @@ -49,6 +53,7 @@ "column.blocks": "Utilizatori bluccati", "column.community": "Linea pubblica lucale", "column.direct": "Missaghji diretti", + "column.directory": "Percorre i prufili", "column.domain_blocks": "Duminii piattati", "column.favourites": "Favuriti", "column.follow_requests": "Dumande d'abbunamentu", @@ -58,6 +63,7 @@ "column.notifications": "Nutificazione", "column.pins": "Statuti puntarulati", "column.public": "Linea pubblica glubale", + "column.status": "Toot", "column_back_button.label": "Ritornu", "column_header.hide_settings": "Piattà i parametri", "column_header.moveLeft_settings": "Spiazzà à manca", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Site sicuru·a che vulete supprime sta lista?", "confirmations.domain_block.confirm": "Piattà tuttu u duminiu", "confirmations.domain_block.message": "Site sicuru·a che vulete piattà tuttu à {domain}? Saria forse abbastanza di bluccà ò piattà alcuni conti da quallà. Ùn viderete più nunda da quallà indè e linee pubbliche o e nutificazione. I vostri abbunati da stu duminiu saranu tolti.", + "confirmations.logout.confirm": "Scunnettassi", + "confirmations.logout.message": "Site sicuru·a che vulete scunnettà vi?", "confirmations.mute.confirm": "Piattà", "confirmations.mute.message": "Site sicuru·a che vulete piattà @{name}?", "confirmations.redraft.confirm": "Sguassà è riscrive", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Risponde avà sguasserà u missaghju chì scrivite. Site sicuru·a chì vulete cuntinuà?", "confirmations.unfollow.confirm": "Disabbunassi", "confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?", + "directory.federated": "Da u fediverse cunisciutu", + "directory.local": "Solu da {domain}", + "directory.new_arrivals": "Ultimi arrivi", + "directory.recently_active": "Attività ricente", "embed.instructions": "Integrà stu statutu à u vostru situ cù u codice quì sottu.", "embed.preview": "Assumiglierà à qualcosa cusì:", "emoji_button.activity": "Attività", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Bàsichi", "home.column_settings.show_reblogs": "Vede e spartere", "home.column_settings.show_replies": "Vede e risposte", - "home.column_settings.update_live": "Mette à ghjornu in tempu reale", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# ghjornu} other {# ghjorni}}", "intervals.full.hours": "{number, plural, one {# ora} other {# ore}}", "intervals.full.minutes": "{number, plural, one {# minuta} other {# minute}}", @@ -250,10 +262,9 @@ "navigation_bar.personal": "Persunale", "navigation_bar.pins": "Statuti puntarulati", "navigation_bar.preferences": "Preferenze", - "navigation_bar.profile_directory": "Annuariu di i prufili", "navigation_bar.public_timeline": "Linea pubblica glubale", "navigation_bar.security": "Sicurità", - "notification.and_n_others": "è {count, plural, one {# altru} other {# altri}}", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} hà aghjuntu u vostru statutu à i so favuriti", "notification.follow": "{name} v'hà seguitatu", "notification.mention": "{name} v'hà mintuvatu", @@ -358,6 +369,7 @@ "status.show_more": "Slibrà", "status.show_more_all": "Slibrà tuttu", "status.show_thread": "Vede u filu", + "status.uncached_media_warning": "Micca dispunibule", "status.unmute_conversation": "Ùn piattà più a cunversazione", "status.unpin": "Spuntarulà da u prufile", "suggestions.dismiss": "Righjittà a pruposta", @@ -373,7 +385,7 @@ "time_remaining.moments": "Ci fermanu qualchi mumentu", "time_remaining.seconds": "{number, plural, one {# siconda ferma} other {# siconde fermanu}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} parlanu", - "trends.refresh": "Attualizà", + "trends.trending_now": "Tindenze d'avà", "ui.beforeunload": "A bruttacopia sarà persa s'ellu hè chjosu Mastodon.", "upload_area.title": "Drag & drop per caricà un fugliale", "upload_button.label": "Aghjunghje un media (JPEG, PNG, GIF, WebM, MP4, MOV)", @@ -384,7 +396,7 @@ "upload_form.undo": "Sguassà", "upload_modal.analyzing_picture": "Analisi di u ritrattu…", "upload_modal.apply": "Affettà", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.description_placeholder": "Chì tempi brevi ziu, quandu solfeghji", "upload_modal.detect_text": "Ditettà testu da u ritrattu", "upload_modal.edit_media": "Cambià media", "upload_modal.hint": "Cliccate o sguillate u chjerchju nant'à a vista per sceglie u puntu fucale chì sarà sempre in vista indè tutte e miniature.", diff --git a/app/javascript/mastodon/locales/cs.json b/app/javascript/mastodon/locales/cs.json index 46a57b3b8..8acf27cb3 100644 --- a/app/javascript/mastodon/locales/cs.json +++ b/app/javascript/mastodon/locales/cs.json @@ -4,7 +4,7 @@ "account.block": "Zablokovat uživatele @{name}", "account.block_domain": "Skrýt vše z {domain}", "account.blocked": "Blokován/a", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Zrušit požadavek o sledování", "account.direct": "Poslat přímou zprávu uživateli @{name}", "account.domain_blocked": "Doména skryta", "account.edit_profile": "Upravit profil", @@ -16,6 +16,7 @@ "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.", "account.follows_you": "Sleduje vás", "account.hide_reblogs": "Skrýt boosty od uživatele @{name}", + "account.last_status": "Naposledy aktivní", "account.link_verified_on": "Vlastnictví tohoto odkazu bylo zkontrolováno {date}", "account.locked_info": "Stav soukromí tohoto účtu je nastaven na zamčeno. Jeho vlastník ručně posuzuje, kdo ho může sledovat.", "account.media": "Média", @@ -24,6 +25,7 @@ "account.mute": "Skrýt uživatele @{name}", "account.mute_notifications": "Skrýt oznámení od uživatele @{name}", "account.muted": "Skryt/a", + "account.never_active": "Nikdy", "account.posts": "Tooty", "account.posts_with_replies": "Tooty a odpovědi", "account.report": "Nahlásit uživatele @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Přestat sledovat", "account.unmute": "Odkrýt uživatele @{name}", "account.unmute_notifications": "Odkrýt oznámení od uživatele @{name}", + "alert.rate_limited.message": "Prosím zkuste to znovu za {retry_time, time, medium}.", + "alert.rate_limited.title": "Rychlost omezena", "alert.unexpected.message": "Objevila se neočekávaná chyba.", "alert.unexpected.title": "Jejda!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} za týden", "boost_modal.combo": "Příště můžete pro přeskočení kliknout na {combo}", "bundle_column_error.body": "Při načítání tohoto komponentu se něco pokazilo.", "bundle_column_error.retry": "Zkuste to znovu", @@ -49,6 +53,7 @@ "column.blocks": "Blokovaní uživatelé", "column.community": "Místní časová osa", "column.direct": "Přímé zprávy", + "column.directory": "Prozkoumat profily", "column.domain_blocks": "Skryté domény", "column.favourites": "Oblíbené", "column.follow_requests": "Požadavky o sledování", @@ -58,6 +63,7 @@ "column.notifications": "Oznámení", "column.pins": "Připnuté tooty", "column.public": "Federovaná časová osa", + "column.status": "Toot", "column_back_button.label": "Zpět", "column_header.hide_settings": "Skrýt nastavení", "column_header.moveLeft_settings": "Posunout sloupec doleva", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Jste si jistý/á, že chcete tento seznam navždy smazat?", "confirmations.domain_block.confirm": "Skrýt celou doménu", "confirmations.domain_block.message": "Jste si opravdu, opravdu jistý/á, že chcete blokovat celou doménu {domain}? Ve většině případů stačí zablokovat nebo skrýt pár konkrétních uživatelů, což se doporučuje. Z této domény neuvidíte obsah v žádné veřejné časové ose ani v oznámeních. Vaši sledující z této domény budou odstraněni.", + "confirmations.logout.confirm": "Odhlásit", + "confirmations.logout.message": "Jste si jistý/á, že se chcete odhlásit?", "confirmations.mute.confirm": "Skrýt", "confirmations.mute.message": "Jste si jistý/á, že chcete skrýt uživatele {name}?", "confirmations.redraft.confirm": "Smazat a přepsat", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Odpovězením nyní přepíšete zprávu, kterou aktuálně píšete. Jste si jistý/á, že chcete pokračovat?", "confirmations.unfollow.confirm": "Přestat sledovat", "confirmations.unfollow.message": "jste si jistý/á, že chcete přestat sledovat uživatele {name}?", + "directory.federated": "Ze známého fedivesmíru", + "directory.local": "Pouze z {domain}", + "directory.new_arrivals": "Nově příchozí", + "directory.recently_active": "Nedávno aktivní", "embed.instructions": "Pro přidání tootu na vaši webovou stránku zkopírujte níže uvedený kód.", "embed.preview": "Takhle to bude vypadat:", "emoji_button.activity": "Aktivita", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Základní", "home.column_settings.show_reblogs": "Zobrazit boosty", "home.column_settings.show_replies": "Zobrazit odpovědi", - "home.column_settings.update_live": "Aktualizovat v reálném čase", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# den} few {# dny} many {# dne} other {# dní}}", "intervals.full.hours": "{number, plural, one {# hodina} few {# hodiny} many {# hodiny} other {# hodin}}", "intervals.full.minutes": "{number, plural, one {# minuta} few {# minuty} many {# minuty} other {# minut}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Osobní", "navigation_bar.pins": "Připnuté tooty", "navigation_bar.preferences": "Předvolby", - "navigation_bar.profile_directory": "Adresář profilů", "navigation_bar.public_timeline": "Federovaná časová osa", "navigation_bar.security": "Zabezpečení", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Zobrazit více", "status.show_more_all": "Zobrazit více pro všechny", "status.show_thread": "Zobrazit vlákno", + "status.uncached_media_warning": "Nedostupné", "status.unmute_conversation": "Odkrýt konverzaci", "status.unpin": "Odepnout z profilu", "suggestions.dismiss": "Odmítnout návrh", @@ -373,22 +385,22 @@ "time_remaining.moments": "Zbývá několik sekund", "time_remaining.seconds": "{number, plural, one {Zbývá # sekunda} few {Zbývají # sekundy} many {Zbývá # sekundy} other {Zbývá # sekund}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {člověk} few {lidé} many {lidí} other {lidí}} hovoří", - "trends.refresh": "Refresh", + "trends.trending_now": "Aktuální trendy", "ui.beforeunload": "Váš koncept se ztratí, pokud Mastodon opustíte.", "upload_area.title": "Přetažením nahrajete", "upload_button.label": "Přidat média (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "Byl překročen limit nahraných souborů.", "upload_error.poll": "Nahrávání souborů není povoleno u anket.", "upload_form.description": "Popis pro zrakově postižené", - "upload_form.edit": "Edit", + "upload_form.edit": "Upravit", "upload_form.undo": "Smazat", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Analyzuji obrázek…", + "upload_modal.apply": "Použít", + "upload_modal.description_placeholder": "Příliš žluťoučký kůň úpěl ďábelské ódy", + "upload_modal.detect_text": "Detekovat text z obrázku", + "upload_modal.edit_media": "Upravit média", + "upload_modal.hint": "Kliknutím na nebo přetáhnutím kruhu na náhledu vyberte bod soustředění, který bude vždy zobrazen na všech náhledech.", + "upload_modal.preview_label": "Náhled ({ratio})", "upload_progress.label": "Nahrávám…", "video.close": "Zavřít video", "video.exit_fullscreen": "Ukončit celou obrazovku", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 0bd6f19d2..cdf2656d7 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -16,6 +16,7 @@ "account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.", "account.follows_you": "Yn eich dilyn chi", "account.hide_reblogs": "Cuddio bwstiau o @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}", "account.locked_info": "Mae'r statws preifatrwydd cyfrif hwn wedi'i osod i gloi. Mae'r perchennog yn adolygu'r sawl sy'n gallu eu dilyn.", "account.media": "Cyfryngau", @@ -24,6 +25,7 @@ "account.mute": "Tawelu @{name}", "account.mute_notifications": "Cuddio hysbysiadau o @{name}", "account.muted": "Distewyd", + "account.never_active": "Never", "account.posts": "Tŵtiau", "account.posts_with_replies": "Tŵtiau ac atebion", "account.report": "Adrodd @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Dad-ddilyn", "account.unmute": "Dad-dawelu @{name}", "account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Digwyddodd gwall annisgwyl.", "alert.unexpected.title": "Wps!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Defnyddwyr a flociwyd", "column.community": "Ffrwd lleol", "column.direct": "Negeseuon preifat", + "column.directory": "Browse profiles", "column.domain_blocks": "Parthau cuddiedig", "column.favourites": "Ffefrynnau", "column.follow_requests": "Ceisiadau dilyn", @@ -58,6 +63,7 @@ "column.notifications": "Hysbysiadau", "column.pins": "Tŵtiau wedi eu pinio", "column.public": "Ffrwd y ffederasiwn", + "column.status": "Toot", "column_back_button.label": "Nôl", "column_header.hide_settings": "Cuddio dewisiadau", "column_header.moveLeft_settings": "Symud y golofn i'r chwith", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ydych chi'n sicr eich bod eisiau dileu y rhestr hwn am byth?", "confirmations.domain_block.confirm": "Cuddio parth cyfan", "confirmations.domain_block.message": "A ydych yn hollol, hollol sicr eich bod am flocio y {domain} cyfan? Yn y nifer helaeth o achosion mae blocio neu tawelu ambell gyfrif yn ddigonol ac yn well. Ni fyddwch yn gweld cynnwys o'r parth hwnnw mewn unrhyw ffrydiau cyhoeddus na chwaith yn eich hysbysiadau. Bydd hyn yn cael gwared o'ch dilynwyr o'r parth hwnnw.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Tawelu", "confirmations.mute.message": "Ydych chi'n sicr eich bod am ddistewi {name}?", "confirmations.redraft.confirm": "Dileu & ailddrafftio", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Bydd ateb nawr yn cymryd lle y neges yr ydych yn cyfansoddi ar hyn o bryd. Ydych chi'n sicr yr ydych am barhau?", "confirmations.unfollow.confirm": "Dad-ddilynwch", "confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Mewnblannwch y tŵt hwn ar eich gwefan drwy gopïo'r côd isod.", "embed.preview": "Dyma sut olwg fydd arno:", "emoji_button.activity": "Gweithgarwch", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personol", "navigation_bar.pins": "Tŵtiau wedi eu pinio", "navigation_bar.preferences": "Dewisiadau", - "navigation_bar.profile_directory": "Cyfeiriadur Proffil", "navigation_bar.public_timeline": "Ffrwd y ffederasiwn", "navigation_bar.security": "Diogelwch", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Dangos mwy", "status.show_more_all": "Dangos mwy i bawb", "status.show_thread": "Dangos edefyn", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Dad-dawelu sgwrs", "status.unpin": "Dadbinio o'r proffil", "suggestions.dismiss": "Diswyddo", @@ -373,7 +385,7 @@ "time_remaining.moments": "Munudau ar ôl", "time_remaining.seconds": "{number, plural, one {# eiliad} other {# o eiliadau}} ar ôl", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} yn siarad", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Mi fyddwch yn colli eich drafft os gadewch Mastodon.", "upload_area.title": "Llusgwch & gollwing i uwchlwytho", "upload_button.label": "Ychwanegwch gyfryngau (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/da.json b/app/javascript/mastodon/locales/da.json index b021f9aa1..14b0f7563 100644 --- a/app/javascript/mastodon/locales/da.json +++ b/app/javascript/mastodon/locales/da.json @@ -4,7 +4,7 @@ "account.block": "Bloker @{name}", "account.block_domain": "Skjul alt fra {domain}", "account.blocked": "Blokeret", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Annullér følgeranmodning", "account.direct": "Send en direkte besked til @{name}", "account.domain_blocked": "Domænet er blevet skjult", "account.edit_profile": "Rediger profil", @@ -16,14 +16,16 @@ "account.follows.empty": "Denne bruger følger endnu ikke nogen.", "account.follows_you": "Følger dig", "account.hide_reblogs": "Skjul fremhævelserne fra @{name}", + "account.last_status": "Sidst aktiv", "account.link_verified_on": "Ejerskabet af dette link blev tjekket den %{date}", - "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", + "account.locked_info": "Denne kontos privatlivsstatus er sat til låst. Ejeren bedømmer manuelt, hvem der kan følge dem.", "account.media": "Medie", "account.mention": "Nævn @{name}", "account.moved_to": "{name} er flyttet til:", "account.mute": "Dæmp @{name}", "account.mute_notifications": "Dæmp notifikationer fra @{name}", "account.muted": "Dæmpet", + "account.never_active": "Aldrig", "account.posts": "Trut", "account.posts_with_replies": "Trut og svar", "account.report": "Rapporter @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Følg ikke længere", "account.unmute": "Fjern dæmpningen af @{name}", "account.unmute_notifications": "Fjern dæmpningen af notifikationer fra @{name}", + "alert.rate_limited.message": "Prøv venligst igen efter {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Der opstod en uventet fejl.", "alert.unexpected.title": "Ups!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} per uge", "boost_modal.combo": "Du kan trykke {combo} for at springe dette over næste gang", "bundle_column_error.body": "Noget gik galt under indlæsningen af dette komponent.", "bundle_column_error.retry": "Prøv igen", @@ -49,6 +53,7 @@ "column.blocks": "Blokerede brugere", "column.community": "Lokal tidslinje", "column.direct": "Direkte beskeder", + "column.directory": "Gennemse profiler", "column.domain_blocks": "Skjulte domæner", "column.favourites": "Favoritter", "column.follow_requests": "Anmodning om at følge", @@ -58,6 +63,7 @@ "column.notifications": "Notifikationer", "column.pins": "Fastgjorte trut", "column.public": "Fælles tidslinje", + "column.status": "Toot", "column_back_button.label": "Tilbage", "column_header.hide_settings": "Skjul indstillinger", "column_header.moveLeft_settings": "Flyt kolonne til venstre", @@ -73,20 +79,20 @@ "compose_form.lock_disclaimer": "Din konto er ikke {locked}. Alle kan følge dig for at se dine følger-kun indlæg.", "compose_form.lock_disclaimer.lock": "låst", "compose_form.placeholder": "Hvad har du på hjertet?", - "compose_form.poll.add_option": "Add a choice", - "compose_form.poll.duration": "Poll duration", - "compose_form.poll.option_placeholder": "Choice {number}", - "compose_form.poll.remove_option": "Remove this choice", + "compose_form.poll.add_option": "Tilføj valgmulighed", + "compose_form.poll.duration": "Afstemningens varighed", + "compose_form.poll.option_placeholder": "Valgmulighed {number}", + "compose_form.poll.remove_option": "Fjern denne valgmulighed", "compose_form.publish": "Trut", "compose_form.publish_loud": "{publish}!", - "compose_form.sensitive.hide": "Mark media as sensitive", + "compose_form.sensitive.hide": "Markér medie som følsomt", "compose_form.sensitive.marked": "Medie er markeret som værende følsomt", "compose_form.sensitive.unmarked": "Mediet er ikke markeret som værende følsomt", "compose_form.spoiler.marked": "Teksten er skjult bag en advarsel", "compose_form.spoiler.unmarked": "Teksten er ikke skjult", "compose_form.spoiler_placeholder": "Skriv din advarsel her", "confirmation_modal.cancel": "Annuller", - "confirmations.block.block_and_report": "Block & Report", + "confirmations.block.block_and_report": "Blokér og anmeld", "confirmations.block.confirm": "Bloker", "confirmations.block.message": "Er du sikker på, du vil blokere {name}?", "confirmations.delete.confirm": "Slet", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Er du sikker på, du vil slette denne liste?", "confirmations.domain_block.confirm": "Skjul helt domæne", "confirmations.domain_block.message": "Er du helt sikker på du vil blokere hele {domain} domænet? I de fleste tilfælde vil få specifikke blokeringer eller dæmpninger være nok og at fortrække. Du vil ikke se indhold fra det domæne hverken på offentlige tidslinjer eller i dine notifikationer. Dine følgere fra det domæne vil blive fjernet.", + "confirmations.logout.confirm": "Log ud", + "confirmations.logout.message": "Er du sikker på du vil logge ud?", "confirmations.mute.confirm": "Dæmp", "confirmations.mute.message": "Er du sikker på, du vil dæmpe {name}?", "confirmations.redraft.confirm": "Slet & omskriv", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Hvis du svarer nu vil du overskrive den besked du er ved at skrive. Er du sikker på, du vil fortsætte?", "confirmations.unfollow.confirm": "Følg ikke længere", "confirmations.unfollow.message": "Er du sikker på, du ikke længere vil følge {name}?", + "directory.federated": "Fra kendt fedivers", + "directory.local": "Kun fra {domain}", + "directory.new_arrivals": "Nye ankomster", + "directory.recently_active": "Senest aktiv", "embed.instructions": "Indlejre denne status på din side ved at kopiere nedenstående kode.", "embed.preview": "Det kommer til at se således ud:", "emoji_button.activity": "Aktivitet", @@ -113,14 +125,14 @@ "emoji_button.nature": "Natur", "emoji_button.not_found": "Ingen emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objekter", - "emoji_button.people": "Mennesker", + "emoji_button.people": "Personer", "emoji_button.recent": "Oftest brugt", "emoji_button.search": "Søg...", "emoji_button.search_results": "Søgeresultater", "emoji_button.symbols": "Symboler", "emoji_button.travel": "Rejser & steder", "empty_column.account_timeline": "Ingen bidrag her!", - "empty_column.account_unavailable": "Profile unavailable", + "empty_column.account_unavailable": "Profil utilgængelig", "empty_column.blocks": "Du har ikke blokeret nogen endnu.", "empty_column.community": "Den lokale tidslinje er tom. Skriv noget offentligt for at starte lavinen!", "empty_column.direct": "Du har endnu ingen direkte beskeder. Når du sender eller modtager en, vil den vises her.", @@ -139,7 +151,7 @@ "follow_request.authorize": "Godkend", "follow_request.reject": "Afvis", "getting_started.developers": "Udviklere", - "getting_started.directory": "Profile directory", + "getting_started.directory": "Profilliste", "getting_started.documentation": "Dokumentation", "getting_started.heading": "Kom igang", "getting_started.invite": "Inviter folk", @@ -149,36 +161,36 @@ "hashtag.column_header.tag_mode.all": "og {additional}", "hashtag.column_header.tag_mode.any": "eller {additional}", "hashtag.column_header.tag_mode.none": "uden {additional}", - "hashtag.column_settings.select.no_options_message": "No suggestions found", - "hashtag.column_settings.select.placeholder": "Enter hashtags…", - "hashtag.column_settings.tag_mode.all": "All of these", - "hashtag.column_settings.tag_mode.any": "Any of these", - "hashtag.column_settings.tag_mode.none": "None of these", + "hashtag.column_settings.select.no_options_message": "Ingen forslag fundet", + "hashtag.column_settings.select.placeholder": "Indtast hashtags…", + "hashtag.column_settings.tag_mode.all": "Alle disse", + "hashtag.column_settings.tag_mode.any": "Nogle af disse", + "hashtag.column_settings.tag_mode.none": "Ingen af disse", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", "home.column_settings.basic": "Grundlæggende", "home.column_settings.show_reblogs": "Vis fremhævelser", "home.column_settings.show_replies": "Vis svar", "home.column_settings.update_live": "Update in real-time", - "intervals.full.days": "{number, plural, one {# day} other {# days}}", - "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", - "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", + "intervals.full.days": "{number, plural, one {# dag} other {# dage}}", + "intervals.full.hours": "{number, plural, one {# time} other {# timer}}", + "intervals.full.minutes": "{number, plural, one {# minut} other {# minutter}}", "introduction.federation.action": "Næste", - "introduction.federation.federated.headline": "Federated", + "introduction.federation.federated.headline": "Fælles", "introduction.federation.federated.text": "Offentlige bidrag fra andre servere af fediversen vil komme til syne i den federated timeline.", - "introduction.federation.home.headline": "Home", - "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", - "introduction.federation.local.headline": "Local", - "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", + "introduction.federation.home.headline": "Hjem", + "introduction.federation.home.text": "Statusser fra personer du følger vil blive vist i dit hjemmefeed. Du kan følge alle på enhver server!", + "introduction.federation.local.headline": "Lokal", + "introduction.federation.local.text": "Offentlige statusser fra personer på samme server som dig vil blive vist i det lokale feed.", "introduction.interactions.action": "Slut tutorial!", "introduction.interactions.favourite.headline": "Favorisere", - "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", + "introduction.interactions.favourite.text": "Du kan gemme en status til senere (og vise forfatteren at du kunne lide den) ved at favorisere den.", "introduction.interactions.reblog.headline": "Boost", - "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reblog.text": "Du kan delete andres statusser med dine følgere ved at booste dem.", "introduction.interactions.reply.headline": "Svar", "introduction.interactions.reply.text": "Du kan svare andres og din egen bidrag, hvilke vil kæde dem sammen i en konversation.", "introduction.welcome.action": "Læd os gå!", "introduction.welcome.headline": "Første skridt", - "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", + "introduction.welcome.text": "Velkommen til fediverset! Om få øjeblikke vil du kunne dele statusser og tale med dine venner på en bred vifte af servere. Men denne server, {domain}, er speciel. Det er på denne server at din profil har hjemme så husk dens navn.", "keyboard_shortcuts.back": "for at navigere dig tilbage", "keyboard_shortcuts.blocked": "for at åbne listen over blokerede brugere", "keyboard_shortcuts.boost": "for at fremhæve", @@ -207,24 +219,24 @@ "keyboard_shortcuts.search": "for at fokusere søgningen", "keyboard_shortcuts.start": "for at åbne \"kom igen\" kolonnen", "keyboard_shortcuts.toggle_hidden": "for at vise/skjule tekst bag CW", - "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", + "keyboard_shortcuts.toggle_sensitivity": "for at vise/skjule medier", "keyboard_shortcuts.toot": "for at påbegynde et helt nyt trut", "keyboard_shortcuts.unfocus": "for at fjerne fokus fra skriveområde/søgning", "keyboard_shortcuts.up": "for at bevæge dig op ad listen", "lightbox.close": "Luk", "lightbox.next": "Næste", "lightbox.previous": "Forrige", - "lightbox.view_context": "View context", + "lightbox.view_context": "Vis kontekst", "lists.account.add": "Tilføj til liste", "lists.account.remove": "Fjern fra liste", "lists.delete": "Slet liste", "lists.edit": "Rediger liste", - "lists.edit.submit": "Change title", + "lists.edit.submit": "Skift titel", "lists.new.create": "Tilføj liste", "lists.new.title_placeholder": "Ny liste titel", "lists.search": "Søg iblandt folk du følger", "lists.subheading": "Dine lister", - "load_pending": "{count, plural, one {# new item} other {# new items}}", + "load_pending": "{count, plural, one {# nyt punkt} other {# nye punkter}}", "loading_indicator.label": "Indlæser...", "media_gallery.toggle_visible": "Ændre synlighed", "missing_indicator.label": "Ikke fundet", @@ -241,7 +253,7 @@ "navigation_bar.favourites": "Favoritter", "navigation_bar.filters": "Dæmpede ord", "navigation_bar.follow_requests": "Følgeanmodninger", - "navigation_bar.follows_and_followers": "Follows and followers", + "navigation_bar.follows_and_followers": "Følger og følgere", "navigation_bar.info": "Om denne instans", "navigation_bar.keyboard_shortcuts": "Hurtigtast", "navigation_bar.lists": "Lister", @@ -250,50 +262,49 @@ "navigation_bar.personal": "Personligt", "navigation_bar.pins": "Fastgjorte trut", "navigation_bar.preferences": "Præferencer", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Fælles tidslinje", "navigation_bar.security": "Sikkerhed", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} favoriserede din status", "notification.follow": "{name} fulgte dig", "notification.mention": "{name} nævnte dig", - "notification.poll": "A poll you have voted in has ended", - "notification.reblog": "{name} fremhævede din status", + "notification.poll": "En afstemning, du stemte i, er slut", + "notification.reblog": "{name} boostede din status", "notifications.clear": "Ryd notifikationer", "notifications.clear_confirmation": "Er du sikker på, du vil rydde alle dine notifikationer permanent?", - "notifications.column_settings.alert": "Skrivebords notifikationer", + "notifications.column_settings.alert": "Skrivebordsnotifikationer", "notifications.column_settings.favourite": "Favoritter:", - "notifications.column_settings.filter_bar.advanced": "Display all categories", - "notifications.column_settings.filter_bar.category": "Quick filter bar", - "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.filter_bar.advanced": "Vis alle kategorier", + "notifications.column_settings.filter_bar.category": "Hurtigfilter", + "notifications.column_settings.filter_bar.show": "Vis", "notifications.column_settings.follow": "Nye følgere:", - "notifications.column_settings.mention": "Omtale:", - "notifications.column_settings.poll": "Poll results:", - "notifications.column_settings.push": "Push notifikationer", - "notifications.column_settings.reblog": "Fremhævelser:", + "notifications.column_settings.mention": "Statusser der nævner dig:", + "notifications.column_settings.poll": "Afstemningsresultat:", + "notifications.column_settings.push": "Pushnotifikationer", + "notifications.column_settings.reblog": "Boosts:", "notifications.column_settings.show": "Vis i kolonne", "notifications.column_settings.sound": "Afspil lyd", "notifications.filter.all": "Alle", "notifications.filter.boosts": "Boosts", "notifications.filter.favourites": "Favoritter", "notifications.filter.follows": "Følger", - "notifications.filter.mentions": "Mentions", - "notifications.filter.polls": "Poll results", + "notifications.filter.mentions": "Statusser der nævner dig", + "notifications.filter.polls": "Afstemningsresultat", "notifications.group": "{count} notifikationer", - "poll.closed": "Closed", - "poll.refresh": "Refresh", - "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", - "poll.vote": "Vote", - "poll_button.add_poll": "Add a poll", - "poll_button.remove_poll": "Remove poll", - "privacy.change": "Ændre status privatliv", - "privacy.direct.long": "Post til kun de nævnte brugere", + "poll.closed": "Lukket", + "poll.refresh": "Opdatér", + "poll.total_votes": "{count, plural, one {# stemme} other {# stemmer}}", + "poll.vote": "Stem", + "poll_button.add_poll": "Tilføj en afstemning", + "poll_button.remove_poll": "Fjern afstemning", + "privacy.change": "Skift status visningsindstillinger", + "privacy.direct.long": "Udgiv kun til nævnte brugere", "privacy.direct.short": "Direkte", - "privacy.private.long": "Post kun til følgere", + "privacy.private.long": "Udgiv kun til følgere", "privacy.private.short": "Kun for følgere", - "privacy.public.long": "Post til offentlige tidslinjer", + "privacy.public.long": "Udgiv på offentlige tidslinjer", "privacy.public.short": "Offentligt", - "privacy.unlisted.long": "Post ikke til offentlige tidslinjer", + "privacy.unlisted.long": "Udgiv ikke på offentlige tidslinjer", "privacy.unlisted.short": "Ikke listet", "regeneration_indicator.label": "Indlæser…", "regeneration_indicator.sublabel": "Din startside er ved at blive forberedt!", @@ -305,32 +316,32 @@ "reply_indicator.cancel": "Annuller", "report.forward": "Videresend til {target}", "report.forward_hint": "Kontoen er fra en anden server. Vil du også sende en anonym kopi af anmeldelsen dertil?", - "report.hint": "Anmeldelsen vil blive sendt til moderatorene af din instans. Du kan give en forklaring for hvorfor du anmelder denne konto nedenfor:", + "report.hint": "Anmeldelsen vil blive sendt til moderatorene af din instans. Du kan give en forklaring på hvorfor du anmelder denne konto nedenfor:", "report.placeholder": "Yderligere kommentarer", "report.submit": "Indsend", "report.target": "Anmelder {target}", "search.placeholder": "Søg", "search_popout.search_format": "Avanceret søgeformat", - "search_popout.tips.full_text": "Simpel tekst returnerer statusser du har skrevet, favoriseret, fremhævet, eller er blevet nævnt i, lige så vel som matchende brugernavne, visningsnavne, og hashtags.", - "search_popout.tips.hashtag": "emnetag", + "search_popout.tips.full_text": "Simpel tekst returnerer statusser du har skrevet, favoriseret, boostet, eller er blevet nævnt i såvel som matchende brugernavne, profilnavne, og hashtags.", + "search_popout.tips.hashtag": "hashtag", "search_popout.tips.status": "status", - "search_popout.tips.text": "Simpelt tekst returnerer passende visningsnavne, brugernavne og hashtags", + "search_popout.tips.text": "Simpel tekst returnerer matchende profilnavne, brugernavne og hashtags", "search_popout.tips.user": "bruger", - "search_results.accounts": "Folk", - "search_results.hashtags": "Emnetags", + "search_results.accounts": "Personer", + "search_results.hashtags": "Hashtags", "search_results.statuses": "Trut", - "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", - "search_results.total": "{count, number} {count, plural, et {result} andre {results}}", - "status.admin_account": "Open moderation interface for @{name}", - "status.admin_status": "Open this status in the moderation interface", + "search_results.statuses_fts_disabled": "Denne Mastodonserver har ikke aktiveret for søgning af statusser via deres indhold.", + "search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}", + "status.admin_account": "Åben modereringsvisning for @{name}", + "status.admin_status": "Åben denne status i modereringsvisningen", "status.block": "Bloker @{name}", - "status.cancel_reblog_private": "Fremhæv ikke længere", - "status.cannot_reblog": "Denne post kan ikke fremhæves", - "status.copy": "Copy link to status", + "status.cancel_reblog_private": "Fjern boost", + "status.cannot_reblog": "Denne post kan ikke boostes", + "status.copy": "Kopiér link til status", "status.delete": "Slet", "status.detailed_status": "Detaljeret visning af samtale", "status.direct": "Send direkte besked til @{name}", - "status.embed": "Indlejre", + "status.embed": "Integrér", "status.favourite": "Favorit", "status.filtered": "Filtreret", "status.load_more": "Indlæs mere", @@ -343,13 +354,13 @@ "status.pin": "Fastgør til profil", "status.pinned": "Fastgjort trut", "status.read_more": "Læs mere", - "status.reblog": "Fremhæv", - "status.reblog_private": "Fremhæv til oprindeligt publikum", - "status.reblogged_by": "{name} fremhævede", - "status.reblogs.empty": "Der er endnu ingen der har fremhævet dette trut. Når der er nogen der gør, vil det blive vist her.", + "status.reblog": "Boost", + "status.reblog_private": "Boost til det oprindelige publikum", + "status.reblogged_by": "{name} boostede", + "status.reblogs.empty": "Der er endnu ingen der har boostet dette trut. Når der er nogen der gør, vil det blive vist her.", "status.redraft": "Slet og omskriv", - "status.reply": "Svar", - "status.replyAll": "Svar samtale", + "status.reply": "Besvar", + "status.replyAll": "Besvar samtale", "status.report": "Anmeld @{name}", "status.sensitive_warning": "Følsomt indhold", "status.share": "Del", @@ -357,41 +368,42 @@ "status.show_less_all": "Vis mindre for alle", "status.show_more": "Vis mere", "status.show_more_all": "Vis mere for alle", - "status.show_thread": "Show thread", - "status.unmute_conversation": "Fjern dæmpningen fra samtale", - "status.unpin": "Fjern som fastgjort fra profil", - "suggestions.dismiss": "Dismiss suggestion", - "suggestions.header": "You might be interested in…", + "status.show_thread": "Vis tråd", + "status.uncached_media_warning": "Ikke tilgængelig", + "status.unmute_conversation": "Genaktivér samtale", + "status.unpin": "Frigør fra profil", + "suggestions.dismiss": "Afvis foreslag", + "suggestions.header": "Du er måske interesseret i…", "tabs_bar.federated_timeline": "Fælles", "tabs_bar.home": "Hjem", "tabs_bar.local_timeline": "Lokal", "tabs_bar.notifications": "Notifikationer", "tabs_bar.search": "Søg", - "time_remaining.days": "{number, plural, one {# day} other {# days}} left", - "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left", - "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", - "time_remaining.moments": "Moments remaining", - "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", - "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} snakker", - "trends.refresh": "Refresh", + "time_remaining.days": "{number, plural, one {# dag} other {# dage}} tilbage", + "time_remaining.hours": "{number, plural, one {# time} other {# timer}} tilbage", + "time_remaining.minutes": "{number, plural, one {# minut} other {# minutter}} tilbage", + "time_remaining.moments": "Få øjeblikke tilbage", + "time_remaining.seconds": "{number, plural, one {# sekund} other {# sekunder}} tilbage", + "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {personer}} snakker", + "trends.trending_now": "Hot lige nu", "ui.beforeunload": "Din kladde vil gå tabt hvis du forlader Mastodon.", "upload_area.title": "Træk og slip for at uploade", "upload_button.label": "Tilføj medie (JPEG, PNG, GIF, WebM, MP4, MOV)", - "upload_error.limit": "File upload limit exceeded.", - "upload_error.poll": "File upload not allowed with polls.", - "upload_form.description": "Beskriv for de svagtseende", - "upload_form.edit": "Edit", + "upload_error.limit": "Uploadgrænse overskredet.", + "upload_error.poll": "Filupload ikke tilladt sammen med afstemninger.", + "upload_form.description": "Beskriv for svagtseende", + "upload_form.edit": "Redigér", "upload_form.undo": "Slet", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Analyserer billede…", + "upload_modal.apply": "Anvend", + "upload_modal.description_placeholder": "En hurtig brun ræv hopper over den dovne hund", + "upload_modal.detect_text": "Find tekst i billede på automatisk vis", + "upload_modal.edit_media": "Redigér medie", + "upload_modal.hint": "Klik eller træk cirklen på billedet for at vælge et fokuspunkt.", + "upload_modal.preview_label": "Forhåndsvisning ({ratio})", "upload_progress.label": "Uploader...", "video.close": "Luk video", - "video.exit_fullscreen": "Gå ud af fuldskærm", + "video.exit_fullscreen": "Forlad fuldskærm", "video.expand": "Udvid video", "video.fullscreen": "Fuldskærm", "video.hide": "Skjul video", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 28b41baf7..845bc5156 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -16,6 +16,7 @@ "account.follows.empty": "Dieses Profil folgt noch niemandem.", "account.follows_you": "Folgt dir", "account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen", + "account.last_status": "Zuletzt aktiv", "account.link_verified_on": "Besitz dieses Links wurde geprüft am {date}", "account.locked_info": "Der Privatsphärenstatus dieses Accounts wurde auf gesperrt gesetzt. Die Person bestimmt manuell wer ihm/ihr folgen darf.", "account.media": "Medien", @@ -24,6 +25,7 @@ "account.mute": "@{name} stummschalten", "account.mute_notifications": "Benachrichtigungen von @{name} verbergen", "account.muted": "Stummgeschaltet", + "account.never_active": "Nie", "account.posts": "Beiträge", "account.posts_with_replies": "Beiträge und Antworten", "account.report": "@{name} melden", @@ -36,6 +38,8 @@ "account.unfollow": "Entfolgen", "account.unmute": "@{name} nicht mehr stummschalten", "account.unmute_notifications": "Benachrichtigungen von @{name} einschalten", + "alert.rate_limited.message": "Bitte versuche es nach {retry_time, time, medium}.", + "alert.rate_limited.title": "Anfragelimit überschritten", "alert.unexpected.message": "Ein unerwarteter Fehler ist aufgetreten.", "alert.unexpected.title": "Hoppla!", "autosuggest_hashtag.per_week": "{count} pro Woche", @@ -49,6 +53,7 @@ "column.blocks": "Blockierte Profile", "column.community": "Lokale Zeitleiste", "column.direct": "Direktnachrichten", + "column.directory": "Profile durchsuchen", "column.domain_blocks": "Versteckte Domains", "column.favourites": "Favoriten", "column.follow_requests": "Folgeanfragen", @@ -58,6 +63,7 @@ "column.notifications": "Mitteilungen", "column.pins": "Angeheftete Beiträge", "column.public": "Föderierte Zeitleiste", + "column.status": "Toot", "column_back_button.label": "Zurück", "column_header.hide_settings": "Einstellungen verbergen", "column_header.moveLeft_settings": "Spalte nach links verschieben", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Bist du dir sicher, dass du diese Liste permanent löschen möchtest?", "confirmations.domain_block.confirm": "Die ganze Domain verbergen", "confirmations.domain_block.message": "Bist du dir wirklich sicher, dass du die ganze Domain {domain} blockieren willst? In den meisten Fällen reichen ein paar gezielte Blockierungen oder Stummschaltungen aus. Nach der Blockierung wirst du nichts mehr von dieser Domain in öffentlichen Zeitleisten oder Benachrichtigungen sehen. Deine Folger_innen von dieser Domain werden auch entfernt.", + "confirmations.logout.confirm": "Abmelden", + "confirmations.logout.message": "Bist du sicher, dass du dich abmelden möchtest?", "confirmations.mute.confirm": "Stummschalten", "confirmations.mute.message": "Bist du dir sicher, dass du {name} stummschalten möchtest?", "confirmations.redraft.confirm": "Löschen und neu erstellen", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Wenn du jetzt antwortest wird es die gesamte Nachricht verwerfen, die du gerade schreibst. Möchtest du wirklich fortfahren?", "confirmations.unfollow.confirm": "Entfolgen", "confirmations.unfollow.message": "Bist du dir sicher, dass du {name} entfolgen möchtest?", + "directory.federated": "Aus dem Fediverse", + "directory.local": "Nur von {domain}", + "directory.new_arrivals": "Neue Benutzer", + "directory.recently_active": "Kürzlich aktiv", "embed.instructions": "Du kannst diesen Beitrag auf deiner Webseite einbetten, indem du den folgenden Code einfügst.", "embed.preview": "So wird es aussehen:", "emoji_button.activity": "Aktivitäten", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Einfach", "home.column_settings.show_reblogs": "Geteilte Beiträge anzeigen", "home.column_settings.show_replies": "Antworten anzeigen", - "home.column_settings.update_live": "In Echtzeit aktualisieren", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# Tag} other {# Tage}}", "intervals.full.hours": "{number, plural, one {# Stunde} other {# Stunden}}", "intervals.full.minutes": "{number, plural, one {# Minute} other {# Minuten}}", @@ -250,10 +262,9 @@ "navigation_bar.personal": "Persönlich", "navigation_bar.pins": "Angeheftete Beiträge", "navigation_bar.preferences": "Einstellungen", - "navigation_bar.profile_directory": "Profilverzeichnis", "navigation_bar.public_timeline": "Föderierte Zeitleiste", "navigation_bar.security": "Sicherheit", - "notification.and_n_others": "und {count, plural, one {# andere Person} other {# andere Personen}}", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} hat deinen Beitrag favorisiert", "notification.follow": "{name} folgt dir", "notification.mention": "{name} hat dich erwähnt", @@ -358,6 +369,7 @@ "status.show_more": "Mehr anzeigen", "status.show_more_all": "Alle Inhaltswarnungen aufklappen", "status.show_thread": "Zeige Konversation", + "status.uncached_media_warning": "Nicht verfügbar", "status.unmute_conversation": "Stummschaltung von Konversation aufheben", "status.unpin": "Vom Profil lösen", "suggestions.dismiss": "Empfehlung ausblenden", @@ -373,7 +385,7 @@ "time_remaining.moments": "Schließt in Kürze", "time_remaining.seconds": "{number, plural, one {# Sekunde} other {# Sekunden}} verbleibend", "trends.count_by_accounts": "{count} {rawCount, plural, eine {Person} other {Personen}} reden darüber", - "trends.refresh": "Aktualisieren", + "trends.trending_now": "In den Trends", "ui.beforeunload": "Dein Entwurf geht verloren, wenn du Mastodon verlässt.", "upload_area.title": "Zum Hochladen hereinziehen", "upload_button.label": "Mediendatei hinzufügen ({formats})", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 9cb4b74a7..0d682c983 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -1132,6 +1132,15 @@ { "descriptors": [ { + "defaultMessage": "Uploading...", + "id": "upload_progress.label" + } + ], + "path": "app/javascript/mastodon/features/compose/components/upload_progress.json" + }, + { + "descriptors": [ + { "defaultMessage": "Delete", "id": "upload_form.undo" }, @@ -1572,10 +1581,6 @@ { "descriptors": [ { - "defaultMessage": "Basic", - "id": "home.column_settings.basic" - }, - { "defaultMessage": "Show boosts", "id": "home.column_settings.show_reblogs" }, @@ -1957,6 +1962,14 @@ "id": "notifications.column_settings.push" }, { + "defaultMessage": "Basic", + "id": "home.column_settings.basic" + }, + { + "defaultMessage": "Update in real-time", + "id": "home.column_settings.update_live" + }, + { "defaultMessage": "Quick filter bar", "id": "notifications.column_settings.filter_bar.category" }, @@ -2015,6 +2028,10 @@ { "descriptors": [ { + "defaultMessage": "and {count, plural, one {# other} other {# others}}", + "id": "notification.and_n_others" + }, + { "defaultMessage": "{name} followed you", "id": "notification.follow" }, @@ -2271,6 +2288,10 @@ "id": "confirmations.block.block_and_report" }, { + "defaultMessage": "Toot", + "id": "column.status" + }, + { "defaultMessage": "Are you sure you want to block {name}?", "id": "confirmations.block.message" } diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 68c59817f..bdd1da36c 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -4,7 +4,7 @@ "account.block": "Αποκλισμός @{name}", "account.block_domain": "Απόκρυψε τα πάντα από το {domain}", "account.blocked": "Αποκλεισμένος/η", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Ακύρωση αιτήματος παρακολούθησης", "account.direct": "Προσωπικό μήνυμα προς @{name}", "account.domain_blocked": "Κρυμμένος τομέας", "account.edit_profile": "Επεξεργασία προφίλ", @@ -16,6 +16,7 @@ "account.follows.empty": "Αυτός ο χρήστης δεν ακολουθεί κανέναν ακόμα.", "account.follows_you": "Σε ακολουθεί", "account.hide_reblogs": "Απόκρυψη προωθήσεων από @{name}", + "account.last_status": "Τελευταία δραστηριότητα", "account.link_verified_on": "Η ιδιοκτησία αυτού του συνδέσμου ελέχθηκε την {date}", "account.locked_info": "Η κατάσταση απορρήτου αυτού του λογαριασμού είναι κλειδωμένη. Ο ιδιοκτήτης επιβεβαιώνει χειροκίνητα ποιος μπορεί να τον ακολουθήσει.", "account.media": "Πολυμέσα", @@ -24,6 +25,7 @@ "account.mute": "Σώπασε @{name}", "account.mute_notifications": "Σώπασε τις ειδοποιήσεις από @{name}", "account.muted": "Αποσιωπημένος/η", + "account.never_active": "Ποτέ", "account.posts": "Τουτ", "account.posts_with_replies": "Τουτ και απαντήσεις", "account.report": "Κατάγγειλε @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Διακοπή παρακολούθησης", "account.unmute": "Διακοπή αποσιώπησης @{name}", "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}", + "alert.rate_limited.message": "Παρακαλούμε δοκίμασε ξανά αφού περάσει η {retry_time, time, medium}.", + "alert.rate_limited.title": "Περιορισμός συχνότητας", "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.", "alert.unexpected.title": "Εεπ!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} ανα εβδομάδα", "boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις αυτό την επόμενη φορά", "bundle_column_error.body": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.", "bundle_column_error.retry": "Δοκίμασε ξανά", @@ -49,6 +53,7 @@ "column.blocks": "Αποκλεισμένοι χρήστες", "column.community": "Τοπική ροή", "column.direct": "Προσωπικά μηνύματα", + "column.directory": "Δες προφίλ", "column.domain_blocks": "Κρυμμένοι τομείς", "column.favourites": "Αγαπημένα", "column.follow_requests": "Αιτήματα ακολούθησης", @@ -58,6 +63,7 @@ "column.notifications": "Ειδοποιήσεις", "column.pins": "Καρφιτσωμένα τουτ", "column.public": "Ομοσπονδιακή ροή", + "column.status": "Toot", "column_back_button.label": "Πίσω", "column_header.hide_settings": "Απόκρυψη ρυθμίσεων", "column_header.moveLeft_settings": "Μεταφορά κολώνας αριστερά", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Σίγουρα θες να διαγράψεις οριστικά αυτή τη λίστα;", "confirmations.domain_block.confirm": "Απόκρυψη ολόκληρου του τομέα", "confirmations.domain_block.message": "Σίγουρα θες να μπλοκάρεις ολόκληρο το {domain}; Συνήθως μερικά εστιασμένα μπλοκ ή αποσιωπήσεις επαρκούν και προτιμούνται. Δεν θα βλέπεις περιεχόμενο από αυτό τον κόμβο σε καμία δημόσια ροή, ούτε στις ειδοποιήσεις σου. Όσους ακόλουθους έχεις αυτό αυτό τον κόμβο θα αφαιρεθούν.", + "confirmations.logout.confirm": "Αποσύνδεση", + "confirmations.logout.message": "Σίγουρα θέλεις να αποσυνδεθείς;", "confirmations.mute.confirm": "Αποσιώπηση", "confirmations.mute.message": "Σίγουρα θες να αποσιωπήσεις {name};", "confirmations.redraft.confirm": "Διαγραφή & ξαναγράψιμο", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Απαντώντας τώρα θα αντικαταστήσεις το κείμενο που ήδη γράφεις. Σίγουρα θέλεις να συνεχίσεις;", "confirmations.unfollow.confirm": "Διακοπή παρακολούθησης", "confirmations.unfollow.message": "Σίγουρα θες να πάψεις να ακολουθείς τον/την {name};", + "directory.federated": "Από το γνωστό fediverse", + "directory.local": "Μόνο από {domain}", + "directory.new_arrivals": "Νέες αφίξεις", + "directory.recently_active": "Πρόσφατα ενεργοί", "embed.instructions": "Ενσωματώστε αυτή την κατάσταση στην ιστοσελίδα σας αντιγράφοντας τον παρακάτω κώδικα.", "embed.preview": "Ορίστε πως θα φαίνεται:", "emoji_button.activity": "Δραστηριότητα", @@ -155,10 +167,10 @@ "hashtag.column_settings.tag_mode.any": "Οποιοδήποτε από αυτά", "hashtag.column_settings.tag_mode.none": "Κανένα από αυτά", "hashtag.column_settings.tag_toggle": "Προσθήκη επιπλέον ταμπελών για την κολώνα", - "home.column_settings.basic": "Βασικά", + "home.column_settings.basic": "Βασικές ρυθμίσεις", "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων", "home.column_settings.show_replies": "Εμφάνιση απαντήσεων", - "home.column_settings.update_live": "Ζωντανή ενημέρωση", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# μέρα} other {# μέρες}}", "intervals.full.hours": "{number, plural, one {# ώρα} other {# ώρες}}", "intervals.full.minutes": "{number, plural, one {# λεπτό} other {# λεπτά}}", @@ -241,7 +253,7 @@ "navigation_bar.favourites": "Αγαπημένα", "navigation_bar.filters": "Αποσιωπημένες λέξεις", "navigation_bar.follow_requests": "Αιτήματα ακολούθησης", - "navigation_bar.follows_and_followers": "Ακολουθεί και ακολουθείται", + "navigation_bar.follows_and_followers": "Ακολουθείς και σε ακολουθούν", "navigation_bar.info": "Πληροφορίες κόμβου", "navigation_bar.keyboard_shortcuts": "Συντομεύσεις", "navigation_bar.lists": "Λίστες", @@ -250,14 +262,13 @@ "navigation_bar.personal": "Προσωπικά", "navigation_bar.pins": "Καρφιτσωμένα τουτ", "navigation_bar.preferences": "Προτιμήσεις", - "navigation_bar.profile_directory": "Κατάλογος λογαριασμών", "navigation_bar.public_timeline": "Ομοσπονδιακή ροή", "navigation_bar.security": "Ασφάλεια", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "Ο/Η {name} σημείωσε ως αγαπημένη την κατάστασή σου", "notification.follow": "Ο/Η {name} σε ακολούθησε", "notification.mention": "Ο/Η {name} σε ανέφερε", - "notification.poll": "Έλαβε τέλος μια από τις ψηφοφορίες που συμμετείχες", + "notification.poll": "Τελείωσε μια από τις ψηφοφορίες που συμμετείχες", "notification.reblog": "Ο/Η {name} προώθησε την κατάστασή σου", "notifications.clear": "Καθαρισμός ειδοποιήσεων", "notifications.clear_confirmation": "Σίγουρα θέλεις να καθαρίσεις όλες τις ειδοποιήσεις σου;", @@ -358,13 +369,14 @@ "status.show_more": "Δείξε περισσότερα", "status.show_more_all": "Δείξε περισσότερα για όλα", "status.show_thread": "Εμφάνιση νήματος", + "status.uncached_media_warning": "Μη διαθέσιμα", "status.unmute_conversation": "Διέκοψε την αποσιώπηση της συζήτησης", "status.unpin": "Ξεκαρφίτσωσε από το προφίλ", "suggestions.dismiss": "Απόρριψη πρότασης", "suggestions.header": "Ίσως να ενδιαφέρεσαι για…", "tabs_bar.federated_timeline": "Ομοσπονδιακή", "tabs_bar.home": "Αρχική", - "tabs_bar.local_timeline": "Τοπικά", + "tabs_bar.local_timeline": "Τοπική", "tabs_bar.notifications": "Ειδοποιήσεις", "tabs_bar.search": "Αναζήτηση", "time_remaining.days": "απομένουν {number, plural, one {# ημέρα} other {# ημέρες}}", @@ -373,22 +385,22 @@ "time_remaining.moments": "Απομένουν στιγμές", "time_remaining.seconds": "απομένουν {number, plural, one {# δευτερόλεπτο} other {# δευτερόλεπτα}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} μιλάνε", - "trends.refresh": "Refresh", + "trends.trending_now": "Δημοφιλή τώρα", "ui.beforeunload": "Το προσχέδιό σου θα χαθεί αν φύγεις από το Mastodon.", "upload_area.title": "Drag & drop για να ανεβάσεις", "upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "Υπέρβαση ορίου μεγέθους ανεβασμένων αρχείων.", "upload_error.poll": "Στις δημοσκοπήσεις δεν επιτρέπεται η μεταφόρτωση αρχείου.", "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης", - "upload_form.edit": "Edit", + "upload_form.edit": "Ενημέρωση", "upload_form.undo": "Διαγραφή", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Ανάλυση εικόνας…", + "upload_modal.apply": "Εφαρμογή", + "upload_modal.description_placeholder": "Λύκος μαύρος και ισχνός του πατέρα του καημός", + "upload_modal.detect_text": "Αναγνώριση κειμένου από την εικόνα", + "upload_modal.edit_media": "Επεξεργασία Πολυμέσων", + "upload_modal.hint": "Κάνε κλικ ή σείρε τον κύκλο στην προεπισκόπηση για να επιλέξεις το σημείο εστίασης που θα είναι πάντα εμφανές σε όλες τις μικρογραφίες.", + "upload_modal.preview_label": "Προεπισκόπηση ({ratio})", "upload_progress.label": "Ανεβαίνει...", "video.close": "Κλείσε το βίντεο", "video.exit_fullscreen": "Έξοδος από πλήρη οθόνη", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 260b43c53..15c579d51 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -63,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pinned toots", "column.public": "Federated timeline", + "column.status": "Toot", "column_back_button.label": "Back", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -173,6 +174,7 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_replies": "Show replies", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# day} other {# days}}", "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -267,6 +269,7 @@ "navigation_bar.preferences": "Preferences", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} favourited your status", "notification.follow": "{name} followed you", "notification.mention": "{name} mentioned you", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 763c31bb8..31750050e 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -4,7 +4,7 @@ "account.block": "Bloki @{name}", "account.block_domain": "Kaŝi ĉion de {domain}", "account.blocked": "Blokita", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Nuligi peto de sekvado", "account.direct": "Rekte mesaĝi @{name}", "account.domain_blocked": "Domajno kaŝita", "account.edit_profile": "Redakti profilon", @@ -16,6 +16,7 @@ "account.follows.empty": "Tiu uzanto ankoraŭ ne sekvas iun.", "account.follows_you": "Sekvas vin", "account.hide_reblogs": "Kaŝi diskonigojn de @{name}", + "account.last_status": "Lasta aktiva", "account.link_verified_on": "La posedanto de tiu ligilo estis kontrolita je {date}", "account.locked_info": "La privateco de tiu konto estas elektita kiel fermita. La posedanto povas mane akcepti tiun, kiu povas sekvi rin.", "account.media": "Aŭdovidaĵoj", @@ -24,6 +25,7 @@ "account.mute": "Silentigi @{name}", "account.mute_notifications": "Silentigi sciigojn el @{name}", "account.muted": "Silentigita", + "account.never_active": "Neniam", "account.posts": "Mesaĝoj", "account.posts_with_replies": "Kun respondoj", "account.report": "Signali @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Ne plu sekvi", "account.unmute": "Malsilentigi @{name}", "account.unmute_notifications": "Malsilentigi sciigojn de @{name}", + "alert.rate_limited.message": "Bonvolu reprovi poste {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Neatendita eraro okazis.", "alert.unexpected.title": "Ups!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} semajne", "boost_modal.combo": "Vi povas premi {combo} por preterpasi sekvafoje", "bundle_column_error.body": "Io misfunkciis en la ŝargado de ĉi tiu elemento.", "bundle_column_error.retry": "Bonvolu reprovi", @@ -49,6 +53,7 @@ "column.blocks": "Blokitaj uzantoj", "column.community": "Loka tempolinio", "column.direct": "Rektaj mesaĝoj", + "column.directory": "Browse profiles", "column.domain_blocks": "Kaŝitaj domajnoj", "column.favourites": "Stelumoj", "column.follow_requests": "Petoj de sekvado", @@ -58,6 +63,7 @@ "column.notifications": "Sciigoj", "column.pins": "Alpinglitaj mesaĝoj", "column.public": "Fratara tempolinio", + "column.status": "Toot", "column_back_button.label": "Reveni", "column_header.hide_settings": "Kaŝi agordojn", "column_header.moveLeft_settings": "Movi kolumnon maldekstren", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ĉu vi certas, ke vi volas porĉiame forigi ĉi tiun liston?", "confirmations.domain_block.confirm": "Kaŝi la tutan domajnon", "confirmations.domain_block.message": "Ĉu vi vere, vere certas, ke vi volas tute bloki {domain}? Plej ofte, trafa blokado kaj silentigado sufiĉas kaj preferindas. Vi ne vidos enhavon de tiu domajno en publika tempolinio aŭ en viaj sciigoj. Viaj sekvantoj de tiu domajno estos forigitaj.", + "confirmations.logout.confirm": "Elsaluti", + "confirmations.logout.message": "Ĉu vi certas ke vi volas elsaluti?", "confirmations.mute.confirm": "Silentigi", "confirmations.mute.message": "Ĉu vi certas, ke vi volas silentigi {name}?", "confirmations.redraft.confirm": "Forigi kaj reskribi", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Respondi nun anstataŭigos la mesaĝon, kiun vi nun skribas. Ĉu vi certas, ke vi volas daŭrigi?", "confirmations.unfollow.confirm": "Ne plu sekvi", "confirmations.unfollow.message": "Ĉu vi certas, ke vi volas ĉesi sekvi {name}?", + "directory.federated": "El konata fediverso", + "directory.local": "Nur de {domain}", + "directory.new_arrivals": "Novaj veniĝoj", + "directory.recently_active": "Recently active", "embed.instructions": "Enkorpigu ĉi tiun mesaĝon en vian retejon per kopio de la suba kodo.", "embed.preview": "Ĝi aperos tiel:", "emoji_button.activity": "Agadoj", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Bazaj agordoj", "home.column_settings.show_reblogs": "Montri diskonigojn", "home.column_settings.show_replies": "Montri respondojn", - "home.column_settings.update_live": "Ĝisdatigo en realtempa", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# tago} other {# tagoj}}", "intervals.full.hours": "{number, plural, one {# horo} other {# horoj}}", "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutoj}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Persone", "navigation_bar.pins": "Alpinglitaj mesaĝoj", "navigation_bar.preferences": "Preferoj", - "navigation_bar.profile_directory": "Profilujo", "navigation_bar.public_timeline": "Fratara tempolinio", "navigation_bar.security": "Sekureco", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Grandigi", "status.show_more_all": "Grandigi ĉiujn", "status.show_thread": "Montri la fadenon", + "status.uncached_media_warning": "Nedisponebla", "status.unmute_conversation": "Malsilentigi la konversacion", "status.unpin": "Depingli de profilo", "suggestions.dismiss": "Forigi la proponon", @@ -373,22 +385,22 @@ "time_remaining.moments": "Momenteto restas", "time_remaining.seconds": "{number, plural, one {# sekundo} other {# sekundoj}} restas", "trends.count_by_accounts": "{count} {rawCount, plural, one {persono} other {personoj}} parolas", - "trends.refresh": "Refresh", + "trends.trending_now": "Nunaj furoraĵoj", "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.", "upload_area.title": "Altreni kaj lasi por alŝuti", "upload_button.label": "Aldoni aŭdovidaĵon (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "Limo de dosiera alŝutado transpasita.", "upload_error.poll": "Alŝuto de dosiero ne permesita kun balotenketo.", "upload_form.description": "Priskribi por misvidantaj homoj", - "upload_form.edit": "Edit", + "upload_form.edit": "Redakti", "upload_form.undo": "Forigi", "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.apply": "Apliki", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.edit_media": "Redakti aŭdvidaĵo", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.preview_label": "Antaŭvido ({ratio})", "upload_progress.label": "Alŝutado…", "video.close": "Fermi videon", "video.exit_fullscreen": "Eksigi plenekrana", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 415faf509..a033f6e1f 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -4,7 +4,7 @@ "account.block": "Bloquear a @{name}", "account.block_domain": "Ocultar todo de {domain}", "account.blocked": "Bloqueado", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Cancelar la solicitud de seguimiento", "account.direct": "Mensaje directo a @{name}", "account.domain_blocked": "Dominio oculto", "account.edit_profile": "Editar perfil", @@ -16,6 +16,7 @@ "account.follows.empty": "Este usuario todavía no sigue a nadie.", "account.follows_you": "Te sigue", "account.hide_reblogs": "Ocultar retoots de @{name}", + "account.last_status": "Última actividad", "account.link_verified_on": "El proprietario de este link fue comprobado el {date}", "account.locked_info": "El estado de privacidad de esta cuenta està configurado como bloqueado. El proprietario debe revisar manualmente quien puede seguirle.", "account.media": "Multimedia", @@ -24,6 +25,7 @@ "account.mute": "Silenciar a @{name}", "account.mute_notifications": "Silenciar notificaciones de @{name}", "account.muted": "Silenciado", + "account.never_active": "Nunca", "account.posts": "Toots", "account.posts_with_replies": "Toots con respuestas", "account.report": "Reportar a @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Dejar de seguir", "account.unmute": "Dejar de silenciar a @{name}", "account.unmute_notifications": "Dejar de silenciar las notificaciones de @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Tarifa limitada", "alert.unexpected.message": "Hubo un error inesperado.", "alert.unexpected.title": "¡Ups!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Usuarios bloqueados", "column.community": "Línea de tiempo local", "column.direct": "Mensajes directos", + "column.directory": "Buscar perfiles", "column.domain_blocks": "Dominios ocultados", "column.favourites": "Favoritos", "column.follow_requests": "Solicitudes de seguimiento", @@ -58,6 +63,7 @@ "column.notifications": "Notificaciones", "column.pins": "Toots fijados", "column.public": "Línea de tiempo federada", + "column.status": "Toot", "column_back_button.label": "Atrás", "column_header.hide_settings": "Ocultar configuración", "column_header.moveLeft_settings": "Mover columna a la izquierda", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "¿Seguro que quieres borrar esta lista permanentemente?", "confirmations.domain_block.confirm": "Ocultar dominio entero", "confirmations.domain_block.message": "¿Seguro de que quieres bloquear al dominio {domain} entero? En general unos cuantos bloqueos y silenciados concretos es suficiente y preferible.", + "confirmations.logout.confirm": "Cerrar sesión", + "confirmations.logout.message": "¿Estás seguro de querer cerrar la sesión?", "confirmations.mute.confirm": "Silenciar", "confirmations.mute.message": "¿Estás seguro de que quieres silenciar a {name}?", "confirmations.redraft.confirm": "Borrar y volver a borrador", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Responder sobrescribirá el mensaje que estás escribiendo. ¿Estás seguro de que deseas continuar?", "confirmations.unfollow.confirm": "Dejar de seguir", "confirmations.unfollow.message": "¿Estás seguro de que quieres dejar de seguir a {name}?", + "directory.federated": "Desde el fediverso conocido", + "directory.local": "Sólo de {domain}", + "directory.new_arrivals": "Recién llegados", + "directory.recently_active": "Recientemente activo", "embed.instructions": "Añade este toot a tu sitio web con el siguiente código.", "embed.preview": "Así es como se verá:", "emoji_button.activity": "Actividad", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Básico", "home.column_settings.show_reblogs": "Mostrar retoots", "home.column_settings.show_replies": "Mostrar respuestas", - "home.column_settings.update_live": "Actualizar en tiempo real", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# día} other {# días}}", "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}", "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Toots fijados", "navigation_bar.preferences": "Preferencias", - "navigation_bar.profile_directory": "Directorio de perfiles", "navigation_bar.public_timeline": "Historia federada", "navigation_bar.security": "Seguridad", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostrar más", "status.show_more_all": "Mostrar más para todo", "status.show_thread": "Ver hilo", + "status.uncached_media_warning": "No disponible", "status.unmute_conversation": "Dejar de silenciar conversación", "status.unpin": "Dejar de fijar", "suggestions.dismiss": "Descartar sugerencia", @@ -373,21 +385,21 @@ "time_remaining.moments": "Momentos restantes", "time_remaining.seconds": "{number, plural, one {# segundo restante} other {# segundos restantes}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {persona} other {personas}} hablando", - "trends.refresh": "Refresh", + "trends.trending_now": "Tendencia ahora", "ui.beforeunload": "Tu borrador se perderá si sales de Mastodon.", "upload_area.title": "Arrastra y suelta para subir", "upload_button.label": "Subir multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "Límite de subida de archivos excedido.", "upload_error.poll": "Subida de archivos no permitida con encuestas.", "upload_form.description": "Describir para los usuarios con dificultad visual", - "upload_form.edit": "Edit", + "upload_form.edit": "Editar", "upload_form.undo": "Borrar", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", + "upload_modal.analyzing_picture": "Analizando imagen…", + "upload_modal.apply": "Aplicar", + "upload_modal.description_placeholder": "Un rápido zorro marrón salta sobre el perro perezoso", + "upload_modal.detect_text": "Detectar texto de la imagen", + "upload_modal.edit_media": "Editar multimedia", + "upload_modal.hint": "Haga clic o arrastre el círculo en la vista previa para elegir el punto focal que siempre estará a la vista en todas las miniaturas.", "upload_modal.preview_label": "Preview ({ratio})", "upload_progress.label": "Subiendo…", "video.close": "Cerrar video", diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index 0d708eac2..1d1dfd35a 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -16,6 +16,7 @@ "account.follows.empty": "See kasutaja ei jälgi veel kedagi.", "account.follows_you": "Jälgib sind", "account.hide_reblogs": "Peida upitused kasutajalt @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Selle lingi autorsust kontrolliti {date}", "account.locked_info": "Selle konto privaatsus on lukustatud. Omanik vaatab manuaalselt üle, kes teda jägida saab.", "account.media": "Meedia", @@ -24,6 +25,7 @@ "account.mute": "Vaigista @{name}", "account.mute_notifications": "Vaigista teated kasutajalt @{name}", "account.muted": "Vaigistatud", + "account.never_active": "Never", "account.posts": "Tuututused", "account.posts_with_replies": "Tuututused ja vastused", "account.report": "Raporteeri @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Ära jälgi", "account.unmute": "Ära vaigista @{name}", "account.unmute_notifications": "Ära vaigista teateid kasutajalt @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Tekkis ootamatu viga.", "alert.unexpected.title": "Oih!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokeeritud kasutajad", "column.community": "Kohalik ajajoon", "column.direct": "Otsesõnumid", + "column.directory": "Browse profiles", "column.domain_blocks": "Peidetud domeenid", "column.favourites": "Lemmikud", "column.follow_requests": "Jälgimistaotlused", @@ -58,6 +63,7 @@ "column.notifications": "Teated", "column.pins": "Kinnitatud upitused", "column.public": "Föderatiivne ajajoon", + "column.status": "Toot", "column_back_button.label": "Tagasi", "column_header.hide_settings": "Peida sätted", "column_header.moveLeft_settings": "Liiguta tulp vasakule", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Oled kindel, et soovid selle nimekirja püsivalt kustutada?", "confirmations.domain_block.confirm": "Peida terve domeen", "confirmations.domain_block.message": "Oled ikka päris kindel, et soovid blokeerida terve {domain}? Enamikul juhtudel piisab mõnest sihitud blokist või vaigistusest, mis on eelistatav. Sa ei näe selle domeeni sisu üheski avalikus ajajoones või teadetes. Sinu jälgijad sellest domeenist eemaldatakse.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Vaigista", "confirmations.mute.message": "Oled kindel, et soovid {name} vaigistada?", "confirmations.redraft.confirm": "Kustuta & taasalusta", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Kohene vastamine kirjutab üle sõnumi, mida hetkel koostad. Oled kindel, et soovid jätkata?", "confirmations.unfollow.confirm": "Ära jälgi", "confirmations.unfollow.message": "Oled kindel, et ei soovi jälgida {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Manusta see staatus oma veebilehele, kopeerides alloleva koodi.", "embed.preview": "Nii näeb see välja:", "emoji_button.activity": "Tegevus", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Peamine", "home.column_settings.show_reblogs": "Näita upitusi", "home.column_settings.show_replies": "Näita vastuseid", - "home.column_settings.update_live": "Uuenda reaalajas", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# päev} other {# päevad}}", "intervals.full.hours": "{number, plural, one {# tund} other {# tundi}}", "intervals.full.minutes": "{number, plural, one {# minut} other {# minutit}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Isiklik", "navigation_bar.pins": "Kinnitatud tuutid", "navigation_bar.preferences": "Eelistused", - "navigation_bar.profile_directory": "Profiilikataloog", "navigation_bar.public_timeline": "Föderatiivne ajajoon", "navigation_bar.security": "Turvalisus", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Näita veel", "status.show_more_all": "Näita enam kõigile", "status.show_thread": "Kuva lõim", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Ära vaigista vestlust", "status.unpin": "Kinnita profiililt lahti", "suggestions.dismiss": "Eira soovitust", @@ -373,7 +385,7 @@ "time_remaining.moments": "Hetked jäänud", "time_remaining.seconds": "{number, plural, one {# sekund} other {# sekundit}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {inimene} other {inimesed}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Sinu mustand läheb kaotsi, kui lahkud Mastodonist.", "upload_area.title": "Lohista & aseta üleslaadimiseks", "upload_button.label": "Lisa meedia (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index da16bf669..f1fc17fdd 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -4,7 +4,7 @@ "account.block": "Blokeatu @{name}", "account.block_domain": "Ezkutatu {domain} domeinuko guztia", "account.blocked": "Blokeatuta", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Ezeztatu jarraitzeko eskaria", "account.direct": "Mezu zuzena @{name}(r)i", "account.domain_blocked": "Ezkutatutako domeinua", "account.edit_profile": "Aldatu profila", @@ -16,6 +16,7 @@ "account.follows.empty": "Erabiltzaile honek ez du inor jarraitzen oraindik.", "account.follows_you": "Jarraitzen dizu", "account.hide_reblogs": "Ezkutatu @{name}(r)en bultzadak", + "account.last_status": "Azkenekoz aktiboa", "account.link_verified_on": "Esteka honen jabetzaren egiaztaketa data: {date}", "account.locked_info": "Kontu honen pribatutasun egoera blokeatuta gisa ezarri da. Jabeak eskuz erabakitzen du nork jarraitu diezaioken.", "account.media": "Multimedia", @@ -24,6 +25,7 @@ "account.mute": "Mututu @{name}", "account.mute_notifications": "Mututu @{name}(r)en jakinarazpenak", "account.muted": "Mutututa", + "account.never_active": "Inoiz ez", "account.posts": "Toot", "account.posts_with_replies": "Toot eta erantzunak", "account.report": "Salatu @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Utzi jarraitzeari", "account.unmute": "Desmututu @{name}", "account.unmute_notifications": "Desmututu @{name}(r)en jakinarazpenak", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Ustekabeko errore bat gertatu da.", "alert.unexpected.title": "Ene!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} asteko", "boost_modal.combo": "{combo} sakatu dezakezu hurrengoan hau saltatzeko", "bundle_column_error.body": "Zerbait okerra gertatu da osagai hau kargatzean.", "bundle_column_error.retry": "Saiatu berriro", @@ -49,6 +53,7 @@ "column.blocks": "Blokeatutako erabiltzaileak", "column.community": "Denbora-lerro lokala", "column.direct": "Mezu zuzenak", + "column.directory": "Arakatu profilak", "column.domain_blocks": "Ezkutatutako domeinuak", "column.favourites": "Gogokoak", "column.follow_requests": "Jarraitzeko eskariak", @@ -58,6 +63,7 @@ "column.notifications": "Jakinarazpenak", "column.pins": "Pinned toot", "column.public": "Federatutako denbora-lerroa", + "column.status": "Toot", "column_back_button.label": "Atzera", "column_header.hide_settings": "Ezkutatu ezarpenak", "column_header.moveLeft_settings": "Eraman zutabea ezkerrera", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ziur behin betiko ezabatu nahi duzula zerrenda hau?", "confirmations.domain_block.confirm": "Ezkutatu domeinu osoa", "confirmations.domain_block.message": "Ziur, erabat ziur, {domain} domeinu osoa blokeatu nahi duzula? Gehienetan gutxi batzuk blokeatu edo mututzearekin nahikoa da. Ez duzu domeinu horretako edukirik ikusiko denbora lerroetan edo jakinarazpenetan. Domeinu horretako zure jarraitzaileak kenduko dira ere.", + "confirmations.logout.confirm": "Amaitu saioa", + "confirmations.logout.message": "Ziur saioa amaitu nahi duzula?", "confirmations.mute.confirm": "Mututu", "confirmations.mute.message": "Ziur {name} mututu nahi duzula?", "confirmations.redraft.confirm": "Ezabatu eta berridatzi", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Orain erantzuteak idazten ari zaren mezua gainidatziko du. Ziur jarraitu nahi duzula?", "confirmations.unfollow.confirm": "Utzi jarraitzeari", "confirmations.unfollow.message": "Ziur {name} jarraitzeari utzi nahi diozula?", + "directory.federated": "Fedibertso ezagunekoak", + "directory.local": "{domain} domeinukoak soilik", + "directory.new_arrivals": "Iritsi berriak", + "directory.recently_active": "Duela gutxi aktibo", "embed.instructions": "Txertatu mezu hau zure webgunean beheko kodea kopatuz.", "embed.preview": "Hau da izango duen itxura:", "emoji_button.activity": "Jarduera", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Oinarrizkoa", "home.column_settings.show_reblogs": "Erakutsi bultzadak", "home.column_settings.show_replies": "Erakutsi erantzunak", - "home.column_settings.update_live": "Eguneratu denbora errealean", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {egun #} other {# egun}}", "intervals.full.hours": "{number, plural, one {ordu #} other {# ordu}}", "intervals.full.minutes": "{number, plural, one {minutu #} other {# minutu}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Pertsonala", "navigation_bar.pins": "Finkatutako toot-ak", "navigation_bar.preferences": "Hobespenak", - "navigation_bar.profile_directory": "Profilen direktorioa", "navigation_bar.public_timeline": "Federatutako denbora-lerroa", "navigation_bar.security": "Segurtasuna", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Erakutsi gehiago", "status.show_more_all": "Erakutsi denetarik gehiago", "status.show_thread": "Erakutsi haria", + "status.uncached_media_warning": "Ez eskuragarri", "status.unmute_conversation": "Desmututu elkarrizketa", "status.unpin": "Desfinkatu profiletik", "suggestions.dismiss": "Errefusatu proposamena", @@ -373,22 +385,22 @@ "time_remaining.moments": "Amaitzekotan", "time_remaining.seconds": "{number, plural, one {segundo #} other {# segundo}} amaitzeko", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} hitz egiten", - "trends.refresh": "Refresh", + "trends.trending_now": "Joera orain", "ui.beforeunload": "Zure zirriborroa galduko da Mastodon uzten baduzu.", "upload_area.title": "Arrastatu eta jaregin igotzeko", "upload_button.label": "Gehitu multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "Fitxategi igoera muga gaindituta.", "upload_error.poll": "Ez da inkestetan fitxategiak igotzea onartzen.", "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat", - "upload_form.edit": "Edit", + "upload_form.edit": "Editatu", "upload_form.undo": "Ezabatu", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.analyzing_picture": "Irudia aztertzen…", + "upload_modal.apply": "Aplikatu", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.detect_text": "Antzeman irudiko testua", + "upload_modal.edit_media": "Editatu multimedia", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.preview_label": "Aurreikusi({ratio})", "upload_progress.label": "Igotzen...", "video.close": "Itxi bideoa", "video.exit_fullscreen": "Irten pantaila osotik", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 9804cd4c8..9382ec5ee 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -4,7 +4,7 @@ "account.block": "مسدودسازی @{name}", "account.block_domain": "پنهانسازی همه چیز از سرور {domain}", "account.blocked": "مسدودشده", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "لغو درخواست پیگیری", "account.direct": "پیغام خصوصی به @{name}", "account.domain_blocked": "دامین پنهانشده", "account.edit_profile": "ویرایش نمایه", @@ -16,7 +16,8 @@ "account.follows.empty": "این کاربر هنوز هیچ کسی را پی نمیگیرد.", "account.follows_you": "پیگیر شماست", "account.hide_reblogs": "پنهان کردن بازبوقهای @{name}", - "account.link_verified_on": "مالکیت این نشانی در تایخ {date} بررسی شد", + "account.last_status": "Last active", + "account.link_verified_on": "مالکیت این نشانی در تاریخ {date} بررسی شد", "account.locked_info": "این حساب خصوصی است. صاحب این حساب تصمیم میگیرد که چه کسی میتواند پیگیرش باشد.", "account.media": "عکس و ویدیو", "account.mention": "نامبردن از @{name}", @@ -24,6 +25,7 @@ "account.mute": "بیصدا کردن @{name}", "account.mute_notifications": "بیصداکردن اعلانها از طرف @{name}", "account.muted": "بیصداشده", + "account.never_active": "Never", "account.posts": "نوشتهها", "account.posts_with_replies": "نوشتهها و پاسخها", "account.report": "گزارش @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "پایان پیگیری", "account.unmute": "باصدا کردن @{name}", "account.unmute_notifications": "باصداکردن اعلانها از طرف @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "خطای پیشبینینشدهای رخ داد.", "alert.unexpected.title": "ای وای!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} در هفته", "boost_modal.combo": "دکمهٔ {combo} را بزنید تا دیگر این را نبینید", "bundle_column_error.body": "هنگام بازکردن این بخش خطایی رخ داد.", "bundle_column_error.retry": "تلاش دوباره", @@ -49,6 +53,7 @@ "column.blocks": "کاربران مسدودشده", "column.community": "نوشتههای محلی", "column.direct": "پیغامهای خصوصی", + "column.directory": "Browse profiles", "column.domain_blocks": "دامینهای پنهانشده", "column.favourites": "پسندیدهها", "column.follow_requests": "درخواستهای پیگیری", @@ -58,6 +63,7 @@ "column.notifications": "اعلانها", "column.pins": "نوشتههای ثابت", "column.public": "نوشتههای همهجا", + "column.status": "Toot", "column_back_button.label": "بازگشت", "column_header.hide_settings": "نهفتن تنظیمات", "column_header.moveLeft_settings": "انتقال ستون به راست", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "آیا واقعاً میخواهید این فهرست را برای همیشه پاک کنید؟", "confirmations.domain_block.confirm": "پنهانسازی کل دامین", "confirmations.domain_block.message": "آیا جدی جدی میخواهید کل دامین {domain} را مسدود کنید؟ بیشتر وقتها مسدودکردن یا بیصداکردن چند حساب کاربری خاص کافی است و توصیه میشود. پس از این کار شما هیچ نوشتهای را از این دامین در فهرست نوشتههای عمومی یا اعلانهایتان نخواهید دید. پیگیران شما از این دامین هم حذف خواهد شد.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "بیصدا کن", "confirmations.mute.message": "آیا واقعاً میخواهید {name} را بیصدا کنید؟", "confirmations.redraft.confirm": "پاککردن و بازنویسی", @@ -103,6 +111,10 @@ "confirmations.reply.message": "اگر الان پاسخ دهید، چیزی که در حال نوشتنش بودید پاک خواهد شد. آیا همین را میخواهید؟", "confirmations.unfollow.confirm": "لغو پیگیری", "confirmations.unfollow.message": "آیا واقعاً میخواهید به پیگیری از {name} پایان دهید؟", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "برای جاگذاری این نوشته در سایت خودتان، کد زیر را کپی کنید.", "embed.preview": "نوشتهٔ جاگذاریشده این گونه به نظر خواهد رسید:", "emoji_button.activity": "فعالیت", @@ -128,7 +140,7 @@ "empty_column.favourited_statuses": "شما هنوز هیچ بوقی را نپسندیدهاید. وقتی بوقی را بپسندید، اینجا نمایش خواهد یافت.", "empty_column.favourites": "هنوز هیچ کسی این بوق را نپسندیده است. وقتی کسی آن را بپسندد، نامش اینجا نمایش خواهد یافت.", "empty_column.follow_requests": "شما هنوز هیچ درخواست پیگیریای ندارید. وقتی چنین درخواستی بگیرید، اینجا نمایش خواهد یافت.", - "empty_column.hashtag": "هنوز هیچ چیزی با این هشتگ نیست.", + "empty_column.hashtag": "هنوز هیچ چیزی با این برچسب (هشتگ) نیست.", "empty_column.home": "شما هنوز پیگیر کسی نیستید. {public} را ببینید یا چیزی را جستجو کنید تا کاربران دیگر را ببینید.", "empty_column.home.public_timeline": "فهرست نوشتههای همهجا", "empty_column.list": "در این فهرست هنوز چیزی نیست. وقتی اعضای این فهرست چیزی بنویسند، اینجا ظاهر خواهد شد.", @@ -158,7 +170,7 @@ "home.column_settings.basic": "اصلی", "home.column_settings.show_reblogs": "نمایش بازبوقها", "home.column_settings.show_replies": "نمایش پاسخها", - "home.column_settings.update_live": "بهروزرسانی لحظهای", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# روز} other {# روز}}", "intervals.full.hours": "{number, plural, one {# ساعت} other {# ساعت}}", "intervals.full.minutes": "{number, plural, one {# دقیقه} other {# دقیقه}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "شخصی", "navigation_bar.pins": "نوشتههای ثابت", "navigation_bar.preferences": "ترجیحات", - "navigation_bar.profile_directory": "فهرست گزیدهٔ کاربران", "navigation_bar.public_timeline": "نوشتههای همهجا", "navigation_bar.security": "امنیت", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -312,12 +323,12 @@ "search.placeholder": "جستجو", "search_popout.search_format": "راهنمای جستجوی پیشرفته", "search_popout.tips.full_text": "جستجوی متنی ساده میتواند بوقهایی که شما نوشتهاید، پسندیدهاید، بازبوقیدهاید، یا در آنها از شما نام برده شده است را پیدا کند. همچنین نامهای کاربری، نام نمایشیافته، و هشتگها را هم شامل میشود.", - "search_popout.tips.hashtag": "هشتگ", + "search_popout.tips.hashtag": "برچسب", "search_popout.tips.status": "نوشته", - "search_popout.tips.text": "جستجوی متنی ساده برای نامها، نامهای کاربری، و هشتگها", + "search_popout.tips.text": "جستجوی متنی ساده برای نامها، نامهای کاربری، و برچسبها", "search_popout.tips.user": "کاربر", "search_results.accounts": "افراد", - "search_results.hashtags": "هشتگها", + "search_results.hashtags": "برچسبها", "search_results.statuses": "بوقها", "search_results.statuses_fts_disabled": "جستجوی محتوای بوقها در این سرور ماستدون ممکن نیست.", "search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}", @@ -358,6 +369,7 @@ "status.show_more": "نمایش", "status.show_more_all": "نمایش بیشتر همه", "status.show_thread": "نمایش گفتگو", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "باصداکردن گفتگو", "status.unpin": "برداشتن نوشتهٔ ثابت نمایه", "suggestions.dismiss": "پیشنهاد را نادیده بگیر", @@ -373,22 +385,22 @@ "time_remaining.moments": "زمان باقیمانده", "time_remaining.seconds": "{number, plural, one {# ثانیه} other {# ثانیه}} باقی مانده", "trends.count_by_accounts": "{count} {rawCount, plural, one {نفر نوشته است} other {نفر نوشتهاند}}", - "trends.refresh": "Refresh", + "trends.trending_now": "پرطرفدار", "ui.beforeunload": "اگر از ماستدون خارج شوید پیشنویس شما پاک خواهد شد.", "upload_area.title": "برای بارگذاری به اینجا بکشید", "upload_button.label": "افزودن عکس و ویدیو (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "از حد مجاز باگذاری فراتر رفتید.", "upload_error.poll": "باگذاری پرونده در نظرسنجیها ممکن نیست.", "upload_form.description": "نوشتهٔ توضیحی برای کمبینایان و نابینایان", - "upload_form.edit": "Edit", + "upload_form.edit": "ویرایش", "upload_form.undo": "حذف", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "در حال پردازش تصویر…", + "upload_modal.apply": "اجرا", + "upload_modal.description_placeholder": "مردی با بیل مادرزنش را کشت", + "upload_modal.detect_text": "پیدا کردن نوشته از درون تصویر", + "upload_modal.edit_media": "ویرایش تصویر", + "upload_modal.hint": "حتی اگر تصویر بریده یا کوچک شود، نقطهٔ کانونی آن همیشه دیده خواهد شد. نقطهٔ کانونی را با کلیک یا جابهجا کردن آن تنظیم کنید.", + "upload_modal.preview_label": "پیشنمایش ({ratio})", "upload_progress.label": "بارگذاری...", "video.close": "بستن ویدیو", "video.exit_fullscreen": "خروج از حالت تمام صفحه", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index baed4f0a5..01b5edad1 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -16,6 +16,7 @@ "account.follows.empty": "Tämä käyttäjä ei vielä seuraa ketään.", "account.follows_you": "Seuraa sinua", "account.hide_reblogs": "Piilota buustaukset käyttäjältä @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Tämän linkin omistaja tarkistettiin {date}", "account.locked_info": "Tämän tili on yksityinen. Käyttäjä vahvistaa itse kuka voi seurata häntä.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Mykistä @{name}", "account.mute_notifications": "Mykistä ilmoitukset käyttäjältä @{name}", "account.muted": "Mykistetty", + "account.never_active": "Never", "account.posts": "Tuuttaukset", "account.posts_with_replies": "Tuuttaukset ja vastaukset", "account.report": "Raportoi @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Lakkaa seuraamasta", "account.unmute": "Poista käyttäjän @{name} mykistys", "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Tapahtui odottamaton virhe.", "alert.unexpected.title": "Hups!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Estetyt käyttäjät", "column.community": "Paikallinen aikajana", "column.direct": "Viestit", + "column.directory": "Browse profiles", "column.domain_blocks": "Piilotetut verkkotunnukset", "column.favourites": "Suosikit", "column.follow_requests": "Seuraamispyynnöt", @@ -58,6 +63,7 @@ "column.notifications": "Ilmoitukset", "column.pins": "Kiinnitetty tuuttaus", "column.public": "Yleinen aikajana", + "column.status": "Toot", "column_back_button.label": "Takaisin", "column_header.hide_settings": "Piilota asetukset", "column_header.moveLeft_settings": "Siirrä saraketta vasemmalle", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Haluatko varmasti poistaa tämän listan kokonaan?", "confirmations.domain_block.confirm": "Piilota koko verkko-osoite", "confirmations.domain_block.message": "Haluatko aivan varmasti estää koko verkko-osoitteen {domain}? Useimmiten jokunen kohdistettu esto ja mykistys riittää, ja se on suositeltavampi tapa toimia.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mykistä", "confirmations.mute.message": "Haluatko varmasti mykistää käyttäjän {name}?", "confirmations.redraft.confirm": "Poista & palauta muokattavaksi", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Jos vastaat nyt, vastaus korvaa tällä hetkellä työstämäsi viestin. Oletko varma, että haluat jatkaa?", "confirmations.unfollow.confirm": "Lakkaa seuraamasta", "confirmations.unfollow.message": "Haluatko varmasti lakata seuraamasta käyttäjää {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Upota statuspäivitys sivullesi kopioimalla alla oleva koodi.", "embed.preview": "Se tulee näyttämään tältä:", "emoji_button.activity": "Aktiviteetit", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Kiinnitetyt tuuttaukset", "navigation_bar.preferences": "Asetukset", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Yleinen aikajana", "navigation_bar.security": "Tunnukset", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Näytä lisää", "status.show_more_all": "Näytä lisää kaikista", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Poista keskustelun mykistys", "status.unpin": "Irrota profiilista", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Luonnos häviää, jos poistut Mastodonista.", "upload_area.title": "Lataa raahaamalla ja pudottamalla tähän", "upload_button.label": "Lisää mediaa", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 12025baff..7cfe9829a 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -4,11 +4,11 @@ "account.block": "Bloquer @{name}", "account.block_domain": "Tout masquer venant de {domain}", "account.blocked": "Bloqué", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Annuler la demande de suivi", "account.direct": "Envoyer un message direct à @{name}", "account.domain_blocked": "Domaine caché", "account.edit_profile": "Modifier le profil", - "account.endorse": "Figure sur le profil", + "account.endorse": "Mettre en avant sur le profil", "account.follow": "Suivre", "account.followers": "Abonné⋅e⋅s", "account.followers.empty": "Personne ne suit cet utilisateur·rice pour l’instant.", @@ -16,6 +16,7 @@ "account.follows.empty": "Cet·te utilisateur·rice ne suit personne pour l’instant.", "account.follows_you": "Vous suit", "account.hide_reblogs": "Masquer les partages de @{name}", + "account.last_status": "Dernière activité", "account.link_verified_on": "La propriété de ce lien a été vérifiée le {date}", "account.locked_info": "Ce compte est verrouillé. Son propriétaire approuve manuellement qui peut le ou la suivre.", "account.media": "Média", @@ -24,6 +25,7 @@ "account.mute": "Masquer @{name}", "account.mute_notifications": "Ignorer les notifications de @{name}", "account.muted": "Silencé", + "account.never_active": "Jamais", "account.posts": "Pouets", "account.posts_with_replies": "Pouets et réponses", "account.report": "Signaler @{name}", @@ -32,14 +34,16 @@ "account.show_reblogs": "Afficher les partages de @{name}", "account.unblock": "Débloquer @{name}", "account.unblock_domain": "Ne plus masquer {domain}", - "account.unendorse": "Ne figure pas sur le profil", + "account.unendorse": "Ne pas mettre en avant sur le profil", "account.unfollow": "Ne plus suivre", "account.unmute": "Ne plus masquer @{name}", "account.unmute_notifications": "Réactiver les notifications de @{name}", + "alert.rate_limited.message": "Veuillez réessayer après {retry_time, time, medium}.", + "alert.rate_limited.title": "Taux limité", "alert.unexpected.message": "Une erreur inattendue s’est produite.", "alert.unexpected.title": "Oups !", - "autosuggest_hashtag.per_week": "{count} per week", - "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour pouvoir passer ceci, la prochaine fois", + "autosuggest_hashtag.per_week": "{count} par semaine", + "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour passer ceci, la prochaine fois", "bundle_column_error.body": "Une erreur s’est produite lors du chargement de ce composant.", "bundle_column_error.retry": "Réessayer", "bundle_column_error.title": "Erreur réseau", @@ -48,7 +52,8 @@ "bundle_modal_error.retry": "Réessayer", "column.blocks": "Comptes bloqués", "column.community": "Fil public local", - "column.direct": "Messages directs", + "column.direct": "Messages privés", + "column.directory": "Parcourir les profils", "column.domain_blocks": "Domaines cachés", "column.favourites": "Favoris", "column.follow_requests": "Demandes de suivi", @@ -58,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pouets épinglés", "column.public": "Fil public global", + "column.status": "Toot", "column_back_button.label": "Retour", "column_header.hide_settings": "Masquer les paramètres", "column_header.moveLeft_settings": "Déplacer la colonne vers la gauche", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Êtes-vous sûr·e de vouloir supprimer définitivement cette liste ?", "confirmations.domain_block.confirm": "Masquer le domaine entier", "confirmations.domain_block.message": "Êtes-vous vraiment, vraiment sûr⋅e de vouloir bloquer {domain} en entier ? Dans la plupart des cas, quelques blocages ou masquages ciblés sont suffisants et préférables. Vous ne verrez plus de contenu provenant de ce domaine, ni dans fils publics, ni dans vos notifications. Vos abonné·e·s utilisant ce domaine seront retiré·e·s.", + "confirmations.logout.confirm": "Déconnexion", + "confirmations.logout.message": "Êtes-vous sûr de vouloir vous déconnecter ?", "confirmations.mute.confirm": "Masquer", "confirmations.mute.message": "Confirmez-vous le masquage de {name} ?", "confirmations.redraft.confirm": "Effacer et ré-écrire", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Répondre maintenant écrasera le message que vous êtes en train de composer. Voulez-vous vraiment continuer ?", "confirmations.unfollow.confirm": "Ne plus suivre", "confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name} ?", + "directory.federated": "De la fédiverse connue", + "directory.local": "De {domain} seulement", + "directory.new_arrivals": "Nouveaux arrivants", + "directory.recently_active": "Récemment actif", "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.", "embed.preview": "Il apparaîtra comme cela :", "emoji_button.activity": "Activités", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Basique", "home.column_settings.show_reblogs": "Afficher les partages", "home.column_settings.show_replies": "Afficher les réponses", - "home.column_settings.update_live": "Mettre à jour en temps réel", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# jour} other {# jours}}", "intervals.full.hours": "{number, plural, one {# heure} other {# heures}}", "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", @@ -171,7 +183,7 @@ "introduction.federation.local.text": "Les messages publics de personnes se trouvant sur le même serveur que vous apparaîtront sur le fil public local.", "introduction.interactions.action": "Finir le tutoriel !", "introduction.interactions.favourite.headline": "Favoris", - "introduction.interactions.favourite.text": "Vous pouvez garder un pouet pour plus tard, et faire savoir à son auteur·ice que vous l'avez aimé, en le favorisant.", + "introduction.interactions.favourite.text": "Vous pouvez garder un pouet pour plus tard et faire savoir à son auteur·ice que vous l’avez aimé, en le favorisant.", "introduction.interactions.reblog.headline": "Repartager", "introduction.interactions.reblog.text": "Vous pouvez partager les pouets d'autres personnes avec vos abonné·e·s en les repartageant.", "introduction.interactions.reply.headline": "Répondre", @@ -242,7 +254,7 @@ "navigation_bar.filters": "Mots silenciés", "navigation_bar.follow_requests": "Demandes de suivi", "navigation_bar.follows_and_followers": "Abonnements et abonné⋅e·s", - "navigation_bar.info": "Plus d’informations", + "navigation_bar.info": "À propos de ce serveur", "navigation_bar.keyboard_shortcuts": "Raccourcis clavier", "navigation_bar.lists": "Listes", "navigation_bar.logout": "Déconnexion", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personnel", "navigation_bar.pins": "Pouets épinglés", "navigation_bar.preferences": "Préférences", - "navigation_bar.profile_directory": "Annuaire des profils", "navigation_bar.public_timeline": "Fil public global", "navigation_bar.security": "Sécurité", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -321,8 +332,8 @@ "search_results.statuses": "Pouets", "search_results.statuses_fts_disabled": "La recherche de pouets par leur contenu n'est pas activée sur ce serveur Mastodon.", "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}", - "status.admin_account": "Ouvrir l'interface de modération pour @{name}", - "status.admin_status": "Ouvrir ce statut dans l'interface de modération", + "status.admin_account": "Ouvrir l’interface de modération pour @{name}", + "status.admin_status": "Ouvrir ce statut dans l’interface de modération", "status.block": "Bloquer @{name}", "status.cancel_reblog_private": "Dé-booster", "status.cannot_reblog": "Cette publication ne peut être boostée", @@ -358,6 +369,7 @@ "status.show_more": "Déplier", "status.show_more_all": "Tout déplier", "status.show_thread": "Lire le fil", + "status.uncached_media_warning": "Indisponible", "status.unmute_conversation": "Ne plus masquer la conversation", "status.unpin": "Retirer du profil", "suggestions.dismiss": "Rejeter la suggestion", @@ -373,22 +385,22 @@ "time_remaining.moments": "Encore quelques instants", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} restantes", "trends.count_by_accounts": "{count} {rawCount, plural, one {personne} other {personnes}} discutent", - "trends.refresh": "Refresh", + "trends.trending_now": "Tendance en ce moment", "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.", "upload_area.title": "Glissez et déposez pour envoyer", - "upload_button.label": "Joindre un média (JPEG, PNG, GIF, WebM, MP4, MOV)", + "upload_button.label": "Joindre un média ({formats})", "upload_error.limit": "Taille maximale d'envoi de fichier dépassée.", - "upload_error.poll": "L'envoi de fichiers n'est pas autorisé avec les sondages.", + "upload_error.poll": "L’envoi de fichiers n’est pas autorisé avec les sondages.", "upload_form.description": "Décrire pour les malvoyant·e·s", - "upload_form.edit": "Edit", + "upload_form.edit": "Modifier", "upload_form.undo": "Supprimer", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Analyse de l’image en cours…", + "upload_modal.apply": "Appliquer", + "upload_modal.description_placeholder": "Buvez de ce whisky que le patron juge fameux", + "upload_modal.detect_text": "Détecter le texte de l’image", + "upload_modal.edit_media": "Modifier le média", + "upload_modal.hint": "Cliquez ou faites glisser le cercle sur l’aperçu pour choisir le point focal qui sera toujours visible sur toutes les miniatures.", + "upload_modal.preview_label": "Aperçu ({ratio})", "upload_progress.label": "Envoi en cours…", "video.close": "Fermer la vidéo", "video.exit_fullscreen": "Quitter le plein écran", diff --git a/app/javascript/mastodon/locales/ga.json b/app/javascript/mastodon/locales/ga.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/app/javascript/mastodon/locales/ga.json @@ -0,0 +1 @@ +{} diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index fcbc16017..3cc44f43e 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -4,7 +4,7 @@ "account.block": "Bloquear @{name}", "account.block_domain": "Ocultar calquer contido de {domain}", "account.blocked": "Bloqueada", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Cancelar petición de seguemento", "account.direct": "Mensaxe directa @{name}", "account.domain_blocked": "Dominio agochado", "account.edit_profile": "Editar perfil", @@ -16,6 +16,7 @@ "account.follows.empty": "Esta usuaria aínda non segue a ninguén.", "account.follows_you": "Séguete", "account.hide_reblogs": "Ocultar repeticións de @{name}", + "account.last_status": "Último activo", "account.link_verified_on": "A propiedade de esta ligazón foi comprobada en {date}", "account.locked_info": "O estado da intimidade de esta conta estableceuse en pechado. A persoa dona da conta revisa quen pode seguila.", "account.media": "Medios", @@ -24,6 +25,7 @@ "account.mute": "Acalar @{name}", "account.mute_notifications": "Acalar as notificacións de @{name}", "account.muted": "Acalada", + "account.never_active": "Nunca", "account.posts": "Toots", "account.posts_with_replies": "Toots e respostas", "account.report": "Informar sobre @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Non seguir", "account.unmute": "Non acalar @{name}", "account.unmute_notifications": "Desbloquear as notificacións de @{name}", + "alert.rate_limited.message": "Por favor inténteo tras {retry_time, time, medium}.", + "alert.rate_limited.title": "Taxa limitada", "alert.unexpected.message": "Aconteceu un fallo non agardado.", "alert.unexpected.title": "Vaia!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} por semana", "boost_modal.combo": "Pulse {combo} para saltar esto a próxima vez", "bundle_column_error.body": "Houbo un fallo mentras se cargaba este compoñente.", "bundle_column_error.retry": "Inténteo de novo", @@ -49,6 +53,7 @@ "column.blocks": "Usuarias bloqueadas", "column.community": "Liña temporal local", "column.direct": "Mensaxes directas", + "column.directory": "Ver perfiles", "column.domain_blocks": "Dominios agochados", "column.favourites": "Favoritas", "column.follow_requests": "Peticións de seguimento", @@ -58,6 +63,7 @@ "column.notifications": "Notificacións", "column.pins": "Mensaxes fixadas", "column.public": "Liña temporal federada", + "column.status": "Toot", "column_back_button.label": "Atrás", "column_header.hide_settings": "Agochar axustes", "column_header.moveLeft_settings": "Mover a columna hacia a esquerda", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Estás seguro de que queres eliminar permanentemente esta lista?", "confirmations.domain_block.confirm": "Agochar un dominio completo", "confirmations.domain_block.message": "Realmente está segura de que quere bloquear por completo o dominio {domain}? Normalmente é suficiente, e preferible, bloquear de xeito selectivo varios elementos. Non verá contidos de ese dominio en ningunha liña temporal ou nas notificacións. As súas seguidoras en ese dominio serán eliminadas.", + "confirmations.logout.confirm": "Desconectar", + "confirmations.logout.message": "Seguro que desexa desconectar?", "confirmations.mute.confirm": "Acalar", "confirmations.mute.message": "Está segura de que quere acalar a {name}?", "confirmations.redraft.confirm": "Eliminar e reescribir", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Respostando agora sobreescribirá a mensaxe que está a compoñer. Segura de querer proceder?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "Quere deixar de seguir a {name}?", + "directory.federated": "Desde o fediverso coñecido", + "directory.local": "Só desde {domain}", + "directory.new_arrivals": "Novas achegas", + "directory.recently_active": "Activo recentemente", "embed.instructions": "Copie o código inferior para incrustar no seu sitio web este estado.", "embed.preview": "Así será mostrado:", "emoji_button.activity": "Actividade", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Básico", "home.column_settings.show_reblogs": "Mostrar repeticións", "home.column_settings.show_replies": "Mostrar respostas", - "home.column_settings.update_live": "Actualizar en tempo real", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural,one {# día} other {# días}}", "intervals.full.hours": "{number, plural, one {# hora} other {# horas}}", "intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Persoal", "navigation_bar.pins": "Mensaxes fixadas", "navigation_bar.preferences": "Preferencias", - "navigation_bar.profile_directory": "Directorio de perfil", "navigation_bar.public_timeline": "Liña temporal federada", "navigation_bar.security": "Seguridade", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostrar máis", "status.show_more_all": "Mostrar máis para todas", "status.show_thread": "Mostrar fío", + "status.uncached_media_warning": "Non dispoñible", "status.unmute_conversation": "Non acalar a conversa", "status.unpin": "Despegar do perfil", "suggestions.dismiss": "Rexeitar suxestión", @@ -373,22 +385,22 @@ "time_remaining.moments": "Está rematando", "time_remaining.seconds": "{number, plural, one {# segundo} other {# segundos}} restantes", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} outras {people}} conversando", - "trends.refresh": "Refresh", + "trends.trending_now": "Tendencias actuais", "ui.beforeunload": "O borrador perderase se sae de Mastodon.", "upload_area.title": "Arrastre e solte para subir", "upload_button.label": "Engadir medios ({formats})", "upload_error.limit": "Excedeu o límite de subida de ficheiros.", "upload_error.poll": "Non se poden subir ficheiros nas sondaxes.", "upload_form.description": "Describa para deficientes visuais", - "upload_form.edit": "Edit", + "upload_form.edit": "Editar", "upload_form.undo": "Eliminar", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Analizando imaxe…", + "upload_modal.apply": "Aplicar", + "upload_modal.description_placeholder": "Un raposo moi feitiño salta sobre o can preguiceiro", + "upload_modal.detect_text": "Detectar texto na imaxe", + "upload_modal.edit_media": "Editar medios", + "upload_modal.hint": "Prema ou arrastre o círculo na vista previa para escolle o punto focal que se verá na vista de todas as miniaturas.", + "upload_modal.preview_label": "Vista previa ({ratio})", "upload_progress.label": "Subindo...", "video.close": "Pechar video", "video.exit_fullscreen": "Saír da pantalla completa", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index e17d451ca..b6cc3e6ce 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "במעקב אחריך", "account.hide_reblogs": "להסתיר הידהודים מאת @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "מדיה", @@ -24,6 +25,7 @@ "account.mute": "להשתיק את @{name}", "account.mute_notifications": "להסתיר התראות מאת @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "הודעות", "account.posts_with_replies": "Toots with replies", "account.report": "לדווח על @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "הפסקת מעקב", "account.unmute": "הפסקת השתקת @{name}", "account.unmute_notifications": "להפסיק הסתרת הודעות מעם @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.", "alert.unexpected.title": "אופס!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "חסימות", "column.community": "ציר זמן מקומי", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "חיבובים", "column.follow_requests": "בקשות מעקב", @@ -58,6 +63,7 @@ "column.notifications": "התראות", "column.pins": "Pinned toot", "column.public": "בפרהסיה", + "column.status": "Toot", "column_back_button.label": "חזרה", "column_header.hide_settings": "הסתרת העדפות", "column_header.moveLeft_settings": "הזחת טור לשמאל", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "הסתר קהילה שלמה", "confirmations.domain_block.message": "באמת באמת לחסום את כל קהילת {domain}? ברב המקרים השתקות נבחרות של מספר משתמשים מסויימים צריכה להספיק.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "להשתיק", "confirmations.mute.message": "להשתיק את {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "להפסיק מעקב", "confirmations.unfollow.message": "להפסיק מעקב אחרי {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "ניתן להטמיע את ההודעה באתרך ע\"י העתקת הקוד שלהלן.", "embed.preview": "דוגמא כיצד זה יראה:", "emoji_button.activity": "פעילות", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "חיצרוצים מקובעים", "navigation_bar.preferences": "העדפות", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "ציר זמן בין-קהילתי", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "הראה יותר", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "הסרת השתקת שיחה", "status.unpin": "לשחרר מקיבוע באודות", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "הטיוטא תאבד אם תעזבו את מסטודון.", "upload_area.title": "ניתן להעלות על ידי Drag & drop", "upload_button.label": "הוספת מדיה", diff --git a/app/javascript/mastodon/locales/hi.json b/app/javascript/mastodon/locales/hi.json index 980b4e457..e2d1eb49d 100644 --- a/app/javascript/mastodon/locales/hi.json +++ b/app/javascript/mastodon/locales/hi.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Follows you", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", "account.report": "Report @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blocked users", "column.community": "Local timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", @@ -58,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pinned toot", "column.public": "Federated timeline", + "column.status": "Toot", "column_back_button.label": "Back", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferences", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index d718915c8..6daabc694 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "te slijedi", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Utišaj @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Postovi", "account.posts_with_replies": "Toots with replies", "account.report": "Prijavi @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Prestani slijediti", "account.unmute": "Poništi utišavanje @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokirani korisnici", "column.community": "Lokalni timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favoriti", "column.follow_requests": "Zahtjevi za slijeđenje", @@ -58,6 +63,7 @@ "column.notifications": "Notifikacije", "column.pins": "Pinned toot", "column.public": "Federalni timeline", + "column.status": "Toot", "column_back_button.label": "Natrag", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Sakrij cijelu domenu", "confirmations.domain_block.message": "Jesi li zaista, zaista siguran da želiš potpuno blokirati {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Utišaj", "confirmations.mute.message": "Jesi li siguran da želiš utišati {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Aktivnost", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Postavke", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federalni timeline", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Pokaži više", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Poništi utišavanje razgovora", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Povuci i spusti kako bi uploadao", "upload_button.label": "Dodaj media", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index f06e748a8..f5a02065b 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -16,6 +16,7 @@ "account.follows.empty": "Ez a felhasználó még senkit sem követ.", "account.follows_you": "Követ téged", "account.hide_reblogs": "@{name} megtolásainak némítása", + "account.last_status": "Last active", "account.link_verified_on": "A linket ellenőriztük: {date}", "account.locked_info": "Ez a fiók zárt. A tulaj engedélyezi, ki követheti őt.", "account.media": "Média", @@ -24,6 +25,7 @@ "account.mute": "@{name} némítása", "account.mute_notifications": "@{name} értesítéseinek némítása", "account.muted": "Némítva", + "account.never_active": "Never", "account.posts": "Tülkölés", "account.posts_with_replies": "Tülkölés válaszokkal", "account.report": "@{name} jelentése", @@ -36,6 +38,8 @@ "account.unfollow": "Követés vége", "account.unmute": "@{name} némítás feloldása", "account.unmute_notifications": "@{name} némított értesítéseinek feloldása", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Váratlan hiba történt.", "alert.unexpected.title": "Hoppá!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Letiltott felhasználók", "column.community": "Helyi idővonal", "column.direct": "Közvetlen üzenetek", + "column.directory": "Browse profiles", "column.domain_blocks": "Rejtett domainek", "column.favourites": "Kedvencek", "column.follow_requests": "Követési kérelmek", @@ -58,6 +63,7 @@ "column.notifications": "Értesítések", "column.pins": "Kitűzött tülkök", "column.public": "Nyilvános idővonal", + "column.status": "Toot", "column_back_button.label": "Vissza", "column_header.hide_settings": "Beállítások elrejtése", "column_header.moveLeft_settings": "Oszlop elmozdítása balra", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Biztos, hogy véglegesen törölni szeretnéd ezt a listát?", "confirmations.domain_block.confirm": "Teljes domain elrejtése", "confirmations.domain_block.message": "Egészen biztos, hogy le szeretnéd tiltani a teljes {domain}-t? A legtöbb esetben néhány célzott tiltás vagy némítás elegendő és kívánatosabb megoldás. Semmilyen tartalmat nem fogsz látni ebből a domainből se idővonalakon, se értesítésekben. Az ebben a domainben lévő követőidet is eltávolítjuk.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Némítás", "confirmations.mute.message": "Biztos, hogy némítani szeretnéd {name}?", "confirmations.redraft.confirm": "Törlés és újraírás", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Ha most válaszolsz, ez felülírja a most szerkesztés alatt álló üzenetet. Mégis ezt szeretnéd?", "confirmations.unfollow.confirm": "Követés visszavonása", "confirmations.unfollow.message": "Biztos, hogy vissza szeretnéd vonni {name} követését?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Ágyazd be ezt a tülköt a weboldaladba az alábbi kód kimásolásával.", "embed.preview": "Így fog kinézni:", "emoji_button.activity": "Aktivitás", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Alapértelmezések", "home.column_settings.show_reblogs": "Megtolások mutatása", "home.column_settings.show_replies": "Válaszok mutatása", - "home.column_settings.update_live": "Frissítés valós időben", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# nap} other {# nap}}", "intervals.full.hours": "{number, plural, one {# óra} other {# óra}}", "intervals.full.minutes": "{number, plural, one {# perc} other {# perc}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Személyes", "navigation_bar.pins": "Kitűzött tülkök", "navigation_bar.preferences": "Beállítások", - "navigation_bar.profile_directory": "Profilok", "navigation_bar.public_timeline": "Föderációs idővonal", "navigation_bar.security": "Biztonság", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Többet", "status.show_more_all": "Többet mindenhol", "status.show_thread": "Szál mutatása", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Beszélgetés némításának kikapcsolása", "status.unpin": "Kitűzés eltávolítása a profilodról", "suggestions.dismiss": "Javaslat elvetése", @@ -373,7 +385,7 @@ "time_remaining.moments": "Pillanatok vannak hátra", "time_remaining.seconds": "{number, plural, one {# másodperc} other {# másodperc}} van hátra", "trends.count_by_accounts": "{count} {rawCount, plural, one {résztvevő} other {résztvevő}} beszélget", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "A piszkozatod el fog veszni, ha elhagyod a Mastodon-t.", "upload_area.title": "Húzd ide a feltöltéshez", "upload_button.label": "Média hozzáadása (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 47e9ee68b..1484c76df 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Հետեւում է քեզ", "account.hide_reblogs": "Թաքցնել @{name}֊ի տարածածները", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Մեդիա", @@ -24,6 +25,7 @@ "account.mute": "Լռեցնել @{name}֊ին", "account.mute_notifications": "Անջատել ծանուցումները @{name}֊ից", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Գրառումներ", "account.posts_with_replies": "Toots with replies", "account.report": "Բողոքել @{name}֊ից", @@ -36,6 +38,8 @@ "account.unfollow": "Չհետեւել", "account.unmute": "Ապալռեցնել @{name}֊ին", "account.unmute_notifications": "Միացնել ծանուցումները @{name}֊ից", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Վա՜յ", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Արգելափակված օգտատերեր", "column.community": "Տեղական հոսք", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Հավանածներ", "column.follow_requests": "Հետեւելու հայցեր", @@ -58,6 +63,7 @@ "column.notifications": "Ծանուցումներ", "column.pins": "Ամրացված թթեր", "column.public": "Դաշնային հոսք", + "column.status": "Toot", "column_back_button.label": "Ետ", "column_header.hide_settings": "Թաքցնել կարգավորումները", "column_header.moveLeft_settings": "Տեղաշարժել սյունը ձախ", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Վստա՞հ ես, որ ուզում ես մշտապես ջնջել այս ցանկը։", "confirmations.domain_block.confirm": "Թաքցնել ամբողջ տիրույթը", "confirmations.domain_block.message": "Հաստատ֊հաստա՞տ վստահ ես, որ ուզում ես արգելափակել ամբողջ {domain} տիրույթը։ Սովորաբար մի երկու թիրախավորված արգելափակում կամ լռեցում բավական է ու նախընտրելի։", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Լռեցնել", "confirmations.mute.message": "Վստա՞հ ես, որ ուզում ես {name}֊ին լռեցնել։", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Ապահետեւել", "confirmations.unfollow.message": "Վստա՞հ ես, որ ուզում ես այլեւս չհետեւել {name}֊ին։", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Այս թութը քո կայքում ներդնելու համար կարող ես պատճենել ներքոհիշյալ կոդը։", "embed.preview": "Ահա, թե ինչ տեսք կունենա այն՝", "emoji_button.activity": "Զբաղմունքներ", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Անձնական", "navigation_bar.pins": "Ամրացված թթեր", "navigation_bar.preferences": "Նախապատվություններ", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Դաշնային հոսք", "navigation_bar.security": "Անվտանգություն", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Ավելին", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Ապալռեցնել խոսակցությունը", "status.unpin": "Հանել անձնական էջից", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Քո սեւագիրը կկորի, եթե լքես Մաստոդոնը։", "upload_area.title": "Քաշիր ու նետիր՝ վերբեռնելու համար", "upload_button.label": "Ավելացնել մեդիա", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 0757e8ff3..c9e48a1a6 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -16,6 +16,7 @@ "account.follows.empty": "Pengguna ini belum mengikuti siapapun.", "account.follows_you": "Mengikuti anda", "account.hide_reblogs": "Sembunyikan boosts dari @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Kepemilikan tautan ini telah dicek pada {date}", "account.locked_info": "Status privasi akun ini disetel untuk dikunci. Pemilik secara manual meninjau siapa yang dapat mengikuti mereka.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Bisukan @{name}", "account.mute_notifications": "Sembunyikan notifikasi dari @{name}", "account.muted": "Dibisukan", + "account.never_active": "Never", "account.posts": "Toot", "account.posts_with_replies": "Postingan dengan balasan", "account.report": "Laporkan @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Berhenti mengikuti", "account.unmute": "Berhenti membisukan @{name}", "account.unmute_notifications": "Munculkan notifikasi dari @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Terjadi kesalahan yang tidak terduga.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Pengguna diblokir", "column.community": "Linimasa Lokal", "column.direct": "Pesan langsung", + "column.directory": "Browse profiles", "column.domain_blocks": "Topik tersembunyi", "column.favourites": "Favorit", "column.follow_requests": "Permintaan mengikuti", @@ -58,6 +63,7 @@ "column.notifications": "Notifikasi", "column.pins": "Pinned toot", "column.public": "Linimasa gabungan", + "column.status": "Toot", "column_back_button.label": "Kembali", "column_header.hide_settings": "Sembunyikan pengaturan", "column_header.moveLeft_settings": "Pindahkan kolom ke kiri", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Apakah anda yakin untuk menghapus daftar ini secara permanen?", "confirmations.domain_block.confirm": "Sembunyikan keseluruhan domain", "confirmations.domain_block.message": "Apakah anda benar benar yakin untuk memblokir keseluruhan {domain}? Dalam kasus tertentu beberapa pemblokiran atau penyembunyian lebih baik.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Bisukan", "confirmations.mute.message": "Apa anda yakin ingin membisukan {name}?", "confirmations.redraft.confirm": "Hapus dan konsep ulang", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?", "confirmations.unfollow.confirm": "Berhenti mengikuti", "confirmations.unfollow.message": "Apakah anda ingin berhenti mengikuti {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Sematkan status ini di website anda dengan menyalin kode di bawah ini.", "embed.preview": "Seperti ini nantinya:", "emoji_button.activity": "Aktivitas", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Pengaturan", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Linimasa gabungan", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Tampilkan semua", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Naskah anda akan hilang jika anda keluar dari Mastodon.", "upload_area.title": "Seret & lepaskan untuk mengunggah", "upload_button.label": "Tambahkan media", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index ff096f5cf..6c1b7fa8b 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Sequas tu", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Celar @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Mesaji", "account.posts_with_replies": "Toots with replies", "account.report": "Denuncar @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Ne plus sequar", "account.unmute": "Ne plus celar @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokusita uzeri", "column.community": "Lokala tempolineo", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favorati", "column.follow_requests": "Demandi di sequado", @@ -58,6 +63,7 @@ "column.notifications": "Savigi", "column.pins": "Pinned toot", "column.public": "Federata tempolineo", + "column.status": "Toot", "column_back_button.label": "Retro", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "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.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferi", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federata tempolineo", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Montrar plue", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Tranar faligar por kargar", "upload_button.label": "Adjuntar kontenajo", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index 0e791e13d..dc43bcb5c 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -4,7 +4,7 @@ "account.block": "Blocca @{name}", "account.block_domain": "Nascondi tutto da {domain}", "account.blocked": "Bloccato", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Annulla richiesta di seguito", "account.direct": "Invia messaggio privato a @{name}", "account.domain_blocked": "Dominio nascosto", "account.edit_profile": "Modifica profilo", @@ -16,6 +16,7 @@ "account.follows.empty": "Questo utente non segue ancora nessuno.", "account.follows_you": "Ti segue", "account.hide_reblogs": "Nascondi condivisioni da @{name}", + "account.last_status": "Last active", "account.link_verified_on": "La proprietà di questo link è stata controllata il {date}", "account.locked_info": "Il livello di privacy di questo account è impostato a \"bloccato\". Il proprietario esamina manualmente le richieste di seguirlo.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Silenzia @{name}", "account.mute_notifications": "Silenzia notifiche da @{name}", "account.muted": "Silenziato", + "account.never_active": "Never", "account.posts": "Toot", "account.posts_with_replies": "Toot e risposte", "account.report": "Segnala @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Non seguire", "account.unmute": "Non silenziare @{name}", "account.unmute_notifications": "Non silenziare più le notifiche da @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Si è verificato un errore inatteso.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per settimana", @@ -49,6 +53,7 @@ "column.blocks": "Utenti bloccati", "column.community": "Timeline locale", "column.direct": "Messaggi diretti", + "column.directory": "Browse profiles", "column.domain_blocks": "Domini nascosti", "column.favourites": "Apprezzati", "column.follow_requests": "Richieste di amicizia", @@ -58,6 +63,7 @@ "column.notifications": "Notifiche", "column.pins": "Toot fissati in cima", "column.public": "Timeline federata", + "column.status": "Toot", "column_back_button.label": "Indietro", "column_header.hide_settings": "Nascondi impostazioni", "column_header.moveLeft_settings": "Sposta colonna a sinistra", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Sei sicuro di voler cancellare definitivamente questa lista?", "confirmations.domain_block.confirm": "Nascondi intero dominio", "confirmations.domain_block.message": "Sei davvero sicuro che vuoi bloccare l'intero {domain}? Nella maggior parte dei casi, pochi blocchi o silenziamenti mirati sono sufficienti e preferibili. Non vedrai nessun contenuto di quel dominio né nelle timeline pubbliche né nelle notifiche. I tuoi seguaci di quel dominio saranno eliminati.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Silenzia", "confirmations.mute.message": "Sei sicuro di voler silenziare {name}?", "confirmations.redraft.confirm": "Cancella e riscrivi", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Se rispondi ora, il messaggio che stai componendo sarà sovrascritto. Sei sicuro di voler continuare?", "confirmations.unfollow.confirm": "Smetti di seguire", "confirmations.unfollow.message": "Sei sicuro che non vuoi più seguire {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Inserisci questo status nel tuo sito copiando il codice qui sotto.", "embed.preview": "Ecco come apparirà:", "emoji_button.activity": "Attività", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Semplice", "home.column_settings.show_reblogs": "Mostra post condivisi", "home.column_settings.show_replies": "Mostra risposte", - "home.column_settings.update_live": "Aggiornama in tempo reale", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# giorno} other {# giorni}}", "intervals.full.hours": "{number, plural, one {# ora} other {# ore}}", "intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personale", "navigation_bar.pins": "Toot fissati in cima", "navigation_bar.preferences": "Impostazioni", - "navigation_bar.profile_directory": "Directory dei profili", "navigation_bar.public_timeline": "Timeline federata", "navigation_bar.security": "Sicurezza", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostra di più", "status.show_more_all": "Mostra di più per tutti", "status.show_thread": "Mostra thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Annulla silenzia conversazione", "status.unpin": "Non fissare in cima al profilo", "suggestions.dismiss": "Elimina suggerimento", @@ -373,22 +385,22 @@ "time_remaining.moments": "Restano pochi istanti", "time_remaining.seconds": "{number, plural, one {# secondo} other {# secondi}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {persona ne sta} other {persone ne stanno}} parlando", - "trends.refresh": "Aggiorna", + "trends.trending_now": "Di tendenza ora", "ui.beforeunload": "La bozza andrà persa se esci da Mastodon.", "upload_area.title": "Trascina per caricare", "upload_button.label": "Aggiungi file multimediale", "upload_error.limit": "Limite al caricamento di file superato.", "upload_error.poll": "Caricamento file non consentito nei sondaggi.", "upload_form.description": "Descrizione per utenti con disabilità visive", - "upload_form.edit": "Edit", + "upload_form.edit": "Modifica", "upload_form.undo": "Cancella", - "upload_modal.analyzing_picture": "Analyzing picture…", + "upload_modal.analyzing_picture": "Analisi immagine…", "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.description_placeholder": "Ma la volpe col suo balzo ha raggiunto il quieto Fido", + "upload_modal.detect_text": "Rileva testo dall'immagine", + "upload_modal.edit_media": "Modifica media", "upload_modal.hint": "Clicca o trascina il cerchio sull'anteprima per scegliere il punto focale che sarà sempre visualizzato su tutte le miniature.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.preview_label": "Anteprima ({ratio})", "upload_progress.label": "Sto caricando...", "video.close": "Chiudi video", "video.exit_fullscreen": "Esci da modalità a schermo intero", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index d28fe4247..64baed71d 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -16,6 +16,7 @@ "account.follows.empty": "まだ誰もフォローしていません。", "account.follows_you": "フォローされています", "account.hide_reblogs": "@{name}さんからのブーストを非表示", + "account.last_status": "最後の活動", "account.link_verified_on": "このリンクの所有権は{date}に確認されました", "account.locked_info": "このアカウントは承認制アカウントです。相手が承認するまでフォローは完了しません。", "account.media": "メディア", @@ -24,6 +25,7 @@ "account.mute": "@{name}さんをミュート", "account.mute_notifications": "@{name}さんからの通知を受け取らない", "account.muted": "ミュート済み", + "account.never_active": "活動なし", "account.posts": "投稿", "account.posts_with_replies": "投稿と返信", "account.report": "@{name}さんを通報", @@ -36,6 +38,8 @@ "account.unfollow": "フォロー解除", "account.unmute": "@{name}さんのミュートを解除", "account.unmute_notifications": "@{name}さんからの通知を受け取るようにする", + "alert.rate_limited.message": "{retry_time, time, medium} 後に再試行してください。", + "alert.rate_limited.title": "制限に達しました", "alert.unexpected.message": "不明なエラーが発生しました。", "alert.unexpected.title": "エラー!", "autosuggest_hashtag.per_week": "{count} 回 / 週", @@ -49,6 +53,7 @@ "column.blocks": "ブロックしたユーザー", "column.community": "ローカルタイムライン", "column.direct": "ダイレクトメッセージ", + "column.directory": "Browse profiles", "column.domain_blocks": "非表示にしたドメイン", "column.favourites": "お気に入り", "column.follow_requests": "フォローリクエスト", @@ -58,6 +63,7 @@ "column.notifications": "通知", "column.pins": "固定されたトゥート", "column.public": "連合タイムライン", + "column.status": "Toot", "column_back_button.label": "戻る", "column_header.hide_settings": "設定を隠す", "column_header.moveLeft_settings": "カラムを左に移動する", @@ -99,6 +105,8 @@ "confirmations.delete_list.message": "本当にこのリストを完全に削除しますか?", "confirmations.domain_block.confirm": "ドメイン全体を非表示", "confirmations.domain_block.message": "本当に{domain}全体を非表示にしますか? 多くの場合は個別にブロックやミュートするだけで充分であり、また好ましいです。公開タイムラインにそのドメインのコンテンツが表示されなくなり、通知も届かなくなります。そのドメインのフォロワーはアンフォローされます。", + "confirmations.logout.confirm": "ログアウト", + "confirmations.logout.message": "本当にログアウトしますか?", "confirmations.mute.confirm": "ミュート", "confirmations.mute.message": "本当に{name}さんをミュートしますか?", "confirmations.redraft.confirm": "削除して下書きに戻す", @@ -107,6 +115,10 @@ "confirmations.reply.message": "今返信すると現在作成中のメッセージが上書きされます。本当に実行しますか?", "confirmations.unfollow.confirm": "フォロー解除", "confirmations.unfollow.message": "本当に{name}さんのフォローを解除しますか?", + "directory.federated": "既知の連合全体", + "directory.local": "{domain} のみ", + "directory.new_arrivals": "新着順", + "directory.recently_active": "最近の活動順", "embed.instructions": "下記のコードをコピーしてウェブサイトに埋め込みます。", "embed.preview": "表示例:", "emoji_button.activity": "活動", @@ -162,7 +174,7 @@ "home.column_settings.basic": "基本設定", "home.column_settings.show_reblogs": "ブースト表示", "home.column_settings.show_replies": "返信表示", - "home.column_settings.update_live": "リアルタイムで更新", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number}日", "intervals.full.hours": "{number}時間", "intervals.full.minutes": "{number}分", @@ -254,7 +266,6 @@ "navigation_bar.personal": "個人用", "navigation_bar.pins": "固定したトゥート", "navigation_bar.preferences": "ユーザー設定", - "navigation_bar.profile_directory": "ディレクトリ", "navigation_bar.public_timeline": "連合タイムライン", "navigation_bar.misc": "その他", "navigation_bar.security": "セキュリティ", @@ -363,6 +374,7 @@ "status.show_more": "もっと見る", "status.show_more_all": "全て見る", "status.show_thread": "スレッドを表示", + "status.uncached_media_warning": "利用できません", "status.unmute_conversation": "会話のミュートを解除", "status.unpin": "プロフィールへの固定を解除", "suggestions.dismiss": "隠す", @@ -378,7 +390,7 @@ "time_remaining.moments": "まもなく終了", "time_remaining.seconds": "残り{number}秒", "trends.count_by_accounts": "{count}人がトゥート", - "trends.refresh": "更新", + "trends.trending_now": "トレンドタグ", "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。", "upload_area.title": "ドラッグ&ドロップでアップロード", "upload_button.label": "メディアを追加 ({formats})", @@ -389,7 +401,7 @@ "upload_form.undo": "削除", "upload_modal.analyzing_picture": "画像を解析中…", "upload_modal.apply": "適用", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.description_placeholder": "素早い茶色の狐はのろまな犬を飛び越える", "upload_modal.detect_text": "画像からテキストを検出", "upload_modal.edit_media": "メディアを編集", "upload_modal.hint": "画像をクリックするか円をドラッグすると全てのサムネイルで注目する場所を選ぶことができます", diff --git a/app/javascript/mastodon/locales/ka.json b/app/javascript/mastodon/locales/ka.json index fecfb519c..e2a6ee6c6 100644 --- a/app/javascript/mastodon/locales/ka.json +++ b/app/javascript/mastodon/locales/ka.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "მოგყვებათ", "account.hide_reblogs": "დაიმალოს ბუსტები @{name}-სგან", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "მედია", @@ -24,6 +25,7 @@ "account.mute": "გააჩუმე @{name}", "account.mute_notifications": "გააჩუმე შეტყობინებები @{name}-სგან", "account.muted": "გაჩუმებული", + "account.never_active": "Never", "account.posts": "ტუტები", "account.posts_with_replies": "ტუტები და პასუხები", "account.report": "დაარეპორტე @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "ნუღარ მიჰყვები", "account.unmute": "ნუღარ აჩუმებ @{name}-ს", "account.unmute_notifications": "ნუღარ აჩუმებ შეტყობინებებს @{name}-სგან", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "წარმოიშვა მოულოდნელი შეცდომა.", "alert.unexpected.title": "უპს!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "დაბლოკილი მომხმარებლები", "column.community": "ლოკალური თაიმლაინი", "column.direct": "პირდაპირი წერილები", + "column.directory": "Browse profiles", "column.domain_blocks": "დამალული დომენები", "column.favourites": "ფავორიტები", "column.follow_requests": "დადევნების მოთხოვნები", @@ -58,6 +63,7 @@ "column.notifications": "შეტყობინებები", "column.pins": "აპინული ტუტები", "column.public": "ფედერალური თაიმლაინი", + "column.status": "Toot", "column_back_button.label": "უკან", "column_header.hide_settings": "პარამეტრების დამალვა", "column_header.moveLeft_settings": "სვეტის მარცხნივ გადატანა", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "დარწმუნებული ხართ, გსურთ სამუდამოდ გააუქმოთ ეს სია?", "confirmations.domain_block.confirm": "მთელი დომენის დამალვა", "confirmations.domain_block.message": "ნაღდად, ნაღდად, დარწმუნებული ხართ, გსურთ დაბლოკოთ მთელი {domain}? უმეტეს შემთხვევაში რამდენიმე გამიზნული ბლოკი ან გაჩუმება საკმარისი და უკეთესია. კონტენტს ამ დომენიდან ვერ იხილავთ ვერც ერთ ღია თაიმლაინზე ან თქვენს შეტყობინებებში. ამ დომენიდან არსებული მიმდევრები ამოიშლება.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "გაჩუმება", "confirmations.mute.message": "დარწმუნებული ხართ, გსურთ გააჩუმოთ {name}?", "confirmations.redraft.confirm": "გაუქმება და გადანაწილება", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "ნუღარ მიჰყვები", "confirmations.unfollow.message": "დარწმუნებული ხართ, აღარ გსურთ მიჰყვებოდეთ {name}-ს?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "ეს სტატუსი ჩასვით თქვენს ვებ-საიტზე შემდეგი კოდის კოპირებით.", "embed.preview": "ესაა თუ როგორც გამოჩნდება:", "emoji_button.activity": "აქტივობა", @@ -250,7 +262,6 @@ "navigation_bar.personal": "პირადი", "navigation_bar.pins": "აპინული ტუტები", "navigation_bar.preferences": "პრეფერენსიები", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "ფედერალური თაიმლაინი", "navigation_bar.security": "უსაფრთხოება", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "აჩვენე მეტი", "status.show_more_all": "აჩვენე მეტი ყველაზე", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "საუბარზე გაჩუმების მოშორება", "status.unpin": "პროფილიდან პინის მოშორება", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} საუბრობს", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "თქვენი დრაფტი გაუქმდება თუ დატოვებთ მასტოდონს.", "upload_area.title": "გადმოწიეთ და ჩააგდეთ ასატვირთათ", "upload_button.label": "მედიის დამატება", diff --git a/app/javascript/mastodon/locales/kk.json b/app/javascript/mastodon/locales/kk.json index 8710ae90b..a07302f0a 100644 --- a/app/javascript/mastodon/locales/kk.json +++ b/app/javascript/mastodon/locales/kk.json @@ -16,6 +16,7 @@ "account.follows.empty": "Ешкімге жазылмапты.", "account.follows_you": "Сізге жазылыпты", "account.hide_reblogs": "@{name} атты қолданушының әрекеттерін жасыру", + "account.last_status": "Last active", "account.link_verified_on": "Сілтеме меншігі расталған күн {date}", "account.locked_info": "Бұл қолданушы өзі туралы мәліметтерді жасырған. Тек жазылғандар ғана көре алады.", "account.media": "Медиа", @@ -24,6 +25,7 @@ "account.mute": "Үнсіз қылу @{name}", "account.mute_notifications": "@{name} туралы ескертпелерді жасыру", "account.muted": "Үнсіз", + "account.never_active": "Never", "account.posts": "Жазбалар", "account.posts_with_replies": "Жазбалар мен жауаптар", "account.report": "Шағымдану @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Оқымау", "account.unmute": "@{name} ескертпелерін қосу", "account.unmute_notifications": "@{name} ескертпелерін көрсету", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Бір нәрсе дұрыс болмады.", "alert.unexpected.title": "Өй!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Бұғатталғандар", "column.community": "Жергілікті желі", "column.direct": "Жеке хаттар", + "column.directory": "Browse profiles", "column.domain_blocks": "Жасырылған домендер", "column.favourites": "Таңдаулылар", "column.follow_requests": "Жазылу сұранымдары", @@ -58,6 +63,7 @@ "column.notifications": "Ескертпелер", "column.pins": "Жабыстырылған жазбалар", "column.public": "Жаһандық желі", + "column.status": "Toot", "column_back_button.label": "Артқа", "column_header.hide_settings": "Баптауларды жасыр", "column_header.moveLeft_settings": "Бағананы солға жылжыту", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Бұл тізімді жоясыз ба шынымен?", "confirmations.domain_block.confirm": "Бұл доменді бұғатта", "confirmations.domain_block.message": "Бұл домендегі {domain} жазбаларды шынымен бұғаттайсыз ба? Кейде үнсіз қылып тастау да жеткілікті.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Үнсіз қылу", "confirmations.mute.message": "{name} атты қолданушы үнсіз болсын ба?", "confirmations.redraft.confirm": "Өшіруді құптау", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Жауабыңыз жазып жатқан жазбаңыздың үстіне кетеді. Жалғастырамыз ба?", "confirmations.unfollow.confirm": "Оқымау", "confirmations.unfollow.message": "\"{name} атты қолданушыға енді жазылғыңыз келмей ме?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Төмендегі кодты көшіріп алу арқылы жазбаны басқа сайттарға да орналастыра аласыз.", "embed.preview": "Былай көрінетін болады:", "emoji_button.activity": "Белсенділік", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Жеке", "navigation_bar.pins": "Жабыстырылғандар", "navigation_bar.preferences": "Басымдықтар", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Жаһандық желі", "navigation_bar.security": "Қауіпсіздік", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Толығырақ", "status.show_more_all": "Бәрін толығымен", "status.show_thread": "Желіні көрсет", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Пікірталасты үнсіз қылмау", "status.unpin": "Профильден алып тастау", "suggestions.dismiss": "Өткізіп жіберу", @@ -373,7 +385,7 @@ "time_remaining.moments": "Қалған уақыт", "time_remaining.seconds": "{number, plural, one {# секунд} other {# секунд}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} жазған екен", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Mastodon желісінен шықсаңыз, нобайыңыз сақталмайды.", "upload_area.title": "Жүктеу үшін сүйреп әкеліңіз", "upload_button.label": "Медиа қосу (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index ac6a3ca91..3ec9a8a16 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -16,6 +16,7 @@ "account.follows.empty": "이 유저는 아직 아무도 팔로우 하고 있지 않습니다.", "account.follows_you": "날 팔로우합니다", "account.hide_reblogs": "@{name}의 부스트를 숨기기", + "account.last_status": "마지막 활동", "account.link_verified_on": "{date}에 이 링크의 소유권이 확인 됨", "account.locked_info": "이 계정의 프라이버시 설정은 잠금으로 설정되어 있습니다. 계정 소유자가 수동으로 팔로어를 승인합니다.", "account.media": "미디어", @@ -24,6 +25,7 @@ "account.mute": "@{name} 뮤트", "account.mute_notifications": "@{name}의 알림을 뮤트", "account.muted": "뮤트 됨", + "account.never_active": "없음", "account.posts": "툿", "account.posts_with_replies": "툿과 답장", "account.report": "@{name} 신고", @@ -36,6 +38,8 @@ "account.unfollow": "팔로우 해제", "account.unmute": "뮤트 해제", "account.unmute_notifications": "@{name}의 알림 뮤트 해제", + "alert.rate_limited.message": "{retry_time, time, medium}에 다시 시도해 주세요.", + "alert.rate_limited.title": "빈도 제한", "alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.", "alert.unexpected.title": "앗!", "autosuggest_hashtag.per_week": "주간 {count}회", @@ -49,6 +53,7 @@ "column.blocks": "차단 중인 사용자", "column.community": "로컬 타임라인", "column.direct": "다이렉트 메시지", + "column.directory": "프로필 둘러보기", "column.domain_blocks": "숨겨진 도메인", "column.favourites": "즐겨찾기", "column.follow_requests": "팔로우 요청", @@ -58,6 +63,7 @@ "column.notifications": "알림", "column.pins": "고정된 툿", "column.public": "연합 타임라인", + "column.status": "Toot", "column_back_button.label": "돌아가기", "column_header.hide_settings": "설정 숨기기", "column_header.moveLeft_settings": "왼쪽으로 이동", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "정말로 이 리스트를 삭제하시겠습니까?", "confirmations.domain_block.confirm": "도메인 전체를 숨김", "confirmations.domain_block.message": "정말로 {domain} 전체를 숨기시겠습니까? 대부분의 경우 개별 차단이나 뮤트로 충분합니다. 모든 공개 타임라인과 알림에서 해당 도메인에서 작성된 컨텐츠를 보지 못합니다. 해당 도메인 팔로워와의 관계가 사라집니다.", + "confirmations.logout.confirm": "로그아웃", + "confirmations.logout.message": "정말로 로그아웃 하시겠습니까?", "confirmations.mute.confirm": "뮤트", "confirmations.mute.message": "정말로 {name}를 뮤트하시겠습니까?", "confirmations.redraft.confirm": "삭제하고 다시 쓰기", @@ -103,6 +111,10 @@ "confirmations.reply.message": "답글을 달기 위해 현재 작성 중인 메시지가 덮어 씌워집니다. 진행하시겠습니까?", "confirmations.unfollow.confirm": "언팔로우", "confirmations.unfollow.message": "정말로 {name}를 언팔로우하시겠습니까?", + "directory.federated": "알려진 연합우주로부터", + "directory.local": "{domain}에서만", + "directory.new_arrivals": "새로운 사람들", + "directory.recently_active": "최근 활동", "embed.instructions": "아래의 코드를 복사하여 대화를 원하는 곳으로 공유하세요.", "embed.preview": "다음과 같이 표시됩니다:", "emoji_button.activity": "활동", @@ -158,7 +170,7 @@ "home.column_settings.basic": "기본 설정", "home.column_settings.show_reblogs": "부스트 표시", "home.column_settings.show_replies": "답글 표시", - "home.column_settings.update_live": "실시간 업데이트", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number} 일", "intervals.full.hours": "{number} 시간", "intervals.full.minutes": "{number} 분", @@ -250,10 +262,9 @@ "navigation_bar.personal": "개인용", "navigation_bar.pins": "고정된 툿", "navigation_bar.preferences": "사용자 설정", - "navigation_bar.profile_directory": "프로필 디렉토리", "navigation_bar.public_timeline": "연합 타임라인", "navigation_bar.security": "보안", - "notification.and_n_others": "그리고 {count}개의 기타 항목", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name}님이 즐겨찾기 했습니다", "notification.follow": "{name}님이 나를 팔로우 했습니다", "notification.mention": "{name}님이 답글을 보냈습니다", @@ -282,7 +293,7 @@ "notifications.group": "{count} 개의 알림", "poll.closed": "마감됨", "poll.refresh": "새로고침", - "poll.total_votes": "{count} 명 참여", + "poll.total_votes": "{count} 표", "poll.vote": "투표", "poll_button.add_poll": "투표 추가", "poll_button.remove_poll": "투표 삭제", @@ -358,6 +369,7 @@ "status.show_more": "더 보기", "status.show_more_all": "모두 펼치기", "status.show_thread": "글타래 보기", + "status.uncached_media_warning": "사용할 수 없음", "status.unmute_conversation": "이 대화의 뮤트 해제하기", "status.unpin": "고정 해제", "suggestions.dismiss": "추천 지우기", @@ -373,7 +385,7 @@ "time_remaining.moments": "남은 시간", "time_remaining.seconds": "{number} 초 남음", "trends.count_by_accounts": "{count} 명의 사람들이 말하고 있습니다", - "trends.refresh": "새로고침", + "trends.trending_now": "지금 유행중", "ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.", "upload_area.title": "드래그 & 드롭으로 업로드", "upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/lt.json b/app/javascript/mastodon/locales/lt.json index b844e2898..2de037f16 100644 --- a/app/javascript/mastodon/locales/lt.json +++ b/app/javascript/mastodon/locales/lt.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Follows you", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,10 +25,11 @@ "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", "account.report": "Report @{name}", - "account.requested": "Awaiting approval. Click to cancel follow request", + "account.requested": "Awaiting approval", "account.share": "Share @{name}'s profile", "account.show_reblogs": "Show boosts from @{name}", "account.unblock": "Unblock @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blocked users", "column.community": "Local timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", @@ -58,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pinned toot", "column.public": "Federated timeline", + "column.status": "Toot", "column_back_button.label": "Back", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferences", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media ({formats})", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index b4e45a854..8d281c9d5 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -16,6 +16,7 @@ "account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.", "account.follows_you": "Seko tev", "account.hide_reblogs": "Paslēpt paceltos ierakstus no lietotāja @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Šīs saites piederība ir pārbaudīta {date}", "account.locked_info": "Šī konta privātuma status ir iestatīts slēgts. Īpašnieks izskatīs un izvēlēsies kas viņam drīkst sekot.", "account.media": "Mēdiji", @@ -24,6 +25,7 @@ "account.mute": "Apklusināt @{name}", "account.mute_notifications": "Nerādīt paziņojumus no @{name}", "account.muted": "Apklusināts", + "account.never_active": "Never", "account.posts": "Ieraksti", "account.posts_with_replies": "Ieraksti un atbildes", "account.report": "Ziņot par lietotāju @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Nesekot", "account.unmute": "Noņemt apklusinājumu no lietotāja @{name}", "account.unmute_notifications": "Rādīt paziņojumus no lietotāja @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Negaidīta kļūda.", "alert.unexpected.title": "Ups!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Bloķētie lietotāji", "column.community": "Lokālā laika līnija", "column.direct": "Privātās ziņas", + "column.directory": "Browse profiles", "column.domain_blocks": "Paslēptie domēni", "column.favourites": "Favorīti", "column.follow_requests": "Sekotāju pieprasījumi", @@ -58,6 +63,7 @@ "column.notifications": "Paziņojumi", "column.pins": "Piespraustie ziņojumi", "column.public": "Federatīvā laika līnija", + "column.status": "Toot", "column_back_button.label": "Atpakaļ", "column_header.hide_settings": "Paslēpt iestatījumus", "column_header.moveLeft_settings": "Pārvietot kolonu pa kreisi", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Vai tiešam vēlies neatgriezeniski dzēst šo sarakstu?", "confirmations.domain_block.confirm": "Paslēpt visu domēnu", "confirmations.domain_block.message": "Vai tu tiešām, tiešam vēlies bloķēt visu domēnu {domain}? Lielākajā daļā gadījumu pietiek ja nobloķē vai apklusini kādu. Tu neredzēsi saturu vai paziņojumus no šī domēna nevienā laika līnijā. Tavi sekotāji no šī domēna tiks noņemti.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Apklusināt", "confirmations.mute.message": "Vai Tu tiešām velies apklusināt {name}?", "confirmations.redraft.confirm": "Dzēst un pārrakstīt", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Atbildot tagad tava ziņa ko šobrīd raksti tiks pārrakstīta. Vai tiešām vēlies turpināt?", "confirmations.unfollow.confirm": "Nesekot", "confirmations.unfollow.message": "Vai tiešam vairs nevēlies sekot lietotājam {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Iegul šo ziņojumu savā mājaslapā kopējot kodu zemāk.", "embed.preview": "Tas izskatīsies šādi:", "emoji_button.activity": "Aktivitāte", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferences", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media ({formats})", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 556204753..9bd5eef72 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Follows you", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,10 +25,11 @@ "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", "account.report": "Report @{name}", - "account.requested": "Awaiting approval. Click to cancel follow request", + "account.requested": "Awaiting approval", "account.share": "Share @{name}'s profile", "account.show_reblogs": "Show boosts from @{name}", "account.unblock": "Unblock @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blocked users", "column.community": "Local timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", @@ -58,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pinned toot", "column.public": "Federated timeline", + "column.status": "Toot", "column_back_button.label": "Back", "column_header.hide_settings": "Hide settings", "column_header.moveLeft_settings": "Move column to the left", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "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. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferences", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "upload_area.title": "Drag & drop to upload", "upload_button.label": "Add media ({formats})", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 6cfcf6bd6..73e7b3905 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -4,7 +4,7 @@ "account.block": "Blokkeer @{name}", "account.block_domain": "Verberg alles van {domain}", "account.blocked": "Geblokkeerd", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Volgverzoek annuleren", "account.direct": "Direct Message @{name}", "account.domain_blocked": "Domein verborgen", "account.edit_profile": "Profiel bewerken", @@ -16,6 +16,7 @@ "account.follows.empty": "Deze gebruiker volgt nog niemand.", "account.follows_you": "Volgt jou", "account.hide_reblogs": "Verberg boosts van @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Eigendom van deze link is gecontroleerd op {date}", "account.locked_info": "De privacystatus van dit account is op besloten gezet. De eigenaar bepaalt handmatig wie hen kan volgen.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Negeer @{name}", "account.mute_notifications": "Negeer meldingen van @{name}", "account.muted": "Genegeerd", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots en reacties", "account.report": "Rapporteer @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Ontvolgen", "account.unmute": "@{name} niet langer negeren", "account.unmute_notifications": "@{name} meldingen niet langer negeren", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Er deed zich een onverwachte fout voor", "alert.unexpected.title": "Oeps!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Geblokkeerde gebruikers", "column.community": "Lokale tijdlijn", "column.direct": "Directe berichten", + "column.directory": "Browse profiles", "column.domain_blocks": "Genegeerde servers", "column.favourites": "Favorieten", "column.follow_requests": "Volgverzoeken", @@ -58,6 +63,7 @@ "column.notifications": "Meldingen", "column.pins": "Vastgezette toots", "column.public": "Globale tijdlijn", + "column.status": "Toot", "column_back_button.label": "Terug", "column_header.hide_settings": "Instellingen verbergen", "column_header.moveLeft_settings": "Kolom naar links verplaatsen", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?", "confirmations.domain_block.confirm": "Verberg alles van deze server", "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wilt negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en beter. Je zult geen toots van deze server op openbare tijdlijnen zien of in jouw meldingen. Jouw volgers van deze server worden verwijderd.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Negeren", "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?", "confirmations.redraft.confirm": "Verwijderen en herschrijven", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Door nu te reageren overschrijf je de toot die je op dit moment aan het schrijven bent. Weet je zeker dat je verder wil gaan?", "confirmations.unfollow.confirm": "Ontvolgen", "confirmations.unfollow.message": "Weet je het zeker dat je {name} wilt ontvolgen?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed deze toot op jouw website, door de onderstaande code te kopiëren.", "embed.preview": "Zo komt het eruit te zien:", "emoji_button.activity": "Activiteiten", @@ -224,7 +236,7 @@ "lists.new.title_placeholder": "Naam nieuwe lijst", "lists.search": "Zoek naar mensen die je volgt", "lists.subheading": "Jouw lijsten", - "load_pending": "{count, plural, one {# new item} other {# new items}}", + "load_pending": "{count, plural, one {# nieuw item} other {# nieuwe items}}", "loading_indicator.label": "Laden…", "media_gallery.toggle_visible": "Media wel/niet tonen", "missing_indicator.label": "Niet gevonden", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Persoonlijk", "navigation_bar.pins": "Vastgezette toots", "navigation_bar.preferences": "Instellingen", - "navigation_bar.profile_directory": "Gebruikersgids", "navigation_bar.public_timeline": "Globale tijdlijn", "navigation_bar.security": "Beveiliging", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -319,7 +330,7 @@ "search_results.accounts": "Gebruikers", "search_results.hashtags": "Hashtags", "search_results.statuses": "Toots", - "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", + "search_results.statuses_fts_disabled": "Het zoeken in toots is op deze Mastodonserver niet ingeschakeld.", "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}", "status.admin_account": "Moderatie-omgeving van @{name} openen", "status.admin_status": "Deze toot in de moderatie-omgeving openen", @@ -358,6 +369,7 @@ "status.show_more": "Meer tonen", "status.show_more_all": "Alles meer tonen", "status.show_thread": "Gesprek tonen", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Gesprek niet langer negeren", "status.unpin": "Van profielpagina losmaken", "suggestions.dismiss": "Voorstel verwerpen", @@ -373,22 +385,22 @@ "time_remaining.moments": "Nog enkele ogenblikken resterend", "time_remaining.seconds": "{number, plural, one {# seconde} other {# seconden}} te gaan", "trends.count_by_accounts": "{count} {rawCount, plural, one {persoon praat} other {mensen praten}} hierover", - "trends.refresh": "Refresh", + "trends.trending_now": "Trends", "ui.beforeunload": "Je concept zal verloren gaan als je Mastodon verlaat.", "upload_area.title": "Hiernaar toe slepen om te uploaden", "upload_button.label": "Media toevoegen ({formats})", "upload_error.limit": "Uploadlimiet van bestand overschreden.", "upload_error.poll": "Het uploaden van bestanden is in polls niet toegestaan.", "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking", - "upload_form.edit": "Edit", + "upload_form.edit": "Bewerken", "upload_form.undo": "Verwijderen", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.analyzing_picture": "Afbeelding analyseren…", + "upload_modal.apply": "Toepassen", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.detect_text": "Tekst in een afbeelding detecteren", + "upload_modal.edit_media": "Media bewerken", + "upload_modal.hint": "Klik of sleep de cirkel in de voorvertoning naar een centraal punt dat op elke thumbnail zichtbaar moet blijven.", + "upload_modal.preview_label": "Voorvertoning ({ratio})", "upload_progress.label": "Uploaden...", "video.close": "Video sluiten", "video.exit_fullscreen": "Volledig scherm sluiten", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json new file mode 100644 index 000000000..dda402494 --- /dev/null +++ b/app/javascript/mastodon/locales/nn.json @@ -0,0 +1,414 @@ +{ + "account.add_or_remove_from_list": "Legg til eller ta vekk fra liste", + "account.badges.bot": "Robot", + "account.block": "Blokkér @{name}", + "account.block_domain": "Gøyme alt innhald for domenet {domain}", + "account.blocked": "Blokkert", + "account.cancel_follow_request": "Avslutt føljar-førespurnad", + "account.direct": "Direkte meld @{name}", + "account.domain_blocked": "Domenet er gøymt", + "account.edit_profile": "Rediger profil", + "account.endorse": "Framhev på profilen din", + "account.follow": "Følj", + "account.followers": "Føljare", + "account.followers.empty": "Er ikkje nokon som føljar denne brukaren ennå.", + "account.follows": "Føljingar", + "account.follows.empty": "Denne brukaren foljer ikkje nokon ennå.", + "account.follows_you": "Føljar deg", + "account.hide_reblogs": "Gøym robotar for @{name}", + "account.last_status": "Sist aktiv", + "account.link_verified_on": "Eigerskap for denne linken er sist sjekket den {date}", + "account.locked_info": "Brukarens privat-status er satt til lukka. Eigaren må manuelt døme kvem som kan følje honom.", + "account.media": "Media", + "account.mention": "Nemne @{name}", + "account.moved_to": "{name} har flytta til:", + "account.mute": "Målbind @{name}", + "account.mute_notifications": "Målbind notifikasjoner ifrå @{name}", + "account.muted": "Målbindt", + "account.never_active": "Aldri", + "account.posts": "Tutar", + "account.posts_with_replies": "Tutar og svar", + "account.report": "Rapporter @{name}", + "account.requested": "Venter på samtykke. Klikk for å avbryte føljar-førespurnad", + "account.share": "Del @{name} sin profil", + "account.show_reblogs": "Sjå framhevingar ifrå @{name}", + "account.unblock": "Avblokker @{name}", + "account.unblock_domain": "Vis {domain}", + "account.unendorse": "Ikkje framhev på profil", + "account.unfollow": "Avfølja", + "account.unmute": "Av-demp @{name}", + "account.unmute_notifications": "Av-demp notifikasjoner ifrå @{name}", + "alert.rate_limited.message": "Ver vennlig og prøv igjen {retry_time, time, medium}.", + "alert.rate_limited.title": "Bregrensa rate", + "alert.unexpected.message": "Eit uforventa problem har hendt.", + "alert.unexpected.title": "Oops!", + "autosuggest_hashtag.per_week": "{count} per veke", + "boost_modal.combo": "Du kan trykke {combo} for å hoppe over dette neste gong", + "bundle_column_error.body": "Noko gikk gale mens komponent ble nedlasta.", + "bundle_column_error.retry": "Prøv igjen", + "bundle_column_error.title": "Tenarmaskin feil", + "bundle_modal_error.close": "Lukk", + "bundle_modal_error.message": "Noko gikk gale mens komponent var i ferd med å bli nedlasta.", + "bundle_modal_error.retry": "Prøv igjen", + "column.blocks": "Blokka brukare", + "column.community": "Lokal samtid", + "column.direct": "Direkte meldingar", + "column.directory": "Sjå gjennom profiler", + "column.domain_blocks": "Gøymte domener", + "column.favourites": "Favorittar", + "column.follow_requests": "Føljarførespurnad", + "column.home": "Heim", + "column.lists": "Lister", + "column.mutes": "Målbindte brukare", + "column.notifications": "Varslinger", + "column.pins": "Festa tuter", + "column.public": "Federert samtid", + "column.status": "Toot", + "column_back_button.label": "Tilbake", + "column_header.hide_settings": "Skjul innstillingar", + "column_header.moveLeft_settings": "Flytt feltet til venstre", + "column_header.moveRight_settings": "Flytt feltet til høgre", + "column_header.pin": "Fest", + "column_header.show_settings": "Vis innstillingar", + "column_header.unpin": "Løys", + "column_subheading.settings": "Innstillingar", + "community.column_settings.media_only": "Kun medie", + "compose_form.direct_message_warning": "Denne tuten vil kun verte synleg for nemnde brukarar.", + "compose_form.direct_message_warning_learn_more": "Lær meir", + "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?", + "compose_form.poll.add_option": "Add a choice", + "compose_form.poll.duration": "Poll duration", + "compose_form.poll.option_placeholder": "Choice {number}", + "compose_form.poll.remove_option": "Remove this choice", + "compose_form.publish": "Toot", + "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.hide": "Mark media as sensitive", + "compose_form.sensitive.marked": "Media is marked as sensitive", + "compose_form.sensitive.unmarked": "Media is not marked as sensitive", + "compose_form.spoiler.marked": "Text is hidden behind warning", + "compose_form.spoiler.unmarked": "Text is not hidden", + "compose_form.spoiler_placeholder": "Write your warning here", + "confirmation_modal.cancel": "Cancel", + "confirmations.block.block_and_report": "Block & Report", + "confirmations.block.confirm": "Block", + "confirmations.block.message": "Are you sure you want to block {name}?", + "confirmations.delete.confirm": "Delete", + "confirmations.delete.message": "Are you sure you want to delete this status?", + "confirmations.delete_list.confirm": "Delete", + "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", + "confirmations.domain_block.confirm": "Hide entire domain", + "confirmations.domain_block.message": "Er du ordentleg, ordentleg sikker på at du vill blokkere heile {domain}? I dei tilfeller er det bedre med ein målretta blokkering eller demping av individuelle brukare.", + "confirmations.logout.confirm": "Logg ut", + "confirmations.logout.message": "Er du sikker på at du vill logge ut?", + "confirmations.mute.confirm": "Målbind", + "confirmations.mute.message": "Er du sikker på at d vill målbinde {name}?", + "confirmations.redraft.confirm": "Slett & gjennopprett", + "confirmations.redraft.message": "Er du sikker på at du vill slette statusen og gjennoprette den? Favoritter og framhevinger vill bli borte, og svar til den originale posten vill bli einstøing.", + "confirmations.reply.confirm": "Svar", + "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", + "confirmations.unfollow.confirm": "Unfollow", + "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", + "embed.instructions": "Embed this status on your website by copying the code below.", + "embed.preview": "Here is what it will look like:", + "emoji_button.activity": "Activity", + "emoji_button.custom": "Custom", + "emoji_button.flags": "Flags", + "emoji_button.food": "Food & Drink", + "emoji_button.label": "Insert emoji", + "emoji_button.nature": "Nature", + "emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", + "emoji_button.objects": "Objects", + "emoji_button.people": "People", + "emoji_button.recent": "Frequently used", + "emoji_button.search": "Search...", + "emoji_button.search_results": "Search results", + "emoji_button.symbols": "Symbols", + "emoji_button.travel": "Travel & Places", + "empty_column.account_timeline": "No toots here!", + "empty_column.account_unavailable": "Profile unavailable", + "empty_column.blocks": "You haven't blocked any users yet.", + "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", + "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.domain_blocks": "There are no hidden domains yet.", + "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", + "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", + "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", + "empty_column.hashtag": "There is nothing in this hashtag yet.", + "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", + "empty_column.home.public_timeline": "the public timeline", + "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", + "empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", + "empty_column.mutes": "You haven't muted any users yet.", + "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", + "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other servers to fill it up", + "follow_request.authorize": "Authorize", + "follow_request.reject": "Reject", + "getting_started.developers": "Developers", + "getting_started.directory": "Profile directory", + "getting_started.documentation": "Documentation", + "getting_started.heading": "Getting started", + "getting_started.invite": "Invite people", + "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", + "getting_started.security": "Security", + "getting_started.terms": "Terms of service", + "hashtag.column_header.tag_mode.all": "and {additional}", + "hashtag.column_header.tag_mode.any": "or {additional}", + "hashtag.column_header.tag_mode.none": "without {additional}", + "hashtag.column_settings.select.no_options_message": "No suggestions found", + "hashtag.column_settings.select.placeholder": "Enter hashtags…", + "hashtag.column_settings.tag_mode.all": "All of these", + "hashtag.column_settings.tag_mode.any": "Any of these", + "hashtag.column_settings.tag_mode.none": "None of these", + "hashtag.column_settings.tag_toggle": "Include additional tags in this column", + "home.column_settings.basic": "Basic", + "home.column_settings.show_reblogs": "Show boosts", + "home.column_settings.show_replies": "Show replies", + "home.column_settings.update_live": "Update in real-time", + "intervals.full.days": "{number, plural, one {# day} other {# days}}", + "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", + "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", + "introduction.federation.action": "Next", + "introduction.federation.federated.headline": "Federated", + "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", + "introduction.federation.home.headline": "Home", + "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", + "introduction.federation.local.headline": "Local", + "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", + "introduction.interactions.action": "Finish toot-orial!", + "introduction.interactions.favourite.headline": "Favourite", + "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", + "introduction.interactions.reblog.headline": "Boost", + "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", + "introduction.interactions.reply.headline": "Reply", + "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", + "introduction.welcome.action": "Let's go!", + "introduction.welcome.headline": "First steps", + "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", + "keyboard_shortcuts.back": "to navigate back", + "keyboard_shortcuts.blocked": "to open blocked users list", + "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.direct": "to open direct messages column", + "keyboard_shortcuts.down": "to move down in the list", + "keyboard_shortcuts.enter": "to open status", + "keyboard_shortcuts.favourite": "to favourite", + "keyboard_shortcuts.favourites": "to open favourites list", + "keyboard_shortcuts.federated": "to open federated timeline", + "keyboard_shortcuts.heading": "Keyboard Shortcuts", + "keyboard_shortcuts.home": "to open home timeline", + "keyboard_shortcuts.hotkey": "Hotkey", + "keyboard_shortcuts.legend": "to display this legend", + "keyboard_shortcuts.local": "to open local timeline", + "keyboard_shortcuts.mention": "to mention author", + "keyboard_shortcuts.muted": "to open muted users list", + "keyboard_shortcuts.my_profile": "to open your profile", + "keyboard_shortcuts.notifications": "to open notifications column", + "keyboard_shortcuts.pinned": "to open pinned toots list", + "keyboard_shortcuts.profile": "to open author's profile", + "keyboard_shortcuts.reply": "to reply", + "keyboard_shortcuts.requests": "to open follow requests list", + "keyboard_shortcuts.search": "to focus search", + "keyboard_shortcuts.start": "to open \"get started\" column", + "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", + "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": "Close", + "lightbox.next": "Next", + "lightbox.previous": "Previous", + "lightbox.view_context": "View context", + "lists.account.add": "Add to list", + "lists.account.remove": "Remove from list", + "lists.delete": "Delete list", + "lists.edit": "Edit list", + "lists.edit.submit": "Change title", + "lists.new.create": "Add list", + "lists.new.title_placeholder": "New list title", + "lists.search": "Search among people you follow", + "lists.subheading": "Your lists", + "load_pending": "{count, plural, one {# new item} other {# new items}}", + "loading_indicator.label": "Loading...", + "media_gallery.toggle_visible": "Toggle visibility", + "missing_indicator.label": "Not found", + "missing_indicator.sublabel": "This resource could not be found", + "mute_modal.hide_notifications": "Hide notifications from this user?", + "navigation_bar.apps": "Mobile apps", + "navigation_bar.blocks": "Blocked users", + "navigation_bar.community_timeline": "Local timeline", + "navigation_bar.compose": "Compose new toot", + "navigation_bar.direct": "Direct messages", + "navigation_bar.discover": "Discover", + "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.edit_profile": "Edit profile", + "navigation_bar.favourites": "Favourites", + "navigation_bar.filters": "Muted words", + "navigation_bar.follow_requests": "Follow requests", + "navigation_bar.follows_and_followers": "Follows and followers", + "navigation_bar.info": "About this server", + "navigation_bar.keyboard_shortcuts": "Hotkeys", + "navigation_bar.lists": "Lists", + "navigation_bar.logout": "Logout", + "navigation_bar.mutes": "Muted users", + "navigation_bar.personal": "Personal", + "navigation_bar.pins": "Pinned toots", + "navigation_bar.preferences": "Preferences", + "navigation_bar.public_timeline": "Federated timeline", + "navigation_bar.security": "Security", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", + "notification.favourite": "{name} favourited your status", + "notification.follow": "{name} followed you", + "notification.mention": "{name} mentioned you", + "notification.poll": "A poll you have voted in has ended", + "notification.reblog": "{name} boosted your status", + "notifications.clear": "Clear notifications", + "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", + "notifications.column_settings.alert": "Desktop notifications", + "notifications.column_settings.favourite": "Favourites:", + "notifications.column_settings.filter_bar.advanced": "Display all categories", + "notifications.column_settings.filter_bar.category": "Quick filter bar", + "notifications.column_settings.filter_bar.show": "Show", + "notifications.column_settings.follow": "New followers:", + "notifications.column_settings.mention": "Mentions:", + "notifications.column_settings.poll": "Poll results:", + "notifications.column_settings.push": "Push notifications", + "notifications.column_settings.reblog": "Boosts:", + "notifications.column_settings.show": "Show in column", + "notifications.column_settings.sound": "Play sound", + "notifications.filter.all": "All", + "notifications.filter.boosts": "Boosts", + "notifications.filter.favourites": "Favourites", + "notifications.filter.follows": "Follows", + "notifications.filter.mentions": "Mentions", + "notifications.filter.polls": "Poll results", + "notifications.group": "{count} notifications", + "poll.closed": "Closed", + "poll.refresh": "Refresh", + "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", + "poll.vote": "Vote", + "poll_button.add_poll": "Add a poll", + "poll_button.remove_poll": "Remove poll", + "privacy.change": "Adjust status privacy", + "privacy.direct.long": "Post to mentioned users only", + "privacy.direct.short": "Direct", + "privacy.private.long": "Post to followers only", + "privacy.private.short": "Followers-only", + "privacy.public.long": "Post to public timelines", + "privacy.public.short": "Public", + "privacy.unlisted.long": "Do not show in public timelines", + "privacy.unlisted.short": "Unlisted", + "regeneration_indicator.label": "Loading…", + "regeneration_indicator.sublabel": "Your home feed is being prepared!", + "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": "Cancel", + "report.forward": "Forward to {target}", + "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", + "report.hint": "The report will be sent to your server moderators. You can provide an explanation of why you are reporting this account below:", + "report.placeholder": "Additional comments", + "report.submit": "Submit", + "report.target": "Report {target}", + "search.placeholder": "Search", + "search_popout.search_format": "Advanced search format", + "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", + "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.accounts": "People", + "search_results.hashtags": "Hashtags", + "search_results.statuses": "Toots", + "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", + "search_results.total": "{count, number} {count, plural, one {result} other {results}}", + "status.admin_account": "Open moderation interface for @{name}", + "status.admin_status": "Open this status in the moderation interface", + "status.block": "Block @{name}", + "status.cancel_reblog_private": "Unboost", + "status.cannot_reblog": "This post cannot be boosted", + "status.copy": "Copy link to status", + "status.delete": "Delete", + "status.detailed_status": "Detailed conversation view", + "status.direct": "Direct message @{name}", + "status.embed": "Embed", + "status.favourite": "Favourite", + "status.filtered": "Filtered", + "status.load_more": "Load more", + "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", + "status.pinned": "Pinned toot", + "status.read_more": "Read more", + "status.reblog": "Boost", + "status.reblog_private": "Boost to original audience", + "status.reblogged_by": "{name} boosted", + "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", + "status.redraft": "Delete & re-draft", + "status.reply": "Reply", + "status.replyAll": "Reply to thread", + "status.report": "Report @{name}", + "status.sensitive_warning": "Sensitive content", + "status.share": "Share", + "status.show_less": "Show less", + "status.show_less_all": "Show less for all", + "status.show_more": "Show more", + "status.show_more_all": "Show more for all", + "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", + "status.unmute_conversation": "Unmute conversation", + "status.unpin": "Unpin from profile", + "suggestions.dismiss": "Dismiss suggestion", + "suggestions.header": "You might be interested in…", + "tabs_bar.federated_timeline": "Federated", + "tabs_bar.home": "Home", + "tabs_bar.local_timeline": "Local", + "tabs_bar.notifications": "Notifications", + "tabs_bar.search": "Search", + "time_remaining.days": "{number, plural, one {# day} other {# days}} left", + "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left", + "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", + "time_remaining.moments": "Moments remaining", + "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", + "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", + "trends.trending_now": "Trending now", + "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", + "upload_area.title": "Drag & drop to upload", + "upload_button.label": "Add media ({formats})", + "upload_error.limit": "File upload limit exceeded.", + "upload_error.poll": "File upload not allowed with polls.", + "upload_form.description": "Describe for the visually impaired", + "upload_form.edit": "Edit", + "upload_form.undo": "Delete", + "upload_modal.analyzing_picture": "Analyzing picture…", + "upload_modal.apply": "Apply", + "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", + "upload_modal.detect_text": "Detect text from picture", + "upload_modal.edit_media": "Edit media", + "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", + "upload_modal.preview_label": "Preview ({ratio})", + "upload_progress.label": "Uploading...", + "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" +} diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index b310efd69..8fc722037 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Følger deg", "account.hide_reblogs": "Skjul fremhevinger fra @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Demp @{name}", "account.mute_notifications": "Ignorer varsler fra @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Innlegg", "account.posts_with_replies": "Toots with replies", "account.report": "Rapportér @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Avfølg", "account.unmute": "Avdemp @{name}", "account.unmute_notifications": "Vis varsler fra @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokkerte brukere", "column.community": "Lokal tidslinje", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Likt", "column.follow_requests": "Følgeforespørsler", @@ -58,6 +63,7 @@ "column.notifications": "Varsler", "column.pins": "Pinned toot", "column.public": "Felles tidslinje", + "column.status": "Toot", "column_back_button.label": "Tilbake", "column_header.hide_settings": "Gjem innstillinger", "column_header.moveLeft_settings": "Flytt feltet til venstre", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Er du sikker på at du vil slette denne listen permanent?", "confirmations.domain_block.confirm": "Skjul alt fra domenet", "confirmations.domain_block.message": "Er du sikker på at du vil skjule hele domenet {domain}? I de fleste tilfeller er det bedre med målrettet blokkering eller demping.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Demp", "confirmations.mute.message": "Er du sikker på at du vil dempe {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Slutt å følge", "confirmations.unfollow.message": "Er du sikker på at du vil slutte å følge {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Kopier koden under for å bygge inn denne statusen på hjemmesiden din.", "embed.preview": "Slik kommer det til å se ut:", "emoji_button.activity": "Aktivitet", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Festa tuter", "navigation_bar.preferences": "Preferanser", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Felles tidslinje", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Vis mer", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Ikke demp samtale", "status.unpin": "Angre festing på profilen", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.", "upload_area.title": "Dra og slipp for å laste opp", "upload_button.label": "Legg til media", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 76b578021..d5abe89fb 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -16,6 +16,7 @@ "account.follows.empty": "Aqueste utilizaire sèc pas degun pel moment.", "account.follows_you": "Vos sèc", "account.hide_reblogs": "Rescondre los partatges de @{name}", + "account.last_status": "Last active", "account.link_verified_on": "La proprietat d’aqueste ligam foguèt verificada lo {date}", "account.locked_info": "L’estatut de privacitat del compte es configurat sus clavat. Lo proprietari causís qual pòt sègre son compte.", "account.media": "Mèdias", @@ -24,6 +25,7 @@ "account.mute": "Rescondre @{name}", "account.mute_notifications": "Rescondre las notificacions de @{name}", "account.muted": "Mes en silenci", + "account.never_active": "Never", "account.posts": "Tuts", "account.posts_with_replies": "Tuts e responsas", "account.report": "Senhalar @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Quitar de sègre", "account.unmute": "Quitar de rescondre @{name}", "account.unmute_notifications": "Mostrar las notificacions de @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Una error s’es producha.", "alert.unexpected.title": "Ops !", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Personas blocadas", "column.community": "Flux public local", "column.direct": "Messatges dirèctes", + "column.directory": "Browse profiles", "column.domain_blocks": "Domenis resconduts", "column.favourites": "Favorits", "column.follow_requests": "Demandas d’abonament", @@ -58,6 +63,7 @@ "column.notifications": "Notificacions", "column.pins": "Tuts penjats", "column.public": "Flux public global", + "column.status": "Toot", "column_back_button.label": "Tornar", "column_header.hide_settings": "Amagar los paramètres", "column_header.moveLeft_settings": "Desplaçar la colomna a man drecha", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Volètz vertadièrament suprimir aquesta lista per totjorn ?", "confirmations.domain_block.confirm": "Amagar tot lo domeni", "confirmations.domain_block.message": "Volètz vertadièrament blocar complètament {domain} ? De còps cal pas que blocar o rescondre unas personas solament.\nVeiretz pas cap de contengut d’aquel domeni dins cap de flux public o dins vòstras notificacions. Vòstres seguidors d’aquel domeni seràn levats.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Rescondre", "confirmations.mute.message": "Volètz vertadièrament rescondre {name} ?", "confirmations.redraft.confirm": "Escafar & tornar formular", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Respondre remplaçarà lo messatge que sètz a escriure. Volètz vertadièrament contunhar ?", "confirmations.unfollow.confirm": "Quitar de sègre", "confirmations.unfollow.message": "Volètz vertadièrament quitar de sègre {name} ?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.", "embed.preview": "Semblarà aquò :", "emoji_button.activity": "Activitats", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Basic", "home.column_settings.show_reblogs": "Mostrar los partatges", "home.column_settings.show_replies": "Mostrar las responsas", - "home.column_settings.update_live": "Actualizacion en dirècte", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# jorn} other {# jorns}}", "intervals.full.hours": "{number, plural, one {# ora} other {# oras}}", "intervals.full.minutes": "{number, plural, one {# minuta} other {# minutas}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Tuts penjats", "navigation_bar.preferences": "Preferéncias", - "navigation_bar.profile_directory": "Annuari de perfils", "navigation_bar.public_timeline": "Flux public global", "navigation_bar.security": "Seguretat", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Desplegar", "status.show_more_all": "Los desplegar totes", "status.show_thread": "Mostrar lo fil", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Tornar mostrar la conversacion", "status.unpin": "Tirar del perfil", "suggestions.dismiss": "Regetar la suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments restants", "time_remaining.seconds": "demòra{number, plural, one { # segonda} other {n # segondas}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} ne charra other {people}} ne charran", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Vòstre brolhon serà perdut se quitatz Mastodon.", "upload_area.title": "Lisatz e depausatz per mandar", "upload_button.label": "Ajustar un mèdia (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 0793dbe01..395f3927a 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -16,6 +16,7 @@ "account.follows.empty": "Ten użytkownik nie śledzi jeszcze nikogo.", "account.follows_you": "Śledzi Cię", "account.hide_reblogs": "Ukryj podbicia od @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Własność tego odnośnika została potwierdzona {date}", "account.locked_info": "To konto jest prywatne. Właściciel ręcznie wybiera kto może go śledzić.", "account.media": "Zawartość multimedialna", @@ -24,6 +25,7 @@ "account.mute": "Wycisz @{name}", "account.mute_notifications": "Wycisz powiadomienia o @{name}", "account.muted": "Wyciszony", + "account.never_active": "Never", "account.posts": "Wpisy", "account.posts_with_replies": "Wpisy i odpowiedzi", "account.report": "Zgłoś @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Przestań śledzić", "account.unmute": "Cofnij wyciszenie @{name}", "account.unmute_notifications": "Cofnij wyciszenie powiadomień od @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Wystąpił nieoczekiwany błąd.", "alert.unexpected.title": "O nie!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Zablokowani użytkownicy", "column.community": "Lokalna oś czasu", "column.direct": "Wiadomości bezpośrednie", + "column.directory": "Browse profiles", "column.domain_blocks": "Ukryte domeny", "column.favourites": "Ulubione", "column.follow_requests": "Prośby o śledzenie", @@ -58,6 +63,7 @@ "column.notifications": "Powiadomienia", "column.pins": "Przypięte wpisy", "column.public": "Globalna oś czasu", + "column.status": "Toot", "column_back_button.label": "Wróć", "column_header.hide_settings": "Ukryj ustawienia", "column_header.moveLeft_settings": "Przesuń kolumnę w lewo", @@ -99,6 +105,8 @@ "confirmations.delete_list.message": "Czy na pewno chcesz bezpowrotnie usunąć tą listę?", "confirmations.domain_block.confirm": "Ukryj wszysyko z domeny", "confirmations.domain_block.message": "Czy na pewno chcesz zablokować całą domenę {domain}? Zwykle lepszym rozwiązaniem jest blokada lub wyciszenie kilku użytkowników.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Wycisz", "confirmations.mute.message": "Czy na pewno chcesz wyciszyć {name}?", "confirmations.redraft.confirm": "Usuń i przeredaguj", @@ -107,6 +115,10 @@ "confirmations.reply.message": "W ten sposób utracisz wpis który obecnie tworzysz. Czy na pewno chcesz to zrobić?", "confirmations.unfollow.confirm": "Przestań śledzić", "confirmations.unfollow.message": "Czy na pewno zamierzasz przestać śledzić {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Osadź ten wpis na swojej stronie wklejając poniższy kod.", "embed.preview": "Tak będzie to wyglądać:", "emoji_button.activity": "Aktywność", @@ -255,7 +267,6 @@ "navigation_bar.personal": "Osobiste", "navigation_bar.pins": "Przypięte wpisy", "navigation_bar.preferences": "Preferencje", - "navigation_bar.profile_directory": "Katalog profilów", "navigation_bar.public_timeline": "Globalna oś czasu", "navigation_bar.security": "Bezpieczeństwo", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -363,6 +374,7 @@ "status.show_more": "Rozwiń", "status.show_more_all": "Rozwiń wszystkie", "status.show_thread": "Pokaż wątek", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Cofnij wyciszenie konwersacji", "status.unpin": "Odepnij z profilu", "suggestions.dismiss": "Odrzuć sugestię", @@ -378,7 +390,7 @@ "time_remaining.moments": "Pozostała chwila", "time_remaining.seconds": "{number, plural, one {Pozostała # sekunda} few {Pozostały # sekundy} many {Pozostało # sekund} other {Pozostało # sekund}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {osoba rozmawia} few {osoby rozmawiają} other {osób rozmawia}} o tym", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Utracisz tworzony wpis, jeżeli opuścisz Mastodona.", "upload_area.title": "Przeciągnij i upuść aby wysłać", "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)", @@ -388,7 +400,7 @@ "upload_form.edit": "Edit", "upload_form.undo": "Usuń", "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.apply": "Zastosuj", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Detect text from picture", "upload_modal.edit_media": "Edit media", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 523378276..debf9e6f6 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -16,6 +16,7 @@ "account.follows.empty": "Esse usuário não segue ninguém no momento.", "account.follows_you": "Segue você", "account.hide_reblogs": "Esconder compartilhamentos de @{name}", + "account.last_status": "Last active", "account.link_verified_on": "A posse desse link foi verificada em {date}", "account.locked_info": "Essa conta está trancada. Se você a seguir sua solicitação será revisada manualmente.", "account.media": "Mídia", @@ -24,6 +25,7 @@ "account.mute": "Silenciar @{name}", "account.mute_notifications": "Silenciar notificações de @{name}", "account.muted": "Silenciado", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots e respostas", "account.report": "Denunciar @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Deixar de seguir", "account.unmute": "Não silenciar @{name}", "account.unmute_notifications": "Retirar silêncio das notificações vindas de @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Um erro inesperado ocorreu.", "alert.unexpected.title": "Eita!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Usuários bloqueados", "column.community": "Local", "column.direct": "Mensagens diretas", + "column.directory": "Browse profiles", "column.domain_blocks": "Domínios escondidos", "column.favourites": "Favoritos", "column.follow_requests": "Seguidores pendentes", @@ -58,6 +63,7 @@ "column.notifications": "Notificações", "column.pins": "Postagens fixadas", "column.public": "Global", + "column.status": "Toot", "column_back_button.label": "Voltar", "column_header.hide_settings": "Esconder configurações", "column_header.moveLeft_settings": "Mover coluna para a esquerda", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Você tem certeza que quer deletar permanentemente a lista?", "confirmations.domain_block.confirm": "Esconder o domínio inteiro", "confirmations.domain_block.message": "Você quer mesmo bloquear {domain} inteiro? Na maioria dos casos, silenciar ou bloquear alguns usuários é o suficiente e o recomendado. Você não vai ver conteúdo desse domínio em nenhuma das timelines públicas ou nas suas notificações. Seus seguidores desse domínio serão removidos.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Silenciar", "confirmations.mute.message": "Você tem certeza de que quer silenciar {name}?", "confirmations.redraft.confirm": "Apagar & usar como rascunho", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Responder agora vai sobrescrever a mensagem que você está compondo. Você tem certeza que quer continuar?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "Você tem certeza de que quer deixar de seguir {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Incorpore esta postagem em seu site copiando o código abaixo.", "embed.preview": "Aqui está uma previsão de como ficará:", "emoji_button.activity": "Atividades", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Pessoal", "navigation_bar.pins": "Postagens fixadas", "navigation_bar.preferences": "Preferências", - "navigation_bar.profile_directory": "Diretório de perfis", "navigation_bar.public_timeline": "Global", "navigation_bar.security": "Segurança", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostrar mais", "status.show_more_all": "Mostrar mais para todas as mensagens", "status.show_thread": "Mostrar sequência", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Desativar silêncio desta conversa", "status.unpin": "Desafixar do perfil", "suggestions.dismiss": "Ignorar a sugestão", @@ -373,7 +385,7 @@ "time_remaining.moments": "Momentos restantes", "time_remaining.seconds": "{number, plural, one {# segundo restante} other {# segundos restantes}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {pessoa} other {pessoas}} falando sobre", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Seu rascunho será perdido se você sair do Mastodon.", "upload_area.title": "Arraste e solte para enviar", "upload_button.label": "Adicionar mídia (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt-PT.json index 7ce628422..feba8fd9a 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt-PT.json @@ -16,6 +16,7 @@ "account.follows.empty": "Este utilizador ainda não segue alguém.", "account.follows_you": "É teu seguidor", "account.hide_reblogs": "Esconder partilhas de @{name}", + "account.last_status": "Last active", "account.link_verified_on": "A posse deste link foi verificada em {date}", "account.locked_info": "O estatuto de privacidade desta conta é fechado. O dono revê manualmente que a pode seguir.", "account.media": "Média", @@ -24,6 +25,7 @@ "account.mute": "Silenciar @{name}", "account.mute_notifications": "Silenciar notificações de @{name}", "account.muted": "Silenciada", + "account.never_active": "Never", "account.posts": "Publicações", "account.posts_with_replies": "Publicações e respostas", "account.report": "Denunciar @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Deixar de seguir", "account.unmute": "Não silenciar @{name}", "account.unmute_notifications": "Deixar de silenciar @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Ocorreu um erro inesperado.", "alert.unexpected.title": "Bolas!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Utilizadores Bloqueados", "column.community": "Cronologia local", "column.direct": "Mensagens directas", + "column.directory": "Browse profiles", "column.domain_blocks": "Domínios escondidos", "column.favourites": "Favoritos", "column.follow_requests": "Seguidores pendentes", @@ -58,6 +63,7 @@ "column.notifications": "Notificações", "column.pins": "Publicações fixas", "column.public": "Cronologia federada", + "column.status": "Toot", "column_back_button.label": "Voltar", "column_header.hide_settings": "Esconder configurações", "column_header.moveLeft_settings": "Mover coluna para a esquerda", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Tens a certeza de que desejas eliminar permanentemente esta lista?", "confirmations.domain_block.confirm": "Esconder tudo deste domínio", "confirmations.domain_block.message": "De certeza que queres bloquear completamente o domínio {domain}? Na maioria dos casos, silenciar ou bloquear alguns utilizadores é suficiente e é o recomendado. Não irás ver conteúdo daquele domínio em cronologia alguma nem nas tuas notificações. Os teus seguidores daquele domínio serão removidos.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Silenciar", "confirmations.mute.message": "De certeza que queres silenciar {name}?", "confirmations.redraft.confirm": "Apagar & redigir", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Responder agora irá reescrever a mensagem que estás a compor actualmente. Tens a certeza que queres continuar?", "confirmations.unfollow.confirm": "Deixar de seguir", "confirmations.unfollow.message": "De certeza que queres deixar de seguir {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Publica esta publicação no teu site copiando o código abaixo.", "embed.preview": "Podes ver aqui como irá ficar:", "emoji_button.activity": "Actividade", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Pessoal", "navigation_bar.pins": "Toots afixados", "navigation_bar.preferences": "Preferências", - "navigation_bar.profile_directory": "Directório de perfis", "navigation_bar.public_timeline": "Cronologia federada", "navigation_bar.security": "Segurança", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Mostrar mais", "status.show_more_all": "Mostrar mais para todas", "status.show_thread": "Mostrar conversa", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Deixar de silenciar esta conversa", "status.unpin": "Não fixar no perfil", "suggestions.dismiss": "Dispensar a sugestão", @@ -373,7 +385,7 @@ "time_remaining.moments": "Momentos restantes", "time_remaining.seconds": "{número, plural, um {# second} outro {# seconds}} faltam", "trends.count_by_accounts": "{count} {rawCount, plural, uma {person} outra {people}} a falar", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "O teu rascunho será perdido se abandonares o Mastodon.", "upload_area.title": "Arraste e solte para enviar", "upload_button.label": "Adicionar media", diff --git a/app/javascript/mastodon/locales/ro.json b/app/javascript/mastodon/locales/ro.json index 141ccd5ab..038b8ddd4 100644 --- a/app/javascript/mastodon/locales/ro.json +++ b/app/javascript/mastodon/locales/ro.json @@ -16,6 +16,7 @@ "account.follows.empty": "Acest utilizator nu urmărește pe nimeni incă.", "account.follows_you": "Te urmărește", "account.hide_reblogs": "Ascunde redistribuirile de la @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Deținerea acestui link a fost verificată la {date}", "account.locked_info": "Acest profil este privat. Această persoană gestioneaz manual cine o urmărește.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Oprește @{name}", "account.mute_notifications": "Oprește notificările de la @{name}", "account.muted": "Oprit", + "account.never_active": "Never", "account.posts": "Postări", "account.posts_with_replies": "Postări și replici", "account.report": "Raportează @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Nu mai urmări", "account.unmute": "Activează notificările de la @{name}", "account.unmute_notifications": "Activează notificările de la @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "A apărut o eroare neașteptată.", "alert.unexpected.title": "Hopa!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Utilizatori blocați", "column.community": "Fluxul Local", "column.direct": "Mesaje directe", + "column.directory": "Browse profiles", "column.domain_blocks": "Domenii ascunse", "column.favourites": "Favorite", "column.follow_requests": "Cereri de urmărire", @@ -58,6 +63,7 @@ "column.notifications": "Notificări", "column.pins": "Postări fixate", "column.public": "Flux global", + "column.status": "Toot", "column_back_button.label": "Înapoi", "column_header.hide_settings": "Ascunde setările", "column_header.moveLeft_settings": "Mută coloana la stânga", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ești sigur că vrei să ștergi permanent această listă?", "confirmations.domain_block.confirm": "Ascunde tot domeniul", "confirmations.domain_block.message": "Ești absolut sigur că vrei să blochezi complet {domain}? În cele mai multe cazuri raportarea sau oprirea anumitor lucruri este suficientă și de preferat. Nu vei mai vedea nici un conținut de la acest domeniu in nici un flux public sau în notificările tale. Urmăritorii tăi de la acele domenii vor fi eliminați.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Oprește", "confirmations.mute.message": "Ești sigur că vrei să oprești {name}?", "confirmations.redraft.confirm": "Șterge și salvează ca ciornă", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Răspunzând la asta acum, mesajul pe care îl compui în prezent se va șterge. Ești sigur că vrei să continui?", "confirmations.unfollow.confirm": "Nu mai urmări", "confirmations.unfollow.message": "Ești sigur că nu mai vrei să îl urmărești pe {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Inserează această postare pe site-ul tău adăugând codul de mai jos.", "embed.preview": "Cam așa va arăta:", "emoji_button.activity": "Activitate", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Postări fixate", "navigation_bar.preferences": "Preferințe", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Flux global", "navigation_bar.security": "Securitate", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Arată mai mult", "status.show_more_all": "Arată mai mult pentru toți", "status.show_thread": "Arată topicul", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Repornește conversația", "status.unpin": "Eliberează din profil", "suggestions.dismiss": "Omite sugestia", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} vorbesc", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Postarea se va pierde dacă părăsești pagina.", "upload_area.title": "Trage și eliberează pentru a încărca", "upload_button.label": "Adaugă media (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index afc064a6b..69bd5a422 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -16,6 +16,7 @@ "account.follows.empty": "Этот пользователь ни на кого не подписан.", "account.follows_you": "Подписан(а) на вас", "account.hide_reblogs": "Скрыть реблоги от @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Владение этой ссылкой было проверено {date}", "account.locked_info": "Это закрытый аккаунт. Его владелец вручную одобряет подписчиков.", "account.media": "Медиа", @@ -24,6 +25,7 @@ "account.mute": "Скрыть @{name}", "account.mute_notifications": "Скрыть уведомления от @{name}", "account.muted": "Скрыт", + "account.never_active": "Never", "account.posts": "Посты", "account.posts_with_replies": "Посты с ответами", "account.report": "Пожаловаться", @@ -36,6 +38,8 @@ "account.unfollow": "Отписаться", "account.unmute": "Снять глушение", "account.unmute_notifications": "Показывать уведомления от @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Что-то пошло не так.", "alert.unexpected.title": "Ой!", "autosuggest_hashtag.per_week": "{count} / неделю", @@ -49,6 +53,7 @@ "column.blocks": "Список блокировки", "column.community": "Локальная лента", "column.direct": "Личные сообщения", + "column.directory": "Browse profiles", "column.domain_blocks": "Скрытые домены", "column.favourites": "Понравившееся", "column.follow_requests": "Запросы на подписку", @@ -58,6 +63,7 @@ "column.notifications": "Уведомления", "column.pins": "Закреплённый пост", "column.public": "Глобальная лента", + "column.status": "Toot", "column_back_button.label": "Назад", "column_header.hide_settings": "Скрыть настройки", "column_header.moveLeft_settings": "Передвинуть колонку влево", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Вы действительно хотите навсегда удалить этот список?", "confirmations.domain_block.confirm": "Блокировать весь домен", "confirmations.domain_block.message": "Вы на самом деле уверены, что хотите блокировать весь {domain}? В большинстве случаев нескольких отдельных блокировок или глушений достаточно.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Заглушить", "confirmations.mute.message": "Вы уверены, что хотите заглушить {name}?", "confirmations.redraft.confirm": "Удалить и исправить", @@ -103,6 +111,10 @@ "confirmations.reply.message": "При ответе текст набираемого сообщения будет перезаписан. Продолжить?", "confirmations.unfollow.confirm": "Отписаться", "confirmations.unfollow.message": "Вы уверены, что хотите отписаться от {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Встройте этот статус на Вашем сайте, скопировав код внизу.", "embed.preview": "Так это будет выглядеть:", "emoji_button.activity": "Занятия", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Основные", "home.column_settings.show_reblogs": "Показывать продвижения", "home.column_settings.show_replies": "Показывать ответы", - "home.column_settings.update_live": "Обновлять в реальном времени", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# день} few {# дня} other {# дней}}", "intervals.full.hours": "{number, plural, one {# час} few {# часа} other {# часов}}", "intervals.full.minutes": "{number, plural, one {# минута} few {# минуты} other {# минут}}", @@ -249,8 +261,7 @@ "navigation_bar.mutes": "Список скрытых пользователей", "navigation_bar.personal": "Личное", "navigation_bar.pins": "Закреплённые посты", - "navigation_bar.preferences": "Опции", - "navigation_bar.profile_directory": "Каталог профилей", + "navigation_bar.preferences": "Настройки", "navigation_bar.public_timeline": "Глобальная лента", "navigation_bar.security": "Безопасность", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Развернуть", "status.show_more_all": "Развернуть для всех", "status.show_thread": "Показать обсуждение", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Снять глушение с обсуждения", "status.unpin": "Открепить от профиля", "suggestions.dismiss": "Удалить предложение", @@ -372,8 +384,8 @@ "time_remaining.minutes": "{number, plural, one {осталась # минута} few {осталось # минуты} many {осталось # минут} other {осталось # минут}}", "time_remaining.moments": "остались считанные мгновения", "time_remaining.seconds": "{number, plural, one {осталась # секунду} few {осталось # секунды} many {осталось # секунд} other {осталось # секунд}}", - "trends.count_by_accounts": "Популярно у {count} {rawCount, plural, one {человека} few {человек} many {человек} other {человек}}", - "trends.refresh": "Обновить", + "trends.count_by_accounts": "{count} {rawCount, plural, one {человек говорит} few {человека говорят} other {человек говорят}} про это", + "trends.trending_now": "Самое актуальное", "ui.beforeunload": "Ваш черновик будет утерян, если вы покинете Mastodon.", "upload_area.title": "Перетащите сюда, чтобы загрузить", "upload_button.label": "Добавить медиаконтент", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 4a7625aae..89a472d89 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -16,14 +16,16 @@ "account.follows.empty": "Tento užívateľ ešte nikoho nenásleduje.", "account.follows_you": "Následuje ťa", "account.hide_reblogs": "Skry vyzdvihnutia od @{name}", + "account.last_status": "Naposledy aktívny", "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}", "account.locked_info": "Stav súkromia pre tento účet je nastavený na zamknutý. Jeho vlastník sám prehodnocuje, kto ho môže sledovať.", "account.media": "Médiá", "account.mention": "Spomeň @{name}", "account.moved_to": "{name} sa presunul/a na:", - "account.mute": "Ignorovať @{name}", + "account.mute": "Nevšímaj si @{name}", "account.mute_notifications": "Stĺm oboznámenia od @{name}", "account.muted": "Utíšený/á", + "account.never_active": "Nikdy", "account.posts": "Príspevkov", "account.posts_with_replies": "Príspevky aj s odpoveďami", "account.report": "Nahlás @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Prestaň následovať", "account.unmute": "Prestaň ignorovať @{name}", "account.unmute_notifications": "Zruš stĺmenie oboznámení od @{name}", + "alert.rate_limited.message": "Prosím, skús to znova za {retry_time, time, medium}.", + "alert.rate_limited.title": "Tempo obmedzené", "alert.unexpected.message": "Vyskytla sa nečakaná chyba.", "alert.unexpected.title": "Ups!", "autosuggest_hashtag.per_week": "{count} týždenne", @@ -49,6 +53,7 @@ "column.blocks": "Blokovaní užívatelia", "column.community": "Miestna časová os", "column.direct": "Súkromné správy", + "column.directory": "Prehľadávaj profily", "column.domain_blocks": "Skryté domény", "column.favourites": "Obľúbené", "column.follow_requests": "Žiadosti o sledovanie", @@ -58,6 +63,7 @@ "column.notifications": "Oboznámenia", "column.pins": "Pripnuté príspevky", "column.public": "Federovaná časová os", + "column.status": "Toot", "column_back_button.label": "Späť", "column_header.hide_settings": "Skryť nastavenia", "column_header.moveLeft_settings": "Presuň stĺpec doľava", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Si si istý/á, že chceš natrvalo vymazať tento zoznam?", "confirmations.domain_block.confirm": "Skry celú doménu", "confirmations.domain_block.message": "Si si naozaj istý/á, že chceš blokovať celú doménu {domain}? Vo väčšine prípadov stačí blokovať alebo ignorovať pár konkrétnych užívateľov, čo sa doporučuje. Neuvidíš obsah z tejto domény v žiadnej verejnej časovej osi, ani v oznámeniach. Tvoji následovníci pochádzajúci z tejto domény budú odstránení.", + "confirmations.logout.confirm": "Odhlás sa", + "confirmations.logout.message": "Si si istý/á, že sa chceš odhlásiť?", "confirmations.mute.confirm": "Ignoruj", "confirmations.mute.message": "Naozaj chceš ignorovať {name}?", "confirmations.redraft.confirm": "Vyčisti a prepíš", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Odpovedaním akurát teraz prepíšeš správu, ktorú máš práve rozpísanú. Si si istý/á, že chceš pokračovať?", "confirmations.unfollow.confirm": "Nesleduj", "confirmations.unfollow.message": "Naozaj chceš prestať sledovať {name}?", + "directory.federated": "Zo známého fedivesmíru", + "directory.local": "Iba z {domain}", + "directory.new_arrivals": "Nové príchody", + "directory.recently_active": "Nedávno aktívne", "embed.instructions": "Umiestni kód uvedený nižšie pre pridanie tohto statusu na tvoju web stránku.", "embed.preview": "Tu je ako to bude vyzerať:", "emoji_button.activity": "Aktivita", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Základné", "home.column_settings.show_reblogs": "Zobraziť povýšené", "home.column_settings.show_replies": "Ukázať odpovede", - "home.column_settings.update_live": "Aktualizuj v reálnom čase", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# deň} few {# dní} many {# dní} other {# dní}}", "intervals.full.hours": "{number, plural, one {# hodina} few {# hodín} many {# hodín} other {# hodín}}", "intervals.full.minutes": "{number, plural, one {# minúta} few {# minút} many {# minút} other {# minút}}", @@ -250,10 +262,9 @@ "navigation_bar.personal": "Osobné", "navigation_bar.pins": "Pripnuté príspevky", "navigation_bar.preferences": "Voľby", - "navigation_bar.profile_directory": "Katalóg profilov", "navigation_bar.public_timeline": "Federovaná časová os", "navigation_bar.security": "Zabezbečenie", - "notification.and_n_others": "a {count, plural,one {# ostatní} other {# ostatných}}", + "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} si obľúbil/a tvoj príspevok", "notification.follow": "{name} ťa začal/a následovať", "notification.mention": "{name} ťa spomenul/a", @@ -358,6 +369,7 @@ "status.show_more": "Ukáž viac", "status.show_more_all": "Všetkým ukáž viac", "status.show_thread": "Ukáž diskusné vlákno", + "status.uncached_media_warning": "Nedostupný/é", "status.unmute_conversation": "Prestaň ignorovať konverzáciu", "status.unpin": "Odopni z profilu", "suggestions.dismiss": "Zavrhni návrh", @@ -373,7 +385,7 @@ "time_remaining.moments": "Ostáva už iba chviľka", "time_remaining.seconds": "Ostáva {number, plural, one {# sekunda} few {# sekúnd} many {# sekúnd} other {# sekúnd}}", "trends.count_by_accounts": "{count} {rawCount, plural, one {človek vraví} other {ľudia vravia}}", - "trends.refresh": "Obnov", + "trends.trending_now": "Teraz populárne", "ui.beforeunload": "Čo máš rozpísané sa stratí, ak opustíš Mastodon.", "upload_area.title": "Pretiahni a pusť pre nahratie", "upload_button.label": "Pridaj médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)", @@ -382,13 +394,13 @@ "upload_form.description": "Opis pre slabo vidiacich", "upload_form.edit": "Uprav", "upload_form.undo": "Vymaž", - "upload_modal.analyzing_picture": "Analyzing picture…", + "upload_modal.analyzing_picture": "Analyzujem obrázok…", "upload_modal.apply": "Použi", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", + "upload_modal.description_placeholder": "Rýchla hnedá líška skáče ponad lenivého psa", + "upload_modal.detect_text": "Rozpoznaj text z obrázka", "upload_modal.edit_media": "Uprav médiá", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.preview_label": "Náhľad ({ratio})", "upload_progress.label": "Nahráva sa...", "video.close": "Zavri video", "video.exit_fullscreen": "Vypni zobrazenie na celú obrazovku", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json index 8a5a0d4bb..d7d78c41c 100644 --- a/app/javascript/mastodon/locales/sl.json +++ b/app/javascript/mastodon/locales/sl.json @@ -16,6 +16,7 @@ "account.follows.empty": "Ta uporabnik še ne sledi nikomur.", "account.follows_you": "Sledi tebi", "account.hide_reblogs": "Skrij spodbude od @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Lastništvo te povezave je bilo preverjeno {date}", "account.locked_info": "Stanje zasebnosti računa je nastavljeno na zaklenjeno. Lastnik ročno pregleda, kdo ga lahko spremlja.", "account.media": "Mediji", @@ -24,6 +25,7 @@ "account.mute": "Utišaj @{name}", "account.mute_notifications": "Utišaj obvestila od @{name}", "account.muted": "Utišan", + "account.never_active": "Never", "account.posts": "Tuti", "account.posts_with_replies": "Tuti in odgovori", "account.report": "Prijavi @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Prenehaj slediti", "account.unmute": "Odtišaj @{name}", "account.unmute_notifications": "Vklopi obvestila od @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Zgodila se je nepričakovana napaka.", "alert.unexpected.title": "Uups!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokirani uporabniki", "column.community": "Lokalna časovnica", "column.direct": "Neposredna sporočila", + "column.directory": "Browse profiles", "column.domain_blocks": "Skrite domene", "column.favourites": "Priljubljene", "column.follow_requests": "Sledi prošnjam", @@ -58,6 +63,7 @@ "column.notifications": "Obvestila", "column.pins": "Pripeti tuti", "column.public": "Združena časovnica", + "column.status": "Toot", "column_back_button.label": "Nazaj", "column_header.hide_settings": "Skrij nastavitve", "column_header.moveLeft_settings": "Premakni stolpec na levo", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ali ste prepričani, da želite trajno izbrisati ta seznam?", "confirmations.domain_block.confirm": "Skrij celotno domeno", "confirmations.domain_block.message": "Ali ste res, res prepričani, da želite blokirati celotno {domain}? V večini primerov je nekaj ciljnih blokiranj ali utišanj dovolj in boljše. Vsebino iz te domene ne boste videli v javnih časovnicah ali obvestilih. Vaši sledilci iz te domene bodo odstranjeni.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Utišanje", "confirmations.mute.message": "Ali ste prepričani, da želite utišati {name}?", "confirmations.redraft.confirm": "Izbriši in preoblikuj", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Odgovarjanje bo prepisalo sporočilo, ki ga trenutno sestavljate. Ali ste prepričani, da želite nadaljevati?", "confirmations.unfollow.confirm": "Prenehaj slediti", "confirmations.unfollow.message": "Ali ste prepričani, da ne želite več slediti {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Vstavi ta status na svojo spletno stran tako, da kopirate spodnjo kodo.", "embed.preview": "Tako bo izgledalo:", "emoji_button.activity": "Dejavnost", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Osnovno", "home.column_settings.show_reblogs": "Pokaži spodbude", "home.column_settings.show_replies": "Pokaži odgovore", - "home.column_settings.update_live": "Posodabljaj v realnem času", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# dan} two {# dni} few {# dni} other {# dni}}", "intervals.full.hours": "{number, plural, one {# ura} two {# uri} few {# ure} other {# ur}}", "intervals.full.minutes": "{number, plural, one {# minuta} two {# minuti} few {# minute} other {# minut}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Osebno", "navigation_bar.pins": "Pripeti tuti", "navigation_bar.preferences": "Nastavitve", - "navigation_bar.profile_directory": "Imenik profilov", "navigation_bar.public_timeline": "Združena časovnica", "navigation_bar.security": "Varnost", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Prikaži več", "status.show_more_all": "Prikaži več za vse", "status.show_thread": "Prikaži objavo", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Odtišaj pogovor", "status.unpin": "Odpni iz profila", "suggestions.dismiss": "Zavrni predlog", @@ -373,7 +385,7 @@ "time_remaining.moments": "Preostali trenutki", "time_remaining.seconds": "{number, plural, one {# sekunda} other {# sekund}} je ostalo", "trends.count_by_accounts": "{count} {rawCount, plural, one {oseba} other {ljudi}} govori", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Vaš osnutek bo izgubljen, če zapustite Mastodona.", "upload_area.title": "Za pošiljanje povlecite in spustite", "upload_button.label": "Dodaj medije ({formats})", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index 9877ca93f..0f851051c 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -16,6 +16,7 @@ "account.follows.empty": "Ky përdorues ende s’ndjek njeri.", "account.follows_you": "Ju ndjek", "account.hide_reblogs": "Fshih përforcime nga @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Pronësia e kësaj lidhjeje qe kontrolluar më {date}", "account.locked_info": "Gjendja e privatësisë së kësaj llogarie është caktuar si e kyçur. I zoti merr dorazi në shqyrtim cilët mund ta ndjekin.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Heshtoni @{name}", "account.mute_notifications": "Heshtoji njoftimet prej @{name}", "account.muted": "Heshtuar", + "account.never_active": "Never", "account.posts": "Mesazhe", "account.posts_with_replies": "Mesazhe dhe përgjigje", "account.report": "Raportojeni @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Resht së ndjekuri", "account.unmute": "Ktheji zërin @{name}", "account.unmute_notifications": "Hiqua ndalimin e shfaqjes njoftimeve nga @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Ndodhi një gabim të papritur.", "alert.unexpected.title": "Hëm!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Përdorues të bllokuar", "column.community": "Rrjedhë kohore vendore", "column.direct": "Mesazhe të drejtpërdrejta", + "column.directory": "Browse profiles", "column.domain_blocks": "Përkatësi të fshehura", "column.favourites": "Të parapëlqyer", "column.follow_requests": "Kërkesa për ndjekje", @@ -58,6 +63,7 @@ "column.notifications": "Njoftime", "column.pins": "Mesazhe të fiksuar", "column.public": "Rrjedhë kohore e federuar", + "column.status": "Toot", "column_back_button.label": "Mbrapsht", "column_header.hide_settings": "Fshihi rregullimet", "column_header.moveLeft_settings": "Shpjere shtyllën majtas", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Jeni i sigurt që doni të fshihet përgjithmonë kjo listë?", "confirmations.domain_block.confirm": "Fshih krejt përkatësinë", "confirmations.domain_block.message": "Jeni i sigurt, shumë i sigurt se doni të bllokohet krejt {domain}? Në shumicën e rasteve, ndoca bllokime ose heshtime me synim të caktuar janë të mjaftueshme dhe të parapëlqyera. S’keni për të parë lëndë nga kjo përkatësi në ndonjë rrjedhë kohore publike, apo te njoftimet tuaja. Ndjekësit tuaj prej asaj përkatësie do të hiqen.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Heshtoje", "confirmations.mute.message": "Jeni i sigurt se doni të heshtohet {name}?", "confirmations.redraft.confirm": "Fshijeni & rihartojeni", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Përgjigja tani do të shkaktojë mbishkrimin e mesazhit që po hartoni. Jeni i sigurt se doni të vazhdohet më tej?", "confirmations.unfollow.confirm": "Resht së ndjekuri", "confirmations.unfollow.message": "Jeni i sigurt se doni të mos ndiqet më {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Trupëzojeni këtë gjendje në sajtin tuaj duke kopjuar kodin më poshtë.", "embed.preview": "Ja si do të duket:", "emoji_button.activity": "Veprimtari", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personale", "navigation_bar.pins": "Mesazhe të fiksuar", "navigation_bar.preferences": "Parapëlqime", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Rrjedhë kohore të federuarish", "navigation_bar.security": "Siguri", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Shfaq më tepër", "status.show_more_all": "Shfaq më tepër për të tërë", "status.show_thread": "Shfaq rrjedhën", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Ktheji zërin bisedës", "status.unpin": "Shfiksoje nga profili", "suggestions.dismiss": "Mos e merr parasysh sugjerimin", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, një {person} {people} të tjerë} po flasin", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Skica juaj do të humbë nëse dilni nga Mastodon-i.", "upload_area.title": "Merreni & vëreni që të ngarkohet", "upload_button.label": "Shtoni media (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index e60e2c7e8..fb6a365ce 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Prati Vas", "account.hide_reblogs": "Sakrij podrške koje daje korisnika @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Mediji", @@ -24,6 +25,7 @@ "account.mute": "Ućutkaj korisnika @{name}", "account.mute_notifications": "Isključi obaveštenja od korisnika @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Statusa", "account.posts_with_replies": "Toots with replies", "account.report": "Prijavi @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Otprati", "account.unmute": "Ukloni ućutkavanje korisniku @{name}", "account.unmute_notifications": "Uključi nazad obaveštenja od korisnika @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blokirani korisnici", "column.community": "Lokalna lajna", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Omiljeni", "column.follow_requests": "Zahtevi za praćenje", @@ -58,6 +63,7 @@ "column.notifications": "Obaveštenja", "column.pins": "Prikačeni tutovi", "column.public": "Federisana lajna", + "column.status": "Toot", "column_back_button.label": "Nazad", "column_header.hide_settings": "Sakrij postavke", "column_header.moveLeft_settings": "Pomeri kolonu ulevo", @@ -95,6 +101,8 @@ "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.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Ućutkaj", "confirmations.mute.message": "Da li stvarno želite da ućutkate korisnika {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Otprati", "confirmations.unfollow.message": "Da li ste sigurni da želite da otpratite korisnika {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Ugradi ovaj status na Vaš veb sajt kopiranjem koda ispod.", "embed.preview": "Ovako će da izgleda:", "emoji_button.activity": "Aktivnost", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Prikačeni tutovi", "navigation_bar.preferences": "Podešavanja", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federisana lajna", "navigation_bar.security": "Security", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Prikaži više", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Uključi prepisku", "status.unpin": "Otkači sa profila", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Ako napustite Mastodont, izgubićete napisani nacrt.", "upload_area.title": "Prevucite ovde da otpremite", "upload_button.label": "Dodaj multimediju", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index 82833630c..064934f54 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -16,6 +16,7 @@ "account.follows.empty": "Корисник тренутно не прати никога.", "account.follows_you": "Прати Вас", "account.hide_reblogs": "Сакриј подршке које даје корисника @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Медији", @@ -24,6 +25,7 @@ "account.mute": "Ућуткај корисника @{name}", "account.mute_notifications": "Искључи обавештења од корисника @{name}", "account.muted": "Ућуткан", + "account.never_active": "Never", "account.posts": "Трубе", "account.posts_with_replies": "Трубе и одговори", "account.report": "Пријави @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Отпрати", "account.unmute": "Уклони ућуткавање кориснику @{name}", "account.unmute_notifications": "Укључи назад обавештења од корисника @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Појавила се неочекивана грешка.", "alert.unexpected.title": "Упс!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Блокирани корисници", "column.community": "Локална временска линија", "column.direct": "Директне поруке", + "column.directory": "Browse profiles", "column.domain_blocks": "Скривени домени", "column.favourites": "Омиљене", "column.follow_requests": "Захтеви за праћење", @@ -58,6 +63,7 @@ "column.notifications": "Обавештења", "column.pins": "Прикачене трубе", "column.public": "Здружена временска линија", + "column.status": "Toot", "column_back_button.label": "Назад", "column_header.hide_settings": "Сакриј поставке", "column_header.moveLeft_settings": "Помери колону улево", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Да ли сте сигурни да желите да бесповратно обришете ову листу?", "confirmations.domain_block.confirm": "Сакриј цео домен", "confirmations.domain_block.message": "Да ли сте заиста сигурни да желите да блокирате цео домен {domain}? У већини случајева, неколико добро промишљених блокирања или ућуткавања су довољна и препоручљива.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Ућуткај", "confirmations.mute.message": "Да ли стварно желите да ућуткате корисника {name}?", "confirmations.redraft.confirm": "Избриши и преправи", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Отпрати", "confirmations.unfollow.message": "Да ли сте сигурни да желите да отпратите корисника {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Угради овај статус на Ваш веб сајт копирањем кода испод.", "embed.preview": "Овако ће да изгледа:", "emoji_button.activity": "Активност", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Прикачене трубе", "navigation_bar.preferences": "Подешавања", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Здружена временска линија", "navigation_bar.security": "Безбедност", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Прикажи више", "status.show_more_all": "Прикажи више за све", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Укључи преписку", "status.unpin": "Откачи са профила", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {човек} other {људи}} прича", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Ако напустите Мастодонт, изгубићете написани нацрт.", "upload_area.title": "Превуците овде да отпремите", "upload_button.label": "Додај мултимедију (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index db28900ba..f666a4b6e 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -16,6 +16,7 @@ "account.follows.empty": "Den här användaren följer inte någon ännu.", "account.follows_you": "Följer dig", "account.hide_reblogs": "Dölj knuffar från @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ägarskapet för det här kontot kontrollerades den {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Tysta @{name}", "account.mute_notifications": "Stäng av notifieringar från @{name}", "account.muted": "Tystad", + "account.never_active": "Never", "account.posts": "Inlägg", "account.posts_with_replies": "Toots och svar", "account.report": "Rapportera @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Sluta följa", "account.unmute": "Sluta tysta @{name}", "account.unmute_notifications": "Återaktivera notifikationer från @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "Ett oväntat fel uppstod.", "alert.unexpected.title": "Hoppsan!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blockerade användare", "column.community": "Lokal tidslinje", "column.direct": "Direktmeddelanden", + "column.directory": "Browse profiles", "column.domain_blocks": "Dolda domäner", "column.favourites": "Favoriter", "column.follow_requests": "Följförfrågningar", @@ -58,6 +63,7 @@ "column.notifications": "Meddelanden", "column.pins": "Nålade toots", "column.public": "Förenad tidslinje", + "column.status": "Toot", "column_back_button.label": "Tillbaka", "column_header.hide_settings": "Dölj inställningar", "column_header.moveLeft_settings": "Flytta kolumnen till vänster", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Är du säker på att du vill radera denna lista permanent?", "confirmations.domain_block.confirm": "Dölj hela domänen", "confirmations.domain_block.message": "Är du verkligen säker på att du vill blockera hela {domain}? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer sluta se innehåll från {domain}-domänen i den allmänna tidslinjen och i dina egna notifieringar. Du kommer även sluta följa alla eventuella följare du har från {domain}.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Tysta", "confirmations.mute.message": "Är du säker du vill tysta ner {name}?", "confirmations.redraft.confirm": "Radera och gör om", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Om du svarar nu kommer det att ersätta meddelandet du håller på att skriva. Är du säker på att du vill fortsätta?", "confirmations.unfollow.confirm": "Sluta följa", "confirmations.unfollow.message": "Är du säker på att du vill sluta följa {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Bädda in den här statusen på din webbplats genom att kopiera koden nedan.", "embed.preview": "Så här kommer det att se ut:", "emoji_button.activity": "Aktivitet", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Grundläggande", "home.column_settings.show_reblogs": "Visa knuffar", "home.column_settings.show_replies": "Visa svar", - "home.column_settings.update_live": "Uppdatera i realtid", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# dag} other {# dagar}}", "intervals.full.hours": "{hours, plural, one {# timme} other {# timmar}}", "intervals.full.minutes": "{minutes, plural, one {1 minut} other {# minuter}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Nålade inlägg (toots)", "navigation_bar.preferences": "Inställningar", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Förenad tidslinje", "navigation_bar.security": "Säkerhet", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Visa mer", "status.show_more_all": "Visa mer för alla", "status.show_thread": "Visa tråd", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Öppna konversation", "status.unpin": "Ångra fäst i profil", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{hours, plural, one {# sekund} other {# sekunder}} kvar", "trends.count_by_accounts": "{count} {rawCount, plural, en {person} andra {people}} pratar", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "Ditt utkast kommer att förloras om du lämnar Mastodon.", "upload_area.title": "Dra & släpp för att ladda upp", "upload_button.label": "Lägg till media", diff --git a/app/javascript/mastodon/locales/ta.json b/app/javascript/mastodon/locales/ta.json index 7fa7db98b..3caf301d0 100644 --- a/app/javascript/mastodon/locales/ta.json +++ b/app/javascript/mastodon/locales/ta.json @@ -16,6 +16,7 @@ "account.follows.empty": "இந்த பயனர் இதுவரை யாரையும் பின்தொடரவில்லை.", "account.follows_you": "நீ பின் தொடர்கிறாய்", "account.hide_reblogs": "இருந்து ஊக்கியாக மறை @{name}", + "account.last_status": "Last active", "account.link_verified_on": "இந்த இணைப்பை உரிமையாளர் சரிபார்க்கப்பட்டது {date}", "account.locked_info": "இந்தக் கணக்கு தனியுரிமை நிலை பூட்டப்பட்டுள்ளது. அவர்களைப் பின்தொடர்பவர் யார் என்பதை உரிமையாளர் கைமுறையாக மதிப்பாய்வு செய்கிறார்.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "ஊமையான @{name}", "account.mute_notifications": "அறிவிப்புகளை முடக்கு @{name}", "account.muted": "முடக்கியது", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots மற்றும் பதில்கள்", "account.report": "Report @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "பின்தொடராட்", "account.unmute": "தடுப்புநீக்கு @{name}", "account.unmute_notifications": "அறிவிப்புகளை அகற்றவும் @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "எதிர் பாராத பிழை ஏற்பட்டு விட்டது.", "alert.unexpected.title": "அச்சச்சோ!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "தடுக்கப்பட்ட பயனர்கள்", "column.community": "உள்ளூர் காலக்கெடு", "column.direct": "நேரடி செய்திகள்", + "column.directory": "Browse profiles", "column.domain_blocks": "மறைந்த களங்கள்", "column.favourites": "விருப்பத்துக்குகந்த", "column.follow_requests": "கோரிக்கைகளை பின்பற்றவும்", @@ -58,6 +63,7 @@ "column.notifications": "Notifications", "column.pins": "Pinned toot", "column.public": "கூட்டாட்சி காலக்கெடு", + "column.status": "Toot", "column_back_button.label": "ஆதரி", "column_header.hide_settings": "அமைப்புகளை மறை", "column_header.moveLeft_settings": "நெடுவரிசையை இடதுபுறமாக நகர்த்தவும்", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "இந்த பட்டியலில் நிரந்தரமாக நீக்க விரும்புகிறீர்களா?", "confirmations.domain_block.confirm": "முழு டொமைனை மறை", "confirmations.domain_block.message": "நீங்கள் உண்மையில், நிச்சயமாக நீங்கள் முழு தடுக்க வேண்டும் நிச்சயமாக {domain}? பெரும்பாலான சந்தர்ப்பங்களில் ஒரு சில இலக்குகள் அல்லது மியூட்கள் போதுமானவை மற்றும் சிறந்தவை. எந்த பொது நேரத்திலும் அல்லது உங்கள் அறிவிப்புகளிலும் அந்தக் களத்திலிருந்து உள்ளடக்கத்தை நீங்கள் பார்க்க மாட்டீர்கள். அந்த களத்தில் இருந்து உங்கள் ஆதரவாளர்கள் அகற்றப்படுவார்கள்.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "ஊமையான", "confirmations.mute.message": "நிச்சயமாக நீங்கள் முடக்க விரும்புகிறீர்களா {name}?", "confirmations.redraft.confirm": "நீக்கு & redraft", @@ -103,6 +111,10 @@ "confirmations.reply.message": "இப்போது பதில், தற்போது நீங்கள் உருவாக்கும் செய்தி மேலெழுதப்படும். நீங்கள் தொடர விரும்புகிறீர்களா?", "confirmations.unfollow.confirm": "பின்தொடராட்", "confirmations.unfollow.message": "நிச்சயமாக நீங்கள் பின்தொடர விரும்புகிறீர்களா {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "கீழே உள்ள குறியீட்டை நகலெடுப்பதன் மூலம் உங்கள் இணையதளத்தில் இந்த நிலையை உட்பொதிக்கவும்.", "embed.preview": "இது போன்ற தோற்றத்தை இங்கு காணலாம்:", "emoji_button.activity": "நடவடிக்கை", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "பொருத்தப்பட்டன toots", "navigation_bar.preferences": "விருப்பங்கள்", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "கூட்டாட்சி காலக்கெடு", "navigation_bar.security": "பத்திரம்", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "மேலும் காட்ட", "status.show_more_all": "அனைவருக்கும் மேலும் காட்டு", "status.show_thread": "நூல் காட்டு", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "ஊமையாக உரையாடல் இல்லை", "status.unpin": "சுயவிவரத்திலிருந்து நீக்கவும்", "suggestions.dismiss": "பரிந்துரை விலக்க", @@ -373,7 +385,7 @@ "time_remaining.moments": "தருணங்கள் மீதமுள்ளன", "time_remaining.seconds": "{number, plural, one {# second} மற்ற {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} மற்ற {people}} உரையாடு", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "நீங்கள் வெளியே சென்றால் உங்கள் வரைவு இழக்கப்படும் மஸ்தோடோன்.", "upload_area.title": "பதிவேற்ற & இழுக்கவும்", "upload_button.label": "மீடியாவைச் சேர்க்கவும் (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index 0f7a617bb..5827dbb3a 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -16,6 +16,7 @@ "account.follows.empty": "ఈ వినియోగదారి ఇంకా ఎవరినీ అనుసరించడంలేదు.", "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు", "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు", + "account.last_status": "Last active", "account.link_verified_on": "ఈ లంకె యొక్క యాజమాన్యం {date}న పరీక్షించబడింది", "account.locked_info": "ఈ ఖాతా యొక్క గోప్యత స్థితి లాక్ చేయబడి వుంది. ఈ ఖాతాను ఎవరు అనుసరించవచ్చో యజమానే నిర్ణయం తీసుకుంటారు.", "account.media": "మీడియా", @@ -24,6 +25,7 @@ "account.mute": "@{name}ను మ్యూట్ చెయ్యి", "account.mute_notifications": "@{name}నుంచి ప్రకటనలను మ్యూట్ చెయ్యి", "account.muted": "మ్యూట్ అయినవి", + "account.never_active": "Never", "account.posts": "టూట్లు", "account.posts_with_replies": "టూట్లు మరియు ప్రత్యుత్తరములు", "account.report": "@{name}పై ఫిర్యాదుచేయు", @@ -36,6 +38,8 @@ "account.unfollow": "అనుసరించవద్దు", "account.unmute": "@{name}పై మ్యూట్ ని తొలగించు", "account.unmute_notifications": "@{name} నుంచి ప్రకటనలపై మ్యూట్ ని తొలగించు", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "అనుకోని తప్పు జరిగినది.", "alert.unexpected.title": "అయ్యో!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "బ్లాక్ చేయబడిన వినియోగదారులు", "column.community": "స్థానిక కాలక్రమం", "column.direct": "ప్రత్యక్ష సందేశాలు", + "column.directory": "Browse profiles", "column.domain_blocks": "దాచిన డొమైన్లు", "column.favourites": "ఇష్టపడినవి", "column.follow_requests": "అనుసరించడానికి అభ్యర్ధనలు", @@ -58,6 +63,7 @@ "column.notifications": "ప్రకటనలు", "column.pins": "Pinned toot", "column.public": "సమాఖ్య కాలక్రమం", + "column.status": "Toot", "column_back_button.label": "వెనక్కి", "column_header.hide_settings": "అమర్పులను దాచిపెట్టు", "column_header.moveLeft_settings": "నిలువు వరుసను ఎడమకి తరలించు", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "మీరు ఖచ్చితంగా ఈ జాబితాను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?", "confirmations.domain_block.confirm": "మొత్తం డొమైన్ను దాచు", "confirmations.domain_block.message": "మీరు నిజంగా నిజంగా మొత్తం {domain} ని బ్లాక్ చేయాలనుకుంటున్నారా? చాలా సందర్భాలలో కొన్ని లక్ష్యంగా ఉన్న బ్లాక్స్ లేదా మ్యూట్స్ సరిపోతాయి మరియు ఉత్తమమైనవి. మీరు ఆ డొమైన్ నుండి కంటెంట్ను ఏ ప్రజా కాలక్రమాలలో లేదా మీ నోటిఫికేషన్లలో చూడలేరు. ఆ డొమైన్ నుండి మీ అనుచరులు తీసివేయబడతారు.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "మ్యూట్ చేయి", "confirmations.mute.message": "{name}ను మీరు ఖచ్చితంగా మ్యూట్ చేయాలనుకుంటున్నారా?", "confirmations.redraft.confirm": "తొలగించు & తిరగరాయు", @@ -103,6 +111,10 @@ "confirmations.reply.message": "ఇప్పుడే ప్రత్యుత్తరం ఇస్తే మీరు ప్రస్తుతం వ్రాస్తున్న సందేశం తిరగరాయబడుతుంది. మీరు ఖచ్చితంగా కొనసాగించాలనుకుంటున్నారా?", "confirmations.unfollow.confirm": "అనుసరించవద్దు", "confirmations.unfollow.message": "{name}ను మీరు ఖచ్చితంగా అనుసరించవద్దనుకుంటున్నారా?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "దిగువ కోడ్ను కాపీ చేయడం ద్వారా మీ వెబ్సైట్లో ఈ స్టేటస్ ని పొందుపరచండి.", "embed.preview": "అది ఈ క్రింది విధంగా కనిపిస్తుంది:", "emoji_button.activity": "కార్యకలాపాలు", @@ -250,7 +262,6 @@ "navigation_bar.personal": "వ్యక్తిగతం", "navigation_bar.pins": "అతికించిన టూట్లు", "navigation_bar.preferences": "ప్రాధాన్యతలు", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "సమాఖ్య కాలక్రమం", "navigation_bar.security": "భద్రత", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "ఇంకా చూపించు", "status.show_more_all": "అన్నిటికీ ఇంకా చూపించు", "status.show_thread": "గొలుసును చూపించు", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "సంభాషణను అన్మ్యూట్ చేయి", "status.unpin": "ప్రొఫైల్ నుండి పీకివేయు", "suggestions.dismiss": "సూచనను రద్దు చేయి", @@ -373,7 +385,7 @@ "time_remaining.moments": "కొన్ని క్షణాలు మాత్రమే మిగిలి ఉన్నాయి", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} మాట్లాడుతున్నారు", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "మీరు మాస్టొడొన్ను వదిలివేస్తే మీ డ్రాఫ్ట్లు పోతాయి.", "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి", "upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 5bf79ded8..33eb315f1 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -4,7 +4,7 @@ "account.block": "ปิดกั้น @{name}", "account.block_domain": "ซ่อนทุกอย่างจาก {domain}", "account.blocked": "ปิดกั้นอยู่", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "ยกเลิกคำขอติดตาม", "account.direct": "ส่งข้อความโดยตรงถึง @{name}", "account.domain_blocked": "ซ่อนโดเมนอยู่", "account.edit_profile": "แก้ไขโปรไฟล์", @@ -16,6 +16,7 @@ "account.follows.empty": "ผู้ใช้นี้ยังไม่ได้ติดตามใคร", "account.follows_you": "ติดตามคุณ", "account.hide_reblogs": "ซ่อนการดันจาก @{name}", + "account.last_status": "ใช้งานล่าสุด", "account.link_verified_on": "ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ {date}", "account.locked_info": "มีการตั้งสถานะความเป็นส่วนตัวของบัญชีนี้เป็นล็อคอยู่ เจ้าของตรวจทานผู้ที่สามารถติดตามเขาด้วยตนเอง", "account.media": "สื่อ", @@ -24,6 +25,7 @@ "account.mute": "ปิดเสียง @{name}", "account.mute_notifications": "ปิดเสียงการแจ้งเตือนจาก @{name}", "account.muted": "ปิดเสียงอยู่", + "account.never_active": "ไม่เลย", "account.posts": "โพสต์", "account.posts_with_replies": "โพสต์และการตอบกลับ", "account.report": "รายงาน @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "เลิกติดตาม", "account.unmute": "เลิกปิดเสียง @{name}", "account.unmute_notifications": "เลิกปิดเสียงการแจ้งเตือนจาก @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "เกิดข้อผิดพลาดที่ไม่คาดคิด", "alert.unexpected.title": "อุปส์!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} ต่อสัปดาห์", "boost_modal.combo": "คุณสามารถกด {combo} เพื่อข้ามสิ่งนี้ในครั้งถัดไป", "bundle_column_error.body": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้", "bundle_column_error.retry": "ลองอีกครั้ง", @@ -49,6 +53,7 @@ "column.blocks": "ผู้ใช้ที่ปิดกั้นอยู่", "column.community": "เส้นเวลาในเว็บ", "column.direct": "ข้อความโดยตรง", + "column.directory": "เรียกดูโปรไฟล์", "column.domain_blocks": "โดเมนที่ซ่อนอยู่", "column.favourites": "รายการโปรด", "column.follow_requests": "คำขอติดตาม", @@ -58,6 +63,7 @@ "column.notifications": "การแจ้งเตือน", "column.pins": "โพสต์ที่ปักหมุด", "column.public": "เส้นเวลาที่ติดต่อกับภายนอก", + "column.status": "Toot", "column_back_button.label": "ย้อนกลับ", "column_header.hide_settings": "ซ่อนการตั้งค่า", "column_header.moveLeft_settings": "ย้ายคอลัมน์ไปทางซ้าย", @@ -95,6 +101,8 @@ "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.logout.confirm": "ออกจากระบบ", + "confirmations.logout.message": "คุณแน่ใจหรือไม่ว่าต้องการออกจากระบบ?", "confirmations.mute.confirm": "ปิดเสียง", "confirmations.mute.message": "คุณแน่ใจหรือไม่ว่าต้องการปิดเสียง {name}?", "confirmations.redraft.confirm": "ลบแล้วร่างใหม่", @@ -103,6 +111,10 @@ "confirmations.reply.message": "การตอบกลับตอนนี้จะเขียนทับข้อความที่คุณกำลังเขียน คุณแน่ใจหรือไม่ว่าต้องการดำเนินการต่อ?", "confirmations.unfollow.confirm": "เลิกติดตาม", "confirmations.unfollow.message": "คุณแน่ใจหรือไม่ว่าต้องการเลิกติดตาม {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "ฝังสถานะนี้ในเว็บไซต์ของคุณโดยคัดลอกโค้ดด้านล่าง", "embed.preview": "นี่คือลักษณะที่จะปรากฏ:", "emoji_button.activity": "กิจกรรม", @@ -158,7 +170,7 @@ "home.column_settings.basic": "พื้นฐาน", "home.column_settings.show_reblogs": "แสดงการดัน", "home.column_settings.show_replies": "แสดงการตอบกลับ", - "home.column_settings.update_live": "อัปเดตตามเวลาจริง", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, other {# วัน}}", "intervals.full.hours": "{number, plural, other {# ชั่วโมง}}", "intervals.full.minutes": "{number, plural, other {# นาที}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "ส่วนบุคคล", "navigation_bar.pins": "โพสต์ที่ปักหมุด", "navigation_bar.preferences": "การกำหนดลักษณะ", - "navigation_bar.profile_directory": "ไดเรกทอรีโปรไฟล์", "navigation_bar.public_timeline": "เส้นเวลาที่ติดต่อกับภายนอก", "navigation_bar.security": "ความปลอดภัย", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "แสดงเพิ่มเติม", "status.show_more_all": "แสดงเพิ่มเติมทั้งหมด", "status.show_thread": "แสดงกระทู้", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "เลิกปิดเสียงการสนทนา", "status.unpin": "ถอนหมุดจากโปรไฟล์", "suggestions.dismiss": "ยกเลิกข้อเสนอแนะ", @@ -372,23 +384,23 @@ "time_remaining.minutes": "เหลืออีก {number, plural, other {# นาที}}", "time_remaining.moments": "ช่วงเวลาที่เหลือ", "time_remaining.seconds": "เหลืออีก {number, plural, other {# วินาที}}", - "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "trends.count_by_accounts": "{count} {rawCount, plural, other {คน}}กำลังคุย", + "trends.trending_now": "แนวโน้มตอนนี้", "ui.beforeunload": "แบบร่างของคุณจะหายไปหากคุณออกจาก Mastodon", "upload_area.title": "ลากแล้วปล่อยเพื่ออัปโหลด", "upload_button.label": "เพิ่มสื่อ (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "เกินขีดจำกัดการอัปโหลดไฟล์", "upload_error.poll": "ไม่อนุญาตให้อัปโหลดไฟล์กับการลงคะแนน", "upload_form.description": "อธิบายสำหรับผู้บกพร่องทางการมองเห็น", - "upload_form.edit": "Edit", + "upload_form.edit": "แก้ไข", "upload_form.undo": "ลบ", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", + "upload_modal.analyzing_picture": "กำลังวิเคราะห์รูปภาพ…", + "upload_modal.apply": "นำไปใช้", "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", + "upload_modal.edit_media": "แก้ไขสื่อ", "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.preview_label": "ตัวอย่าง ({ratio})", "upload_progress.label": "กำลังอัปโหลด...", "video.close": "ปิดวิดีโอ", "video.exit_fullscreen": "ออกจากเต็มหน้าจอ", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 3638b0582..2c4d820de 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -1,45 +1,49 @@ { - "account.add_or_remove_from_list": "Listelere ekle veya kaldır", + "account.add_or_remove_from_list": "Listeye ekle veya kaldır", "account.badges.bot": "Bot", - "account.block": "Engelle @{name}", + "account.block": "@{name} adlı kişiyi engelle", "account.block_domain": "{domain} alanından her şeyi gizle", "account.blocked": "Engellenmiş", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Takip isteğini iptal et", "account.direct": "Mesaj gönder : @{name}", "account.domain_blocked": "Alan adı gizlendi", "account.edit_profile": "Profili düzenle", "account.endorse": "Profildeki özellik", "account.follow": "Takip et", - "account.followers": "Takipçiler", + "account.followers": "Takipçi", "account.followers.empty": "Henüz kimse bu kullanıcıyı takip etmiyor.", "account.follows": "Takip ettikleri", "account.follows.empty": "Bu kullanıcı henüz kimseyi takip etmiyor.", "account.follows_you": "Seni takip ediyor", - "account.hide_reblogs": "@{name} kişisinden boost'ları gizle", + "account.hide_reblogs": "@{name} kişisinin yinelemelerini gizle", + "account.last_status": "Son aktivite", "account.link_verified_on": "Bu bağlantının mülkiyeti {date} tarihinde kontrol edildi", - "account.locked_info": "Bu hesabın gizlilik durumu kilitli olarak ayarlanmış. Sahibi, onu kimin takip edebileceğini elle inceler.", + "account.locked_info": "Bu hesabın gizlilik durumu kilitli olarak ayarlanmış. Sahibi, onu kimin takip edebileceğini elle inceliyor.", "account.media": "Medya", "account.mention": "@{name} kullanıcısından bahset", "account.moved_to": "{name} şuraya taşındı:", - "account.mute": "@{name} kullanıcısını sessize al", - "account.mute_notifications": "@{name} kullanıcısının bildirimlerini kapat", - "account.muted": "Sesi kısık", - "account.posts": "Gönderiler", + "account.mute": "@{name} adlı kişiyi sessize al", + "account.mute_notifications": "@{name} adlı kişinin bildirimlerini kapat", + "account.muted": "Susturuldu", + "account.never_active": "Asla", + "account.posts": "Gönderi", "account.posts_with_replies": "Gönderiler ve yanıtlar", - "account.report": "@{name} kullanıcısını bildir", - "account.requested": "Onay bekliyor. Takip isteğini iptal etmek için tıklayın", + "account.report": "@{name} adlı kişiyi bildir", + "account.requested": "Onay Bekleniyor. Takip isteğini iptal etmek için tıklayın", "account.share": "@{name} kullanıcısının profilini paylaş", - "account.show_reblogs": "@{name} kullanıcısından boostları göster", - "account.unblock": "Engeli kaldır @{name}", + "account.show_reblogs": "@{name} kullanıcısının yinelemelerini göster", + "account.unblock": "@{name} adlı kişinin engelini kaldır", "account.unblock_domain": "{domain} göster", "account.unendorse": "Profilde özellik yok", - "account.unfollow": "Takipten vazgeç", - "account.unmute": "Sesi aç : @{name}", - "account.unmute_notifications": "@{name} kullanıcısından bildirimleri aç", + "account.unfollow": "Takipi bırak", + "account.unmute": "@{name} adlı kişinin sesini aç", + "account.unmute_notifications": "@{name} adlı kişinin bildirimlerini aç", + "alert.rate_limited.message": "Lütfen sonra tekrar deneyin {retry_time, time, medium}.", + "alert.rate_limited.title": "Oran sınırlıdır", "alert.unexpected.message": "Beklenmedik bir hata oluştu.", "alert.unexpected.title": "Hay aksi!", - "autosuggest_hashtag.per_week": "{count} per week", - "boost_modal.combo": "Bir dahaki sefere {combo} tuşuna basabilirsiniz", + "autosuggest_hashtag.per_week": "Haftada {count}", + "boost_modal.combo": "Bir daha ki sefere {combo} tuşuna basabilirsiniz", "bundle_column_error.body": "Bu bileşen yüklenirken bir şeyler ters gitti.", "bundle_column_error.retry": "Tekrar deneyin", "bundle_column_error.title": "Ağ hatası", @@ -49,6 +53,7 @@ "column.blocks": "Engellenen kullanıcılar", "column.community": "Yerel zaman tüneli", "column.direct": "Doğrudan mesajlar", + "column.directory": "Profillere göz at", "column.domain_blocks": "Gizli alan adları", "column.favourites": "Favoriler", "column.follow_requests": "Takip istekleri", @@ -58,6 +63,7 @@ "column.notifications": "Bildirimler", "column.pins": "Sabitlenmiş gönderi", "column.public": "Federe zaman tüneli", + "column.status": "Toot", "column_back_button.label": "Geri", "column_header.hide_settings": "Ayarları gizle", "column_header.moveLeft_settings": "Sütunu sola taşı", @@ -79,7 +85,7 @@ "compose_form.poll.remove_option": "Bu seçimi kaldır", "compose_form.publish": "Gönder", "compose_form.publish_loud": "{publish}!", - "compose_form.sensitive.hide": "Mark media as sensitive", + "compose_form.sensitive.hide": "Medyayı hassas olarak işaretle", "compose_form.sensitive.marked": "Medya hassas olarak işaretlendi", "compose_form.sensitive.unmarked": "Medya hassas olarak işaretlenmemiş", "compose_form.spoiler.marked": "Metin uyarının arkasına gizlenir", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Bu listeyi kalıcı olarak silmek istediğinize emin misiniz?", "confirmations.domain_block.confirm": "Alan adının tamamını gizle", "confirmations.domain_block.message": "tüm {domain} alan adını engellemek istediğinizden emin misiniz? Genellikle birkaç hedefli engel ve susturma işi görür ve tercih edilir.", + "confirmations.logout.confirm": "Çıkış Yap", + "confirmations.logout.message": "Çıkış yapmak istediğinize emin misiniz?", "confirmations.mute.confirm": "Sessize al", "confirmations.mute.message": "{name} kullanıcısını sessize almak istiyor musunuz?", "confirmations.redraft.confirm": "Sil ve yeniden tasarla", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Şimdi yanıtlarken o an oluşturduğunuz mesajın üzerine yazılır. Devam etmek istediğinize emin misiniz?", "confirmations.unfollow.confirm": "Takibi kaldır", "confirmations.unfollow.message": "{name}'yi takipten çıkarmak istediğinizden emin misiniz?", + "directory.federated": "From known fediverse", + "directory.local": "Yalnızca {domain} adresinden", + "directory.new_arrivals": "Yeni gelenler", + "directory.recently_active": "Son zamanlarda aktif", "embed.instructions": "Aşağıdaki kodu kopyalayarak bu durumu sitenize gömün.", "embed.preview": "İşte nasıl görüneceği:", "emoji_button.activity": "Aktivite", @@ -120,7 +132,7 @@ "emoji_button.symbols": "Semboller", "emoji_button.travel": "Seyahat ve Yerler", "empty_column.account_timeline": "Burada hiç gönderi yok!", - "empty_column.account_unavailable": "Profile unavailable", + "empty_column.account_unavailable": "Profil kullanılamıyor", "empty_column.blocks": "Henüz bir kullanıcıyı engellemediniz.", "empty_column.community": "Yerel zaman çizelgesi boş. Daha fazla eğlence için herkese açık bir gönderi paylaşın!", "empty_column.direct": "Henüz doğrudan mesajınız yok. Bir tane gönderdiğinizde veya aldığınızda burada görünecektir.", @@ -159,20 +171,20 @@ "home.column_settings.show_reblogs": "Boost edilenleri göster", "home.column_settings.show_replies": "Cevapları göster", "home.column_settings.update_live": "Update in real-time", - "intervals.full.days": "{number, plural, one {# day} other {# days}}", - "intervals.full.hours": "{number, plural, one {# hour} other {# hours}}", - "intervals.full.minutes": "{number, plural, one {# minute} other {# minutes}}", + "intervals.full.days": "{number, plural, one {# gün} other {# gün}}", + "intervals.full.hours": "{number, plural, one {# saat} other {# saat}}", + "intervals.full.minutes": "{number, plural, one {# dakika} other {# dakika}}", "introduction.federation.action": "İleri", "introduction.federation.federated.headline": "Birleşik", "introduction.federation.federated.text": "Diğer dosya sunucularından gelen genel gönderiler, birleşik zaman çizelgesinde görünecektir.", "introduction.federation.home.headline": "Ana sayfa", - "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", + "introduction.federation.home.text": "Takip ettiğiniz kişilerin yayınları ana sayfada gösterilecek. Herhangi bir sunucudaki herkesi takip edebilirsiniz!", "introduction.federation.local.headline": "Yerel", "introduction.federation.local.text": "Aynı sunucudaki kişilerin gönderileri yerel zaman tünelinde gözükecektir.", "introduction.interactions.action": "Öğreticiyi bitirin!", "introduction.interactions.favourite.headline": "Favori", "introduction.interactions.favourite.text": "Bir gönderiyi favorilerinize alarak sonrası için saklayabilirsiniz ve yazara gönderiyi beğendiğinizi söyleyebilirsiniz.", - "introduction.interactions.reblog.headline": "Boost", + "introduction.interactions.reblog.headline": "Yinele", "introduction.interactions.reblog.text": "Başkalarının gönderilerini boostlayarak kendi takipçilerinizle paylaşabillirsiniz.", "introduction.interactions.reply.headline": "Yanıt", "introduction.interactions.reply.text": "Başkalarının gönderilerini ve kendi gönderilerinizi yanıtlayabilirsiniz. Bir konuşmada zincirli bir şekilde olacaklardır.", @@ -207,14 +219,14 @@ "keyboard_shortcuts.search": "aramaya odaklanmak için", "keyboard_shortcuts.start": "\"başlayın\" sütununu açmak için", "keyboard_shortcuts.toggle_hidden": "CW'den önceki yazıyı göstermek/gizlemek için", - "keyboard_shortcuts.toggle_sensitivity": "to show/hide media", + "keyboard_shortcuts.toggle_sensitivity": "medyayı göstermek/gizlemek için", "keyboard_shortcuts.toot": "yeni bir gönderiye başlamak için", "keyboard_shortcuts.unfocus": "aramada bir gönderiye odaklanmamak için", "keyboard_shortcuts.up": "listede yukarıya çıkmak için", "lightbox.close": "Kapat", "lightbox.next": "Sonraki", "lightbox.previous": "Önceli", - "lightbox.view_context": "View context", + "lightbox.view_context": "İçeriği göster", "lists.account.add": "Listeye ekle", "lists.account.remove": "Listeden kaldır", "lists.delete": "Listeyi sil", @@ -224,7 +236,7 @@ "lists.new.title_placeholder": "Yeni liste başlığı", "lists.search": "Takip ettiğiniz kişiler arasından arayın", "lists.subheading": "Listeleriniz", - "load_pending": "{count, plural, one {# new item} other {# new items}}", + "load_pending": "{count, plural, one {# yeni öğe} other {# yeni öğe}}", "loading_indicator.label": "Yükleniyor...", "media_gallery.toggle_visible": "Görünürlüğü değiştir", "missing_indicator.label": "Bulunamadı", @@ -241,7 +253,7 @@ "navigation_bar.favourites": "Favoriler", "navigation_bar.filters": "Susturulmuş kelimeler", "navigation_bar.follow_requests": "Takip istekleri", - "navigation_bar.follows_and_followers": "Follows and followers", + "navigation_bar.follows_and_followers": "Takip edilenler ve takipçiler", "navigation_bar.info": "Genişletilmiş bilgi", "navigation_bar.keyboard_shortcuts": "Klavye kısayolları", "navigation_bar.lists": "Listeler", @@ -250,13 +262,12 @@ "navigation_bar.personal": "Kişisel", "navigation_bar.pins": "Sabitlenmiş gönderiler", "navigation_bar.preferences": "Tercihler", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federe zaman tüneli", "navigation_bar.security": "Güvenlik", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", "notification.favourite": "{name} senin durumunu favorilere ekledi", "notification.follow": "{name} seni takip ediyor", - "notification.mention": "{name} mentioned you", + "notification.mention": "{name} senden bahsetti", "notification.poll": "Oy verdiğiniz bir anket bitti", "notification.reblog": "{name} senin durumunu boost etti", "notifications.clear": "Bildirimleri temizle", @@ -282,7 +293,7 @@ "notifications.group": "{count} bildirim", "poll.closed": "Kapandı", "poll.refresh": "Yenile", - "poll.total_votes": "{count, plural, one {# vote} other {# votes}}", + "poll.total_votes": "{count, plural, one {# oy} other {# oy}}", "poll.vote": "Oy ver", "poll_button.add_poll": "Bir anket ekleyin", "poll_button.remove_poll": "Anket kaldır", @@ -311,15 +322,15 @@ "report.target": "Raporlama", "search.placeholder": "Ara", "search_popout.search_format": "Gelişmiş arama formatı", - "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", - "search_popout.tips.hashtag": "hashtag", + "search_popout.tips.full_text": "Basit metin yazdığınız, tercih ettiğiniz, yinelediğiniz veya bunlardan bahsettiğiniz durumların yanı sıra kullanıcı adlarını, görünen adları ve hashtag'leri eşleştiren durumları döndürür.", + "search_popout.tips.hashtag": "etiketler", "search_popout.tips.status": "durum", - "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", + "search_popout.tips.text": "Basit metin, eşleşen görünen adları, kullanıcı adlarını ve hashtag'leri döndürür", "search_popout.tips.user": "kullanıcı", "search_results.accounts": "İnsanlar", "search_results.hashtags": "Hashtagler", "search_results.statuses": "Gönderiler", - "search_results.statuses_fts_disabled": "Searching toots by their content is not enabled on this Mastodon server.", + "search_results.statuses_fts_disabled": "Bu Mastodon sunucusunda gönderi içeriğine göre arama etkin değil.", "search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}", "status.admin_account": "@{name} için denetim arayüzünü açın", "status.admin_status": "Denetim arayüzünde bu durumu açın", @@ -358,7 +369,8 @@ "status.show_more": "Daha fazla göster", "status.show_more_all": "Hepsi için daha fazla göster", "status.show_thread": "Başlığı göster", - "status.unmute_conversation": "Unmute conversation", + "status.uncached_media_warning": "Mevcut değil", + "status.unmute_conversation": "Sohbeti aç", "status.unpin": "Profilden sabitlemeyi kaldır", "suggestions.dismiss": "Öneriyi görmezden gel", "suggestions.header": "Şuna ilgi duyuyor olabilirsiniz…", @@ -367,28 +379,28 @@ "tabs_bar.local_timeline": "Yerel", "tabs_bar.notifications": "Bildirimler", "tabs_bar.search": "Ara", - "time_remaining.days": "{number, plural, one {# day} other {# days}} left", - "time_remaining.hours": "{number, plural, one {# hour} other {# hours}} left", - "time_remaining.minutes": "{number, plural, one {# minute} other {# minutes}} left", - "time_remaining.moments": "Moments remaining", - "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", - "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", - "trends.refresh": "Refresh", + "time_remaining.days": "{number, plural, one {# gün} other {# gün}} kaldı", + "time_remaining.hours": "{number, plural, one {# saat} other {# saat}} kaldı", + "time_remaining.minutes": "{number, plural, one {# dakika} other {# dakika}} kaldı", + "time_remaining.moments": "Sadece birkaç dakika kaldı", + "time_remaining.seconds": "{number, plural, one {# saniye} other {# saniye}} kaldı", + "trends.count_by_accounts": "{count} {rawCount, plural, one {kişi} other {kişi}} konuşuyor", + "trends.trending_now": "Şu an popüler", "ui.beforeunload": "Mastodon'dan ayrılırsanız taslağınız kaybolacak.", "upload_area.title": "Karşıya yükleme için sürükle bırak yapınız", "upload_button.label": "Görsel ekle", "upload_error.limit": "Dosya yükleme sınırı aşıldı.", "upload_error.poll": "Anketlerde dosya yüklemesine izin verilmez.", - "upload_form.description": "Describe for the visually impaired", - "upload_form.edit": "Edit", + "upload_form.description": "Görme engelliler için açıklama", + "upload_form.edit": "Düzenle", "upload_form.undo": "Geri al", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Resmi analiz ediyor…", + "upload_modal.apply": "Uygula", + "upload_modal.description_placeholder": "Pijamalı hasta yağız şoföre çabucak güvendi", + "upload_modal.detect_text": "Resimdeki metni algıla", + "upload_modal.edit_media": "Medyayı düzenle", + "upload_modal.hint": "Her zaman tüm küçük resimlerde görüntülenecek odak noktasını seçmek için ön izlemedeki daireyi tıklayın veya sürükleyin.", + "upload_modal.preview_label": "Ön izleme ({ratio})", "upload_progress.label": "Yükleniyor...", "video.close": "Videoyu kapat", "video.exit_fullscreen": "Tam ekrandan çık", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 69bf016f9..6ccb20fc6 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -4,7 +4,7 @@ "account.block": "Заблокувати @{name}", "account.block_domain": "Заглушити {domain}", "account.blocked": "Заблоковані", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "Скасувати запит на підписку", "account.direct": "Пряме повідомлення @{name}", "account.domain_blocked": "Домен приховано", "account.edit_profile": "Редагувати профіль", @@ -16,6 +16,7 @@ "account.follows.empty": "Цей користувач ще ні на кого не підписався.", "account.follows_you": "Підписаний(-а) на Вас", "account.hide_reblogs": "Сховати передмухи від @{name}", + "account.last_status": "Крайня активність", "account.link_verified_on": "Права власності на це посилання були перевірені {date}", "account.locked_info": "Статус конфіденційності цього облікового запису встановлено у заблокований. Власник вручну переглядає, хто може за ним стежити.", "account.media": "Медіа", @@ -24,6 +25,7 @@ "account.mute": "Заглушити @{name}", "account.mute_notifications": "Не показувати сповіщення від @{name}", "account.muted": "Заглушений", + "account.never_active": "Ніколи", "account.posts": "Дмухи", "account.posts_with_replies": "Дмухи й відповіді", "account.report": "Поскаржитися на @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "Відписатися", "account.unmute": "Зняти глушення з @{name}", "account.unmute_notifications": "Показувати сповіщення від @{name}", + "alert.rate_limited.message": "Спробуйте ще раз через {retry_time, time, medium}.", + "alert.rate_limited.title": "Швидкість обмежена", "alert.unexpected.message": "Трапилась неочікувана помилка.", "alert.unexpected.title": "Ой!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "{count} в тиждень", "boost_modal.combo": "Ви можете натиснути {combo}, щоб пропустити це наступного разу", "bundle_column_error.body": "Щось пішло не так під час завантаження компоненту.", "bundle_column_error.retry": "Спробуйте ще раз", @@ -49,6 +53,7 @@ "column.blocks": "Заблоковані користувачі", "column.community": "Локальна стрічка", "column.direct": "Прямі повідомлення", + "column.directory": "Переглянути профілі", "column.domain_blocks": "Приховані домени", "column.favourites": "Вподобане", "column.follow_requests": "Запити на підписку", @@ -58,6 +63,7 @@ "column.notifications": "Сповіщення", "column.pins": "Закріплені дмухи", "column.public": "Глобальна стрічка", + "column.status": "Toot", "column_back_button.label": "Назад", "column_header.hide_settings": "Приховати налаштування", "column_header.moveLeft_settings": "Змістити колонку вліво", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "Ви впевнені, що хочете видалити цей список назавжди?", "confirmations.domain_block.confirm": "Сховати весь домен", "confirmations.domain_block.message": "Ви точно, точно впевнені, що хочете заблокувати весь домен {domain}? У більшості випадків для нормальної роботи краще заблокувати/заглушити лише деяких користувачів. Ви не зможете бачити контент з цього домену у будь-яких стрічках або ваших сповіщеннях. Ваші підписники з цього домену будуть відписані від вас.", + "confirmations.logout.confirm": "Вийти", + "confirmations.logout.message": "Ви впевнені, що хочете вийти?", "confirmations.mute.confirm": "Заглушити", "confirmations.mute.message": "Ви впевнені, що хочете заглушити {name}?", "confirmations.redraft.confirm": "Видалити та перестворити", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Поточна відповідь перезапише повідомлення, яке ви зараз пишете. Ви впевнені, що хочете продовжити?", "confirmations.unfollow.confirm": "Відписатися", "confirmations.unfollow.message": "Ви впевнені, що хочете відписатися від {name}?", + "directory.federated": "З відомого федесвіту", + "directory.local": "Тільки з домену {domain}", + "directory.new_arrivals": "Нові надходження", + "directory.recently_active": "Активні нещодавно", "embed.instructions": "Вбудуйте цей статус до вашого вебсайту, скопіювавши код нижче.", "embed.preview": "Ось як він виглядатиме:", "emoji_button.activity": "Заняття", @@ -158,7 +170,7 @@ "home.column_settings.basic": "Основні", "home.column_settings.show_reblogs": "Показувати передмухи", "home.column_settings.show_replies": "Показувати відповіді", - "home.column_settings.update_live": "Оновлювати в реальному часі", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number, plural, one {# день} few {# дні} other {# днів}}", "intervals.full.hours": "{number, plural, one {# година} few {# години} other {# годин}}", "intervals.full.minutes": "{number, plural, one {# хвилина} few {# хвилини} other {# хвилин}}", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Особисте", "navigation_bar.pins": "Закріплені дмухи", "navigation_bar.preferences": "Налаштування", - "navigation_bar.profile_directory": "Каталог профілів", "navigation_bar.public_timeline": "Глобальна стрічка", "navigation_bar.security": "Безпека", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "Розгорнути", "status.show_more_all": "Show more for all", "status.show_thread": "Показати ланцюжок", + "status.uncached_media_warning": "Недоступно", "status.unmute_conversation": "Зняти глушення з діалогу", "status.unpin": "Відкріпити від профілю", "suggestions.dismiss": "Відхилити пропозицію", @@ -372,23 +384,23 @@ "time_remaining.minutes": "{number, plural, one {# хвилина} few {# хвилини} other {# хвилин}}", "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# секунда} few {# секунди} other {# секунд}}", - "trends.count_by_accounts": "{count} {rawCount, plural, one {людина} few {людини} many {людей} other {людей}} talking", - "trends.refresh": "Refresh", + "trends.count_by_accounts": "{count} {rawCount, plural, one {людина} few {людини} many {людей} other {людей}} обговорюють це", + "trends.trending_now": "Актуальні", "ui.beforeunload": "Вашу чернетку буде втрачено, якщо ви покинете Mastodon.", "upload_area.title": "Перетягніть сюди, щоб завантажити", "upload_button.label": "Додати медіаконтент ({formats})", "upload_error.limit": "Ліміт завантаження файлів перевищено.", "upload_error.poll": "Не можна завантажувати файли до опитувань.", "upload_form.description": "Опишіть для людей з вадами зору", - "upload_form.edit": "Edit", + "upload_form.edit": "Змінити", "upload_form.undo": "Видалити", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "Аналізуємо малюнок…", + "upload_modal.apply": "Застосувати", + "upload_modal.description_placeholder": "Щурячий бугай із їжаком-харцизом в'ючись підписали ґешефт у єнах", + "upload_modal.detect_text": "Виявити текст на малюнку", + "upload_modal.edit_media": "Редагувати медіа", + "upload_modal.hint": "Клацніть або перетягніть коло на превью, щоб обрати точку, яку буде завжди видно на мініатюрах.", + "upload_modal.preview_label": "Переглянути ({ratio})", "upload_progress.label": "Завантаження...", "video.close": "Закрити відео", "video.exit_fullscreen": "Вийти з повноекранного режиму", diff --git a/app/javascript/mastodon/locales/whitelist_pt.json b/app/javascript/mastodon/locales/whitelist_br.json index 0d4f101c7..0d4f101c7 100644 --- a/app/javascript/mastodon/locales/whitelist_pt.json +++ b/app/javascript/mastodon/locales/whitelist_br.json diff --git a/app/javascript/mastodon/locales/whitelist_nn.json b/app/javascript/mastodon/locales/whitelist_nn.json new file mode 100644 index 000000000..0d4f101c7 --- /dev/null +++ b/app/javascript/mastodon/locales/whitelist_nn.json @@ -0,0 +1,2 @@ +[ +] diff --git a/app/javascript/mastodon/locales/whitelist_pt-PT.json b/app/javascript/mastodon/locales/whitelist_pt-PT.json new file mode 100644 index 000000000..0d4f101c7 --- /dev/null +++ b/app/javascript/mastodon/locales/whitelist_pt-PT.json @@ -0,0 +1,2 @@ +[ +] diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 16848831c..2f0373d93 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -4,7 +4,7 @@ "account.block": "屏蔽 @{name}", "account.block_domain": "隐藏来自 {domain} 的内容", "account.blocked": "已屏蔽", - "account.cancel_follow_request": "Cancel follow request", + "account.cancel_follow_request": "取消关注请求", "account.direct": "发送私信给 @{name}", "account.domain_blocked": "网站已屏蔽", "account.edit_profile": "修改个人资料", @@ -16,6 +16,7 @@ "account.follows.empty": "此用户目前尚未关注任何人。", "account.follows_you": "关注了你", "account.hide_reblogs": "隐藏来自 @{name} 的转嘟", + "account.last_status": "Last active", "account.link_verified_on": "此链接的所有权已在 {date} 检查", "account.locked_info": "此账户已锁嘟。账户的主人会手动审核关注者。", "account.media": "媒体", @@ -24,6 +25,7 @@ "account.mute": "隐藏 @{name}", "account.mute_notifications": "隐藏来自 @{name} 的通知", "account.muted": "已隐藏", + "account.never_active": "Never", "account.posts": "嘟文", "account.posts_with_replies": "嘟文和回复", "account.report": "举报 @{name}", @@ -36,9 +38,11 @@ "account.unfollow": "取消关注", "account.unmute": "不再隐藏 @{name}", "account.unmute_notifications": "不再隐藏来自 @{name} 的通知", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "发生了意外错误。", "alert.unexpected.title": "哎呀!", - "autosuggest_hashtag.per_week": "{count} per week", + "autosuggest_hashtag.per_week": "每星期 {count} 条", "boost_modal.combo": "下次按住 {combo} 即可跳过此提示", "bundle_column_error.body": "载入这个组件时发生了错误。", "bundle_column_error.retry": "重试", @@ -49,6 +53,7 @@ "column.blocks": "已屏蔽的用户", "column.community": "本站时间轴", "column.direct": "私信", + "column.directory": "Browse profiles", "column.domain_blocks": "已屏蔽的网站", "column.favourites": "收藏", "column.follow_requests": "关注请求", @@ -58,6 +63,7 @@ "column.notifications": "通知", "column.pins": "置顶嘟文", "column.public": "跨站公共时间轴", + "column.status": "Toot", "column_back_button.label": "返回", "column_header.hide_settings": "隐藏设置", "column_header.moveLeft_settings": "将此栏左移", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "你确定要永久删除这个列表吗?", "confirmations.domain_block.confirm": "隐藏整个网站的内容", "confirmations.domain_block.message": "你真的确定要隐藏所有来自 {domain} 的内容吗?多数情况下,屏蔽或隐藏几个特定的用户就已经足够了。来自该网站的内容将不再出现在你的任何公共时间轴或通知列表里。来自该网站的关注者将会被移除。", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "隐藏", "confirmations.mute.message": "你确定要隐藏 {name} 吗?", "confirmations.redraft.confirm": "删除并重新编辑", @@ -103,6 +111,10 @@ "confirmations.reply.message": "回复此消息将会覆盖当前正在编辑的信息。确定继续吗?", "confirmations.unfollow.confirm": "取消关注", "confirmations.unfollow.message": "你确定要取消关注 {name} 吗?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "要在你的网站上嵌入这条嘟文,请复制以下代码。", "embed.preview": "它会像这样显示出来:", "emoji_button.activity": "活动", @@ -158,7 +170,7 @@ "home.column_settings.basic": "基本设置", "home.column_settings.show_reblogs": "显示转嘟", "home.column_settings.show_replies": "显示回复", - "home.column_settings.update_live": "实时更新", + "home.column_settings.update_live": "Update in real-time", "intervals.full.days": "{number} 天", "intervals.full.hours": "{number} 小时", "intervals.full.minutes": "{number} 分钟", @@ -224,7 +236,7 @@ "lists.new.title_placeholder": "新列表的标题", "lists.search": "搜索你关注的人", "lists.subheading": "你的列表", - "load_pending": "{count, plural, one {# new item} other {# new items}}", + "load_pending": "{count} 项", "loading_indicator.label": "加载中……", "media_gallery.toggle_visible": "切换显示/隐藏", "missing_indicator.label": "找不到内容", @@ -250,7 +262,6 @@ "navigation_bar.personal": "个人", "navigation_bar.pins": "置顶嘟文", "navigation_bar.preferences": "首选项", - "navigation_bar.profile_directory": "用户目录", "navigation_bar.public_timeline": "跨站公共时间轴", "navigation_bar.security": "安全", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "显示内容", "status.show_more_all": "显示所有内容", "status.show_thread": "显示全部对话", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "不再隐藏此对话", "status.unpin": "在个人资料页面取消置顶", "suggestions.dismiss": "关闭建议", @@ -373,22 +385,22 @@ "time_remaining.moments": "即将结束", "time_remaining.seconds": "剩余 {number, plural, one {# 秒} other {# 秒}}", "trends.count_by_accounts": "{count} 人正在讨论", - "trends.refresh": "Refresh", + "trends.trending_now": "现在流行", "ui.beforeunload": "如果你现在离开 Mastodon,你的草稿内容将会丢失。", "upload_area.title": "将文件拖放到此处开始上传", "upload_button.label": "上传媒体文件 (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_error.limit": "文件大小超过限制。", "upload_error.poll": "投票中不允许上传文件。", "upload_form.description": "为视觉障碍人士添加文字说明", - "upload_form.edit": "Edit", + "upload_form.edit": "编辑", "upload_form.undo": "删除", - "upload_modal.analyzing_picture": "Analyzing picture…", - "upload_modal.apply": "Apply", - "upload_modal.description_placeholder": "A quick brown fox jumps over the lazy dog", - "upload_modal.detect_text": "Detect text from picture", - "upload_modal.edit_media": "Edit media", - "upload_modal.hint": "Click or drag the circle on the preview to choose the focal point which will always be in view on all thumbnails.", - "upload_modal.preview_label": "Preview ({ratio})", + "upload_modal.analyzing_picture": "分析图片…", + "upload_modal.apply": "应用", + "upload_modal.description_placeholder": "天地玄黄 宇宙洪荒 日月盈仄 辰宿列张", + "upload_modal.detect_text": "从图片中检测文本", + "upload_modal.edit_media": "编辑媒体", + "upload_modal.hint": "在预览图上点击或拖动圆圈,以选择缩略图的焦点。", + "upload_modal.preview_label": "预览 ({ratio})", "upload_progress.label": "上传中……", "video.close": "关闭视频", "video.exit_fullscreen": "退出全屏", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index f09ceffb3..0a42aa47f 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "關注你", "account.hide_reblogs": "隱藏 @{name} 的轉推", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "媒體", @@ -24,6 +25,7 @@ "account.mute": "將 @{name} 靜音", "account.mute_notifications": "將來自 @{name} 的通知靜音", "account.muted": "靜音", + "account.never_active": "Never", "account.posts": "文章", "account.posts_with_replies": "包含回覆的文章", "account.report": "舉報 @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "取消關注", "account.unmute": "取消 @{name} 的靜音", "account.unmute_notifications": "取消來自 @{name} 通知的靜音", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "發生不可預期的錯誤。", "alert.unexpected.title": "噢!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "封鎖用戶", "column.community": "本站時間軸", "column.direct": "個人訊息", + "column.directory": "Browse profiles", "column.domain_blocks": "隱藏的服務站", "column.favourites": "最愛的文章", "column.follow_requests": "關注請求", @@ -58,6 +63,7 @@ "column.notifications": "通知", "column.pins": "置頂文章", "column.public": "跨站時間軸", + "column.status": "Toot", "column_back_button.label": "返回", "column_header.hide_settings": "隱藏設定", "column_header.moveLeft_settings": "將欄左移", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "你確定要永久刪除這列表嗎?", "confirmations.domain_block.confirm": "隱藏整個網站", "confirmations.domain_block.message": "你真的真的確定要隱藏整個 {domain} ?多數情況下,比較推薦封鎖或靜音幾個特定目標就好。你從此將不會再看到該站的內容和通知。來自該站的關注者亦會被移除。", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "靜音", "confirmations.mute.message": "你確定要將{name}靜音嗎?", "confirmations.redraft.confirm": "刪除並編輯", @@ -103,6 +111,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "取消關注", "confirmations.unfollow.message": "真的不要繼續關注 {name} 了嗎?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "要內嵌此文章,請將以下代碼貼進你的網站。", "embed.preview": "看上去會是這樣:", "emoji_button.activity": "活動", @@ -250,7 +262,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "置頂文章", "navigation_bar.preferences": "偏好設定", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "跨站時間軸", "navigation_bar.security": "安全", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "顯示更多", "status.show_more_all": "顯示更多這類文章", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "解禁對話", "status.unpin": "解除置頂", "suggestions.dismiss": "Dismiss suggestion", @@ -373,7 +385,7 @@ "time_remaining.moments": "Moments remaining", "time_remaining.seconds": "{number, plural, one {# second} other {# seconds}} left", "trends.count_by_accounts": "{count} 位用戶在討論", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "如果你現在離開 Mastodon,你的草稿內容將會被丟棄。", "upload_area.title": "將檔案拖放至此上載", "upload_button.label": "上載媒體檔案", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index af988b320..82d7b6db5 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -16,6 +16,7 @@ "account.follows.empty": "這位使用者尚未關注任何使用者。", "account.follows_you": "關注了你", "account.hide_reblogs": "隱藏來自 @{name} 的轉推", + "account.last_status": "Last active", "account.link_verified_on": "已在 {date} 檢查此連結的擁有者權限", "account.locked_info": "這隻帳戶的隱私狀態被設成鎖定。該擁有者會手動審核能關注這隻帳號的人。", "account.media": "媒體", @@ -24,6 +25,7 @@ "account.mute": "靜音 @{name}", "account.mute_notifications": "靜音來自 @{name} 的通知", "account.muted": "已靜音", + "account.never_active": "Never", "account.posts": "嘟文", "account.posts_with_replies": "嘟文與回覆", "account.report": "檢舉 @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "取消關注", "account.unmute": "取消靜音 @{name}", "account.unmute_notifications": "重新接收來自 @{name} 的通知", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "發生了非預期的錯誤。", "alert.unexpected.title": "哎呀!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "封鎖的使用者", "column.community": "本機時間軸", "column.direct": "私訊", + "column.directory": "Browse profiles", "column.domain_blocks": "隱藏的網域", "column.favourites": "收藏", "column.follow_requests": "關注請求", @@ -58,6 +63,7 @@ "column.notifications": "通知", "column.pins": "釘選的嘟文", "column.public": "聯邦時間軸", + "column.status": "Toot", "column_back_button.label": "上一頁", "column_header.hide_settings": "隱藏設定", "column_header.moveLeft_settings": "將欄位向左移動", @@ -95,6 +101,8 @@ "confirmations.delete_list.message": "確定永久刪除此名單?", "confirmations.domain_block.confirm": "隱藏整個網域", "confirmations.domain_block.message": "真的非常確定封鎖整個 {domain} 嗎?大部分情況下,你只需要封鎖或靜音少數特定的人就能滿足需求了。你將不能在任何公開的時間軸及通知中看到那個網域的內容。你來自該網域的關注者也會被移除。", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "靜音", "confirmations.mute.message": "確定靜音 {name} ?", "confirmations.redraft.confirm": "刪除並重新編輯", @@ -103,6 +111,10 @@ "confirmations.reply.message": "現在回覆將蓋掉您目前正在撰寫的訊息。是否仍要回覆?", "confirmations.unfollow.confirm": "取消關注", "confirmations.unfollow.message": "真的要取消關注 {name} 嗎?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "要嵌入此嘟文,請將以下程式碼貼進你的網站。", "embed.preview": "他會顯示成這樣:", "emoji_button.activity": "活動", @@ -250,7 +262,6 @@ "navigation_bar.personal": "個人", "navigation_bar.pins": "釘選的嘟文", "navigation_bar.preferences": "偏好設定", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "聯邦時間軸", "navigation_bar.security": "安全性", "notification.and_n_others": "and {count, plural, one {# other} other {# others}}", @@ -358,6 +369,7 @@ "status.show_more": "顯示更多", "status.show_more_all": "顯示更多這類嘟文", "status.show_thread": "顯示討論串", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "解除此對話的靜音", "status.unpin": "解除置頂", "suggestions.dismiss": "關閉建議", @@ -373,7 +385,7 @@ "time_remaining.moments": "剩餘時間", "time_remaining.seconds": "剩餘 {number, plural, one {# 秒} other {# 秒}}", "trends.count_by_accounts": "{count} 位使用者在討論", - "trends.refresh": "Refresh", + "trends.trending_now": "Trending now", "ui.beforeunload": "如果離開 Mastodon,你的草稿將會不見。", "upload_area.title": "拖放來上傳", "upload_button.label": "上傳媒體檔案 (JPEG, PNG, GIF, WebM, MP4, MOV)", diff --git a/app/javascript/mastodon/reducers/notifications.js b/app/javascript/mastodon/reducers/notifications.js index 049c70cb4..45d3a5c51 100644 --- a/app/javascript/mastodon/reducers/notifications.js +++ b/app/javascript/mastodon/reducers/notifications.js @@ -35,12 +35,12 @@ const notificationToMap = notification => ImmutableMap({ }); const normalizeNotification = (state, notification, usePendingItems) => { - if (usePendingItems) { - return state.update('pendingItems', list => list.unshift(notificationToMap(notification))); - } - const top = state.get('top'); + if (usePendingItems || !top || !state.get('pendingItems').isEmpty()) { + return state.update('pendingItems', list => list.unshift(notificationToMap(notification))).update('unread', unread => unread + 1); + } + if (!top) { state = state.update('unread', unread => unread + 1); } @@ -54,7 +54,7 @@ const normalizeNotification = (state, notification, usePendingItems) => { }); }; -const expandNormalizedNotifications = (state, notifications, next, usePendingItems) => { +const expandNormalizedNotifications = (state, notifications, next, isLoadingRecent, usePendingItems) => { let items = ImmutableList(); notifications.forEach((n, i) => { @@ -63,6 +63,8 @@ const expandNormalizedNotifications = (state, notifications, next, usePendingIte return state.withMutations(mutable => { if (!items.isEmpty()) { + usePendingItems = isLoadingRecent && (usePendingItems || !mutable.get('top') || !mutable.get('pendingItems').isEmpty()); + mutable.update(usePendingItems ? 'pendingItems' : 'items', list => { const lastIndex = 1 + list.findLastIndex( item => item !== null && (compareId(item.get('id'), items.last().get('id')) > 0 || item.get('id') === items.last().get('id')) @@ -91,7 +93,7 @@ const filterNotifications = (state, accountIds) => { const updateTop = (state, top) => { if (top) { - state = state.set('unread', 0); + state = state.set('unread', state.get('pendingItems').size); } return state.set('top', top); @@ -117,7 +119,7 @@ export default function notifications(state = initialState, action) { case NOTIFICATIONS_UPDATE: return normalizeNotification(state, action.notification, action.usePendingItems); case NOTIFICATIONS_EXPAND_SUCCESS: - return expandNormalizedNotifications(state, action.notifications, action.next, action.usePendingItems); + return expandNormalizedNotifications(state, action.notifications, action.next, action.isLoadingRecent, action.usePendingItems); case ACCOUNT_BLOCK_SUCCESS: return filterNotifications(state, [action.relationship.id]); case ACCOUNT_MUTE_SUCCESS: diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index 0b036f5fe..f3ed2fc59 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -40,6 +40,7 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is if (timeline.endsWith(':pinned')) { mMap.set('items', statuses.map(status => status.get('id'))); } else if (!statuses.isEmpty()) { + usePendingItems = isLoadingRecent && (usePendingItems || !mMap.get('top') || !mMap.get('pendingItems').isEmpty()); mMap.update(usePendingItems ? 'pendingItems' : 'items', ImmutableList(), oldIds => { const newIds = statuses.map(status => status.get('id')); @@ -60,15 +61,16 @@ const expandNormalizedTimeline = (state, timeline, statuses, next, isPartial, is }; const updateTimeline = (state, timeline, status, usePendingItems) => { - if (usePendingItems) { + const top = state.getIn([timeline, 'top']); + + if (usePendingItems || !top || !state.getIn([timeline, 'pendingItems']).isEmpty()) { if (state.getIn([timeline, 'pendingItems'], ImmutableList()).includes(status.get('id')) || state.getIn([timeline, 'items'], ImmutableList()).includes(status.get('id'))) { return state; } - return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id')))); + return state.update(timeline, initialTimeline, map => map.update('pendingItems', list => list.unshift(status.get('id'))).update('unread', unread => unread + 1)); } - const top = state.getIn([timeline, 'top']); const ids = state.getIn([timeline, 'items'], ImmutableList()); const includesId = ids.includes(status.get('id')); const unread = state.getIn([timeline, 'unread'], 0); @@ -128,7 +130,7 @@ const filterTimeline = (timeline, state, relationship, statuses) => { const updateTop = (state, timeline, top) => { return state.update(timeline, initialTimeline, map => map.withMutations(mMap => { - if (top) mMap.set('unread', 0); + if (top) mMap.set('unread', mMap.get('pendingItems').size); mMap.set('top', top); })); }; diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js index e49dcaadb..9418188a7 100644 --- a/app/javascript/packs/public.js +++ b/app/javascript/packs/public.js @@ -14,10 +14,10 @@ function main() { const React = require('react'); const ReactDOM = require('react-dom'); const Rellax = require('rellax'); - const createHistory = require('history').createBrowserHistory; + const { createBrowserHistory } = require('history'); const scrollToDetailedStatus = () => { - const history = createHistory(); + const history = createBrowserHistory(); const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status'); const location = history.location; diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss index f95313a25..5dc067f0e 100644 --- a/app/javascript/styles/mastodon/accounts.scss +++ b/app/javascript/styles/mastodon/accounts.scss @@ -224,6 +224,7 @@ } .account__header__fields { + max-width: 100vw; padding: 0; margin: 15px -15px -15px; border: 0 none; diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 9bb2561cd..529ed8666 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -333,6 +333,22 @@ hr.spacer { } } +.flavour-screen { + display: block; + margin: 10px auto; + max-width: 100%; +} + +.flavour-description { + display: block; + font-size: 16px; + margin: 10px 0; + + & > p { + margin: 10px 0; + } +} + .report-accounts { display: flex; flex-wrap: wrap; @@ -732,3 +748,47 @@ a.name-tag, text-overflow: ellipsis; vertical-align: middle; } + +.admin-account-bio { + display: flex; + flex-wrap: wrap; + margin: 0 -5px; + margin-top: 20px; + + > div { + box-sizing: border-box; + padding: 0 5px; + margin-bottom: 10px; + flex: 1 0 50%; + } + + .account__header__fields, + .account__header__content { + background: lighten($ui-base-color, 8%); + border-radius: 4px; + height: 100%; + } + + .account__header__fields { + margin: 0; + border: 0; + + a { + color: lighten($ui-highlight-color, 8%); + } + + dl:first-child .verified { + border-radius: 0 4px 0 0; + } + + .verified a { + color: $valid-value-color; + } + } + + .account__header__content { + box-sizing: border-box; + padding: 20px; + color: $primary-text-color; + } +} diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss index e769c495b..aa45c0174 100644 --- a/app/javascript/styles/mastodon/containers.scss +++ b/app/javascript/styles/mastodon/containers.scss @@ -753,16 +753,6 @@ } } - .static-icon-button { - color: $action-button-color; - font-size: 18px; - - & > span { - font-size: 14px; - font-weight: 500; - } - } - .directory__list { display: grid; grid-gap: 10px; diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index 12f57b7a9..e80220f27 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -5,7 +5,6 @@ li { margin-bottom: 10px; position: relative; - height: 18px + 12px; } &__chart { @@ -24,13 +23,11 @@ &__text { position: relative; - display: inline-block; + display: flex; padding: 6px 0; line-height: 18px; cursor: default; - white-space: nowrap; overflow: hidden; - text-overflow: ellipsis; input[type=radio], input[type=checkbox] { @@ -82,6 +79,9 @@ top: -1px; border-radius: 50%; vertical-align: middle; + margin-top: auto; + margin-bottom: auto; + flex: 0 0 18px; &.checkbox { border-radius: 4px; @@ -99,6 +99,9 @@ font-weight: 700; padding: 0 10px; text-align: right; + margin-top: auto; + margin-bottom: auto; + flex: 0 0 36px; } &__footer { diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index fe6beba5d..d6403986f 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -180,6 +180,18 @@ a.table-action-link { } } + &__form { + padding: 16px; + border: 1px solid darken($ui-base-color, 8%); + border-top: 0; + background: $ui-base-color; + + .fields-row { + padding-top: 0; + margin-bottom: 0; + } + } + &__row { border: 1px solid darken($ui-base-color, 8%); border-top: 0; @@ -210,6 +222,45 @@ a.table-action-link { &--unpadded { padding: 0; } + + &--with-image { + display: flex; + align-items: center; + } + + &__image { + flex: 0 0 auto; + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; + + .emojione { + width: 32px; + height: 32px; + } + } + + &__text { + flex: 1 1 auto; + } + + &__extra { + flex: 0 0 auto; + text-align: right; + color: $darker-text-color; + font-weight: 500; + } + } + + .directory__tag { + margin: 0; + width: 100%; + + a { + background: transparent; + border-radius: 0; + } } } diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 000b77df5..e69193b71 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -189,22 +189,25 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachments = [] as_array(@object['attachment']).each do |attachment| - next if attachment['url'].blank? + next if attachment['url'].blank? || media_attachments.size >= 4 - href = Addressable::URI.parse(attachment['url']).normalize.to_s - media_attachment = MediaAttachment.create(account: @account, remote_url: href, description: attachment['name'].presence, focus: attachment['focalPoint'], blurhash: supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : nil) - media_attachments << media_attachment + begin + href = Addressable::URI.parse(attachment['url']).normalize.to_s + media_attachment = MediaAttachment.create(account: @account, remote_url: href, description: attachment['name'].presence, focus: attachment['focalPoint'], blurhash: supported_blurhash?(attachment['blurhash']) ? attachment['blurhash'] : nil) + media_attachments << media_attachment - next if unsupported_media_type?(attachment['mediaType']) || skip_download? + next if unsupported_media_type?(attachment['mediaType']) || skip_download? - media_attachment.file_remote_url = href - media_attachment.save + media_attachment.file_remote_url = href + media_attachment.save + rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + RedownloadMediaWorker.perform_in(rand(30..600).seconds, media_attachment.id) + end end media_attachments rescue Addressable::URI::InvalidURIError => e - Rails.logger.debug e - + Rails.logger.debug "Invalid URL in attachment: #{e}" media_attachments end @@ -405,15 +408,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def check_for_spam - spam_check = SpamCheck.new(@status) - - return if spam_check.skip? - - if spam_check.spam? - spam_check.flag! - else - spam_check.remember! - end + SpamCheck.perform(@status) end def forward_for_reply diff --git a/app/lib/activitypub/activity/delete.rb b/app/lib/activitypub/activity/delete.rb index 345060462..dc9ff580c 100644 --- a/app/lib/activitypub/activity/delete.rb +++ b/app/lib/activitypub/activity/delete.rb @@ -13,8 +13,7 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity def delete_person lock_or_return("delete_in_progress:#{@account.id}") do - SuspendAccountService.new.call(@account) - @account.destroy! + SuspendAccountService.new.call(@account, reserve_username: false) end end diff --git a/app/lib/activitypub/activity/move.rb b/app/lib/activitypub/activity/move.rb index d7a5f595c..6c6a2b967 100644 --- a/app/lib/activitypub/activity/move.rb +++ b/app/lib/activitypub/activity/move.rb @@ -10,10 +10,13 @@ class ActivityPub::Activity::Move < ActivityPub::Activity target_account = ActivityPub::FetchRemoteAccountService.new.call(target_uri) - return if target_account.nil? || !target_account.also_known_as.include?(origin_account.uri) + if target_account.nil? || target_account.suspended? || !target_account.also_known_as.include?(origin_account.uri) + unmark_as_processing! + return + end # In case for some reason we didn't have a redirect for the profile already, set it - origin_account.update(moved_to_account: target_account) if origin_account.moved_to_account_id.nil? + origin_account.update(moved_to_account: target_account) # Initiate a re-follow for each follower origin_account.followers.local.select(:id).find_in_batches do |follower_accounts| @@ -40,4 +43,8 @@ class ActivityPub::Activity::Move < ActivityPub::Activity def mark_as_processing! redis.setex("move_in_progress:#{@account.id}", PROCESSING_COOLDOWN, true) end + + def unmark_as_processing! + redis.del("move_in_progress:#{@account.id}") + end end diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index d85a333b3..4fa053744 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -115,8 +115,7 @@ class Formatter end def format_field(account, str, **options) - return reformat(str).html_safe unless account.local? # rubocop:disable Rails/OutputSafety - html = encode_and_link_urls(str, me: true) + html = account.local? ? encode_and_link_urls(str, me: true) : reformat(str) html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify] html.html_safe # rubocop:disable Rails/OutputSafety end diff --git a/app/lib/settings/scoped_settings.rb b/app/lib/settings/scoped_settings.rb index 343996e8a..4d21e0de7 100644 --- a/app/lib/settings/scoped_settings.rb +++ b/app/lib/settings/scoped_settings.rb @@ -5,6 +5,7 @@ module Settings DEFAULTING_TO_UNSCOPED = %w( flavour skin + noindex ).freeze def initialize(object) diff --git a/app/lib/spam_check.rb b/app/lib/spam_check.rb index 0cf1b8790..441697364 100644 --- a/app/lib/spam_check.rb +++ b/app/lib/spam_check.rb @@ -4,9 +4,25 @@ class SpamCheck include Redisable include ActionView::Helpers::TextHelper + # Threshold over which two Nilsimsa values are considered + # to refer to the same text NILSIMSA_COMPARE_THRESHOLD = 95 - NILSIMSA_MIN_SIZE = 10 - EXPIRE_SET_AFTER = 1.week.seconds + + # Nilsimsa doesn't work well on small inputs, so below + # this size, we check only for exact matches with MD5 + NILSIMSA_MIN_SIZE = 10 + + # How long to keep the trail of digests between updates, + # there is no reason to store it forever + EXPIRE_SET_AFTER = 1.week.seconds + + # How many digests to keep in an account's trail. If it's + # too small, spam could rotate around different message templates + MAX_TRAIL_SIZE = 10 + + # How many detected duplicates to allow through before + # considering the message as spam + THRESHOLD = 5 def initialize(status) @account = status.account @@ -21,9 +37,9 @@ class SpamCheck if insufficient_data? false elsif nilsimsa? - any_other_digest?('nilsimsa') { |_, other_digest| nilsimsa_compare_value(digest, other_digest) >= NILSIMSA_COMPARE_THRESHOLD } + digests_over_threshold?('nilsimsa') { |_, other_digest| nilsimsa_compare_value(digest, other_digest) >= NILSIMSA_COMPARE_THRESHOLD } else - any_other_digest?('md5') { |_, other_digest| other_digest == digest } + digests_over_threshold?('md5') { |_, other_digest| other_digest == digest } end end @@ -38,7 +54,7 @@ class SpamCheck # get the correct status ID back, we have to save it in the string value redis.zadd(redis_key, @status.id, digest_with_algorithm) - redis.zremrangebyrank(redis_key, '0', '-10') + redis.zremrangebyrank(redis_key, 0, -(MAX_TRAIL_SIZE + 1)) redis.expire(redis_key, EXPIRE_SET_AFTER) end @@ -78,6 +94,20 @@ class SpamCheck end end + class << self + def perform(status) + spam_check = new(status) + + return if spam_check.skip? + + if spam_check.spam? + spam_check.flag! + else + spam_check.remember! + end + end + end + private def disabled? @@ -149,14 +179,14 @@ class SpamCheck redis.zrange(redis_key, 0, -1) end - def any_other_digest?(filter_algorithm) - other_digests.any? do |record| + def digests_over_threshold?(filter_algorithm) + other_digests.select do |record| algorithm, other_digest, status_id = record.split(':') next unless algorithm == filter_algorithm yield algorithm, other_digest, status_id - end + end.size >= THRESHOLD end def matching_status_ids diff --git a/app/models/account.rb b/app/models/account.rb index 918b17430..e1593fe81 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -119,6 +119,7 @@ class Account < ApplicationRecord :approved?, :pending?, :disabled?, + :unconfirmed_or_pending?, :role, :admin?, :moderator?, diff --git a/app/models/admin/account_action.rb b/app/models/admin/account_action.rb index c7da8b52c..b30a82369 100644 --- a/app/models/admin/account_action.rb +++ b/app/models/admin/account_action.rb @@ -83,19 +83,23 @@ class Admin::AccountAction # A log entry is only interesting if the warning contains # custom text from someone. Otherwise it's just noise. + log_action(:create, warning) if warning.text.present? end def process_reports! - return if report_id.blank? + # If we're doing "mark as resolved" on a single report, + # then we want to keep other reports open in case they + # contain new actionable information. + # + # Otherwise, we will mark all unresolved reports about + # the account as resolved. - authorize(report, :update?) + reports.each { |report| authorize(report, :update?) } - if type == 'none' + reports.each do |report| log_action(:resolve, report) report.resolve!(current_account) - else - Report.where(target_account: target_account).unresolved.update_all(action_taken: true, action_taken_by_account_id: current_account.id) end end @@ -141,6 +145,16 @@ class Admin::AccountAction @report.status_ids if @report && include_statuses end + def reports + @reports ||= begin + if type == 'none' && with_report? + [report] + else + Report.where(target_account: target_account).unresolved + end + end + end + def warning_preset @warning_preset ||= AccountWarningPreset.find(warning_preset_id) if warning_preset_id.present? end diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb index b9c124841..960784222 100644 --- a/app/models/concerns/omniauthable.rb +++ b/app/models/concerns/omniauthable.rb @@ -4,7 +4,7 @@ module Omniauthable extend ActiveSupport::Concern TEMP_EMAIL_PREFIX = 'change@me' - TEMP_EMAIL_REGEX = /\Achange@me/ + TEMP_EMAIL_REGEX = /\A#{TEMP_EMAIL_PREFIX}/.freeze included do devise :omniauthable @@ -28,8 +28,8 @@ module Omniauthable # to prevent the identity being locked with accidentally created accounts. # Note that this may leave zombie accounts (with no associated identity) which # can be cleaned up at a later date. - user = signed_in_resource || identity.user - user = create_for_oauth(auth) if user.nil? + user = signed_in_resource || identity.user + user ||= create_for_oauth(auth) if identity.user.nil? identity.user = user @@ -45,7 +45,18 @@ module Omniauthable # exists, we assign a temporary email and ask the user to verify it on # the next step via Auth::SetupController.show - user = User.new(user_params_from_auth(auth)) + strategy = Devise.omniauth_configs[auth.provider.to_sym].strategy + assume_verified = strategy&.security&.assume_email_is_verified + email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified + email = auth.info.verified_email || auth.info.email + email = nil unless email_is_verified + + user = User.find_by(email: email) if email_is_verified + + return user unless user.nil? + + user = User.new(user_params_from_auth(email, auth)) + user.account.avatar_remote_url = auth.info.image if auth.info.image =~ /\A#{URI.regexp(%w(http https))}\z/ user.skip_confirmation! user.save! @@ -54,14 +65,7 @@ module Omniauthable private - def user_params_from_auth(auth) - strategy = Devise.omniauth_configs[auth.provider.to_sym].strategy - assume_verified = strategy.try(:security).try(:assume_email_is_verified) - email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified - email = auth.info.verified_email || auth.info.email - email = email_is_verified && !User.exists?(email: auth.info.email) && email - display_name = auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' ') - + def user_params_from_auth(email, auth) { email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com", password: Devise.friendly_token[0, 20], @@ -69,7 +73,7 @@ module Omniauthable external: true, account_attributes: { username: ensure_unique_username(auth.uid), - display_name: display_name, + display_name: auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' '), }, } end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 9372a963b..082302619 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -4,7 +4,7 @@ module Remotable extend ActiveSupport::Concern class_methods do - def remotable_attachment(attachment_name, limit) + def remotable_attachment(attachment_name, limit, suppress_errors: true) attribute_name = "#{attachment_name}_remote_url".to_sym method_name = "#{attribute_name}=".to_sym alt_method_name = "reset_#{attachment_name}!".to_sym @@ -22,7 +22,7 @@ module Remotable begin Request.new(:get, url).perform do |response| - next if response.code != 200 + raise Mastodon::UnexpectedResponseError, response unless (200...300).cover?(response.code) content_type = parse_content_type(response.headers.get('content-type').last) extname = detect_extname_from_content_type(content_type) @@ -41,11 +41,11 @@ module Remotable self[attribute_name] = url if has_attribute?(attribute_name) end - rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e + rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e + Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + raise e unless suppress_errors + rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" - nil - rescue Paperclip::Error, Mastodon::DimensionsValidationError => e - Rails.logger.debug "Error processing remote #{attachment_name}: #{e}" nil end end diff --git a/app/models/custom_emoji.rb b/app/models/custom_emoji.rb index b21ad9042..0dacaf654 100644 --- a/app/models/custom_emoji.rb +++ b/app/models/custom_emoji.rb @@ -40,10 +40,11 @@ class CustomEmoji < ApplicationRecord validates_attachment :image, content_type: { content_type: IMAGE_MIME_TYPES }, presence: true, size: { less_than: LIMIT } validates :shortcode, uniqueness: { scope: :domain }, format: { with: /\A#{SHORTCODE_RE_FRAGMENT}\z/ }, length: { minimum: 2 } - scope :local, -> { where(domain: nil) } - scope :remote, -> { where.not(domain: nil) } + scope :local, -> { where(domain: nil) } + scope :remote, -> { where.not(domain: nil) } scope :alphabetic, -> { order(domain: :asc, shortcode: :asc) } scope :by_domain_and_subdomains, ->(domain) { where(domain: domain).or(where(arel_table[:domain].matches('%.' + domain))) } + scope :listed, -> { local.where(disabled: false).where(visible_in_picker: true) } remotable_attachment :image, LIMIT @@ -59,6 +60,12 @@ class CustomEmoji < ApplicationRecord :emoji end + def copy! + copy = self.class.find_or_initialize_by(domain: nil, shortcode: shortcode) + copy.image = image + copy.tap(&:save!) + end + class << self def from_text(text, domain) return [] if text.blank? diff --git a/app/models/custom_emoji_category.rb b/app/models/custom_emoji_category.rb index 7d8c0ee2d..3c87f2b2e 100644 --- a/app/models/custom_emoji_category.rb +++ b/app/models/custom_emoji_category.rb @@ -12,4 +12,6 @@ class CustomEmojiCategory < ApplicationRecord has_many :emojis, class_name: 'CustomEmoji', foreign_key: 'category_id', inverse_of: :category + + validates :name, presence: true, uniqueness: true end diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb index 7649055d2..15b8da1d1 100644 --- a/app/models/custom_emoji_filter.rb +++ b/app/models/custom_emoji_filter.rb @@ -11,6 +11,8 @@ class CustomEmojiFilter scope = CustomEmoji.alphabetic params.each do |key, value| + next if key.to_s == 'page' + scope.merge!(scope_for(key, value)) if value.present? end @@ -22,13 +24,13 @@ class CustomEmojiFilter def scope_for(key, value) case key.to_s when 'local' - CustomEmoji.local + CustomEmoji.local.left_joins(:category).reorder(Arel.sql('custom_emoji_categories.name ASC NULLS FIRST, custom_emojis.shortcode ASC')) when 'remote' CustomEmoji.remote when 'by_domain' - CustomEmoji.where(domain: value.downcase) + CustomEmoji.where(domain: value.strip.downcase) when 'shortcode' - CustomEmoji.search(value) + CustomEmoji.search(value.strip) else raise "Unknown filter: #{key}" end diff --git a/app/models/form/account_batch.rb b/app/models/form/account_batch.rb index f1b7a4566..0b285fde9 100644 --- a/app/models/form/account_batch.rb +++ b/app/models/form/account_batch.rb @@ -69,6 +69,6 @@ class Form::AccountBatch records = accounts.includes(:user) records.each { |account| authorize(account.user, :reject?) } - .each { |account| SuspendAccountService.new.call(account, including_user: true, destroy: true, skip_distribution: true) } + .each { |account| SuspendAccountService.new.call(account, reserve_email: false, reserve_username: false) } end end diff --git a/app/models/form/admin_settings.rb b/app/models/form/admin_settings.rb index 57dd3edd9..f1ee38325 100644 --- a/app/models/form/admin_settings.rb +++ b/app/models/form/admin_settings.rb @@ -38,6 +38,7 @@ class Form::AdminSettings trends show_domain_blocks show_domain_blocks_rationale + noindex ).freeze BOOLEAN_KEYS = %i( @@ -55,6 +56,7 @@ class Form::AdminSettings show_replies_in_public_timelines spam_check_enabled trends + noindex ).freeze UPLOAD_KEYS = %i( diff --git a/app/models/form/custom_emoji_batch.rb b/app/models/form/custom_emoji_batch.rb new file mode 100644 index 000000000..076e8c9e3 --- /dev/null +++ b/app/models/form/custom_emoji_batch.rb @@ -0,0 +1,106 @@ +# frozen_string_literal: true + +class Form::CustomEmojiBatch + include ActiveModel::Model + include Authorization + include AccountableConcern + + attr_accessor :custom_emoji_ids, :action, :current_account, + :category_id, :category_name, :visible_in_picker + + def save + case action + when 'update' + update! + when 'list' + list! + when 'unlist' + unlist! + when 'enable' + enable! + when 'disable' + disable! + when 'copy' + copy! + when 'delete' + delete! + end + end + + private + + def custom_emojis + CustomEmoji.where(id: custom_emoji_ids) + end + + def update! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) } + + category = begin + if category_id.present? + CustomEmojiCategory.find(category_id) + elsif category_name.present? + CustomEmojiCategory.create!(name: category_name) + end + end + + custom_emojis.each do |custom_emoji| + custom_emoji.update(category_id: category&.id) + log_action :update, custom_emoji + end + end + + def list! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.update(visible_in_picker: true) + log_action :update, custom_emoji + end + end + + def unlist! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :update?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.update(visible_in_picker: false) + log_action :update, custom_emoji + end + end + + def enable! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :enable?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.update(disabled: false) + log_action :enable, custom_emoji + end + end + + def disable! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :disable?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.update(disabled: true) + log_action :disable, custom_emoji + end + end + + def copy! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :copy?) } + + custom_emojis.each do |custom_emoji| + copied_custom_emoji = custom_emoji.copy! + log_action :create, copied_custom_emoji + end + end + + def delete! + custom_emojis.each { |custom_emoji| authorize(custom_emoji, :destroy?) } + + custom_emojis.each do |custom_emoji| + custom_emoji.destroy + log_action :destroy, custom_emoji + end + end +end diff --git a/app/models/form/delete_confirmation.rb b/app/models/form/delete_confirmation.rb index 0884a09b8..99d04b331 100644 --- a/app/models/form/delete_confirmation.rb +++ b/app/models/form/delete_confirmation.rb @@ -3,5 +3,5 @@ class Form::DeleteConfirmation include ActiveModel::Model - attr_accessor :password + attr_accessor :password, :username end diff --git a/app/models/form/status_batch.rb b/app/models/form/status_batch.rb index e09cc2594..c4943a7ea 100644 --- a/app/models/form/status_batch.rb +++ b/app/models/form/status_batch.rb @@ -35,7 +35,7 @@ class Form::StatusBatch def delete_statuses Status.where(id: status_ids).reorder(nil).find_each do |status| status.discard - RemovalWorker.perform_async(status.id, redraft: false) + RemovalWorker.perform_async(status.id, immediate: true) Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true) log_action :destroy, status end diff --git a/app/models/form/tag_batch.rb b/app/models/form/tag_batch.rb new file mode 100644 index 000000000..fd517a1a6 --- /dev/null +++ b/app/models/form/tag_batch.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +class Form::TagBatch + include ActiveModel::Model + include Authorization + + attr_accessor :tag_ids, :action, :current_account + + def save + case action + when 'approve' + approve! + when 'reject' + reject! + end + end + + private + + def tags + Tag.where(id: tag_ids) + end + + def approve! + tags.each { |tag| authorize(tag, :update?) } + tags.update_all(trendable: true, reviewed_at: Time.now.utc) + end + + def reject! + tags.each { |tag| authorize(tag, :update?) } + tags.update_all(trendable: false, reviewed_at: Time.now.utc) + end +end diff --git a/app/models/form/two_factor_confirmation.rb b/app/models/form/two_factor_confirmation.rb index b8cf76d05..27ada6533 100644 --- a/app/models/form/two_factor_confirmation.rb +++ b/app/models/form/two_factor_confirmation.rb @@ -3,5 +3,5 @@ class Form::TwoFactorConfirmation include ActiveModel::Model - attr_accessor :code + attr_accessor :otp_attempt end diff --git a/app/models/marker.rb b/app/models/marker.rb new file mode 100644 index 000000000..a5bd2176a --- /dev/null +++ b/app/models/marker.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: markers +# +# id :bigint(8) not null, primary key +# user_id :bigint(8) +# timeline :string default(""), not null +# last_read_id :bigint(8) default(0), not null +# lock_version :integer default(0), not null +# created_at :datetime not null +# updated_at :datetime not null +# + +class Marker < ApplicationRecord + TIMELINES = %w(home notifications).freeze + + belongs_to :user + + validates :timeline, :last_read_id, presence: true + validates :timeline, inclusion: { in: TIMELINES } +end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 83d1858aa..cbe23810b 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -118,17 +118,18 @@ class MediaAttachment < ApplicationRecord validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES validates_attachment_size :file, less_than: IMAGE_LIMIT, unless: :larger_media_format? validates_attachment_size :file, less_than: VIDEO_LIMIT, if: :larger_media_format? - remotable_attachment :file, VIDEO_LIMIT + remotable_attachment :file, VIDEO_LIMIT, suppress_errors: false include Attachmentable validates :account, presence: true - validates :description, length: { maximum: 420 }, if: :local? + validates :description, length: { maximum: 1_500 }, if: :local? scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) } scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) } scope :local, -> { where(remote_url: '') } scope :remote, -> { where.not(remote_url: '') } + scope :cached, -> { remote.where.not(file_file_name: nil) } default_scope { order(id: :asc) } diff --git a/app/models/preview_card.rb b/app/models/preview_card.rb index a792b352b..9d6c1938a 100644 --- a/app/models/preview_card.rb +++ b/app/models/preview_card.rb @@ -43,6 +43,8 @@ class PreviewCard < ApplicationRecord validates_attachment_size :image, less_than: LIMIT remotable_attachment :image, LIMIT + scope :cached, -> { where.not(image_file_name: [nil, '']) } + before_save :extract_dimensions, if: :link? def save_with_optional_image! diff --git a/app/models/report.rb b/app/models/report.rb index 1e707ff1c..fb2e040ee 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -59,6 +59,7 @@ class Report < ApplicationRecord end def resolve!(acting_account) + RemovalWorker.push_bulk(Status.with_discarded.discarded.where(id: status_ids).pluck(:id)) { |status_id| [status_id, { immediate: true }] } update!(action_taken: true, action_taken_by_account_id: acting_account.id) end diff --git a/app/models/status.rb b/app/models/status.rb index 757deea06..b0f610aa2 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -221,6 +221,10 @@ class Status < ApplicationRecord !sensitive? && with_media? end + def reported? + @reported ||= Report.where(target_account: account).unresolved.where('? = ANY(status_ids)', id).exists? + end + def emojis return @emojis if defined?(@emojis) diff --git a/app/models/tag.rb b/app/models/tag.rb index 135e0a030..b52b9bc9f 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -20,13 +20,14 @@ class Tag < ApplicationRecord has_and_belongs_to_many :statuses has_and_belongs_to_many :accounts - has_and_belongs_to_many :sample_accounts, -> { searchable.discoverable.popular.limit(3) }, class_name: 'Account' + has_and_belongs_to_many :sample_accounts, -> { local.discoverable.popular.limit(3) }, class_name: 'Account' has_many :featured_tags, dependent: :destroy, inverse_of: :tag has_one :account_tag_stat, dependent: :destroy - HASHTAG_NAME_RE = '([[:word:]_][[:word:]_·]*[[:alpha:]_·][[:word:]_·]*[[:word:]_])|([[:word:]_]*[[:alpha:]][[:word:]_]*)' - HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/i + HASHTAG_SEPARATORS = "_\u00B7\u200c" + HASHTAG_NAME_RE = "([[:word:]_][[:word:]#{HASHTAG_SEPARATORS}]*[[:alpha:]#{HASHTAG_SEPARATORS}][[:word:]#{HASHTAG_SEPARATORS}]*[[:word:]_])|([[:word:]_]*[[:alpha:]][[:word:]_]*)" + HASHTAG_RE = /(?:^|[^\/\)\w])#(#{HASHTAG_NAME_RE})/i validates :name, presence: true, format: { with: /\A(#{HASHTAG_NAME_RE})\z/i } validate :validate_name_change, if: -> { !new_record? && name_changed? } @@ -38,6 +39,7 @@ class Tag < ApplicationRecord scope :listable, -> { where(listable: [true, nil]) } scope :discoverable, -> { listable.joins(:account_tag_stat).where(AccountTagStat.arel_table[:accounts_count].gt(0)).order(Arel.sql('account_tag_stats.accounts_count desc')) } scope :most_used, ->(account) { joins(:statuses).where(statuses: { account: account }).group(:id).order(Arel.sql('count(*) desc')) } + scope :matches_name, ->(value) { where(arel_table[:name].matches("#{value}%")) } delegate :accounts_count, :accounts_count=, diff --git a/app/models/tag_filter.rb b/app/models/tag_filter.rb new file mode 100644 index 000000000..8921e186b --- /dev/null +++ b/app/models/tag_filter.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class TagFilter + attr_reader :params + + def initialize(params) + @params = params + end + + def results + scope = Tag.unscoped + + params.each do |key, value| + next if key.to_s == 'page' + + scope.merge!(scope_for(key, value.to_s.strip)) if value.present? + end + + scope.order(id: :desc) + end + + private + + def scope_for(key, value) + case key.to_s + when 'directory' + Tag.discoverable + when 'reviewed' + Tag.reviewed.order(reviewed_at: :desc) + when 'unreviewed' + Tag.unreviewed + when 'pending_review' + Tag.pending_review.order(requested_review_at: :desc) + when 'popular' + Tag.order('max_score DESC NULLS LAST') + when 'active' + Tag.order('last_status_at DESC NULLS LAST') + when 'name' + Tag.matches_name(value) + else + raise "Unknown filter: #{key}" + end + end +end diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb index e1b92b175..8cdade42d 100644 --- a/app/models/trending_tags.rb +++ b/app/models/trending_tags.rb @@ -7,8 +7,8 @@ class TrendingTags THRESHOLD = 5 LIMIT = 10 REVIEW_THRESHOLD = 3 - MAX_SCORE_COOLDOWN = 3.days.freeze - MAX_SCORE_HALFLIFE = 6.hours.freeze + MAX_SCORE_COOLDOWN = 2.days.freeze + MAX_SCORE_HALFLIFE = 2.hours.freeze class << self include Redisable @@ -83,6 +83,7 @@ class TrendingTags # Trim older items redis.zremrangebyrank(KEY, 0, -(LIMIT + 1)) + redis.zremrangebyscore(KEY, '(0.3', '-inf') end def get(limit, filtered: true) diff --git a/app/models/user.rb b/app/models/user.rb index 341227d3e..792246b1d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -74,6 +74,7 @@ class User < ApplicationRecord has_many :applications, class_name: 'Doorkeeper::Application', as: :owner has_many :backups, inverse_of: :user has_many :invites, inverse_of: :user + has_many :markers, inverse_of: :user, dependent: :destroy has_one :invite_request, class_name: 'UserInviteRequest', inverse_of: :user, dependent: :destroy accepts_nested_attributes_for :invite_request, reject_if: ->(attributes) { attributes['text'].blank? } @@ -171,6 +172,10 @@ class User < ApplicationRecord confirmed? && approved? && !disabled? && !account.suspended? end + def unconfirmed_or_pending? + !(confirmed? && approved?) + end + def inactive_message !approved? ? :pending : super end diff --git a/app/presenters/instance_presenter.rb b/app/presenters/instance_presenter.rb index 534752932..d8a21fa7c 100644 --- a/app/presenters/instance_presenter.rb +++ b/app/presenters/instance_presenter.rb @@ -33,7 +33,7 @@ class InstancePresenter end def sample_accounts - Rails.cache.fetch('sample_accounts', expires_in: 12.hours) { Account.discoverable.popular.limit(3) } + Rails.cache.fetch('sample_accounts', expires_in: 12.hours) { Account.local.discoverable.popular.limit(3) } end def version_number diff --git a/app/serializers/manifest_serializer.rb b/app/serializers/manifest_serializer.rb index 28127437d..21ec0d4be 100644 --- a/app/serializers/manifest_serializer.rb +++ b/app/serializers/manifest_serializer.rb @@ -55,6 +55,8 @@ class ManifestSerializer < ActiveModel::Serializer { url_template: 'share?title={title}&text={text}&url={url}', action: 'share', + method: 'GET', + enctype: 'application/x-www-form-urlencoded', params: { title: 'title', text: 'text', diff --git a/app/serializers/rest/featured_tag_serializer.rb b/app/serializers/rest/featured_tag_serializer.rb new file mode 100644 index 000000000..08121ff16 --- /dev/null +++ b/app/serializers/rest/featured_tag_serializer.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class REST::FeaturedTagSerializer < ActiveModel::Serializer + attributes :id, :name, :statuses_count, :last_status_at + + def id + object.id.to_s + end +end diff --git a/app/serializers/rest/marker_serializer.rb b/app/serializers/rest/marker_serializer.rb new file mode 100644 index 000000000..2eaf3d507 --- /dev/null +++ b/app/serializers/rest/marker_serializer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class REST::MarkerSerializer < ActiveModel::Serializer + attributes :last_read_id, :version, :updated_at + + def last_read_id + object.last_read_id.to_s + end + + def version + object.lock_version + end +end diff --git a/app/serializers/rest/search_serializer.rb b/app/serializers/rest/search_serializer.rb index 157f543ae..ee9b421eb 100644 --- a/app/serializers/rest/search_serializer.rb +++ b/app/serializers/rest/search_serializer.rb @@ -1,12 +1,7 @@ # frozen_string_literal: true class REST::SearchSerializer < ActiveModel::Serializer - attributes :hashtags - has_many :accounts, serializer: REST::AccountSerializer has_many :statuses, serializer: REST::StatusSerializer - - def hashtags - object.hashtags.map(&:name) - end + has_many :hashtags, serializer: REST::TagSerializer end diff --git a/app/serializers/rest/v2/search_serializer.rb b/app/serializers/rest/v2/search_serializer.rb deleted file mode 100644 index cdb6b3a53..000000000 --- a/app/serializers/rest/v2/search_serializer.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -class REST::V2::SearchSerializer < ActiveModel::Serializer - has_many :accounts, serializer: REST::AccountSerializer - has_many :statuses, serializer: REST::StatusSerializer - has_many :hashtags, serializer: REST::TagSerializer -end diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index 0ec6be503..ae461abf2 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -53,7 +53,7 @@ class BlockDomainService < BaseService def suspend_accounts! blocked_domain_accounts.without_suspended.reorder(nil).find_each do |account| - SuspendAccountService.new.call(account, suspended_at: @domain_block.created_at) + SuspendAccountService.new.call(account, reserve_username: true, suspended_at: @domain_block.created_at) end end diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index a374206eb..19de37717 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -33,6 +33,7 @@ class ProcessMentionsService < BaseService end status.save! + check_for_spam(status) mentions.each { |mention| create_notification(mention) } end @@ -61,4 +62,8 @@ class ProcessMentionsService < BaseService def resolve_account_service ResolveAccountService.new end + + def check_for_spam(status) + SpamCheck.perform(status) + end end diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index b2f712089..1ddce675c 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -8,7 +8,8 @@ class RemoveStatusService < BaseService # @param [Status] status # @param [Hash] options # @option [Boolean] :redraft - # @options [Boolean] :original_removed + # @option [Boolean] :immediate + # @option [Boolean] :original_removed def call(status, **options) @payload = Oj.dump(event: :delete, payload: status.id.to_s) @status = status @@ -32,7 +33,7 @@ class RemoveStatusService < BaseService remove_from_spam_check remove_media - @status.destroy! + @status.destroy! if @options[:immediate] || !@status.reported? else raise Mastodon::RaceConditionError end @@ -158,7 +159,7 @@ class RemoveStatusService < BaseService end def remove_media - return if @options[:redraft] + return if @options[:redraft] || (!@options[:immediate] && @status.reported?) @status.media_attachments.destroy_all end diff --git a/app/services/search_service.rb b/app/services/search_service.rb index fe601bbf4..a5ba5dd11 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -11,7 +11,7 @@ class SearchService < BaseService default_results.tap do |results| if url_query? - results.merge!(url_resource_results) unless url_resource.nil? + results.merge!(url_resource_results) unless url_resource.nil? || (@options[:type].present? && url_resource_symbol != @options[:type].to_sym) elsif @query.present? results[:accounts] = perform_accounts_search! if account_searchable? results[:statuses] = perform_statuses_search! if full_text_searchable? @@ -69,7 +69,7 @@ class SearchService < BaseService end def url_query? - @resolve && @options[:type].blank? && @query =~ /\Ahttps?:\/\// + @resolve && @query =~ /\Ahttps?:\/\// end def url_resource_results diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb index 85da7e921..ecc893931 100644 --- a/app/services/suspend_account_service.rb +++ b/app/services/suspend_account_service.rb @@ -15,7 +15,6 @@ class SuspendAccountService < BaseService favourites follow_requests list_accounts - media_attachments mute_relationships muted_by_relationships notifications @@ -32,14 +31,26 @@ class SuspendAccountService < BaseService targeted_reports ).freeze - # Suspend an account and remove as much of its data as possible + # Suspend or remove an account and remove as much of its data + # as possible. If it's a local account and it has not been confirmed + # or never been approved, then side effects are skipped and both + # the user and account records are removed fully. Otherwise, + # it is controlled by options. # @param [Account] # @param [Hash] options - # @option [Boolean] :including_user Remove the user record as well - # @option [Boolean] :destroy Remove the account record instead of suspending + # @option [Boolean] :reserve_email Keep user record. Only applicable for local accounts + # @option [Boolean] :reserve_username Keep account record + # @option [Boolean] :skip_side_effects Side effects are ActivityPub and streaming API payloads + # @option [Time] :suspended_at Only applicable when :reserve_username is true def call(account, **options) @account = account - @options = options + @options = { reserve_username: true, reserve_email: true }.merge(options) + + if @account.local? && @account.user_unconfirmed_or_pending? + @options[:reserve_email] = false + @options[:reserve_username] = false + @options[:skip_side_effects] = true + end reject_follows! purge_user! @@ -60,27 +71,39 @@ class SuspendAccountService < BaseService def purge_user! return if !@account.local? || @account.user.nil? - if @options[:including_user] - @options[:destroy] = true if !@account.user_confirmed? || @account.user_pending? - @account.user.destroy - else + if @options[:reserve_email] @account.user.disable! @account.user.invites.where(uses: 0).destroy_all + else + @account.user.destroy end end def purge_content! - distribute_delete_actor! if @account.local? && !@options[:skip_distribution] + distribute_delete_actor! if @account.local? && !@options[:skip_side_effects] @account.statuses.reorder(nil).find_in_batches do |statuses| - BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:destroy]) + statuses.reject! { |status| reported_status_ids.include?(status.id) } if @options[:reserve_username] + BatchedRemoveStatusService.new.call(statuses, skip_side_effects: @options[:skip_side_effects]) + end + + @account.media_attachments.reorder(nil).find_each do |media_attachment| + next if @options[:reserve_username] && reported_status_ids.include?(media_attachment.status_id) + + media_attachment.destroy + end + + @account.polls.reorder(nil).find_each do |poll| + next if @options[:reserve_username] && reported_status_ids.include?(poll.status_id) + + poll.destroy end associations_for_destruction.each do |association_name| destroy_all(@account.public_send(association_name)) end - @account.destroy if @options[:destroy] + @account.destroy unless @options[:reserve_username] end def purge_profile! @@ -88,11 +111,13 @@ class SuspendAccountService < BaseService # there is no point wasting time updating # its values first - return if @options[:destroy] + return unless @options[:reserve_username] @account.silenced_at = nil @account.suspended_at = @options[:suspended_at] || Time.now.utc @account.locked = false + @account.memorial = false + @account.discoverable = false @account.display_name = '' @account.note = '' @account.fields = [] @@ -100,6 +125,7 @@ class SuspendAccountService < BaseService @account.followers_count = 0 @account.following_count = 0 @account.moved_to_account = nil + @account.trust_level = :untrusted @account.avatar.destroy @account.header.destroy @account.save! @@ -135,11 +161,15 @@ class SuspendAccountService < BaseService Account.inboxes - delivery_inboxes end + def reported_status_ids + @reported_status_ids ||= Report.where(target_account: @account).unresolved.pluck(:status_ids).flatten.uniq + end + def associations_for_destruction - if @options[:destroy] - ASSOCIATIONS_ON_SUSPEND + ASSOCIATIONS_ON_DESTROY - else + if @options[:reserve_username] ASSOCIATIONS_ON_SUSPEND + else + ASSOCIATIONS_ON_SUSPEND + ASSOCIATIONS_ON_DESTROY end end end diff --git a/app/services/unallow_domain_service.rb b/app/services/unallow_domain_service.rb index d4387c1a1..bd1ad328d 100644 --- a/app/services/unallow_domain_service.rb +++ b/app/services/unallow_domain_service.rb @@ -3,7 +3,7 @@ class UnallowDomainService < BaseService def call(domain_allow) Account.where(domain: domain_allow.domain).find_each do |account| - SuspendAccountService.new.call(account, destroy: true) + SuspendAccountService.new.call(account, reserve_username: false) end domain_allow.destroy diff --git a/app/services/unfollow_service.rb b/app/services/unfollow_service.rb index b7033d7eb..151f3674f 100644 --- a/app/services/unfollow_service.rb +++ b/app/services/unfollow_service.rb @@ -6,9 +6,12 @@ class UnfollowService < BaseService # Unfollow and notify the remote user # @param [Account] source_account Where to unfollow from # @param [Account] target_account Which to unfollow - def call(source_account, target_account) + # @param [Hash] options + # @option [Boolean] :skip_unmerge + def call(source_account, target_account, options = {}) @source_account = source_account @target_account = target_account + @options = options unfollow! || undo_follow_request! end @@ -21,9 +24,11 @@ class UnfollowService < BaseService return unless follow follow.destroy! + create_notification(follow) if !@target_account.local? && @target_account.activitypub? create_reject_notification(follow) if @target_account.local? && !@source_account.local? && @source_account.activitypub? - UnmergeWorker.perform_async(@target_account.id, @source_account.id) + UnmergeWorker.perform_async(@target_account.id, @source_account.id) unless @options[:skip_unmerge] + follow end @@ -33,7 +38,9 @@ class UnfollowService < BaseService return unless follow_request follow_request.destroy! + create_notification(follow_request) unless @target_account.local? + follow_request end diff --git a/app/views/about/_login.html.haml b/app/views/about/_login.html.haml index d286f0d3c..fa58f04d7 100644 --- a/app/views/about/_login.html.haml +++ b/app/views/about/_login.html.haml @@ -1,4 +1,4 @@ -= simple_form_for(new_user, url: user_session_path) do |f| += simple_form_for(new_user, url: user_session_path, namespace: 'login') do |f| .fields-group - if use_seamless_external_login? = f.input :email, placeholder: t('simple_form.labels.defaults.username_or_email'), input_html: { 'aria-label' => t('simple_form.labels.defaults.username_or_email') }, hint: false diff --git a/app/views/about/_registration.html.haml b/app/views/about/_registration.html.haml index ff32ec8c4..1333c68c4 100644 --- a/app/views/about/_registration.html.haml +++ b/app/views/about/_registration.html.haml @@ -1,4 +1,4 @@ -= simple_form_for(new_user, url: user_registration_path) do |f| += simple_form_for(new_user, url: user_registration_path, namespace: 'registration') do |f| .simple_form__overlay-area %p.lead= t('about.federation_hint_html', instance: content_tag(:strong, site_hostname)) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 59babd3b0..40a936e86 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -3,6 +3,34 @@ = render 'application/card', account: @account +- account = @account +- proofs = account.identity_proofs.active +- fields = account.fields +- unless fields.empty? && proofs.empty? && account.note.blank? + .admin-account-bio + - unless fields.empty? && proofs.empty? + %div + .account__header__fields + - proofs.each do |proof| + %dl + %dt= proof.provider.capitalize + %dd.verified + = link_to fa_icon('check'), proof.badge.proof_url, class: 'verified__mark', title: t('accounts.link_verified_on', date: l(proof.updated_at)) + = link_to proof.provider_username, proof.badge.profile_url + + - fields.each do |field| + %dl + %dt.emojify{ title: field.name }= Formatter.instance.format_field(account, field.name, custom_emojify: true) + %dd{ title: field.value, class: custom_field_classes(field) } + - if field.verified? + %span.verified__mark{ title: t('accounts.link_verified_on', date: l(field.verified_at)) } + = fa_icon 'check' + = Formatter.instance.format_field(account, field.value, custom_emojify: true) + + - if account.note.present? + %div + .account__header__content.emojify= Formatter.instance.simplified_format(account, custom_emojify: true) + .dashboard__counters{ style: 'margin-top: 10px' } %div = link_to admin_account_statuses_path(@account.id) do diff --git a/app/views/admin/custom_emojis/_custom_emoji.html.haml b/app/views/admin/custom_emojis/_custom_emoji.html.haml index fbaa9a174..2103b0fa7 100644 --- a/app/views/admin/custom_emojis/_custom_emoji.html.haml +++ b/app/views/admin/custom_emojis/_custom_emoji.html.haml @@ -1,28 +1,31 @@ -%tr - %td - = custom_emoji_tag(custom_emoji) - %td - %samp= ":#{custom_emoji.shortcode}:" - %td - - if custom_emoji.local? - = t('admin.accounts.location.local') - - else - = link_to custom_emoji.domain, admin_custom_emojis_path(by_domain: custom_emoji.domain) - %td - - if custom_emoji.local? - - if custom_emoji.visible_in_picker - = table_link_to 'eye', t('admin.custom_emojis.listed'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: false }, page: params[:page], **@filter_params), method: :patch +.batch-table__row + %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox + = f.check_box :custom_emoji_ids, { multiple: true, include_hidden: false }, custom_emoji.id + .batch-table__row__content.batch-table__row__content--with-image + .batch-table__row__content__image + = custom_emoji_tag(custom_emoji, animate = current_account&.user&.setting_auto_play_gif) + + .batch-table__row__content__text + %samp= ":#{custom_emoji.shortcode}:" + + - if custom_emoji.local? + %span.account-role.bot= custom_emoji.category&.name || t('admin.custom_emojis.uncategorized') + + .batch-table__row__content__extra + - if custom_emoji.local? + = t('admin.accounts.location.local') - else - = table_link_to 'eye-slash', t('admin.custom_emojis.unlisted'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: true }, page: params[:page], **@filter_params), method: :patch - - else - - if custom_emoji.local_counterpart.present? - = link_to safe_join([custom_emoji_tag(custom_emoji.local_counterpart), t('admin.custom_emojis.overwrite')]), copy_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, class: 'table-action-link' + = custom_emoji.domain + + %br/ + + - if custom_emoji.disabled? + = t('admin.custom_emojis.disabled') - else - = table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post - %td - - if custom_emoji.disabled? - = table_link_to 'power-off', t('admin.custom_emojis.enable'), enable_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } - - else - = table_link_to 'power-off', t('admin.custom_emojis.disable'), disable_admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } - %td - = table_link_to 'times', t('admin.custom_emojis.delete'), admin_custom_emoji_path(custom_emoji, page: params[:page], **@filter_params), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } + = t('admin.custom_emojis.enabled') + - if custom_emoji.local? + • + - if custom_emoji.visible_in_picker? + = t('admin.custom_emojis.listed') + - else + = t('admin.custom_emojis.unlisted') diff --git a/app/views/admin/custom_emojis/index.html.haml b/app/views/admin/custom_emojis/index.html.haml index 3a119276c..4fbadee90 100644 --- a/app/views/admin/custom_emojis/index.html.haml +++ b/app/views/admin/custom_emojis/index.html.haml @@ -20,8 +20,7 @@ = form_tag admin_custom_emojis_url, method: 'GET', class: 'simple_form' do .fields-group - Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key| - - if params[key].present? - = hidden_field_tag key, params[key] + = hidden_field_tag key, params[key] if params[key].present? - %i(shortcode by_domain).each do |key| .input.string.optional @@ -31,18 +30,54 @@ %button= t('admin.accounts.search') = link_to t('admin.accounts.reset'), admin_custom_emojis_path, class: 'button negative' -.table-wrapper - %table.table - %thead - %tr - %th= t('admin.custom_emojis.emoji') - %th= t('admin.custom_emojis.shortcode') - %th= t('admin.accounts.domain') - %th - %th - %th - %tbody - = render @custom_emojis += form_for(@form, url: batch_admin_custom_emojis_path) do |f| + = hidden_field_tag :page, params[:page] || 1 + + - Admin::FilterHelper::CUSTOM_EMOJI_FILTERS.each do |key| + = hidden_field_tag key, params[key] if params[key].present? + + .batch-table + .batch-table__toolbar + %label.batch-table__toolbar__select.batch-checkbox-all + = check_box_tag :batch_checkbox_all, nil, false + .batch-table__toolbar__actions + - if params[:local] == '1' + = f.button safe_join([fa_icon('save'), t('generic.save_changes')]), name: :update, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('eye'), t('admin.custom_emojis.list')]), name: :list, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('eye-slash'), t('admin.custom_emojis.unlist')]), name: :unlist, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.enable')]), name: :enable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('power-off'), t('admin.custom_emojis.disable')]), name: :disable, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('times'), t('admin.custom_emojis.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + - unless params[:local] == '1' + = f.button safe_join([fa_icon('copy'), t('admin.custom_emojis.copy')]), name: :copy, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + - if params[:local] == '1' + .batch-table__form.simple_form + .fields-row + .fields-group.fields-row__column.fields-row__column-6 + .input.select.optional + .label_input + = f.select :category_id, options_from_collection_for_select(CustomEmojiCategory.all, 'id', 'name'), prompt: t('admin.custom_emojis.assign_category'), class: 'select optional', 'aria-label': t('admin.custom_emojis.assign_category') + + .fields-group.fields-row__column.fields-row__column-6 + .input.string.optional + .label_input + = f.text_field :category_name, class: 'string optional', placeholder: t('admin.custom_emojis.create_new_category'), 'aria-label': t('admin.custom_emojis.create_new_category') + + .batch-table__body + - if @custom_emojis.empty? + = nothing_here 'nothing-here--under-tabs' + - else + = render partial: 'custom_emoji', collection: @custom_emojis, locals: { f: f } = paginate @custom_emojis + +%hr.spacer/ + = link_to t('admin.custom_emojis.upload'), new_admin_custom_emoji_path, class: 'button' diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml index af7a59802..06f29b79b 100644 --- a/app/views/admin/dashboard/index.html.haml +++ b/app/views/admin/dashboard/index.html.haml @@ -4,35 +4,35 @@ .dashboard__counters %div = link_to admin_accounts_url(local: 1, recent: 1) do - .dashboard__counters__num= number_with_delimiter @users_count + .dashboard__counters__num= number_to_human @users_count, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.total_users' %div %div - .dashboard__counters__num= number_with_delimiter @registrations_week + .dashboard__counters__num= number_to_human @registrations_week, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.week_users_new' %div %div - .dashboard__counters__num= number_with_delimiter @logins_week + .dashboard__counters__num= number_to_human @logins_week, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.week_users_active' %div = link_to admin_pending_accounts_path do - .dashboard__counters__num= number_with_delimiter @pending_users_count + .dashboard__counters__num= number_to_human @pending_users_count, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.pending_users' %div = link_to admin_reports_url do - .dashboard__counters__num= number_with_delimiter @reports_count + .dashboard__counters__num= number_to_human @reports_count, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.open_reports' %div - = link_to admin_tags_path(review: 'pending_review') do - .dashboard__counters__num= number_with_delimiter @pending_tags_count + = link_to admin_tags_path(pending_review: '1') do + .dashboard__counters__num= number_to_human @pending_tags_count, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.pending_tags' %div %div - .dashboard__counters__num= number_with_delimiter @interactions_week + .dashboard__counters__num= number_to_human @interactions_week, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.week_interactions' %div = link_to sidekiq_url do - .dashboard__counters__num= number_with_delimiter @queue_backlog + .dashboard__counters__num= number_to_human @queue_backlog, strip_insignificant_zeros: true .dashboard__counters__label= t 'admin.dashboard.backlog' .dashboard__widgets diff --git a/app/views/admin/domain_allows/new.html.haml b/app/views/admin/domain_allows/new.html.haml index 52599857a..85ab7e464 100644 --- a/app/views/admin/domain_allows/new.html.haml +++ b/app/views/admin/domain_allows/new.html.haml @@ -1,6 +1,3 @@ -- content_for :header_tags do - = javascript_pack_tag 'admin', integrity: true, async: true, crossorigin: 'anonymous' - - content_for :page_title do = t('admin.domain_allows.add_new') diff --git a/app/views/admin/reports/index.html.haml b/app/views/admin/reports/index.html.haml index d73faccb0..bfbd32108 100644 --- a/app/views/admin/reports/index.html.haml +++ b/app/views/admin/reports/index.html.haml @@ -28,7 +28,9 @@ - reports.each do |report| .report-card__summary__item .report-card__summary__item__reported-by - - if report.account.local? + - if report.account.instance_actor? + = site_hostname + - elsif report.account.local? = admin_account_link_to report.account - else = report.account.domain diff --git a/app/views/admin/reports/show.html.haml b/app/views/admin/reports/show.html.haml index fc430e19e..0b84e1788 100644 --- a/app/views/admin/reports/show.html.haml +++ b/app/views/admin/reports/show.html.haml @@ -26,7 +26,9 @@ %td= table_link_to 'file', pluralize(@report.target_account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_reports_path(target_account_id: @report.target_account.id) %tr %th= t('admin.reports.reported_by') - - if @report.account.local? + - if @report.account.instance_actor? + %td{ colspan: 3 }= site_hostname + - elsif @report.account.local? %td= admin_account_link_to @report.account %td= table_link_to 'flag', pluralize(@report.account.targeted_reports.count, t('admin.reports.account.report')), admin_reports_path(target_account_id: @report.account.id) %td= table_link_to 'file', pluralize(@report.account.targeted_moderation_notes.count, t('admin.reports.account.note')), admin_reports_path(target_account_id: @report.account.id) diff --git a/app/views/admin/settings/edit.html.haml b/app/views/admin/settings/edit.html.haml index 5a9b33f04..e96ea0b03 100644 --- a/app/views/admin/settings/edit.html.haml +++ b/app/views/admin/settings/edit.html.haml @@ -71,6 +71,9 @@ .fields-group = f.input :trends, as: :boolean, wrapper: :with_label, label: t('admin.settings.trends.title'), hint: t('admin.settings.trends.desc_html') + .fields-group + = f.input :noindex, as: :boolean, wrapper: :with_label, label: t('admin.settings.default_noindex.title'), hint: t('admin.settings.default_noindex.desc_html') + .fields-group = f.input :hide_followers_count, as: :boolean, wrapper: :with_label, label: t('admin.settings.hide_followers_count.title'), hint: t('admin.settings.hide_followers_count.desc_html') diff --git a/app/views/admin/tags/_tag.html.haml b/app/views/admin/tags/_tag.html.haml index 91af8e492..670f3bc05 100644 --- a/app/views/admin/tags/_tag.html.haml +++ b/app/views/admin/tags/_tag.html.haml @@ -1,16 +1,20 @@ -.directory__tag - = link_to admin_tag_path(tag.id) do - %h4 - = fa_icon 'hashtag' - = tag.name +.batch-table__row + %label.batch-table__row__select.batch-table__row__select--aligned.batch-checkbox + = f.check_box :tag_ids, { multiple: true, include_hidden: false }, tag.id - %small - = t('admin.tags.in_directory', count: tag.accounts_count) - • - = t('admin.tags.unique_uses_today', count: tag.history.first[:accounts]) + .directory__tag + = link_to admin_tag_path(tag.id) do + %h4 + = fa_icon 'hashtag' + = tag.name - - if tag.trending? - = fa_icon 'fire fw' - = t('admin.tags.trending_right_now') + %small + = t('admin.tags.in_directory', count: tag.accounts_count) + • + = t('admin.tags.unique_uses_today', count: tag.history.first[:accounts]) - .trends__item__current= number_to_human tag.history.first[:uses], strip_insignificant_zeros: true + - if tag.trending? + = fa_icon 'fire fw' + = t('admin.tags.trending_right_now') + + .trends__item__current= number_to_human tag.history.first[:uses], strip_insignificant_zeros: true diff --git a/app/views/admin/tags/index.html.haml b/app/views/admin/tags/index.html.haml index d994955ef..ef05a9bd6 100644 --- a/app/views/admin/tags/index.html.haml +++ b/app/views/admin/tags/index.html.haml @@ -5,18 +5,70 @@ .filter-subset %strong= t('admin.tags.context') %ul - %li= filter_link_to t('generic.all'), context: nil - %li= filter_link_to t('admin.tags.directory'), context: 'directory' + %li= filter_link_to t('generic.all'), directory: nil + %li= filter_link_to t('admin.tags.directory'), directory: '1' .filter-subset %strong= t('admin.tags.review') %ul - %li= filter_link_to t('generic.all'), review: nil - %li= filter_link_to t('admin.tags.unreviewed'), review: 'unreviewed' - %li= filter_link_to t('admin.tags.reviewed'), review: 'reviewed' - %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), review: 'pending_review' + %li= filter_link_to t('generic.all'), reviewed: nil, unreviewed: nil, pending_review: nil + %li= filter_link_to t('admin.tags.unreviewed'), unreviewed: '1', reviewed: nil, pending_review: nil + %li= filter_link_to t('admin.tags.reviewed'), reviewed: '1', unreviewed: nil, pending_review: nil + %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{Tag.pending_review.count})"], ' '), pending_review: '1', reviewed: nil, unreviewed: nil + + .filter-subset + %strong= t('generic.order_by') + %ul + %li= filter_link_to t('admin.tags.most_recent'), popular: nil, active: nil + %li= filter_link_to t('admin.tags.most_popular'), popular: '1', active: nil + %li= filter_link_to t('admin.tags.last_active'), active: '1', popular: nil + += form_tag admin_tags_url, method: 'GET', class: 'simple_form' do + .fields-group + - Admin::FilterHelper::TAGS_FILTERS.each do |key| + = hidden_field_tag key, params[key] if params[key].present? + + - %i(name).each do |key| + .input.string.optional + = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.tags.#{key}") + + .actions + %button= t('admin.accounts.search') + = link_to t('admin.accounts.reset'), admin_tags_path, class: 'button negative' %hr.spacer/ -= render @tags += form_for(@form, url: batch_admin_tags_path) do |f| + = hidden_field_tag :page, params[:page] || 1 + = hidden_field_tag :context, params[:context] + = hidden_field_tag :review, params[:review] + + .batch-table + .batch-table__toolbar + %label.batch-table__toolbar__select.batch-checkbox-all + = check_box_tag :batch_checkbox_all, nil, false + .batch-table__toolbar__actions + - if params[:review] == 'pending_review' + = f.button safe_join([fa_icon('check'), t('admin.accounts.approve')]), name: :approve, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + + = f.button safe_join([fa_icon('times'), t('admin.accounts.reject')]), name: :reject, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + - else + %span.neutral-hint= t('generic.no_batch_actions_available') + + .batch-table__body + - if @tags.empty? + = nothing_here 'nothing-here--under-tabs' + - else + = render partial: 'tag', collection: @tags, locals: { f: f } + = paginate @tags + +- if params[:pending_review] == '1' + %hr.spacer/ + + %div{ style: 'overflow: hidden' } + %div{ style: 'float: right' } + = link_to t('admin.accounts.reject_all'), reject_all_admin_tags_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button button--destructive' + + %div + = link_to t('admin.accounts.approve_all'), approve_all_admin_tags_path, method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index d54a43c1e..1d970d637 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -3,7 +3,7 @@ .dashboard__counters %div - = link_to web_url("timelines/tag/#{@tag.name}") do + = link_to tag_url(@tag), target: '_blank', rel: 'noopener' do .dashboard__counters__num= number_with_delimiter @accounts_today .dashboard__counters__label= t 'admin.tags.accounts_today' %div diff --git a/app/views/admin_mailer/new_trending_tag.text.erb b/app/views/admin_mailer/new_trending_tag.text.erb index f3087df37..e4bfdc591 100644 --- a/app/views/admin_mailer/new_trending_tag.text.erb +++ b/app/views/admin_mailer/new_trending_tag.text.erb @@ -2,4 +2,4 @@ <%= raw t('admin_mailer.new_trending_tag.body', name: @tag.name) %> -<%= raw t('application_mailer.view')%> <%= admin_tags_url(review: 'pending_review') %> +<%= raw t('application_mailer.view')%> <%= admin_tags_url(pending_review: '1') %> diff --git a/app/views/settings/deletes/show.html.haml b/app/views/settings/deletes/show.html.haml index 6e2ff31c5..08792e0af 100644 --- a/app/views/settings/deletes/show.html.haml +++ b/app/views/settings/deletes/show.html.haml @@ -20,7 +20,10 @@ %hr.spacer/ - = f.input :password, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_password') + - if current_user.encrypted_password.present? + = f.input :password, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_password') + - else + = f.input :username, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_username') .actions = f.button :button, t('deletes.proceed'), type: :submit, class: 'negative' diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index e64155299..86cf1f695 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -12,7 +12,7 @@ %samp.qr-alternative__code= current_user.otp_secret.scan(/.{4}/).join(' ') .fields-group - = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true + = f.input :otp_attempt, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true .actions = f.button :button, t('two_factor_authentication.enable'), type: :submit diff --git a/app/views/settings/two_factor_authentications/show.html.haml b/app/views/settings/two_factor_authentications/show.html.haml index 259bcd1ef..93509e022 100644 --- a/app/views/settings/two_factor_authentications/show.html.haml +++ b/app/views/settings/two_factor_authentications/show.html.haml @@ -10,7 +10,7 @@ %hr/ = simple_form_for @confirmation, url: settings_two_factor_authentication_path, method: :delete do |f| - = f.input :code, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true + = f.input :otp_attempt, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true .actions = f.button :button, t('two_factor_authentication.disable'), type: :submit diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml index 89dc2a75d..5a2911ecb 100644 --- a/app/views/user_mailer/warning.html.haml +++ b/app/views/user_mailer/warning.html.haml @@ -58,7 +58,7 @@ %table.content-section{ cellspacing: 0, cellpadding: 0 } %tbody %tr - %td.content-cell{ class: @statuses.empty? ? '' : 'content-start' } + %td.content-cell{ class: @statuses.nil? || @statuses.empty? ? '' : 'content-start' } %table.column{ cellspacing: 0, cellpadding: 0 } %tbody %tr diff --git a/app/workers/admin/suspension_worker.rb b/app/workers/admin/suspension_worker.rb index ae8b24d8c..83c815efd 100644 --- a/app/workers/admin/suspension_worker.rb +++ b/app/workers/admin/suspension_worker.rb @@ -6,6 +6,6 @@ class Admin::SuspensionWorker sidekiq_options queue: 'pull' def perform(account_id, remove_user = false) - SuspendAccountService.new.call(Account.find(account_id), including_user: remove_user) + SuspendAccountService.new.call(Account.find(account_id), reserve_username: true, reserve_email: !remove_user) end end diff --git a/app/workers/maintenance/destroy_media_worker.rb b/app/workers/maintenance/destroy_media_worker.rb deleted file mode 100644 index cde33d6d7..000000000 --- a/app/workers/maintenance/destroy_media_worker.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -class Maintenance::DestroyMediaWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull' - - def perform(media_attachment_id) - media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id) - media.destroy - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/app/workers/maintenance/redownload_account_media_worker.rb b/app/workers/maintenance/redownload_account_media_worker.rb deleted file mode 100644 index 6afbe6e19..000000000 --- a/app/workers/maintenance/redownload_account_media_worker.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -class Maintenance::RedownloadAccountMediaWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull', retry: false - - def perform(account_id) - account = account_id.is_a?(Account) ? account_id : Account.find(account_id) - account.reset_avatar! - account.reset_header! - account.save - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/app/workers/maintenance/uncache_media_worker.rb b/app/workers/maintenance/uncache_media_worker.rb deleted file mode 100644 index 4bc62ef75..000000000 --- a/app/workers/maintenance/uncache_media_worker.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -class Maintenance::UncacheMediaWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull' - - def perform(media_attachment_id) - media = media_attachment_id.is_a?(MediaAttachment) ? media_attachment_id : MediaAttachment.find(media_attachment_id) - - return if media.file.blank? - - media.file.destroy - media.save - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/app/workers/maintenance/uncache_preview_worker.rb b/app/workers/maintenance/uncache_preview_worker.rb deleted file mode 100644 index 810ffd8cc..000000000 --- a/app/workers/maintenance/uncache_preview_worker.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -class Maintenance::UncachePreviewWorker - include Sidekiq::Worker - - sidekiq_options queue: 'pull' - - def perform(preview_card_id) - preview_card = PreviewCard.find(preview_card_id) - - return if preview_card.image.blank? - - preview_card.image.destroy - preview_card.save - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/app/workers/redownload_media_worker.rb b/app/workers/redownload_media_worker.rb new file mode 100644 index 000000000..98e995918 --- /dev/null +++ b/app/workers/redownload_media_worker.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +class RedownloadMediaWorker + include Sidekiq::Worker + include ExponentialBackoff + + sidekiq_options queue: 'pull', retry: 3 + + def perform(id) + media_attachment = MediaAttachment.find(id) + + return if media_attachment.remote_url.blank? + + media_attachment.reset_file! + media_attachment.save + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/app/workers/scheduler/ip_cleanup_scheduler.rb b/app/workers/scheduler/ip_cleanup_scheduler.rb index 42620332e..4f44078d8 100644 --- a/app/workers/scheduler/ip_cleanup_scheduler.rb +++ b/app/workers/scheduler/ip_cleanup_scheduler.rb @@ -9,7 +9,7 @@ class Scheduler::IpCleanupScheduler def perform time_ago = RETENTION_PERIOD.ago - SessionActivation.where('updated_at < ?', time_ago).destroy_all - User.where('last_sign_in_at < ?', time_ago).update_all(last_sign_in_ip: nil) + SessionActivation.where('updated_at < ?', time_ago).in_batches.destroy_all + User.where('last_sign_in_at < ?', time_ago).where.not(last_sign_in_ip: nil).in_batches.update_all(last_sign_in_ip: nil) end end diff --git a/app/workers/unfollow_follow_worker.rb b/app/workers/unfollow_follow_worker.rb index 50d3bf034..95549e107 100644 --- a/app/workers/unfollow_follow_worker.rb +++ b/app/workers/unfollow_follow_worker.rb @@ -11,7 +11,7 @@ class UnfollowFollowWorker new_target_account = Account.find(new_target_account_id) FollowService.new.call(follower_account, new_target_account) - UnfollowService.new.call(follower_account, old_target_account) + UnfollowService.new.call(follower_account, old_target_account, skip_unmerge: true) rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError true end diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb index 901043975..46aeaa30b 100644 --- a/app/workers/web/push_notification_worker.rb +++ b/app/workers/web/push_notification_worker.rb @@ -11,7 +11,13 @@ class Web::PushNotificationWorker subscription.push(notification) unless notification.activity.nil? rescue Webpush::ResponseError => e - subscription.destroy! if (400..499).cover?(e.response.code.to_i) + code = e.response.code.to_i + + if (400..499).cover?(code) && ![408, 429].include?(code) + subscription.destroy! + else + raise e + end rescue ActiveRecord::RecordNotFound true end |