From 8a6cba44aada8ad165f2573127de5d88bb98440e Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 4 May 2018 20:17:01 +0200 Subject: [PATCH 001/239] Do not render first page of following and followers collections unless explicitly asked to (#7357) --- .../follower_accounts_controller.rb | 30 ++++++++++--------- .../following_accounts_controller.rb | 30 ++++++++++--------- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/app/controllers/follower_accounts_controller.rb b/app/controllers/follower_accounts_controller.rb index 2d2315034c..ac0d4c54ef 100644 --- a/app/controllers/follower_accounts_controller.rb +++ b/app/controllers/follower_accounts_controller.rb @@ -4,11 +4,10 @@ class FollowerAccountsController < ApplicationController include AccountControllerConcern def index - @follows = Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account) - respond_to do |format| format.html do - @relationships = AccountRelationshipsPresenter.new(@follows.map(&:account_id), current_user.account_id) if user_signed_in? + follows + @relationships = AccountRelationshipsPresenter.new(follows.map(&:account_id), current_user.account_id) if user_signed_in? end format.json do @@ -22,28 +21,31 @@ class FollowerAccountsController < ApplicationController private + def follows + @follows ||= Follow.where(target_account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:account) + end + def page_url(page) account_followers_url(@account, page: page) unless page.nil? end def collection_presenter - page = ActivityPub::CollectionPresenter.new( - id: account_followers_url(@account, page: params.fetch(:page, 1)), - type: :ordered, - size: @account.followers_count, - items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) }, - part_of: account_followers_url(@account), - next: page_url(@follows.next_page), - prev: page_url(@follows.prev_page) - ) if params[:page].present? - page + ActivityPub::CollectionPresenter.new( + id: account_followers_url(@account, page: params.fetch(:page, 1)), + type: :ordered, + size: @account.followers_count, + items: follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.account) }, + part_of: account_followers_url(@account), + next: page_url(follows.next_page), + prev: page_url(follows.prev_page) + ) else ActivityPub::CollectionPresenter.new( id: account_followers_url(@account), type: :ordered, size: @account.followers_count, - first: page + first: page_url(1) ) end end diff --git a/app/controllers/following_accounts_controller.rb b/app/controllers/following_accounts_controller.rb index 169f9057d8..974d95c8e4 100644 --- a/app/controllers/following_accounts_controller.rb +++ b/app/controllers/following_accounts_controller.rb @@ -4,11 +4,10 @@ class FollowingAccountsController < ApplicationController include AccountControllerConcern def index - @follows = Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account) - respond_to do |format| format.html do - @relationships = AccountRelationshipsPresenter.new(@follows.map(&:target_account_id), current_user.account_id) if user_signed_in? + follows + @relationships = AccountRelationshipsPresenter.new(follows.map(&:target_account_id), current_user.account_id) if user_signed_in? end format.json do @@ -22,28 +21,31 @@ class FollowingAccountsController < ApplicationController private + def follows + @follows ||= Follow.where(account: @account).recent.page(params[:page]).per(FOLLOW_PER_PAGE).preload(:target_account) + end + def page_url(page) account_following_index_url(@account, page: page) unless page.nil? end def collection_presenter - page = ActivityPub::CollectionPresenter.new( - id: account_following_index_url(@account, page: params.fetch(:page, 1)), - type: :ordered, - size: @account.following_count, - items: @follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) }, - part_of: account_following_index_url(@account), - next: page_url(@follows.next_page), - prev: page_url(@follows.prev_page) - ) if params[:page].present? - page + ActivityPub::CollectionPresenter.new( + id: account_following_index_url(@account, page: params.fetch(:page, 1)), + type: :ordered, + size: @account.following_count, + items: follows.map { |f| ActivityPub::TagManager.instance.uri_for(f.target_account) }, + part_of: account_following_index_url(@account), + next: page_url(follows.next_page), + prev: page_url(follows.prev_page) + ) else ActivityPub::CollectionPresenter.new( id: account_following_index_url(@account), type: :ordered, size: @account.following_count, - first: page + first: page_url(1) ) end end From 154076e8e71c69fb0dbad464b0cb103c1c0c2d9e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 4 May 2018 21:14:34 +0200 Subject: [PATCH 002/239] Store URIs of follows, follow requests and blocks for ActivityPub (#7160) Same URI passed between follow request and follow, since they are the same thing in ActivityPub. Local URIs are generated during creation using UUIDs and are passed to serializers. --- app/lib/activitypub/activity/block.rb | 2 +- app/lib/activitypub/activity/follow.rb | 2 +- app/lib/activitypub/tag_manager.rb | 4 ++++ app/models/block.rb | 10 ++++++++++ app/models/concerns/account_interactions.rb | 13 ++++++++----- app/models/follow.rb | 13 +++++++++++++ app/models/follow_request.rb | 16 ++++++++++++++-- app/serializers/activitypub/follow_serializer.rb | 2 +- .../20180416210259_add_uri_to_relationships.rb | 7 +++++++ db/schema.rb | 6 ++++-- spec/models/follow_request_spec.rb | 2 +- 11 files changed, 64 insertions(+), 13 deletions(-) create mode 100644 db/migrate/20180416210259_add_uri_to_relationships.rb diff --git a/app/lib/activitypub/activity/block.rb b/app/lib/activitypub/activity/block.rb index f630d5db2a..26da8bdf5c 100644 --- a/app/lib/activitypub/activity/block.rb +++ b/app/lib/activitypub/activity/block.rb @@ -7,6 +7,6 @@ class ActivityPub::Activity::Block < ActivityPub::Activity return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id']) || @account.blocking?(target_account) UnfollowService.new.call(target_account, @account) if target_account.following?(@account) - @account.block!(target_account) + @account.block!(target_account, uri: @json['id']) end end diff --git a/app/lib/activitypub/activity/follow.rb b/app/lib/activitypub/activity/follow.rb index 8adbbb9c33..fbbf358a87 100644 --- a/app/lib/activitypub/activity/follow.rb +++ b/app/lib/activitypub/activity/follow.rb @@ -12,7 +12,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity return end - follow_request = FollowRequest.create!(account: @account, target_account: target_account) + follow_request = FollowRequest.create!(account: @account, target_account: target_account, uri: @json['id']) if target_account.locked? NotifyService.new.call(target_account, follow_request) diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index fa2a8f7d31..908ea96391 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -38,6 +38,10 @@ class ActivityPub::TagManager end end + def generate_uri_for(_target) + URI.join(root_url, 'payloads', SecureRandom.uuid) + end + def activity_uri_for(target) raise ArgumentError, 'target must be a local activity' unless %i(note comment activity).include?(target.object_type) && target.local? diff --git a/app/models/block.rb b/app/models/block.rb index df4a6bbacb..bf3e076003 100644 --- a/app/models/block.rb +++ b/app/models/block.rb @@ -8,6 +8,7 @@ # updated_at :datetime not null # account_id :bigint(8) not null # target_account_id :bigint(8) not null +# uri :string # class Block < ApplicationRecord @@ -19,7 +20,12 @@ class Block < ApplicationRecord validates :account_id, uniqueness: { scope: :target_account_id } + def local? + false # Force uri_for to use uri attribute + end + after_commit :remove_blocking_cache + before_validation :set_uri, only: :create private @@ -27,4 +33,8 @@ class Block < ApplicationRecord Rails.cache.delete("exclude_account_ids_for:#{account_id}") Rails.cache.delete("exclude_account_ids_for:#{target_account_id}") end + + def set_uri + self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil? + end end diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index 4a01eed654..ae43711bea 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -82,16 +82,19 @@ module AccountInteractions has_many :domain_blocks, class_name: 'AccountDomainBlock', dependent: :destroy end - def follow!(other_account, reblogs: nil) + def follow!(other_account, reblogs: nil, uri: nil) reblogs = true if reblogs.nil? - rel = active_relationships.create_with(show_reblogs: reblogs).find_or_create_by!(target_account: other_account) - rel.update!(show_reblogs: reblogs) + rel = active_relationships.create_with(show_reblogs: reblogs, uri: uri) + .find_or_create_by!(target_account: other_account) + + rel.update!(show_reblogs: reblogs) rel end - def block!(other_account) - block_relationships.find_or_create_by!(target_account: other_account) + def block!(other_account, uri: nil) + block_relationships.create_with(uri: uri) + .find_or_create_by!(target_account: other_account) end def mute!(other_account, notifications: nil) diff --git a/app/models/follow.rb b/app/models/follow.rb index 2ca42ff70b..eaf8445f3b 100644 --- a/app/models/follow.rb +++ b/app/models/follow.rb @@ -9,6 +9,7 @@ # account_id :bigint(8) not null # target_account_id :bigint(8) not null # show_reblogs :boolean default(TRUE), not null +# uri :string # class Follow < ApplicationRecord @@ -26,4 +27,16 @@ class Follow < ApplicationRecord validates :account_id, uniqueness: { scope: :target_account_id } scope :recent, -> { reorder(id: :desc) } + + def local? + false # Force uri_for to use uri attribute + end + + before_validation :set_uri, only: :create + + private + + def set_uri + self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil? + end end diff --git a/app/models/follow_request.rb b/app/models/follow_request.rb index d559a8f62f..9c4875564b 100644 --- a/app/models/follow_request.rb +++ b/app/models/follow_request.rb @@ -9,6 +9,7 @@ # account_id :bigint(8) not null # target_account_id :bigint(8) not null # show_reblogs :boolean default(TRUE), not null +# uri :string # class FollowRequest < ApplicationRecord @@ -23,11 +24,22 @@ class FollowRequest < ApplicationRecord validates :account_id, uniqueness: { scope: :target_account_id } def authorize! - account.follow!(target_account, reblogs: show_reblogs) + account.follow!(target_account, reblogs: show_reblogs, uri: uri) MergeWorker.perform_async(target_account.id, account.id) - destroy! end alias reject! destroy! + + def local? + false # Force uri_for to use uri attribute + end + + before_validation :set_uri, only: :create + + private + + def set_uri + self.uri = ActivityPub::TagManager.instance.generate_uri_for(self) if uri.nil? + end end diff --git a/app/serializers/activitypub/follow_serializer.rb b/app/serializers/activitypub/follow_serializer.rb index 86c9992fe3..24dfe96f89 100644 --- a/app/serializers/activitypub/follow_serializer.rb +++ b/app/serializers/activitypub/follow_serializer.rb @@ -5,7 +5,7 @@ class ActivityPub::FollowSerializer < ActiveModel::Serializer attribute :virtual_object, key: :object def id - [ActivityPub::TagManager.instance.uri_for(object.account), '#follows/', object.id].join + ActivityPub::TagManager.instance.uri_for(object) end def type diff --git a/db/migrate/20180416210259_add_uri_to_relationships.rb b/db/migrate/20180416210259_add_uri_to_relationships.rb new file mode 100644 index 0000000000..d8eaca450b --- /dev/null +++ b/db/migrate/20180416210259_add_uri_to_relationships.rb @@ -0,0 +1,7 @@ +class AddUriToRelationships < ActiveRecord::Migration[5.2] + def change + add_column :follows, :uri, :string + add_column :follow_requests, :uri, :string + add_column :blocks, :uri, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 10a8f2edc5..566a320d87 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,10 +10,9 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_04_10_204633) do +ActiveRecord::Schema.define(version: 2018_04_16_210259) do # These are extensions that must be enabled in order to support this database - enable_extension "pg_stat_statements" enable_extension "plpgsql" create_table "account_domain_blocks", force: :cascade do |t| @@ -112,6 +111,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do t.datetime "updated_at", null: false t.bigint "account_id", null: false t.bigint "target_account_id", null: false + t.string "uri" t.index ["account_id", "target_account_id"], name: "index_blocks_on_account_id_and_target_account_id", unique: true end @@ -176,6 +176,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do t.bigint "account_id", null: false t.bigint "target_account_id", null: false t.boolean "show_reblogs", default: true, null: false + t.string "uri" t.index ["account_id", "target_account_id"], name: "index_follow_requests_on_account_id_and_target_account_id", unique: true end @@ -185,6 +186,7 @@ ActiveRecord::Schema.define(version: 2018_04_10_204633) do t.bigint "account_id", null: false t.bigint "target_account_id", null: false t.boolean "show_reblogs", default: true, null: false + t.string "uri" t.index ["account_id", "target_account_id"], name: "index_follows_on_account_id_and_target_account_id", unique: true end diff --git a/spec/models/follow_request_spec.rb b/spec/models/follow_request_spec.rb index 59893a14fa..2cf28b263c 100644 --- a/spec/models/follow_request_spec.rb +++ b/spec/models/follow_request_spec.rb @@ -7,7 +7,7 @@ RSpec.describe FollowRequest, type: :model do let(:target_account) { Fabricate(:account) } it 'calls Account#follow!, MergeWorker.perform_async, and #destroy!' do - expect(account).to receive(:follow!).with(target_account, reblogs: true) + expect(account).to receive(:follow!).with(target_account, reblogs: true, uri: follow_request.uri) expect(MergeWorker).to receive(:perform_async).with(target_account.id, account.id) expect(follow_request).to receive(:destroy!) follow_request.authorize! From f0af3ac6b339c178ae8a21bb51a2b306c0124ed3 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 4 May 2018 22:13:26 +0200 Subject: [PATCH 003/239] Dropdowns accessibility (#7318) * Mark currently selected privacy setting in privacy dropdown * Prevent Enter keypresses from triggering dropdown display toggle twice * Give focus to first/selected item of dropdown menus * Implement keyboard navigation in privacy dropdown * Implement keyboard navigation in generic dropdown menus --- .../mastodon/components/dropdown_menu.js | 46 ++++++++++-- .../compose/components/privacy_dropdown.js | 70 +++++++++++++++---- 2 files changed, 99 insertions(+), 17 deletions(-) diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 982d34718e..0a6e7c6272 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -43,6 +43,7 @@ class DropdownMenu extends React.PureComponent { componentDidMount () { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + if (this.focusedItem) this.focusedItem.focus(); this.setState({ mounted: true }); } @@ -55,6 +56,46 @@ class DropdownMenu extends React.PureComponent { this.node = c; } + setFocusRef = c => { + this.focusedItem = c; + } + + handleKeyDown = e => { + const items = Array.from(this.node.getElementsByTagName('a')); + const index = items.indexOf(e.currentTarget); + let element; + + switch(e.key) { + case 'Enter': + this.handleClick(e); + break; + case 'ArrowDown': + element = items[index+1]; + if (element) { + element.focus(); + } + break; + case 'ArrowUp': + element = items[index-1]; + if (element) { + element.focus(); + } + break; + case 'Home': + element = items[0]; + if (element) { + element.focus(); + } + break; + case 'End': + element = items[items.length-1]; + if (element) { + element.focus(); + } + break; + } + } + handleClick = e => { const i = Number(e.currentTarget.getAttribute('data-index')); const { action, to } = this.props.items[i]; @@ -79,7 +120,7 @@ class DropdownMenu extends React.PureComponent { return (
  • - + {text}
  • @@ -156,9 +197,6 @@ export default class Dropdown extends React.PureComponent { handleKeyDown = e => { switch(e.key) { - case 'Enter': - this.handleClick(e); - break; case 'Escape': this.handleClose(); break; diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js index 6b22ba84a5..a772c1c953 100644 --- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js @@ -42,22 +42,65 @@ class PrivacyDropdownMenu extends React.PureComponent { } } - handleClick = e => { - if (e.key === 'Escape') { - this.props.onClose(); - } else if (!e.key || e.key === 'Enter') { - const value = e.currentTarget.getAttribute('data-index'); - - e.preventDefault(); + handleKeyDown = e => { + const { items } = this.props; + const value = e.currentTarget.getAttribute('data-index'); + const index = items.findIndex(item => { + return (item.value === value); + }); + let element; + switch(e.key) { + case 'Escape': this.props.onClose(); - this.props.onChange(value); + break; + case 'Enter': + this.handleClick(e); + break; + case 'ArrowDown': + element = this.node.childNodes[index + 1]; + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + } + break; + case 'ArrowUp': + element = this.node.childNodes[index - 1]; + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + } + break; + case 'Home': + element = this.node.firstChild; + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + } + break; + case 'End': + element = this.node.lastChild; + if (element) { + element.focus(); + this.props.onChange(element.getAttribute('data-index')); + } + break; } } + handleClick = e => { + const value = e.currentTarget.getAttribute('data-index'); + + e.preventDefault(); + + this.props.onClose(); + this.props.onChange(value); + } + componentDidMount () { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + if (this.focusedItem) this.focusedItem.focus(); this.setState({ mounted: true }); } @@ -70,6 +113,10 @@ class PrivacyDropdownMenu extends React.PureComponent { this.node = c; } + setFocusRef = c => { + this.focusedItem = c; + } + render () { const { mounted } = this.state; const { style, items, value } = this.props; @@ -80,9 +127,9 @@ class PrivacyDropdownMenu extends React.PureComponent { // It should not be transformed when mounting because the resulting // size will be used to determine the coordinate of the menu by // react-overlays -
    +
    {items.map(item => ( -
    +
    @@ -147,9 +194,6 @@ export default class PrivacyDropdown extends React.PureComponent { handleKeyDown = e => { switch(e.key) { - case 'Enter': - this.handleToggle(e); - break; case 'Escape': this.handleClose(); break; From 8913ccb434892e52bedf096ceac015164e4939be Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 00:54:24 +0200 Subject: [PATCH 004/239] Store home feeds for 7 days instead of 14 (#7354) * Store home feeds for 7 days instead of 14 Reduces workload for status fan-out to active followers * Fix test for user model --- app/models/user.rb | 2 +- app/services/fan_out_on_write_service.rb | 4 ++-- spec/models/user_spec.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index a9f3e1da26..f5f542f07d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,7 +41,7 @@ class User < ApplicationRecord include Settings::Extend include Omniauthable - ACTIVE_DURATION = 14.days + ACTIVE_DURATION = 7.days devise :two_factor_authenticatable, otp_secret_encryption_key: Rails.configuration.x.otp_secret diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index 510b80c823..cb82a79ed3 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -37,7 +37,7 @@ class FanOutOnWriteService < BaseService def deliver_to_followers(status) Rails.logger.debug "Delivering status #{status.id} to followers" - status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).reorder(nil).find_in_batches do |followers| + status.account.followers.where(domain: nil).joins(:user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).select(:id).reorder(nil).find_in_batches do |followers| FeedInsertWorker.push_bulk(followers) do |follower| [status.id, follower.id, :home] end @@ -47,7 +47,7 @@ class FanOutOnWriteService < BaseService def deliver_to_lists(status) Rails.logger.debug "Delivering status #{status.id} to lists" - status.account.lists.joins(account: :user).where('users.current_sign_in_at > ?', 14.days.ago).select(:id).reorder(nil).find_in_batches do |lists| + status.account.lists.joins(account: :user).where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago).select(:id).reorder(nil).find_in_batches do |lists| FeedInsertWorker.push_bulk(lists) do |list| [status.id, list.id, :list] end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 760214dede..cc8d88cc85 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -75,7 +75,7 @@ RSpec.describe User, type: :model do describe 'inactive' do it 'returns a relation of inactive users' do specified = Fabricate(:user, current_sign_in_at: 15.days.ago) - Fabricate(:user, current_sign_in_at: 13.days.ago) + Fabricate(:user, current_sign_in_at: 6.days.ago) expect(User.inactive).to match_array([specified]) end From 575c5753e4218e822b11ac8773711246e85c1f60 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sat, 5 May 2018 07:54:56 +0900 Subject: [PATCH 005/239] Fix gap insertion for timeline disconnection (#7363) --- app/javascript/mastodon/reducers/timelines.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/reducers/timelines.js b/app/javascript/mastodon/reducers/timelines.js index dd675d78fb..b09d78b0fb 100644 --- a/app/javascript/mastodon/reducers/timelines.js +++ b/app/javascript/mastodon/reducers/timelines.js @@ -134,7 +134,7 @@ export default function timelines(state = initialState, action) { initialTimeline, map => map.update( 'items', - items => items.first() ? items : items.unshift(null) + items => items.first() ? items.unshift(null) : items ) ); default: From 9a84024b1e3fc7922b2fd537753fe0db96a385ea Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 00:55:09 +0200 Subject: [PATCH 006/239] Improve rendering of bio fields (#7353) Fix #7335 --- .../features/account/components/header.js | 18 ++++---- app/javascript/styles/mastodon/accounts.scss | 44 +++++++++---------- .../styles/mastodon/components.scss | 23 +++++----- app/views/accounts/_header.html.haml | 11 +++-- 4 files changed, 47 insertions(+), 49 deletions(-) diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index bbf886dca8..def6257956 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -142,16 +142,14 @@ export default class Header extends ImmutablePureComponent {
    {fields.size > 0 && ( - - - {fields.map((pair, i) => ( - - - ))} - -
    - -
    +
    + {fields.map((pair, i) => ( +
    +
    +
    +
    + ))} +
    )} {info} diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss index c2d0de4b99..b063ca52dd 100644 --- a/app/javascript/styles/mastodon/accounts.scss +++ b/app/javascript/styles/mastodon/accounts.scss @@ -565,36 +565,41 @@ } .account__header__fields { - border-collapse: collapse; padding: 0; margin: 15px -15px -15px; border: 0 none; border-top: 1px solid lighten($ui-base-color, 4%); border-bottom: 1px solid lighten($ui-base-color, 4%); + font-size: 14px; + line-height: 20px; - th, - td { - padding: 15px; - padding-left: 15px; - border: 0 none; + dl { + display: flex; border-bottom: 1px solid lighten($ui-base-color, 4%); - vertical-align: middle; } - th { - padding-left: 15px; - font-weight: 500; + dt, + dd { + box-sizing: border-box; + padding: 14px; text-align: center; - width: 94px; + max-height: 48px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + } + + dt { + font-weight: 500; + width: 120px; + flex: 0 0 auto; color: $secondary-text-color; background: rgba(darken($ui-base-color, 8%), 0.5); } - td { + dd { + flex: 1 1 auto; color: $darker-text-color; - text-align: center; - width: 100%; - padding-left: 0; } a { @@ -608,12 +613,7 @@ } } - tr { - &:last-child { - th, - td { - border-bottom: 0; - } - } + dl:last-child { + border-bottom: 0; } } diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index f1284b3884..7cf6f4b769 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5163,34 +5163,35 @@ noscript { font-size: 14px; line-height: 20px; overflow: hidden; - border-collapse: collapse; margin: 20px -10px -20px; border-bottom: 0; - tr { + dl { border-top: 1px solid lighten($ui-base-color, 8%); - text-align: center; + display: flex; } - th, - td { + dt, + dd { + box-sizing: border-box; padding: 14px 20px; - vertical-align: middle; - max-height: 40px; + text-align: center; + max-height: 48px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } - th { + dt { color: $darker-text-color; background: darken($ui-base-color, 4%); - max-width: 120px; + width: 120px; + flex: 0 0 auto; font-weight: 500; } - td { - flex: auto; + dd { + flex: 1 1 auto; color: $primary-text-color; background: $ui-base-color; } diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index f246f53262..41315f0393 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -24,12 +24,11 @@ .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account, custom_emojify: true) - unless account.fields.empty? - %table.account__header__fields - %tbody - - account.fields.each do |field| - %tr - %th.emojify= field.name - %td.emojify= Formatter.instance.format_field(account, field.value) + .account__header__fields + - account.fields.each do |field| + %dl + %dt.emojify{ title: field.name }= field.name + %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value) .details-counters .counter{ class: active_nav_class(short_account_url(account)) } From de918cee5ae225b64a61ea96fdc5756201de7c39 Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Sat, 5 May 2018 22:53:59 +0900 Subject: [PATCH 007/239] Add tests for admin/custom_emojis_controller (#7350) --- .../admin/custom_emojis_controller_spec.rb | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 spec/controllers/admin/custom_emojis_controller_spec.rb diff --git a/spec/controllers/admin/custom_emojis_controller_spec.rb b/spec/controllers/admin/custom_emojis_controller_spec.rb new file mode 100644 index 0000000000..b7e2894e90 --- /dev/null +++ b/spec/controllers/admin/custom_emojis_controller_spec.rb @@ -0,0 +1,115 @@ +require 'rails_helper' + +describe Admin::CustomEmojisController do + render_views + + let(:user) { Fabricate(:user, admin: true) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + subject { get :index } + + before do + Fabricate(:custom_emoji) + end + + it 'renders index page' do + expect(subject).to have_http_status 200 + expect(subject).to render_template :index + end + end + + describe 'GET #new' do + subject { get :new } + + it 'renders new page' do + expect(subject).to have_http_status 200 + expect(subject).to render_template :new + end + end + + describe 'POST #create' do + subject { post :create, params: { custom_emoji: params } } + + let(:image) { fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png'), 'image/png') } + + context 'when parameter is valid' do + let(:params) { { shortcode: 'test', image: image } } + + it 'creates custom emoji' do + expect { subject }.to change { CustomEmoji.count }.by(1) + end + end + + context 'when parameter is invalid' do + let(:params) { { shortcode: 't', image: image } } + + it 'renders new' do + expect(subject).to render_template :new + end + end + end + + describe 'PUT #update' do + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test') } + let(:image) { fixture_file_upload(Rails.root.join('spec', 'fixtures', 'files', 'emojo.png'), 'image/png') } + + before do + put :update, params: { id: custom_emoji.id, custom_emoji: params } + end + + context 'when parameter is valid' do + let(:params) { { shortcode: 'updated', image: image } } + + it 'succeeds in updating custom emoji' do + expect(flash[:notice]).to eq I18n.t('admin.custom_emojis.updated_msg') + expect(custom_emoji.reload).to have_attributes(shortcode: 'updated') + end + end + + context 'when parameter is invalid' do + let(:params) { { shortcode: 'u', image: image } } + + it 'fails to update custom emoji' do + expect(flash[:alert]).to eq I18n.t('admin.custom_emojis.update_failed_msg') + expect(custom_emoji.reload).to have_attributes(shortcode: 'test') + end + end + end + + describe 'POST #copy' do + subject { post :copy, params: { id: custom_emoji.id } } + + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test') } + + it 'copies custom emoji' do + expect { subject }.to change { CustomEmoji.where(shortcode: 'test').count }.by(1) + expect(flash[:notice]).to eq I18n.t('admin.custom_emojis.copied_msg') + end + end + + describe 'POST #enable' do + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test', disabled: true) } + + before { post :enable, params: { id: custom_emoji.id } } + + it 'enables custom emoji' do + expect(response).to redirect_to admin_custom_emojis_path + expect(custom_emoji.reload).to have_attributes(disabled: false) + end + end + + describe 'POST #disable' do + let(:custom_emoji) { Fabricate(:custom_emoji, shortcode: 'test', disabled: false) } + + before { post :disable, params: { id: custom_emoji.id } } + + it 'enables custom emoji' do + expect(response).to redirect_to admin_custom_emojis_path + expect(custom_emoji.reload).to have_attributes(disabled: true) + end + end +end From ef1a27332290457ed2f357425ce43291731ee469 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 18:22:34 +0200 Subject: [PATCH 008/239] Fix handling of malformed ActivityPub payloads when URIs are nil (#7370) * Fix handling of malformed ActivityPub payloads when URIs are nil * Gracefully handle JSON-LD canonicalization failures --- app/lib/activitypub/tag_manager.rb | 4 ++++ app/services/activitypub/fetch_remote_status_service.rb | 1 + app/services/activitypub/process_collection_service.rb | 3 +++ 3 files changed, 8 insertions(+) diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index 908ea96391..95d1cf9f35 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -86,6 +86,8 @@ class ActivityPub::TagManager end def local_uri?(uri) + return false if uri.nil? + uri = Addressable::URI.parse(uri) host = uri.normalized_host host = "#{host}:#{uri.port}" if uri.port @@ -99,6 +101,8 @@ class ActivityPub::TagManager end def uri_to_resource(uri, klass) + return if uri.nil? + if local_uri?(uri) case klass.name when 'Account' diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index 930fbad1f1..b6c00a9e7e 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -34,6 +34,7 @@ class ActivityPub::FetchRemoteStatusService < BaseService end def trustworthy_attribution?(uri, attributed_to) + return false if uri.nil? || attributed_to.nil? Addressable::URI.parse(uri).normalized_host.casecmp(Addressable::URI.parse(attributed_to).normalized_host).zero? end diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb index eb93329e97..79cdca297b 100644 --- a/app/services/activitypub/process_collection_service.rb +++ b/app/services/activitypub/process_collection_service.rb @@ -45,5 +45,8 @@ class ActivityPub::ProcessCollectionService < BaseService def verify_account! @account = ActivityPub::LinkedDataSignature.new(@json).verify_account! + rescue JSON::LD::JsonLdError => e + Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}" + nil end end From d806eb8e590a1509c98723308d46b4deec8443a3 Mon Sep 17 00:00:00 2001 From: Reto Kromer Date: Sat, 5 May 2018 21:03:21 +0200 Subject: [PATCH 009/239] uniform email rather than e-mail (#7373) --- config/locales/it.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/locales/it.yml b/config/locales/it.yml index 0518d20e61..e010be02d9 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -135,7 +135,7 @@ it: web: Web action_logs: actions: - change_email_user: "%{name} ha cambiato l'indirizzo e-mail per l'utente %{target}" + change_email_user: "%{name} ha cambiato l'indirizzo email per l'utente %{target}" confirm_user: "%{name} ha confermato l'indirizzo email per l'utente %{target}" create_custom_emoji: "%{name} ha caricato un nuovo emoji %{target}" create_domain_block: "%{name} ha bloccato il dominio %{target}" @@ -152,7 +152,7 @@ it: emoji: Emoji enable: Abilita enabled_msg: Questa emoji è stata abilitata con successo - image_hint: PNG fino a 50KB + image_hint: PNG fino a 50 KB listed: Elencato new: title: Aggiungi nuovo emoji personalizzato @@ -186,9 +186,9 @@ it: undo: Annulla email_domain_blocks: add_new: Aggiungi nuovo - created_msg: Dominio e-mail aggiunto con successo alla lista nera + created_msg: Dominio email aggiunto con successo alla lista nera delete: Elimina - destroyed_msg: Dominio e-mail cancellato con successo dalla lista nera + destroyed_msg: Dominio email cancellato con successo dalla lista nera domain: Dominio new: create: Aggiungi dominio @@ -283,7 +283,7 @@ it: application_mailer: notification_preferences: Cambia preferenze email salutation: "%{name}," - settings: 'Cambia le impostazioni per le e-mail: %{link}' + settings: 'Cambia le impostazioni per le email: %{link}' view: 'Guarda:' view_profile: Mostra profilo view_status: Mostra stati @@ -435,5 +435,5 @@ it: tips: Suggerimenti title: Benvenuto a bordo, %{name}! users: - invalid_email: L'indirizzo e-mail inserito non è valido + invalid_email: L'indirizzo email inserito non è valido invalid_otp_token: Codice d'accesso non valido From 0de45574e0f84aa7df8f80b0b8c1c08e84c23919 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 21:11:19 +0200 Subject: [PATCH 010/239] 4 profile fields max, store only 255 characters per name/value (#7348) Fix #7303 --- app/models/account.rb | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/models/account.rb b/app/models/account.rb index a166fb4746..72ba0398ef 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -74,6 +74,7 @@ class Account < ApplicationRecord validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? } validates :display_name, length: { maximum: 30 }, if: -> { local? && will_save_change_to_display_name? } validates :note, length: { maximum: 160 }, if: -> { local? && will_save_change_to_note? } + validates :fields, length: { maximum: 4 }, if: -> { local? && will_save_change_to_fields? } # Timelines has_many :stream_entries, inverse_of: :account, dependent: :destroy @@ -198,9 +199,11 @@ class Account < ApplicationRecord def fields_attributes=(attributes) fields = [] - attributes.each_value do |attr| - next if attr[:name].blank? - fields << attr + if attributes.is_a?(Hash) + attributes.each_value do |attr| + next if attr[:name].blank? + fields << attr + end end self[:fields] = fields @@ -269,8 +272,8 @@ class Account < ApplicationRecord def initialize(account, attr) @account = account - @name = attr['name'] - @value = attr['value'] + @name = attr['name'].strip[0, 255] + @value = attr['value'].strip[0, 255] @errors = {} end From b7f241faeda9c615010cfed795ac6cafbec058df Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 23:05:43 +0200 Subject: [PATCH 011/239] Do not count search route as compose being mounted in web UI (#7372) Fix #7144 --- app/javascript/mastodon/features/compose/index.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index 67f0e79815..19aae03322 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -43,11 +43,19 @@ export default class Compose extends React.PureComponent { }; componentDidMount () { - this.props.dispatch(mountCompose()); + const { isSearchPage } = this.props; + + if (!isSearchPage) { + this.props.dispatch(mountCompose()); + } } componentWillUnmount () { - this.props.dispatch(unmountCompose()); + const { isSearchPage } = this.props; + + if (!isSearchPage) { + this.props.dispatch(unmountCompose()); + } } onFocus = () => { From 0dcca6b6e8193f7aa40da3a617ac11ec84007e00 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 23:06:29 +0200 Subject: [PATCH 012/239] Improve admin UI for accounts (#7360) * Improve design of account statuses admin UI (consistent with reports) * Make account moderation notes look consistent with report notes * i18n-tasks remove-unused * Fix code style issues * Fix tests --- .../admin/reported_statuses_controller.rb | 19 ------- app/controllers/admin/statuses_controller.rb | 35 ++++--------- app/javascript/styles/mastodon/admin.scss | 3 +- .../_account_moderation_note.html.haml | 15 +++--- app/views/admin/accounts/show.html.haml | 39 ++++++-------- app/views/admin/reports/_status.html.haml | 2 +- app/views/admin/statuses/index.html.haml | 52 ++++++++----------- config/locales/ar.yml | 9 ---- config/locales/ca.yml | 9 ---- config/locales/de.yml | 9 ---- config/locales/en.yml | 11 +--- config/locales/eo.yml | 9 ---- config/locales/es.yml | 9 ---- config/locales/fa.yml | 9 ---- config/locales/fi.yml | 9 ---- config/locales/fr.yml | 9 ---- config/locales/gl.yml | 9 ---- config/locales/he.yml | 6 --- config/locales/hu.yml | 9 ---- config/locales/id.yml | 1 - config/locales/io.yml | 1 - config/locales/it.yml | 9 ---- config/locales/ja.yml | 9 ---- config/locales/ko.yml | 9 ---- config/locales/nl.yml | 9 ---- config/locales/no.yml | 9 ---- config/locales/oc.yml | 9 ---- config/locales/pl.yml | 9 ---- config/locales/pt-BR.yml | 9 ---- config/locales/pt.yml | 9 ---- config/locales/ru.yml | 9 ---- config/locales/sk.yml | 9 ---- config/locales/sr-Latn.yml | 9 ---- config/locales/sr.yml | 9 ---- config/locales/sv.yml | 9 ---- config/locales/th.yml | 1 - config/locales/tr.yml | 1 - config/locales/uk.yml | 1 - config/locales/zh-CN.yml | 9 ---- config/locales/zh-HK.yml | 9 ---- config/locales/zh-TW.yml | 1 - config/routes.rb | 4 +- .../reported_statuses_controller_spec.rb | 49 +++-------------- .../admin/statuses_controller_spec.rb | 48 ++++------------- 44 files changed, 77 insertions(+), 446 deletions(-) diff --git a/app/controllers/admin/reported_statuses_controller.rb b/app/controllers/admin/reported_statuses_controller.rb index 522f68c98e..d3c2f5e9e9 100644 --- a/app/controllers/admin/reported_statuses_controller.rb +++ b/app/controllers/admin/reported_statuses_controller.rb @@ -3,7 +3,6 @@ module Admin class ReportedStatusesController < BaseController before_action :set_report - before_action :set_status, only: [:update, :destroy] def create authorize :status, :update? @@ -14,20 +13,6 @@ module Admin redirect_to admin_report_path(@report) end - def update - authorize @status, :update? - @status.update!(status_params) - log_action :update, @status - redirect_to admin_report_path(@report) - end - - def destroy - authorize @status, :destroy? - RemovalWorker.perform_async(@status.id) - log_action :destroy, @status - render json: @status - end - private def status_params @@ -51,9 +36,5 @@ module Admin def set_report @report = Report.find(params[:report_id]) end - - def set_status - @status = @report.statuses.find(params[:id]) - end end end diff --git a/app/controllers/admin/statuses_controller.rb b/app/controllers/admin/statuses_controller.rb index d5787acfb9..382bfc4a23 100644 --- a/app/controllers/admin/statuses_controller.rb +++ b/app/controllers/admin/statuses_controller.rb @@ -5,7 +5,6 @@ module Admin helper_method :current_params before_action :set_account - before_action :set_status, only: [:update, :destroy] PER_PAGE = 20 @@ -26,40 +25,18 @@ module Admin def create authorize :status, :update? - @form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account)) + @form = Form::StatusBatch.new(form_status_batch_params.merge(current_account: current_account, action: action_from_button)) flash[:alert] = I18n.t('admin.statuses.failed_to_execute') unless @form.save redirect_to admin_account_statuses_path(@account.id, current_params) end - def update - authorize @status, :update? - @status.update!(status_params) - log_action :update, @status - redirect_to admin_account_statuses_path(@account.id, current_params) - end - - def destroy - authorize @status, :destroy? - RemovalWorker.perform_async(@status.id) - log_action :destroy, @status - render json: @status - end - private - def status_params - params.require(:status).permit(:sensitive) - end - def form_status_batch_params params.require(:form_status_batch).permit(:action, status_ids: []) end - def set_status - @status = @account.statuses.find(params[:id]) - end - def set_account @account = Account.find(params[:account_id]) end @@ -72,5 +49,15 @@ module Admin page: page > 1 && page, }.select { |_, value| value.present? } end + + def action_from_button + if params[:nsfw_on] + 'nsfw_on' + elsif params[:nsfw_off] + 'nsfw_off' + elsif params[:delete] + 'delete' + end + end end end diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index a6cc8b62ba..1948a2a231 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -336,7 +336,8 @@ } } -.simple_form.new_report_note { +.simple_form.new_report_note, +.simple_form.new_account_moderation_note { max-width: 100%; } diff --git a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml index 6761a43192..432fb79a6e 100644 --- a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml +++ b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml @@ -1,10 +1,7 @@ -%tr - %td +.speech-bubble + .speech-bubble__bubble = simple_format(h(account_moderation_note.content)) - %td - = account_moderation_note.account.acct - %td - %time.formatted{ datetime: account_moderation_note.created_at.iso8601, title: l(account_moderation_note.created_at) } - = l account_moderation_note.created_at - %td - = link_to t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete if can?(:destroy, account_moderation_note) + .speech-bubble__owner + = admin_account_link_to account_moderation_note.account + %time.formatted{ datetime: account_moderation_note.created_at.iso8601 }= l account_moderation_note.created_at + = table_link_to 'trash', t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete if can?(:destroy, account_moderation_note) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 7312618ee2..2e6de18643 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -2,7 +2,7 @@ = @account.acct .table-wrapper - %table.table + %table.table.inline-table %tbody %tr %th= t('admin.accounts.username') @@ -73,17 +73,17 @@ %tr %th= t('admin.accounts.follows') - %td= @account.following_count + %td= number_to_human @account.following_count %tr %th= t('admin.accounts.followers') - %td= @account.followers_count + %td= number_to_human @account.followers_count %tr %th= t('admin.accounts.statuses') - %td= link_to @account.statuses_count, admin_account_statuses_path(@account.id) + %td= link_to number_to_human(@account.statuses_count), admin_account_statuses_path(@account.id) %tr %th= t('admin.accounts.media_attachments') %td - = link_to @account.media_attachments.count, admin_account_statuses_path(@account.id, { media: true }) + = link_to number_to_human(@account.media_attachments.count), admin_account_statuses_path(@account.id, { media: true }) = surround '(', ')' do = number_to_human_size @account.media_attachments.sum('file_file_size') %tr @@ -120,11 +120,12 @@ = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:suspend, @account) - if !@account.local? && @account.hub_url.present? - %hr + %hr.spacer/ + %h3 OStatus .table-wrapper - %table.table + %table.table.inline-table %tbody %tr %th= t('admin.accounts.feed_url') @@ -148,11 +149,12 @@ = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative' if can?(:unsubscribe, @account) - if !@account.local? && @account.inbox_url.present? - %hr + %hr.spacer/ + %h3 ActivityPub .table-wrapper - %table.table + %table.table.inline-table %tbody %tr %th= t('admin.accounts.inbox_url') @@ -167,24 +169,15 @@ %th= t('admin.accounts.followers_url') %td= link_to @account.followers_url, @account.followers_url -%hr -%h3= t('admin.accounts.moderation_notes') +%hr.spacer/ + += render @moderation_notes = simple_form_for @account_moderation_note, url: admin_account_moderation_notes_path do |f| = render 'shared/error_messages', object: @account_moderation_note - = f.input :content + = f.input :content, placeholder: t('admin.reports.notes.placeholder'), rows: 6 = f.hidden_field :target_account_id .actions - = f.button :button, t('admin.account_moderation_notes.create'), type: :submit - -.table-wrapper - %table.table - %thead - %tr - %th - %th= t('admin.account_moderation_notes.account') - %th= t('admin.account_moderation_notes.created_at') - %tbody - = render @moderation_notes + = f.button :button, t('admin.account_moderation_notes.create'), type: :submit diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 137609539b..9057e6048d 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -7,7 +7,7 @@ %p>< %strong= Formatter.instance.format_spoiler(status) - = Formatter.instance.format(status) + = Formatter.instance.format(status, custom_emojify: true) - unless status.media_attachments.empty? - if status.media_attachments.first.video? diff --git a/app/views/admin/statuses/index.html.haml b/app/views/admin/statuses/index.html.haml index fe25815274..880a24f769 100644 --- a/app/views/admin/statuses/index.html.haml +++ b/app/views/admin/statuses/index.html.haml @@ -3,11 +3,8 @@ - content_for :page_title do = t('admin.statuses.title') - -.back-link - = link_to admin_account_path(@account.id) do - %i.fa.fa-chevron-left.fa-fw - = t('admin.statuses.back_to_account') + \- + = "@#{@account.acct}" .filters .filter-subset @@ -15,33 +12,26 @@ %ul %li= link_to t('admin.statuses.no_media'), admin_account_statuses_path(@account.id, current_params.merge(media: nil)), class: !params[:media] && 'selected' %li= link_to t('admin.statuses.with_media'), admin_account_statuses_path(@account.id, current_params.merge(media: true)), class: params[:media] && 'selected' + .back-link{ style: 'flex: 1 1 auto; text-align: right' } + = link_to admin_account_path(@account.id) do + %i.fa.fa-chevron-left.fa-fw + = t('admin.statuses.back_to_account') -- if @statuses.empty? - .accounts-grid - = render 'accounts/nothing_here' -- else - = form_for(@form, url: admin_account_statuses_path(@account.id)) do |f| - = hidden_field_tag :page, params[:page] - = hidden_field_tag :media, params[:media] - .batch-form-box - .batch-checkbox-all +%hr.spacer/ + += form_for(@form, url: admin_account_statuses_path(@account.id)) do |f| + = hidden_field_tag :page, params[:page] + = hidden_field_tag :media, params[:media] + + .batch-table + .batch-table__toolbar + %label.batch-table__toolbar__select.batch-checkbox-all = check_box_tag :batch_checkbox_all, nil, false - = f.select :action, Form::StatusBatch::ACTION_TYPE.map{|action| [t("admin.statuses.batch.#{action}"), action]} - = f.submit t('admin.statuses.execute'), data: { confirm: t('admin.reports.are_you_sure') }, class: 'button' - .media-spoiler-toggle-buttons - .media-spoiler-show-button.button= t('admin.statuses.media.show') - .media-spoiler-hide-button.button= t('admin.statuses.media.hide') - - @statuses.each do |status| - .account-status{ data: { id: status.id } } - .batch-checkbox - = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id - .activity-stream.activity-stream-headless - .entry= render 'stream_entries/simple_status', status: status - .account-status__actions - - unless status.media_attachments.empty? - = link_to admin_account_status_path(@account.id, status, current_params.merge(status: { sensitive: !status.sensitive })), method: :patch, class: 'icon-button nsfw-button', title: t("admin.reports.nsfw.#{!status.sensitive}") do - = fa_icon status.sensitive? ? 'eye' : 'eye-slash' - = link_to admin_account_status_path(@account.id, status), method: :delete, class: 'icon-button trash-button', title: t('admin.reports.delete'), data: { confirm: t('admin.reports.are_you_sure') }, remote: true do - = fa_icon 'trash' + .batch-table__toolbar__actions + = f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + = f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') } + .batch-table__body + = render partial: 'admin/reports/status', collection: @statuses, locals: { f: f } = paginate @statuses diff --git a/config/locales/ar.yml b/config/locales/ar.yml index e9ca3038e4..a5179ae148 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -52,9 +52,7 @@ ar: unfollow: إلغاء المتابعة admin: account_moderation_notes: - account: مُشرِف create: إنشاء - created_at: التاريخ created_msg: تم إنشاء ملاحظة الإشراف بنجاح ! delete: حذف destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح ! @@ -241,12 +239,8 @@ ar: are_you_sure: هل أنت متأكد ؟ comment: none: لا شيء - delete: حذف id: معرّف ID mark_as_resolved: إعتبار التقرير كمحلول - nsfw: - 'false': الكشف عن الصور - 'true': إخفاء الوسائط المرفقة report: 'التقرير #%{id}' report_contents: المحتويات reported_account: حساب مُبلّغ عنه @@ -305,11 +299,8 @@ ar: back_to_account: العودة إلى صفحة الحساب batch: delete: حذف - execute: تفعيل failed_to_execute: خطأ في التفعيل media: - hide: إخفاء الوسائط - show: إظهار الوسائط title: الوسائط title: منشورات الحساب with_media: بالوسائط diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 2758bb487a..a8c75c32df 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -53,9 +53,7 @@ ca: unfollow: Deixa de seguir admin: account_moderation_notes: - account: Moderador create: Crea - created_at: Data created_msg: La nota de moderació s'ha creat correctament! delete: Suprimeix destroyed_msg: Nota de moderació destruïda amb èxit! @@ -269,7 +267,6 @@ ca: comment: none: Cap created_at: Reportat - delete: Suprimeix id: ID mark_as_resolved: Marca com a resolt mark_as_unresolved: Marcar sense resoldre @@ -279,9 +276,6 @@ ca: create_and_unresolve: Reobrir amb nota delete: Esborrar placeholder: Descriu les accions que s'han pres o qualsevol altra actualització d'aquest informe… - nsfw: - 'false': Mostra els fitxers multimèdia adjunts - 'true': Amaga els fitxers multimèdia adjunts reopen: Reobrir informe report: 'Informe #%{id}' report_contents: Contingut @@ -356,11 +350,8 @@ ca: delete: Suprimeix nsfw_off: Marcar com a no sensible nsfw_on: Marcar com a sensible - execute: Executa failed_to_execute: No s'ha pogut executar media: - hide: Amaga el contingut multimèdia - show: Mostra el contingut multimèdia title: Contingut multimèdia no_media: Sense contingut multimèdia title: Estats del compte diff --git a/config/locales/de.yml b/config/locales/de.yml index 6b2c087354..aa4295c896 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -53,9 +53,7 @@ de: unfollow: Entfolgen admin: account_moderation_notes: - account: Moderator*in create: Erstellen - created_at: Datum created_msg: Moderationsnotiz erfolgreich erstellt! delete: Löschen destroyed_msg: Moderationsnotiz erfolgreich gelöscht! @@ -269,7 +267,6 @@ de: comment: none: Kein created_at: Gemeldet - delete: Löschen id: ID mark_as_resolved: Als gelöst markieren mark_as_unresolved: Als ungelöst markieren @@ -279,9 +276,6 @@ de: create_and_unresolve: Mit Kommentar wieder öffnen delete: Löschen placeholder: Beschreibe, welche Maßnahmen ergriffen wurden oder andere Neuigkeiten zu dieser Meldung… - nsfw: - 'false': Medienanhänge wieder anzeigen - 'true': Medienanhänge verbergen reopen: Meldung wieder öffnen report: 'Meldung #%{id}' report_contents: Inhalt @@ -356,11 +350,8 @@ de: delete: Löschen nsfw_off: Als nicht heikel markieren nsfw_on: Als heikel markieren - execute: Ausführen failed_to_execute: Ausführen fehlgeschlagen media: - hide: Medien verbergen - show: Medien anzeigen title: Medien no_media: Keine Medien title: Beiträge des Kontos diff --git a/config/locales/en.yml b/config/locales/en.yml index f7127f7948..7e389b1c22 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -53,9 +53,7 @@ en: unfollow: Unfollow admin: account_moderation_notes: - account: Moderator - create: Create - created_at: Date + create: Leave note created_msg: Moderation note successfully created! delete: Delete destroyed_msg: Moderation note successfully destroyed! @@ -269,7 +267,6 @@ en: comment: none: None created_at: Reported - delete: Delete id: ID mark_as_resolved: Mark as resolved mark_as_unresolved: Mark as unresolved @@ -279,9 +276,6 @@ en: create_and_unresolve: Reopen with note delete: Delete placeholder: Describe what actions have been taken, or any other updates to this report… - nsfw: - 'false': Unhide media attachments - 'true': Hide media attachments reopen: Reopen report report: 'Report #%{id}' report_contents: Contents @@ -356,11 +350,8 @@ en: delete: Delete nsfw_off: Mark as not sensitive nsfw_on: Mark as sensitive - execute: Execute failed_to_execute: Failed to execute media: - hide: Hide media - show: Show media title: Media no_media: No media title: Account statuses diff --git a/config/locales/eo.yml b/config/locales/eo.yml index c768d8a03d..9c44d0e622 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -52,9 +52,7 @@ eo: unfollow: Ne plu sekvi admin: account_moderation_notes: - account: Kontrolanto create: Krei - created_at: Dato created_msg: Kontrola noto sukcese kreita! delete: Forigi destroyed_msg: Kontrola noto sukcese detruita! @@ -244,12 +242,8 @@ eo: are_you_sure: Ĉu vi certas? comment: none: Nenio - delete: Forigi id: ID mark_as_resolved: Marki kiel solvita - nsfw: - 'false': Malkaŝi aŭdovidajn kunsendaĵojn - 'true': Kaŝi aŭdovidajn kunsendaĵojn report: 'Signalo #%{id}' report_contents: Enhavo reported_account: Signalita konto @@ -320,11 +314,8 @@ eo: delete: Forigi nsfw_off: Malŝalti NSFW nsfw_on: Ŝalti NSFW - execute: Ekigi failed_to_execute: Ekigo malsukcesa media: - hide: Kaŝi aŭdovidaĵojn - show: Montri aŭdovidaĵojn title: Aŭdovidaĵoj no_media: Neniu aŭdovidaĵo title: Mesaĝoj de la konto diff --git a/config/locales/es.yml b/config/locales/es.yml index cd36e3a977..be7dcd81e5 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -53,9 +53,7 @@ es: unfollow: Dejar de seguir admin: account_moderation_notes: - account: Moderador create: Crear - created_at: Fecha created_msg: "¡Nota de moderación creada con éxito!" delete: Borrar destroyed_msg: "¡Nota de moderación destruida con éxito!" @@ -269,7 +267,6 @@ es: comment: none: Ninguno created_at: Denunciado - delete: Eliminar id: ID mark_as_resolved: Marcar como resuelto mark_as_unresolved: Marcar como no resuelto @@ -279,9 +276,6 @@ es: create_and_unresolve: Reabrir con una nota delete: Eliminar placeholder: Especificar qué acciones se han tomado o cualquier otra novedad respecto a esta denuncia… - nsfw: - 'false': Mostrar multimedia - 'true': Ocultar multimedia reopen: Reabrir denuncia report: 'Reportar #%{id}' report_contents: Contenido @@ -356,11 +350,8 @@ es: delete: Eliminar nsfw_off: Marcar contenido como no sensible nsfw_on: Marcar contenido como sensible - execute: Ejecutar failed_to_execute: Falló al ejecutar media: - hide: Ocultar multimedia - show: Mostrar multimedia title: Multimedia no_media: No hay multimedia title: Estado de las cuentas diff --git a/config/locales/fa.yml b/config/locales/fa.yml index a3005547a5..3aa40f0b3e 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -52,9 +52,7 @@ fa: unfollow: پایان پیگیری admin: account_moderation_notes: - account: مدیر create: نوشتن - created_at: تاریخ created_msg: یادداشت مدیر با موفقیت ساخته شد! delete: پاک کردن destroyed_msg: یادداشت مدیر با موفقیت پاک شد! @@ -244,12 +242,8 @@ fa: are_you_sure: آیا مطمئن هستید؟ comment: none: خالی - delete: پاک‌کردن id: شناسه mark_as_resolved: علامت‌گذاری به عنوان حل‌شده - nsfw: - 'false': نمایش پیوست‌های تصویری - 'true': نهفتن پیوست‌های تصویری report: 'گزارش #%{id}' report_contents: محتوا reported_account: حساب گزارش‌شده @@ -308,11 +302,8 @@ fa: delete: پاک‌کردن nsfw_off: NSFW خاموش nsfw_on: NSFW روشن - execute: اجرا failed_to_execute: اجرا نشد media: - hide: نهفتن رسانه - show: نمایش رسانه title: رسانه no_media: بدون رسانه title: نوشته‌های حساب diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 550ad1805e..b313c87236 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -52,9 +52,7 @@ fi: unfollow: Lopeta seuraaminen admin: account_moderation_notes: - account: Moderaattori create: Luo - created_at: Päiväys created_msg: Moderointimerkinnän luonti onnistui! delete: Poista destroyed_msg: Moderointimerkinnän poisto onnistui! @@ -244,12 +242,8 @@ fi: are_you_sure: Oletko varma? comment: none: Ei mitään - delete: Poista id: Tunniste mark_as_resolved: Merkitse ratkaistuksi - nsfw: - 'false': Peru medialiitteiden piilotus - 'true': Piilota medialiitteet report: Raportti nro %{id} report_contents: Sisältö reported_account: Raportoitu tili @@ -320,11 +314,8 @@ fi: delete: Poista nsfw_off: NSFW POIS nsfw_on: NSFW PÄÄLLÄ - execute: Suorita failed_to_execute: Suoritus epäonnistui media: - hide: Piilota media - show: Näytä media title: Media no_media: Ei mediaa title: Tilin tilat diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 462ce7b4b7..3b543fdb7b 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -53,9 +53,7 @@ fr: unfollow: Ne plus suivre admin: account_moderation_notes: - account: Modérateur·ice create: Créer - created_at: Date created_msg: Note de modération créée avec succès ! delete: Supprimer destroyed_msg: Note de modération supprimée avec succès ! @@ -269,7 +267,6 @@ fr: comment: none: Aucun created_at: Signalé - delete: Supprimer id: ID mark_as_resolved: Marquer comme résolu mark_as_unresolved: Marquer comme non-résolu @@ -279,9 +276,6 @@ fr: create_and_unresolve: Ré-ouvrir avec une note delete: Effacer placeholder: Décrivez quelles actions ont été prises, ou toute autre mise à jour de ce signalement… - nsfw: - 'false': Ré-afficher les médias - 'true': Masquer les médias reopen: Ré-ouvrir le signalement report: 'Signalement #%{id}' report_contents: Contenu @@ -356,11 +350,8 @@ fr: delete: Supprimer nsfw_off: Marquer comme non-sensible nsfw_on: Marquer comme sensible - execute: Exécuter failed_to_execute: Erreur d’exécution media: - hide: Masquer les médias - show: Montrer les médias title: Médias no_media: Aucun média title: État du compte diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 6f22702247..eec1b4e1ef 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -53,9 +53,7 @@ gl: unfollow: Deixar de seguir admin: account_moderation_notes: - account: Moderador create: Crear - created_at: Data created_msg: Nota a moderación creada con éxito! delete: Eliminar destroyed_msg: Nota a moderación destruída con éxito! @@ -269,7 +267,6 @@ gl: comment: none: Nada created_at: Reportado - delete: Eliminar id: ID mark_as_resolved: Marcar como resolto mark_as_unresolved: Marcar como non resolto @@ -279,9 +276,6 @@ gl: create_and_unresolve: Voltar a abrir con nota delete: Eliminar placeholder: Describir qué decisións foron tomadas, ou calquer actualización a este informe… - nsfw: - 'false': Non agochar anexos de medios - 'true': Agochar anexos de medios reopen: Voltar a abrir o informe report: 'Informe #%{id}' report_contents: Contidos @@ -356,11 +350,8 @@ gl: delete: Eliminar nsfw_off: Marcar como non sensible nsfw_on: Marcar como sensible - execute: Executar failed_to_execute: Fallou a execución media: - hide: Agochar medios - show: Mostar medios title: Medios no_media: Sen medios title: Estados da conta diff --git a/config/locales/he.yml b/config/locales/he.yml index d641c6e1a5..d66d9f0346 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -52,9 +52,7 @@ he: unfollow: הפסקת מעקב admin: account_moderation_notes: - account: מנחה דיון create: ליצור - created_at: תאריך created_msg: הודעת מנחה נוצרה בהצלחה! delete: למחוק destroyed_msg: הודעת מנחה נמחקה בהצלחה! @@ -181,12 +179,8 @@ he: are_you_sure: 100% על בטוח? comment: none: ללא - delete: מחיקה id: ID mark_as_resolved: סימון כפתור - nsfw: - 'false': לכל המשפחה - 'true': תוכן רגיש report: 'דווח על #%{id}' report_contents: תוכן reported_account: חשבון מדווח diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 7fe431d377..422c059559 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -52,9 +52,7 @@ hu: unfollow: Követés abbahagyása admin: account_moderation_notes: - account: Moderátor create: Új bejegyzés - created_at: Dátum created_msg: Moderációs bejegyzés létrehozva! delete: Törlés destroyed_msg: Moderációs bejegyzés törölve! @@ -244,12 +242,8 @@ hu: are_you_sure: Biztos vagy benne? comment: none: Egyik sem - delete: Törlés id: ID mark_as_resolved: Megjelölés megoldottként - nsfw: - 'false': Média-csatolmányok rejtésének feloldása - 'true': Média-csatolmányok elrejtése report: "#%{id} számú jelentés" report_contents: Tartalom reported_account: Bejelentett fiók @@ -314,11 +308,8 @@ hu: delete: Törlés nsfw_off: Szenzitív tartalom kikapcsolva nsfw_on: Szenzitív tartalom bekapcsolva - execute: Végrehajt failed_to_execute: Végrehajtás sikertelen media: - hide: Média elrejtése - show: Média megjelenítése title: Média no_media: Nem található médiafájl title: Felhasználó tülkjei diff --git a/config/locales/id.yml b/config/locales/id.yml index 5a63b8038a..0476e2848e 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -107,7 +107,6 @@ id: reports: comment: none: Tidak ada - delete: Hapus id: ID mark_as_resolved: Tandai telah diseleseikan report: 'Laporkan #%{id}' diff --git a/config/locales/io.yml b/config/locales/io.yml index 7c25acc47a..bf15de4886 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -106,7 +106,6 @@ io: reports: comment: none: None - delete: Delete id: ID mark_as_resolved: Mark as resolved report: 'Report #%{id}' diff --git a/config/locales/it.yml b/config/locales/it.yml index e010be02d9..c1ac176c45 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -49,9 +49,7 @@ it: unfollow: Non seguire più admin: account_moderation_notes: - account: Moderatore create: Crea - created_at: Data created_msg: Nota di moderazione creata con successo! delete: Elimina destroyed_msg: Nota di moderazione distrutta con successo! @@ -214,7 +212,6 @@ it: assigned: Moderatore assegnato comment: none: Nessuno - delete: Elimina id: ID mark_as_resolved: Segna come risolto mark_as_unresolved: Segna come non risolto @@ -223,9 +220,6 @@ it: create_and_resolve: Risolvi con nota create_and_unresolve: Riapri con nota delete: Elimina - nsfw: - 'false': Mostra gli allegati multimediali - 'true': Nascondi allegati multimediali report_contents: Contenuti resolved: Risolto silence_account: Silenzia account @@ -266,11 +260,8 @@ it: delete: Elimina nsfw_off: NSFW OFF nsfw_on: NSFW ON - execute: Esegui failed_to_execute: Impossibile eseguire media: - hide: Nascondi media - show: Mostra media title: Media no_media: Nessun media with_media: con media diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 5b3cc5f159..bc48613b98 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -53,9 +53,7 @@ ja: unfollow: フォロー解除 admin: account_moderation_notes: - account: モデレータ create: 書き込む - created_at: 日付 created_msg: モデレーションメモを書き込みました! delete: 削除 destroyed_msg: モデレーションメモを削除しました! @@ -269,7 +267,6 @@ ja: comment: none: なし created_at: レポート日時 - delete: 削除 id: ID mark_as_resolved: 解決済みとしてマーク mark_as_unresolved: 未解決として再び開く @@ -279,9 +276,6 @@ ja: create_and_unresolve: 書き込み、未解決として開く delete: 削除 placeholder: このレポートに取られた措置や、その他の更新を記述してください… - nsfw: - 'false': NSFW オフ - 'true': NSFW オン reopen: 再び開く report: レポート#%{id} report_contents: 内容 @@ -356,11 +350,8 @@ ja: delete: 削除 nsfw_off: 閲覧注意のマークを取り除く nsfw_on: 閲覧注意としてマークする - execute: 実行 failed_to_execute: 実行に失敗しました media: - hide: メディアを隠す - show: メディアを表示 title: メディア no_media: メディアなし title: トゥート一覧 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 0f3c6483fb..bd6717d497 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -53,9 +53,7 @@ ko: unfollow: 팔로우 해제 admin: account_moderation_notes: - account: 모더레이터 create: 작성하기 - created_at: 작성 날짜 created_msg: 모더레이션 기록이 성공적으로 작성되었습니다! delete: 삭제 destroyed_msg: 모더레이션 기록이 성공적으로 삭제되었습니다! @@ -271,7 +269,6 @@ ko: comment: none: 없음 created_at: 리포트 시각 - delete: 삭제 id: ID mark_as_resolved: 해결 완료 처리 mark_as_unresolved: 미해결로 표시 @@ -281,9 +278,6 @@ ko: create_and_unresolve: 노트 작성과 함께 미해결로 표시 delete: 삭제 placeholder: 이 리포트에 대한 조치, 다른 업데이트 사항에 대해 설명합니다… - nsfw: - 'false': NSFW 꺼짐 - 'true': NSFW 켜짐 reopen: 리포트 다시 열기 report: '신고 #%{id}' report_contents: 내용 @@ -358,11 +352,8 @@ ko: delete: 삭제 nsfw_off: NSFW 끄기 nsfw_on: NSFW 켜기 - execute: 실행 failed_to_execute: 실행을 실패하였습니다 media: - hide: 미디어 숨기기 - show: 미디어 보여주기 title: 미디어 no_media: 미디어 없음 title: 계정 툿 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 7a488bb0fa..00f21babd0 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -53,9 +53,7 @@ nl: unfollow: Ontvolgen admin: account_moderation_notes: - account: Moderator create: Aanmaken - created_at: Datum created_msg: Aanmaken van opmerking voor moderatoren geslaagd! delete: Verwijderen destroyed_msg: Verwijderen van opmerking voor moderatoren geslaagd! @@ -269,7 +267,6 @@ nl: comment: none: Geen created_at: Gerapporteerd op - delete: Verwijderen id: ID mark_as_resolved: Markeer als opgelost mark_as_unresolved: Markeer als onopgelost @@ -279,9 +276,6 @@ nl: create_and_unresolve: Heropenen met opmerking delete: Verwijderen placeholder: Beschrijf welke acties zijn ondernomen of andere opmerkingen over deze gerapporteerde toot… - nsfw: - 'false': Media tonen - 'true': Media verbergen reopen: Gerapporteerde toot heropenen report: 'Gerapporteerde toot #%{id}' report_contents: Inhoud @@ -356,11 +350,8 @@ nl: delete: Verwijderen nsfw_off: Als niet gevoelig markeren nsfw_on: Als gevoelig markeren - execute: Uitvoeren failed_to_execute: Uitvoeren mislukt media: - hide: Media verbergen - show: Media tonen title: Media no_media: Geen media title: Toots van account diff --git a/config/locales/no.yml b/config/locales/no.yml index 8b84182af6..6ce2c0f013 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -52,9 +52,7 @@ unfollow: Slutte følge admin: account_moderation_notes: - account: Moderator create: Lag - created_at: Dato created_msg: Moderasjonsnotat laget uten problem! delete: Slett destroyed_msg: Moderasjonsnotat slettet uten problem! @@ -244,12 +242,8 @@ are_you_sure: Er du sikker? comment: none: Ingen - delete: Slett id: ID mark_as_resolved: Merk som løst - nsfw: - 'false': Vis mediavedlegg - 'true': Skjul mediavedlegg report: 'Rapportér #%{id}' report_contents: Innhold reported_account: Rapportert konto @@ -314,11 +308,8 @@ delete: Slett nsfw_off: NSFW AV nsfw_on: NSFW PÅ - execute: Utfør failed_to_execute: Utføring mislyktes media: - hide: Skjul media - show: Vis media title: Media no_media: Ingen media title: Kontostatuser diff --git a/config/locales/oc.yml b/config/locales/oc.yml index c248ffd85a..c11fe614b0 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -53,9 +53,7 @@ oc: unfollow: Quitar de sègre admin: account_moderation_notes: - account: Moderator create: Crear - created_at: Data created_msg: Nòta de moderacion ben creada ! delete: Suprimir destroyed_msg: Nòta de moderacion ben suprimida ! @@ -265,7 +263,6 @@ oc: comment: none: Pas cap created_at: Creacion - delete: Suprimir id: ID mark_as_resolved: Marcar coma resolgut mark_as_unresolved: Marcar coma pas resolgut @@ -274,9 +271,6 @@ oc: create_and_resolve: Resòlvre amb una nòta create_and_unresolve: Tornar dobrir amb una nòta placeholder: Explicatz las accions que son estadas menadas o çò qu’es estat fach per aqueste rapòrt… - nsfw: - 'false': Sens contengut sensible - 'true': Contengut sensible activat reopen: Tornar dobrir lo rapòrt report: 'senhalament #%{id}' report_contents: Contenguts @@ -348,11 +342,8 @@ oc: delete: Suprimir nsfw_off: NSFW OFF nsfw_on: NSFW ON - execute: Lançar failed_to_execute: Fracàs media: - hide: Amagar mèdia - show: Mostrar mèdia title: Mèdia no_media: Cap mèdia title: Estatuts del compte diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 7455df2c02..bd38aa6f77 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -53,9 +53,7 @@ pl: unfollow: Przestań śledzić admin: account_moderation_notes: - account: Autor create: Dodaj - created_at: Data created_msg: Pomyślnie dodano notatkę moderacyjną! delete: Usuń destroyed_msg: Pomyślnie usunięto notatkę moderacyjną! @@ -270,7 +268,6 @@ pl: comment: none: Brak created_at: Zgłoszono - delete: Usuń id: ID mark_as_resolved: Oznacz jako rozwiązane mark_as_unresolved: Oznacz jako nierozwiązane @@ -280,9 +277,6 @@ pl: create_and_unresolve: Cofnij rozwiązanie i pozostaw notatkę delete: Usuń placeholder: Opisz wykonane akcje i inne szczegóły dotyczące tego zgłoszenia… - nsfw: - 'false': Nie oznaczaj jako NSFW - 'true': Oznaczaj jako NSFW reopen: Otwórz ponownie report: 'Zgłoszenie #%{id}' report_contents: Zawartość @@ -357,11 +351,8 @@ pl: delete: Usuń nsfw_off: Cofnij NSFW nsfw_on: Oznacz jako NSFW - execute: Wykonaj failed_to_execute: Nie udało się wykonać media: - hide: Ukryj zawartość multimedialną - show: Pokaż zawartość multimedialną title: Media no_media: Bez zawartości multimedialnej title: Wpisy konta diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 4a574a575d..862833d873 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -53,9 +53,7 @@ pt-BR: unfollow: Deixar de seguir admin: account_moderation_notes: - account: Moderador create: Criar - created_at: Data created_msg: Nota de moderação criada com sucesso! delete: Excluir destroyed_msg: Nota de moderação excluída com sucesso! @@ -269,7 +267,6 @@ pt-BR: comment: none: Nenhum created_at: Denunciado - delete: Excluir id: ID mark_as_resolved: Marcar como resolvido mark_as_unresolved: Marcar como não resolvido @@ -279,9 +276,6 @@ pt-BR: create_and_unresolve: Reabrir com nota delete: Excluir placeholder: Descreva que ações foram tomadas, ou quaisquer atualizações sobre esta denúncia… - nsfw: - 'false': Mostrar mídias anexadas - 'true': Esconder mídias anexadas reopen: Reabrir denúncia report: 'Denúncia #%{id}' report_contents: Conteúdos @@ -356,11 +350,8 @@ pt-BR: delete: Deletar nsfw_off: Marcar como não-sensível nsfw_on: Marcar como sensível - execute: Executar failed_to_execute: Falha em executar media: - hide: Esconder mídia - show: Mostrar mídia title: Mídia no_media: Não há mídia title: Postagens da conta diff --git a/config/locales/pt.yml b/config/locales/pt.yml index fb2a6cad1c..62a7ef0ec4 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -52,9 +52,7 @@ pt: unfollow: Deixar de seguir admin: account_moderation_notes: - account: Moderador create: Criar - created_at: Data created_msg: Nota de moderação criada com sucesso! delete: Eliminar destroyed_msg: Nota de moderação excluída com sucesso! @@ -244,12 +242,8 @@ pt: are_you_sure: Tens a certeza? comment: none: Nenhum - delete: Eliminar id: ID mark_as_resolved: Marcar como resolvido - nsfw: - 'false': Mostrar imagens/vídeos - 'true': Esconder imagens/vídeos report: 'Denúncia #%{id}' report_contents: Conteúdos reported_account: Conta denunciada @@ -314,11 +308,8 @@ pt: delete: Eliminar nsfw_off: NSFW OFF nsfw_on: NSFW ON - execute: Executar failed_to_execute: Falhou ao executar media: - hide: Esconder média - show: Mostrar média title: Média no_media: Não há média title: Estado das contas diff --git a/config/locales/ru.yml b/config/locales/ru.yml index bf42257581..603e1f3cab 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -52,9 +52,7 @@ ru: unfollow: Отписаться admin: account_moderation_notes: - account: Модератор create: Создать - created_at: Дата created_msg: Заметка модератора успешно создана! delete: Удалить destroyed_msg: Заметка модератора успешно удалена! @@ -246,12 +244,8 @@ ru: are_you_sure: Вы уверены? comment: none: Нет - delete: Удалить id: ID mark_as_resolved: Отметить как разрешенную - nsfw: - 'false': Показать мультимедийные вложения - 'true': Скрыть мультимедийные вложения report: 'Жалоба #%{id}' report_contents: Содержимое reported_account: Аккаунт нарушителя @@ -322,11 +316,8 @@ ru: delete: Удалить nsfw_off: Выключить NSFW nsfw_on: Включить NSFW - execute: Выполнить failed_to_execute: Не удалось выполнить media: - hide: Скрыть медиаконтент - show: Показать медиаконтент title: Медиаконтент no_media: Без медиаконтента title: Статусы аккаунта diff --git a/config/locales/sk.yml b/config/locales/sk.yml index fc9e9452c5..7fb097f03d 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -53,9 +53,7 @@ sk: unfollow: Prestať sledovať admin: account_moderation_notes: - account: Moderátor create: Vytvoriť - created_at: Dátum created_msg: Poznámka moderátora bola úspešne vytvorená! delete: Zmazať destroyed_msg: Poznámka moderátora bola úspešne zmazaná! @@ -268,7 +266,6 @@ sk: comment: none: Žiadne created_at: Nahlásené - delete: Vymazať id: Identifikácia mark_as_resolved: Označiť ako vyriešené mark_as_unresolved: Označ ako nevyriešené @@ -278,9 +275,6 @@ sk: create_and_unresolve: Otvor znovu, s poznámkou delete: Vymaž placeholder: Opíš aké opatrenia boli urobené, alebo akékoľvek iné aktualizácie k tomuto nahláseniu… - nsfw: - 'false': Odkryť mediálne prílohy - 'true': Skryť mediálne prílohy reopen: Znovu otvor report report: Nahlásiť report_contents: Obsah @@ -355,11 +349,8 @@ sk: delete: Vymazať nsfw_off: Obsah nieje chúlostivý nsfw_on: Označ obeah aka chúlostivý - execute: Vykonať failed_to_execute: Nepodarilo sa vykonať media: - hide: Skryť médiá - show: Zobraziť médiá title: Médiá no_media: Žiadné médiá title: Statusy na účte diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 742c976d19..dba952917a 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -52,9 +52,7 @@ sr-Latn: unfollow: Otprati admin: account_moderation_notes: - account: Moderator create: Napravi - created_at: Datum created_msg: Moderatorska beleška uspešno napravljena! delete: Obriši destroyed_msg: Moderatorska beleška uspešno obrisana! @@ -246,12 +244,8 @@ sr-Latn: are_you_sure: Da li ste sigurni? comment: none: Ništa - delete: Obriši id: ID mark_as_resolved: Označi kao rešen - nsfw: - 'false': Otkrij medijske priloge - 'true': Sakrij medijske priloge report: 'Prijava #%{id}' report_contents: Sadržaj reported_account: Prijavljeni nalog @@ -310,11 +304,8 @@ sr-Latn: delete: Obriši nsfw_off: NSFW isključen nsfw_on: NSFW uključen - execute: Izvrši failed_to_execute: Neuspelo izvršavanje media: - hide: Sakrij multimediju - show: Prikaži multimediju title: Multimedija no_media: Bez multimedije title: Statusi naloga diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 0d55910a6c..74abf0323e 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -52,9 +52,7 @@ sr: unfollow: Отпрати admin: account_moderation_notes: - account: Модератор create: Направи - created_at: Датум created_msg: Модераторска белешка успешно направљена! delete: Обриши destroyed_msg: Модераторска белешка успешно обрисана! @@ -246,12 +244,8 @@ sr: are_you_sure: Да ли сте сигурни? comment: none: Ништа - delete: Обриши id: ID mark_as_resolved: Означи као решен - nsfw: - 'false': Откриј медијске прилоге - 'true': Сакриј медијске прилоге report: 'Пријава #%{id}' report_contents: Садржај reported_account: Пријављени налог @@ -310,11 +304,8 @@ sr: delete: Обриши nsfw_off: NSFW искључен nsfw_on: NSFW укључен - execute: Изврши failed_to_execute: Неуспело извршавање media: - hide: Сакриј мултимедију - show: Прикажи мултимедију title: Мултимедија no_media: Без мултимедије title: Статуси налога diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 845248652f..9e0bb08565 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -53,9 +53,7 @@ sv: unfollow: Sluta följa admin: account_moderation_notes: - account: Moderator create: Skapa - created_at: Datum created_msg: Modereringsnotering skapad utan problem! delete: Ta bort destroyed_msg: Modereringsnotering borttagen utan problem! @@ -269,7 +267,6 @@ sv: comment: none: Ingen created_at: Anmäld - delete: Radera id: ID mark_as_resolved: Markera som löst mark_as_unresolved: Markera som olöst @@ -279,9 +276,6 @@ sv: create_and_unresolve: Återuppta med anteckning delete: Radera placeholder: Beskriv vilka åtgärder som vidtagits eller andra uppdateringar till den här anmälan… - nsfw: - 'false': Visa bifogade mediafiler - 'true': Dölj bifogade mediafiler reopen: Återuppta anmälan report: 'Anmäl #%{id}' report_contents: Innehåll @@ -356,11 +350,8 @@ sv: delete: Radera nsfw_off: Markera som ej känslig nsfw_on: Markera som känslig - execute: Utför failed_to_execute: Misslyckades att utföra media: - hide: Dölj media - show: Visa media title: Media no_media: Ingen media title: Kontostatus diff --git a/config/locales/th.yml b/config/locales/th.yml index 350b93b521..9d93115b0d 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -109,7 +109,6 @@ th: reports: comment: none: None - delete: ลบ id: ไอดี mark_as_resolved: ทำเครื่องหมายว่าจัดการแล้ว report: 'Report #%{id}' diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 6e7aeb77e9..0d78216b60 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -108,7 +108,6 @@ tr: reports: comment: none: Yok - delete: Sil id: ID mark_as_resolved: Giderildi olarak işaretle report: 'Şikayet #%{id}' diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 44f64b5c9e..6fe46b4d98 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -100,7 +100,6 @@ uk: reports: comment: none: Немає - delete: Видалити id: ID mark_as_resolved: Відмітити як вирішену report: 'Скарга #%{id}' diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 78c72bd302..7ea491fd4b 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -52,9 +52,7 @@ zh-CN: unfollow: 取消关注 admin: account_moderation_notes: - account: 管理员 create: 新建 - created_at: 日期 created_msg: 管理备忘建立成功! delete: 删除 destroyed_msg: 管理备忘删除成功! @@ -242,12 +240,8 @@ zh-CN: are_you_sure: 你确定吗? comment: none: 没有 - delete: 删除 id: ID mark_as_resolved: 标记为“已处理” - nsfw: - 'false': 取消 NSFW 标记 - 'true': 添加 NSFW 标记 report: '举报 #%{id}' report_contents: 内容 reported_account: 举报用户 @@ -312,11 +306,8 @@ zh-CN: delete: 删除 nsfw_off: 取消 NSFW 标记 nsfw_on: 添加 NSFW 标记 - execute: 执行 failed_to_execute: 执行失败 media: - hide: 隐藏媒体文件 - show: 显示媒体文件 title: 媒体文件 no_media: 不含媒体文件 title: 帐户嘟文 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index a27b0c04c8..3f91b7191d 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -53,9 +53,7 @@ zh-HK: unfollow: 取消關注 admin: account_moderation_notes: - account: 管理員 create: 新增 - created_at: 日期 created_msg: 管理記錄已新增 delete: 刪除 destroyed_msg: 管理記錄已被刪除 @@ -268,7 +266,6 @@ zh-HK: comment: none: 沒有 created_at: 日期 - delete: 刪除 id: ID mark_as_resolved: 標示為「已處理」 mark_as_unresolved: 標示為「未處理」 @@ -278,9 +275,6 @@ zh-HK: create_and_unresolve: 建立筆記並標示為「未處理」 delete: 刪除 placeholder: 記錄已執行的動作,或其他更新 - nsfw: - 'false': 取消 NSFW 標記 - 'true': 添加 NSFW 標記 reopen: 重開舉報 report: '舉報 #%{id}' report_contents: 舉報內容 @@ -355,11 +349,8 @@ zh-HK: delete: 刪除 nsfw_off: 取消 NSFW 標記 nsfw_on: 添加 NSFW 標記 - execute: 執行 failed_to_execute: 執行失敗 media: - hide: 隱藏媒體檔案 - show: 顯示媒體檔案 title: 媒體檔案 no_media: 不含媒體檔案 title: 帳戶文章 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index f69d22d79a..d8c0f89a96 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -80,7 +80,6 @@ zh-TW: reports: comment: none: 無 - delete: 刪除 id: ID mark_as_resolved: 標記為已解決 report: '檢舉 #%{id}' diff --git a/config/routes.rb b/config/routes.rb index d959301e98..90f6ac594d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -135,7 +135,7 @@ Rails.application.routes.draw do end resources :reports, only: [:index, :show, :update] do - resources :reported_statuses, only: [:create, :update, :destroy] + resources :reported_statuses, only: [:create] end resources :report_notes, only: [:create, :destroy] @@ -156,7 +156,7 @@ Rails.application.routes.draw do resource :silence, only: [:create, :destroy] resource :suspension, only: [:create, :destroy] resource :confirmation, only: [:create] - resources :statuses, only: [:index, :create, :update, :destroy] + resources :statuses, only: [:index, :create] resource :role do member do diff --git a/spec/controllers/admin/reported_statuses_controller_spec.rb b/spec/controllers/admin/reported_statuses_controller_spec.rb index 29957ed37e..7adbf36b9c 100644 --- a/spec/controllers/admin/reported_statuses_controller_spec.rb +++ b/spec/controllers/admin/reported_statuses_controller_spec.rb @@ -22,7 +22,7 @@ describe Admin::ReportedStatusesController do let(:sensitive) { true } let!(:media_attachment) { Fabricate(:media_attachment, status: status) } - context 'updates sensitive column to true' do + context 'when action is nsfw_on' do it 'updates sensitive column' do is_expected.to change { status.reload.sensitive @@ -30,7 +30,7 @@ describe Admin::ReportedStatusesController do end end - context 'updates sensitive column to false' do + context 'when action is nsfw_off' do let(:action) { 'nsfw_off' } let(:sensitive) { false } @@ -41,35 +41,13 @@ describe Admin::ReportedStatusesController do end end - it 'redirects to report page' do - subject.call - expect(response).to redirect_to(admin_report_path(report)) - end - end + context 'when action is delete' do + let(:action) { 'delete' } - describe 'PATCH #update' do - subject do - -> { patch :update, params: { report_id: report, id: status, status: { sensitive: sensitive } } } - end - - let(:status) { Fabricate(:status, sensitive: !sensitive) } - let(:sensitive) { true } - - context 'updates sensitive column to true' do - it 'updates sensitive column' do - is_expected.to change { - status.reload.sensitive - }.from(false).to(true) - end - end - - context 'updates sensitive column to false' do - let(:sensitive) { false } - - it 'updates sensitive column' do - is_expected.to change { - status.reload.sensitive - }.from(true).to(false) + it 'removes a status' do + allow(RemovalWorker).to receive(:perform_async) + subject.call + expect(RemovalWorker).to have_received(:perform_async).with(status_ids.first) end end @@ -78,15 +56,4 @@ describe Admin::ReportedStatusesController do expect(response).to redirect_to(admin_report_path(report)) end end - - describe 'DELETE #destroy' do - it 'removes a status' do - allow(RemovalWorker).to receive(:perform_async) - - delete :destroy, params: { report_id: report, id: status } - expect(response).to have_http_status(200) - expect(RemovalWorker). - to have_received(:perform_async).with(status.id) - end - end end diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb index cbaf397865..6afcc14425 100644 --- a/spec/controllers/admin/statuses_controller_spec.rb +++ b/spec/controllers/admin/statuses_controller_spec.rb @@ -34,13 +34,13 @@ describe Admin::StatusesController do describe 'POST #create' do subject do - -> { post :create, params: { account_id: account.id, form_status_batch: { action: action, status_ids: status_ids } } } + -> { post :create, params: { :account_id => account.id, action => '', :form_status_batch => { status_ids: status_ids } } } end let(:action) { 'nsfw_on' } let(:status_ids) { [media_attached_status.id] } - context 'updates sensitive column to true' do + context 'when action is nsfw_on' do it 'updates sensitive column' do is_expected.to change { media_attached_status.reload.sensitive @@ -48,7 +48,7 @@ describe Admin::StatusesController do end end - context 'updates sensitive column to false' do + context 'when action is nsfw_off' do let(:action) { 'nsfw_off' } let(:sensitive) { false } @@ -59,32 +59,13 @@ describe Admin::StatusesController do end end - it 'redirects to account statuses page' do - subject.call - expect(response).to redirect_to(admin_account_statuses_path(account.id)) - end - end + context 'when action is delete' do + let(:action) { 'delete' } - describe 'PATCH #update' do - subject do - -> { patch :update, params: { account_id: account.id, id: media_attached_status, status: { sensitive: sensitive } } } - end - - context 'updates sensitive column to true' do - it 'updates sensitive column' do - is_expected.to change { - media_attached_status.reload.sensitive - }.from(false).to(true) - end - end - - context 'updates sensitive column to false' do - let(:sensitive) { false } - - it 'updates sensitive column' do - is_expected.to change { - media_attached_status.reload.sensitive - }.from(true).to(false) + it 'removes a status' do + allow(RemovalWorker).to receive(:perform_async) + subject.call + expect(RemovalWorker).to have_received(:perform_async).with(status_ids.first) end end @@ -93,15 +74,4 @@ describe Admin::StatusesController do expect(response).to redirect_to(admin_account_statuses_path(account.id)) end end - - describe 'DELETE #destroy' do - it 'removes a status' do - allow(RemovalWorker).to receive(:perform_async) - - delete :destroy, params: { account_id: account.id, id: status } - expect(response).to have_http_status(200) - expect(RemovalWorker). - to have_received(:perform_async).with(status.id) - end - end end From 2ee5d518f1a9be3309bdbbfd9ff4558a2e010565 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 5 May 2018 23:07:51 +0200 Subject: [PATCH 013/239] Fallback to old on-the-fly URI for follows/blocks if no stored URI (#7371) Fix #7367 --- app/serializers/activitypub/block_serializer.rb | 2 +- app/serializers/activitypub/follow_serializer.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/serializers/activitypub/block_serializer.rb b/app/serializers/activitypub/block_serializer.rb index b3bd9f868e..624ce2fce8 100644 --- a/app/serializers/activitypub/block_serializer.rb +++ b/app/serializers/activitypub/block_serializer.rb @@ -5,7 +5,7 @@ class ActivityPub::BlockSerializer < ActiveModel::Serializer attribute :virtual_object, key: :object def id - [ActivityPub::TagManager.instance.uri_for(object.account), '#blocks/', object.id].join + ActivityPub::TagManager.instance.uri_for(object) || [ActivityPub::TagManager.instance.uri_for(object.account), '#blocks/', object.id].join end def type diff --git a/app/serializers/activitypub/follow_serializer.rb b/app/serializers/activitypub/follow_serializer.rb index 24dfe96f89..bb204ee8f3 100644 --- a/app/serializers/activitypub/follow_serializer.rb +++ b/app/serializers/activitypub/follow_serializer.rb @@ -5,7 +5,7 @@ class ActivityPub::FollowSerializer < ActiveModel::Serializer attribute :virtual_object, key: :object def id - ActivityPub::TagManager.instance.uri_for(object) + ActivityPub::TagManager.instance.uri_for(object) || [ActivityPub::TagManager.instance.uri_for(object.account), '#follows/', object.id].join end def type From 14393f29ef5e28ae92830fa2d47c497baccfaf76 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 May 2018 10:52:36 +0200 Subject: [PATCH 014/239] Add contact e-mail hint to 2FA login form (#7376) --- app/views/auth/sessions/two_factor.html.haml | 7 +++++-- config/locales/en.yml | 1 + config/locales/simple_form.en.yml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml index 2b07c923be..1af3193ae0 100644 --- a/app/views/auth/sessions/two_factor.html.haml +++ b/app/views/auth/sessions/two_factor.html.haml @@ -2,9 +2,12 @@ = t('auth.login') = simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f| - = f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, required: true, autofocus: true, hint: t('simple_form.hints.sessions.otp') + %p.hint{ style: 'margin-bottom: 25px' }= t('simple_form.hints.sessions.otp') + + = f.input :otp_attempt, type: :number, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, required: true, autofocus: true .actions = f.button :button, t('auth.login'), type: :submit -.form-footer= render 'auth/shared/links' + - if Setting.site_contact_email.present? + %p.hint.subtle-hint= t('users.otp_lost_help_html', email: mail_to(Setting.site_contact_email, nil)) diff --git a/config/locales/en.yml b/config/locales/en.yml index 7e389b1c22..bb08ccc547 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -827,5 +827,6 @@ en: users: invalid_email: The e-mail address is invalid invalid_otp_token: Invalid two-factor code + otp_lost_help_html: If you lost access to both, you may get in touch with %{email} seamless_external_login: You are logged in via an external service, so password and e-mail settings are not available. signed_in_as: 'Signed in as:' diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 1a0d60f710..7ba32906d4 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -19,7 +19,7 @@ en: imports: data: CSV file exported from another Mastodon instance sessions: - otp: Enter the Two-factor code from your phone or use one of your recovery codes. + otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:' user: filtered_languages: Checked languages will be filtered from public timelines for you labels: From a1398887aeb1268f3774d320ac3739a10e5dedfd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 May 2018 10:53:10 +0200 Subject: [PATCH 015/239] Add hint about 7 day cooldown for archive takeout (#7375) --- app/views/settings/exports/show.html.haml | 6 +++--- config/locales/en.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index 89d768d3fc..30cd269140 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -10,15 +10,15 @@ %td %tr %th= t('exports.follows') - %td= @export.total_follows + %td= number_to_human @export.total_follows %td= table_link_to 'download', t('exports.csv'), settings_exports_follows_path(format: :csv) %tr %th= t('exports.blocks') - %td= @export.total_blocks + %td= number_to_human @export.total_blocks %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv) %tr %th= t('exports.mutes') - %td= @export.total_mutes + %td= number_to_human @export.total_mutes %td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv) %p.muted-hint= t('exports.archive_takeout.hint_html') diff --git a/config/locales/en.yml b/config/locales/en.yml index bb08ccc547..4f967f9ac4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -457,7 +457,7 @@ en: archive_takeout: date: Date download: Download your archive - hint_html: You can request an archive of your toots and uploaded media. The exported data will be in ActivityPub format, readable by any compliant software. + hint_html: You can request an archive of your toots and uploaded media. The exported data will be in ActivityPub format, readable by any compliant software. You can request an archive every 7 days. in_progress: Compiling your archive... request: Request your archive size: Size From 9d64bcdac75d5b96b2ce0c66c2acf1e12463f034 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 6 May 2018 17:55:50 +0900 Subject: [PATCH 016/239] Port travis_retry for CI (#7379) * Port travis_retry for CI * Add license --- .circleci/config.yml | 4 ++-- Gemfile | 1 - Gemfile.lock | 3 --- bin/retry | 46 ++++++++++++++++++++++++++++++++++++++++++++ spec/spec_helper.rb | 8 -------- 5 files changed, 48 insertions(+), 14 deletions(-) create mode 100755 bin/retry diff --git a/.circleci/config.yml b/.circleci/config.yml index 70d03f6b94..fc9c7e22b7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -90,7 +90,7 @@ aliases: command: ./bin/rails parallel:create parallel:load_schema parallel:prepare - run: name: Run Tests - command: bundle exec parallel_test ./spec/ --group-by filesize --type rspec + command: ./bin/retry bundle exec parallel_test ./spec/ --group-by filesize --type rspec jobs: install: @@ -150,7 +150,7 @@ jobs: - image: circleci/node:8.11.1-stretch steps: - *attach_workspace - - run: yarn test:jest + - run: ./bin/retry yarn test:jest check-i18n: <<: *defaults diff --git a/Gemfile b/Gemfile index 98718f87d0..2beac94d2c 100644 --- a/Gemfile +++ b/Gemfile @@ -112,7 +112,6 @@ group :test do gem 'microformats', '~> 4.0' gem 'rails-controller-testing', '~> 1.0' gem 'rspec-sidekiq', '~> 3.0' - gem 'rspec-retry', '~> 0.5', require: false gem 'simplecov', '~> 0.16', require: false gem 'webmock', '~> 3.3' gem 'parallel_tests', '~> 2.21' diff --git a/Gemfile.lock b/Gemfile.lock index f4be9bf9ca..6a579d53bb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -501,8 +501,6 @@ GEM rspec-expectations (~> 3.7.0) rspec-mocks (~> 3.7.0) rspec-support (~> 3.7.0) - rspec-retry (0.5.7) - rspec-core (> 3.3) rspec-sidekiq (3.0.3) rspec-core (~> 3.0, >= 3.0.0) sidekiq (>= 2.4.0) @@ -726,7 +724,6 @@ DEPENDENCIES redis-rails (~> 5.0) rqrcode (~> 0.10) rspec-rails (~> 3.7) - rspec-retry (~> 0.5) rspec-sidekiq (~> 3.0) rubocop (~> 0.55) ruby-progressbar (~> 1.4) diff --git a/bin/retry b/bin/retry new file mode 100755 index 0000000000..419ece62a5 --- /dev/null +++ b/bin/retry @@ -0,0 +1,46 @@ +#!/bin/bash +# https://github.com/travis-ci/travis-build/blob/cbe49ea239ab37b9b38b5b44d287b7ec7a108c16/lib/travis/build/templates/header.sh#L243-L260 +# +# MIT LICENSE +# +# Copyright (c) 2016 Travis CI GmbH +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +retry() { + local result=0 + local count=1 + + while [ $count -le 3 ]; do + if [ $result -ne 0 ]; then + echo -e "\n${ANSI_RED}The command \"$@\" failed. Retrying, $count of 3.${ANSI_RESET}\n" >&2 + fi + + "$@" && { result=0 && break; } || result=$? + count=$(($count + 1)) + sleep 1 + done + + if [ $count -gt 3 ]; then + echo -e "\n${ANSI_RED}The command \"$@\" failed 3 times.${ANSI_RESET}\n" >&2 + fi + + return $result +} + +retry $@ diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9030329373..a0466dd4bf 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,4 +1,3 @@ -#require 'rspec/retry' require 'simplecov' GC.disable @@ -12,9 +11,6 @@ end gc_counter = -1 RSpec.configure do |config| - #config.verbose_retry = true - #config.display_try_failure_messages = true - config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end @@ -29,10 +25,6 @@ RSpec.configure do |config| end end - #config.around :each do |ex| - # ex.run_with_retry retry: 3 - #end - config.before :suite do Chewy.strategy(:bypass) end From 8c8a850f8ab7106f1da2f42071956c6419d7bd32 Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Sun, 6 May 2018 17:59:03 +0900 Subject: [PATCH 017/239] Add resend confirmation for admin (#7378) * Add confirmations_controller#resend * Add tests for confirmations_controller#resend * Add translations --- .../admin/confirmations_controller.rb | 19 ++++++++++++ app/views/admin/accounts/show.html.haml | 10 ++++-- config/locales/ar.yml | 6 ++++ config/locales/ca.yml | 6 ++++ config/locales/de.yml | 6 ++++ config/locales/en.yml | 6 ++++ config/locales/eo.yml | 6 ++++ config/locales/es.yml | 6 ++++ config/locales/fa.yml | 6 ++++ config/locales/fi.yml | 6 ++++ config/locales/fr.yml | 6 ++++ config/locales/gl.yml | 6 ++++ config/locales/he.yml | 6 ++++ config/locales/hu.yml | 6 ++++ config/locales/id.yml | 6 ++++ config/locales/it.yml | 6 ++++ config/locales/ja.yml | 6 ++++ config/locales/ko.yml | 6 ++++ config/locales/nl.yml | 6 ++++ config/locales/no.yml | 6 ++++ config/locales/oc.yml | 6 ++++ config/locales/pl.yml | 6 ++++ config/locales/pt-BR.yml | 6 ++++ config/locales/pt.yml | 6 ++++ config/locales/ru.yml | 6 ++++ config/locales/sk.yml | 6 ++++ config/locales/sr-Latn.yml | 6 ++++ config/locales/sr.yml | 6 ++++ config/locales/sv.yml | 6 ++++ config/locales/th.yml | 6 ++++ config/locales/tr.yml | 6 ++++ config/locales/zh-CN.yml | 6 ++++ config/locales/zh-HK.yml | 6 ++++ config/routes.rb | 9 ++++-- .../admin/confirmations_controller_spec.rb | 31 +++++++++++++++++++ 35 files changed, 251 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/confirmations_controller.rb b/app/controllers/admin/confirmations_controller.rb index 34dfb458ec..8d3477e660 100644 --- a/app/controllers/admin/confirmations_controller.rb +++ b/app/controllers/admin/confirmations_controller.rb @@ -3,6 +3,7 @@ module Admin class ConfirmationsController < BaseController before_action :set_user + before_action :check_confirmation, only: [:resend] def create authorize @user, :confirm? @@ -11,10 +12,28 @@ module Admin redirect_to admin_accounts_path end + def resend + authorize @user, :confirm? + + @user.resend_confirmation_instructions + + log_action :confirm, @user + + flash[:notice] = I18n.t('admin.accounts.resend_confirmation.success') + redirect_to admin_accounts_path + end + private def set_user @user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound) end + + def check_confirmation + if @user.confirmed? + flash[:error] = I18n.t('admin.accounts.resend_confirmation.already_confirmed') + redirect_to admin_accounts_path + end + end end end diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index 2e6de18643..ed8190af5a 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -36,13 +36,19 @@ %th= t('admin.accounts.email') %td = @account.user_email - - if @account.user_confirmed? - = fa_icon('check') = table_link_to 'edit', t('admin.accounts.change_email.label'), admin_account_change_email_path(@account.id) if can?(:change_email, @account.user) - if @account.user_unconfirmed_email.present? %th= t('admin.accounts.unconfirmed_email') %td = @account.user_unconfirmed_email + %tr + %th= t('admin.accounts.email_status') + %td + - if @account.user&.confirmed? + = t('admin.accounts.confirmed') + - else + = t('admin.accounts.confirming') + = table_link_to 'refresh', t('admin.accounts.resend_confirmation.send'), resend_admin_account_confirmation_path(@account.id), method: :post if can?(:confirm, @account.user) %tr %th= t('admin.accounts.login_status') %td diff --git a/config/locales/ar.yml b/config/locales/ar.yml index a5179ae148..eb0127eb51 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -61,6 +61,7 @@ ar: by_domain: النطاق confirm: تأكيد confirmed: مؤكَّد + confirming: التأكد demote: إنزال الرُتبة الوظيفية disable: تعطيل disable_two_factor_authentication: تعطيل 2FA @@ -69,6 +70,7 @@ ar: domain: النطاق edit: تعديل email: البريد الإلكتروني + email_status: حالة البريد الإلكتروني enable: تفعيل enabled: مفعَّل feed_url: عنوان رابط التغذية @@ -106,6 +108,10 @@ ar: public: عمومي push_subscription_expires: انتهاء الاشتراك ”PuSH“ redownload: تحديث الصورة الرمزية + resend_confirmation: + already_confirmed: هذا المستخدم مؤكد بالفعل + send: أعد إرسال رسالة البريد الالكتروني الخاصة بالتأكيد + success: تم إرسال رسالة التأكيد بنجاح! reset: إعادة التعيين reset_password: إعادة ضبط كلمة السر resubscribe: اشترك مرة أخرى diff --git a/config/locales/ca.yml b/config/locales/ca.yml index a8c75c32df..bdc3f74844 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -70,6 +70,7 @@ ca: title: Canviar adreça de correu de %{username} confirm: Confirma confirmed: Confirmat + confirming: Confirmando demote: Degrada disable: Inhabilita disable_two_factor_authentication: Desactiva 2FA @@ -78,6 +79,7 @@ ca: domain: Domini edit: Edita email: Correu electrònic + email_status: Estado del correo electrónico enable: Habilita enabled: Habilitat feed_url: URL del canal @@ -116,6 +118,10 @@ ca: push_subscription_expires: La subscripció PuSH expira redownload: Actualitza l'avatar remove_avatar: Eliminar avatar + resend_confirmation: + already_confirmed: Este usuario ya está confirmado + send: Reenviar el correo electrónico de confirmación + success: "¡Correo electrónico de confirmación enviado con éxito!" reset: Reinicialitza reset_password: Restableix la contrasenya resubscribe: Torna a subscriure diff --git a/config/locales/de.yml b/config/locales/de.yml index aa4295c896..05d7e01b38 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -70,6 +70,7 @@ de: title: E-Mail-Adresse für %{username} ändern confirm: Bestätigen confirmed: Bestätigt + confirming: Bestätigung demote: Degradieren disable: Ausschalten disable_two_factor_authentication: 2FA abschalten @@ -78,6 +79,7 @@ de: domain: Domain edit: Bearbeiten email: E-Mail + email_status: E-Mail-Status enable: Freischalten enabled: Freigegeben feed_url: Feed-URL @@ -116,6 +118,10 @@ de: push_subscription_expires: PuSH-Abonnement läuft aus redownload: Avatar neu laden remove_avatar: Profilbild entfernen + resend_confirmation: + already_confirmed: Dieser Benutzer wurde bereits bestätigt + send: Bestätigungsmail erneut senden + success: Bestätigungs-E-Mail erfolgreich gesendet! reset: Zurücksetzen reset_password: Passwort zurücksetzen resubscribe: Wieder abonnieren diff --git a/config/locales/en.yml b/config/locales/en.yml index 4f967f9ac4..e18354eac4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -70,6 +70,7 @@ en: title: Change Email for %{username} confirm: Confirm confirmed: Confirmed + confirming: Confirming demote: Demote disable: Disable disable_two_factor_authentication: Disable 2FA @@ -78,6 +79,7 @@ en: domain: Domain edit: Edit email: E-mail + email_status: E-mail Status enable: Enable enabled: Enabled feed_url: Feed URL @@ -116,6 +118,10 @@ en: push_subscription_expires: PuSH subscription expires redownload: Refresh avatar remove_avatar: Remove avatar + resend_confirmation: + already_confirmed: This user is already confirmed + send: Resend confirmation email + success: Confirmation email successfully sent! reset: Reset reset_password: Reset password resubscribe: Resubscribe diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 9c44d0e622..47d591993b 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -61,6 +61,7 @@ eo: by_domain: Domajno confirm: Konfirmi confirmed: Konfirmita + confirming: Konfirmante demote: Degradi disable: Malebligi disable_two_factor_authentication: Malebligi 2FA @@ -69,6 +70,7 @@ eo: domain: Domajno edit: Redakti email: Retpoŝto + email_status: Retpoŝto Stato enable: Ebligi enabled: Ebligita feed_url: URL de la fluo @@ -106,6 +108,10 @@ eo: public: Publika push_subscription_expires: Eksvalidiĝo de la abono al PuSH redownload: Aktualigi profilbildon + resend_confirmation: + already_confirmed: Ĉi tiu uzanto jam estas konfirmita + send: Esend konfirmi retpoŝton + success: Konfirma retpoŝto sukcese sendis reset: Restarigi reset_password: Restarigi pasvorton resubscribe: Reaboni diff --git a/config/locales/es.yml b/config/locales/es.yml index be7dcd81e5..11bee3239b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -70,6 +70,7 @@ es: title: Cambiar el correo electrónico de %{username} confirm: Confirmar confirmed: Confirmado + confirming: Confirmando demote: Degradar disable: Deshabilitar disable_two_factor_authentication: Desactivar autenticación de dos factores @@ -78,6 +79,7 @@ es: domain: Dominio edit: Editar email: E-mail + email_status: E-mail Status enable: Habilitar enabled: Habilitada feed_url: URL de notificaciones @@ -116,6 +118,10 @@ es: push_subscription_expires: Expiración de la suscripción PuSH redownload: Refrescar avatar remove_avatar: Eliminar el avatar + resend_confirmation: + already_confirmed: Este usuario ya está confirmado + send: Reenviar el correo electrónico de confirmación + success: "¡Correo electrónico de confirmación enviado con éxito" reset: Reiniciar reset_password: Reiniciar contraseña resubscribe: Re-suscribir diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 3aa40f0b3e..5255e0e38f 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -61,6 +61,7 @@ fa: by_domain: دامین confirm: تأیید confirmed: تأیید شد + confirming: تأیید demote: تنزل‌دادن disable: غیرفعال disable_two_factor_authentication: غیرفعال‌سازی ورود دومرحله‌ای @@ -69,6 +70,7 @@ fa: domain: دامین edit: ویرایش email: ایمیل + email_status: وضعیت ایمیل enable: فعال enabled: فعال feed_url: نشانی فید @@ -106,6 +108,10 @@ fa: public: عمومی push_subscription_expires: عضویت از راه PuSH منقضی شد redownload: به‌روزرسانی تصویر نمایه + resend_confirmation: + already_confirmed: این کاربر قبلا تایید شده است + send: ایمیل تایید را دوباره بفرستید + success: ایمیل تایید با موفقیت ارسال شد reset: بازنشانی reset_password: بازنشانی رمز resubscribe: اشتراک دوباره diff --git a/config/locales/fi.yml b/config/locales/fi.yml index b313c87236..fca58cc0f1 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -61,6 +61,7 @@ fi: by_domain: Verkko-osoite confirm: Vahvista confirmed: Vahvistettu + confirming: Vahvistavat demote: Alenna disable: Poista käytöstä disable_two_factor_authentication: Poista 2FA käytöstä @@ -69,6 +70,7 @@ fi: domain: Verkko-osoite edit: Muokkaa email: Sähköposti + email_status: Sähköpostin tila enable: Ota käyttöön enabled: Käytössä feed_url: Syötteen URL @@ -106,6 +108,10 @@ fi: public: Julkinen push_subscription_expires: PuSH-tilaus vanhenee redownload: Päivitä profiilikuva + resend_confirmation: + already_confirmed: Tämä käyttäjä on jo vahvistettu + send: Lähetä varmistusviesti uudelleen + success: Vahvistusviesti lähetettiin onnistuneesti reset: Palauta reset_password: Palauta salasana resubscribe: Tilaa uudelleen diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 3b543fdb7b..e7142f3fdb 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -70,6 +70,7 @@ fr: title: Modifier le courriel pour %{username} confirm: Confirmer confirmed: Confirmé + confirming: Confirmant demote: Rétrograder disable: Désactiver disable_two_factor_authentication: Désactiver l’authentification à deux facteurs @@ -78,6 +79,7 @@ fr: domain: Domaine edit: Éditer email: Courriel + email_status: État de la messagerie enable: Activer enabled: Activé feed_url: URL du flux @@ -116,6 +118,10 @@ fr: push_subscription_expires: Expiration de l’abonnement PuSH redownload: Rafraîchir les avatars remove_avatar: Supprimer l'avatar + resend_confirmation: + already_confirmed: Cet utilisateur est déjà confirmé + send: Renvoyer un courriel de confirmation + success: Email de confirmation envoyé avec succès ! reset: Réinitialiser reset_password: Réinitialiser le mot de passe resubscribe: Se réabonner diff --git a/config/locales/gl.yml b/config/locales/gl.yml index eec1b4e1ef..e00c4b4333 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -70,6 +70,7 @@ gl: title: Cambiar o correo-e de %{username} confirm: Confirmar confirmed: Confirmado + confirming: Confirmar demote: Degradar disable: Deshabilitar disable_two_factor_authentication: Deshabilitar 2FA @@ -78,6 +79,7 @@ gl: domain: Dominio edit: Editar email: E-mail + email_status: Estado del correo electrónico enable: Habilitar enabled: Habilitado feed_url: URL fonte @@ -116,6 +118,10 @@ gl: push_subscription_expires: A suscrición PuSH caduca redownload: Actualizar avatar remove_avatar: Eliminar avatar + resend_confirmation: + already_confirmed: Este usuario ya está confirmado + send: Reenviar el correo electrónico de confirmación + success: "¡Correo electrónico de confirmación enviado con éxito!" reset: Restablecer reset_password: Restablecer contrasinal resubscribe: Voltar a suscribir diff --git a/config/locales/he.yml b/config/locales/he.yml index d66d9f0346..c127db3852 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -61,6 +61,7 @@ he: by_domain: שם מתחם confirm: אישור confirmed: אושר + confirming: המאשר demote: הורדה בדרגה disable: לחסום disable_two_factor_authentication: ביטול הזדהות דו-שלבית @@ -69,6 +70,7 @@ he: domain: תחום edit: עריכה email: דוא"ל + email_status: סטטוס דוא"ל enable: לאפשר enabled: מאופשר feed_url: כתובת פיד @@ -106,6 +108,10 @@ he: public: פומבי push_subscription_expires: הרשמה להודעות בדחיפה פגה redownload: לקריאה מחדש של האווטאר + resend_confirmation: + already_confirmed: משתמש זה כבר אושר + send: שלח מחדש דוא"ל אימות + success: הודעת האימייל נשלחה בהצלחה! reset: איפוס reset_password: אתחול סיסמא resubscribe: להרשם מחדש diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 422c059559..0cd0021c16 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -61,6 +61,7 @@ hu: by_domain: Domain confirm: Megerősítés confirmed: Megerősítve + confirming: Megerősítve demote: Lefokozás disable: Kikapcsolás disable_two_factor_authentication: Kétlépcsős azonosítás kikapcsolása @@ -69,6 +70,7 @@ hu: domain: Domain edit: Szerkesztés email: E-mail + email_status: E-mail állapot enable: Engedélyezés enabled: Engedélyezve feed_url: Hírcsatorna URL @@ -106,6 +108,10 @@ hu: public: Nyilvános push_subscription_expires: A PuSH feliratkozás elévül redownload: Profilkép frissítése + resend_confirmation: + already_confirmed: Ezt a felhasználót már megerősítették + send: Küldd újra a megerősítő email-t + success: A megerősítő e-mail sikeresen elküldve! reset: Visszaállítás reset_password: Jelszó visszaállítása resubscribe: Feliratkozás ismét diff --git a/config/locales/id.yml b/config/locales/id.yml index 0476e2848e..4fb75f2b0e 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -29,10 +29,12 @@ id: are_you_sure: Anda yakin? confirm: Konfirmasi confirmed: Dikonfirmasi + confirming: Mengkonfirmasi display_name: Nama domain: Domain edit: Ubah email: E-mail + email_status: Status Email feed_url: URL Feed followers: Pengikut follows: Mengikut @@ -58,6 +60,10 @@ id: profile_url: URL profil public: Publik push_subscription_expires: Langganan PuSH telah kadaluarsa + resend_confirmation: + already_confirmed: Pengguna ini sudah dikonfirmasi + send: Kirim ulang email konfirmasi + success: Email konfirmasi berhasil dikirim! reset_password: Reset kata sandi salmon_url: URL Salmon show: diff --git a/config/locales/it.yml b/config/locales/it.yml index c1ac176c45..eafe6b2a17 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -66,6 +66,7 @@ it: title: Cambia email per %{username} confirm: Conferma confirmed: Confermato + confirming: Confermando demote: Declassa disable: Disabilita disable_two_factor_authentication: Disabilita 2FA @@ -74,6 +75,7 @@ it: domain: Dominio edit: Modifica email: Email + email_status: Stato email enable: Abilita enabled: Abilitato feed_url: URL Feed @@ -111,6 +113,10 @@ it: public: Pubblico redownload: Aggiorna avatar remove_avatar: Rimuovi avatar + resend_confirmation: + already_confirmed: Questo utente è già confermato + send: Reinvia email di conferma + success: Email di conferma inviata con successo! reset: Reimposta reset_password: Reimposta password resubscribe: Riscriversi diff --git a/config/locales/ja.yml b/config/locales/ja.yml index bc48613b98..c7025fc186 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -70,6 +70,7 @@ ja: title: "%{username} さんのメールアドレスを変更" confirm: 確認 confirmed: 確認済み + confirming: 確認中 demote: 降格 disable: 無効化 disable_two_factor_authentication: 二段階認証を無効にする @@ -78,6 +79,7 @@ ja: domain: ドメイン edit: 編集 email: メールアドレス + email_status: メールアドレスの状態 enable: 有効化 enabled: 有効 feed_url: フィードURL @@ -116,6 +118,10 @@ ja: push_subscription_expires: PuSH購読期限 redownload: アバターの更新 remove_avatar: アイコンを削除 + resend_confirmation: + already_confirmed: メールアドレスは確認済みです。 + send: 確認メールを再送 + success: 確認メールを再送信しました! reset: リセット reset_password: パスワード再設定 resubscribe: 再講読 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index bd6717d497..92e99ce501 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -70,6 +70,7 @@ ko: title: "%{username}의 이메일 주소 변경" confirm: 확인 confirmed: 확인됨 + confirming: 확인 중 demote: 모더레이터 강등 disable: 비활성화 disable_two_factor_authentication: 2단계 인증을 비활성화 @@ -78,6 +79,7 @@ ko: domain: 도메인 edit: 편집 email: E-mail + email_status: 이메일 상태 enable: 활성화 enabled: 활성화된 feed_url: 피드 URL @@ -116,6 +118,10 @@ ko: push_subscription_expires: PuSH 구독 기간 만료 redownload: 아바타 업데이트 remove_avatar: 아바타 지우기 + resend_confirmation: + already_confirmed: 이 사용자는 이미 확인되었습니다. + send: 다시 확인 이메일 + success: 확인 이메일이 전송되었습니다. reset: 초기화 reset_password: 비밀번호 초기화 resubscribe: 다시 구독 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 00f21babd0..6ca81b3757 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -70,6 +70,7 @@ nl: title: E-mailadres veranderen voor %{username} confirm: Bevestigen confirmed: Bevestigd + confirming: Bevestiging demote: Degraderen disable: Uitschakelen disable_two_factor_authentication: 2FA uitschakelen @@ -78,6 +79,7 @@ nl: domain: Domein edit: Bewerken email: E-mail + email_status: E-mail Status enable: Inschakelen enabled: Ingeschakeld feed_url: Feed-URL @@ -116,6 +118,10 @@ nl: push_subscription_expires: PuSH-abonnement verloopt op redownload: Avatar vernieuwen remove_avatar: Avatar verwijderen + resend_confirmation: + already_confirmed: Deze gebruiker is al bevestigd + send: Verzend bevestigingsmail opnieuw + success: Bevestigingsmail succesvol verzonden! reset: Opnieuw reset_password: Wachtwoord opnieuw instellen resubscribe: Opnieuw abonneren diff --git a/config/locales/no.yml b/config/locales/no.yml index 6ce2c0f013..837042f851 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -61,6 +61,7 @@ by_domain: Domene confirm: Bekreft confirmed: Bekreftet + confirming: Bekrefte demote: Degrader disable: Deaktiver disable_two_factor_authentication: Skru av 2FA @@ -69,6 +70,7 @@ domain: Domene edit: Redigér email: E-post + email_status: E-poststatus enable: Aktiver enabled: Aktivert feed_url: Feed-URL @@ -106,6 +108,10 @@ public: Offentlig push_subscription_expires: PuSH-abonnent utløper redownload: Oppdater avatar + resend_confirmation: + already_confirmed: Denne brukeren er allerede bekreftet + send: Send bekreftelses-epost på nytt + success: Bekreftelses e-post er vellykket sendt! reset: Tilbakestill reset_password: Nullstill passord resubscribe: Abonner på nytt diff --git a/config/locales/oc.yml b/config/locales/oc.yml index c11fe614b0..e61f7ebd00 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -70,6 +70,7 @@ oc: title: Cambiar l’adreça a %{username} confirm: Confirmar confirmed: Confirmat + confirming: Confirmando demote: Retrogradar disable: Desactivar disable_two_factor_authentication: Desactivar 2FA @@ -78,6 +79,7 @@ oc: domain: Domeni edit: Modificar email: Corrièl + email_status: Estado del correo electrónico enable: Activar enabled: Activat feed_url: Flux URL @@ -116,6 +118,10 @@ oc: push_subscription_expires: Fin de l’abonament PuSH redownload: Actualizar los avatars remove_avatar: Supriir l’avatar + resend_confirmation: + already_confirmed: Este usuario ya está confirmado + send: Reenviar el correo electrónico de confirmación + success: "¡Correo electrónico de confirmación enviado con éxito!" reset: Reïnicializar reset_password: Reïnicializar lo senhal resubscribe: Se tornar abonar diff --git a/config/locales/pl.yml b/config/locales/pl.yml index bd38aa6f77..1fbe0d5c8f 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -70,6 +70,7 @@ pl: title: Zmień adres e-mail dla %{username} confirm: Potwierdź confirmed: Potwierdzono + confirming: Potwierdzam demote: Degraduj disable: Dezaktywuj disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuetapowe @@ -78,6 +79,7 @@ pl: domain: Domena edit: Edytuj email: Adres e-mail + email_status: Status e-maila enable: Aktywuj enabled: Aktywowano feed_url: Adres kanału @@ -116,6 +118,10 @@ pl: push_subscription_expires: Subskrypcja PuSH wygasa redownload: Odśwież awatar remove_avatar: Usun awatar + resend_confirmation: + already_confirmed: Ten użytkownik jest już potwierdzony + send: Wyślij ponownie email potwierdzający + success: E-mail z potwierdzeniem został wysłany! reset: Resetuj reset_password: Resetuj hasło resubscribe: Ponów subskrypcję diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 862833d873..37abeffd9f 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -70,6 +70,7 @@ pt-BR: title: Mudar e-mail para %{username} confirm: Confirmar confirmed: Confirmado + confirming: Confirmando demote: Rebaixar disable: Desativar disable_two_factor_authentication: Desativar 2FA @@ -78,6 +79,7 @@ pt-BR: domain: Domínio edit: Editar email: E-mail + email_status: Estado del correo electrónico enable: Ativar enabled: Ativado feed_url: URL do feed @@ -116,6 +118,10 @@ pt-BR: push_subscription_expires: Inscrição PuSH expira redownload: Atualizar avatar remove_avatar: Remover avatar + resend_confirmation: + already_confirmed: Este usuario ya está confirmado + send: Reenviar el correo electrónico de confirmación + success: "¡Correo electrónico de confirmación enviado con éxito!" reset: Anular reset_password: Modificar senha resubscribe: Reinscrever-se diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 62a7ef0ec4..7c10124ff6 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -61,6 +61,7 @@ pt: by_domain: Domínio confirm: Confirme confirmed: Confirmado + confirming: Confirmer demote: Rebaixar disable: Desativar disable_two_factor_authentication: Desativar 2FA @@ -69,6 +70,7 @@ pt: domain: Domínio edit: Editar email: E-mail + email_status: État de la messagerie enable: Ativar enabled: Ativado feed_url: URL do Feed @@ -106,6 +108,10 @@ pt: public: Público push_subscription_expires: A Inscrição PuSH expira redownload: Atualizar avatar + resend_confirmation: + already_confirmed: Cet utilisateur est déjà confirmé + send: Renvoyer un courriel de confirmation + success: Email de confirmation envoyé avec succès! reset: Restaurar reset_password: Reset palavra-passe resubscribe: Reinscrever diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 603e1f3cab..99825a765a 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -61,6 +61,7 @@ ru: by_domain: Домен confirm: Подтвердить confirmed: Подтверждено + confirming: подтверждающий demote: Разжаловать disable: Отключить disable_two_factor_authentication: Отключить 2FA @@ -69,6 +70,7 @@ ru: domain: Домен edit: Изменить email: E-mail + email_status: Статус электронной почты enable: Включить enabled: Включен feed_url: URL фида @@ -106,6 +108,10 @@ ru: public: Публичный push_subscription_expires: Подписка PuSH истекает redownload: Обновить аватар + resend_confirmation: + already_confirmed: Этот пользователь уже подтвержден + send: Повторно отправить подтверждение по электронной почте + success: Письмо с подтверждением успешно отправлено! reset: Сбросить reset_password: Сбросить пароль resubscribe: Переподписаться diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 7fb097f03d..ef756b474e 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -70,6 +70,7 @@ sk: title: Zmeň email pre %{username} confirm: Potvrdiť confirmed: Potvrdený + confirming: Potvrdzujúci demote: Degradovať disable: Zablokovať disable_two_factor_authentication: Zakázať 2FA @@ -78,6 +79,7 @@ sk: domain: Doména edit: Upraviť email: Email + email_status: Stav Email enable: Povoliť enabled: Povolený feed_url: URL časovej osi @@ -116,6 +118,10 @@ sk: push_subscription_expires: PuSH odoberanie expiruje redownload: Obnoviť avatar remove_avatar: Odstrániť avatár + resend_confirmation: + already_confirmed: Tento používateľ už bol potvrdený + send: Znova odoslať potvrdzovací e-mail + success: Potvrdený e-mail bol úspešne odoslaný! reset: Reset reset_password: Obnoviť heslo resubscribe: Znovu odoberať diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index dba952917a..0c7756c53e 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -61,6 +61,7 @@ sr-Latn: by_domain: Domen confirm: Potvrdi confirmed: Potvrđeno + confirming: Potvrđujući demote: Ražaluj disable: Isključi disable_two_factor_authentication: Isključi 2FA @@ -69,6 +70,7 @@ sr-Latn: domain: Domen edit: Izmeni email: E-pošta + email_status: Status e-pošte enable: Uključi enabled: Uključeno feed_url: Adresa dovoda @@ -106,6 +108,10 @@ sr-Latn: public: Javno push_subscription_expires: PuSH subscription expires redownload: Osveži avatar + resend_confirmation: + already_confirmed: Ovaj korisnik je već potvrđen + send: Ponovo pošaljite e-poruku za potvrdu + success: E-mail potvrde je uspešno poslat! reset: Resetuj reset_password: Resetuj lozinku resubscribe: Ponovo se pretplati diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 74abf0323e..1cb87ff30c 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -61,6 +61,7 @@ sr: by_domain: Домен confirm: Потврди confirmed: Потврђено + confirming: Потврдување demote: Ражалуј disable: Искључи disable_two_factor_authentication: Искључи 2FA @@ -69,6 +70,7 @@ sr: domain: Домен edit: Измени email: Е-пошта + email_status: Е-пошта статус enable: Укључи enabled: Укључено feed_url: Адреса довода @@ -106,6 +108,10 @@ sr: public: Јавно push_subscription_expires: PuSH subscription expires redownload: Освежи аватар + resend_confirmation: + already_confirmed: Овој корисник е веќе потврден + send: Препрати го е-мајлот за потврда + success: Е-пошта за потврда успешно испратена! reset: Ресетуј reset_password: Ресетуј лозинку resubscribe: Поново се претплати diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 9e0bb08565..1b09656555 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -70,6 +70,7 @@ sv: title: Byt E-postadress för %{username} confirm: Bekräfta confirmed: Bekräftad + confirming: Bekräftande demote: Degradera disable: inaktivera disable_two_factor_authentication: Inaktivera 2FA @@ -78,6 +79,7 @@ sv: domain: Domän edit: Redigera email: E-post + email_status: E-poststatus enable: Aktivera enabled: Aktiverad feed_url: Flödes URL @@ -116,6 +118,10 @@ sv: push_subscription_expires: PuSH-prenumerationen löper ut redownload: Uppdatera avatar remove_avatar: Ta bort avatar + resend_confirmation: + already_confirmed: Den här användaren är redan bekräftad + send: Skicka om e-postbekräftelse + success: Bekräftelsemeddelande skickas framgångsrikt! reset: Återställ reset_password: Återställ lösenord resubscribe: Starta en ny prenumeration diff --git a/config/locales/th.yml b/config/locales/th.yml index 9d93115b0d..6804dbd13d 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -29,11 +29,13 @@ th: are_you_sure: แน่ใจนะ? confirm: ยืนยัน confirmed: ยึนยันแล้ว + confirming: ยืนยัน disable_two_factor_authentication: Disable 2FA display_name: ชื่อสำหรับดีสเพล domain: โดแมน edit: แก้ไข email: อีเมล์ + email_status: สถานะอีเมล feed_url: Feed URL followers: ผู้ติดตาม follows: ติดตาม @@ -59,6 +61,10 @@ th: profile_url: Profile URL public: สาธารณะ push_subscription_expires: PuSH subscription expires + resend_confirmation: + already_confirmed: ผู้ใช้รายนี้ได้รับการยืนยันแล้ว + send: ส่งอีเมลยืนยันอีกครั้ง + success: ยืนยันอีเมลเรียบร้อยแล้ว! reset_password: รีเซ็ตรหัสผ่าน salmon_url: Salmon URL show: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 0d78216b60..8bafbface2 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -29,10 +29,12 @@ tr: are_you_sure: Emin misiniz? confirm: Onayla confirmed: Onaylandı + confirming: Onaylama display_name: Görünen adınız domain: Sunucu edit: Düzenle email: E-posta + email_status: Email Durumu feed_url: Besleme linki followers: Takipçiler follows: Takip edilen @@ -58,6 +60,10 @@ tr: profile_url: Profil linki public: Herkese açık push_subscription_expires: PuSH aboneliği dolumu + resend_confirmation: + already_confirmed: Bu kullanıcı zaten onaylandı + send: Doğrulama epostasını yeniden gönder + success: Onay e-postası başarıyla gönderildi! reset_password: Parolayı değiştir salmon_url: Salmon Linki show: diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 7ea491fd4b..5eca9e6a56 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -61,6 +61,7 @@ zh-CN: by_domain: 域名 confirm: 确认 confirmed: 已确认 + confirming: 确认 demote: 降任 disable: 停用 disable_two_factor_authentication: 停用双重认证 @@ -69,6 +70,7 @@ zh-CN: domain: 域名 edit: 编辑 email: 电子邮件地址 + email_status: 电子邮件状态 enable: 启用 enabled: 已启用 feed_url: 订阅 URL @@ -106,6 +108,10 @@ zh-CN: public: 公开页面 push_subscription_expires: PuSH 订阅过期时间 redownload: 刷新头像 + resend_confirmation: + already_confirmed: 该用户已被确认 + send: 重发确认邮件 + success: 确认电子邮件成功发送! reset: 重置 reset_password: 重置密码 resubscribe: 重新订阅 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index 3f91b7191d..c5d8c86968 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -70,6 +70,7 @@ zh-HK: title: 改變 %{username} 的電郵 confirm: 確定 confirmed: 已確定 + confirming: 確定 demote: 降任 disable: 停用 disable_two_factor_authentication: 停用雙重認證 @@ -78,6 +79,7 @@ zh-HK: domain: 域名 edit: 編輯 email: 電郵地址 + email_status: 电子邮件状态 enable: 啟用 enabled: 已啟用 feed_url: Feed URL @@ -116,6 +118,10 @@ zh-HK: push_subscription_expires: PuSH 訂閱過期 redownload: 更新頭像 remove_avatar: 取消頭像 + resend_confirmation: + already_confirmed: 该用户已被确认 + send: 重发确认邮件 + success: 确认电子邮件成功发送! reset: 重設 reset_password: 重設密碼 resubscribe: 重新訂閱 diff --git a/config/routes.rb b/config/routes.rb index 90f6ac594d..4c920cf74f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -155,8 +155,13 @@ Rails.application.routes.draw do resource :reset, only: [:create] resource :silence, only: [:create, :destroy] resource :suspension, only: [:create, :destroy] - resource :confirmation, only: [:create] - resources :statuses, only: [:index, :create] + resources :statuses, only: [:index, :create, :update, :destroy] + + resource :confirmation, only: [:create] do + collection do + post :resend + end + end resource :role do member do diff --git a/spec/controllers/admin/confirmations_controller_spec.rb b/spec/controllers/admin/confirmations_controller_spec.rb index 7c80349646..eec2b2f5c4 100644 --- a/spec/controllers/admin/confirmations_controller_spec.rb +++ b/spec/controllers/admin/confirmations_controller_spec.rb @@ -30,4 +30,35 @@ RSpec.describe Admin::ConfirmationsController, type: :controller do expect(response).to have_http_status(404) end end + + describe 'POST #resernd' do + subject { post :resend, params: { account_id: account.id } } + + let(:account) { Fabricate(:account) } + let!(:user) { Fabricate(:user, confirmed_at: confirmed_at, account: account) } + + before do + allow(UserMailer).to receive(:confirmation_instructions) { double(:email, deliver_later: nil) } + end + + context 'when email is not confirmed' do + let(:confirmed_at) { nil } + + it 'resends confirmation mail' do + expect(subject).to redirect_to admin_accounts_path + expect(flash[:notice]).to eq I18n.t('admin.accounts.resend_confirmation.success') + expect(UserMailer).to have_received(:confirmation_instructions).once + end + end + + context 'when email is confirmed' do + let(:confirmed_at) { Time.zone.now } + + it 'does not resend confirmation mail' do + expect(subject).to redirect_to admin_accounts_path + expect(flash[:error]).to eq I18n.t('admin.accounts.resend_confirmation.already_confirmed') + expect(UserMailer).not_to have_received(:confirmation_instructions) + end + end + end end From 4055ce490c75030c10d847c865d5dfa3814792c6 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 May 2018 11:48:51 +0200 Subject: [PATCH 018/239] Enable custom emojis in profiles (notes, field values, display names) (#7374) Follow-up to #6124 --- app/helpers/stream_entries_helper.rb | 4 ++-- .../mastodon/actions/importer/normalizer.js | 19 +++++++++++-------- app/lib/formatter.rb | 12 ++++++++++-- app/models/account.rb | 6 +++++- app/serializers/rest/account_serializer.rb | 1 + app/views/about/_administration.html.haml | 2 +- app/views/about/_contact.html.haml | 2 +- app/views/accounts/_grid_card.html.haml | 2 +- app/views/accounts/_header.html.haml | 4 ++-- app/views/accounts/_moved_strip.html.haml | 4 ++-- app/views/admin/reports/_account.html.haml | 2 +- app/views/authorize_follows/_card.html.haml | 2 +- app/views/remote_unfollows/_card.html.haml | 2 +- app/views/shared/_landing_strip.html.haml | 2 +- .../stream_entries/_detailed_status.html.haml | 2 +- .../stream_entries/_simple_status.html.haml | 2 +- app/views/stream_entries/_status.html.haml | 2 +- 17 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index c6f12ecd41..707c8e26ce 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -4,8 +4,8 @@ module StreamEntriesHelper EMBEDDED_CONTROLLER = 'statuses' EMBEDDED_ACTION = 'embed' - def display_name(account) - account.display_name.presence || account.username + def display_name(account, **options) + Formatter.instance.format_display_name(account, options) end def account_description(account) diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 5f1274fab6..057bff58bd 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -3,18 +3,25 @@ import emojify from '../../features/emoji/emoji'; const domParser = new DOMParser(); +const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => { + obj[`:${emoji.shortcode}:`] = emoji; + return obj; +}, {}); + export function normalizeAccount(account) { account = { ...account }; + const emojiMap = makeEmojiMap(account); const displayName = account.display_name.length === 0 ? account.username : account.display_name; - account.display_name_html = emojify(escapeTextContentForBrowser(displayName)); - account.note_emojified = emojify(account.note); + + account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap); + account.note_emojified = emojify(account.note, emojiMap); if (account.fields) { account.fields = account.fields.map(pair => ({ ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), - value_emojified: emojify(pair.value), + value_emojified: emojify(pair.value, emojiMap), })); } @@ -42,11 +49,7 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.hidden = normalOldStatus.get('hidden'); } else { const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(//g, '\n').replace(/<\/p>

    /g, '\n\n'); - - const emojiMap = normalStatus.emojis.reduce((obj, emoji) => { - obj[`:${emoji.shortcode}:`] = emoji; - return obj; - }, {}); + const emojiMap = makeEmojiMap(normalStatus); normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 050c651ee9..e1ab05cc0b 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -67,9 +67,17 @@ class Formatter html.html_safe # rubocop:disable Rails/OutputSafety end - def format_field(account, str) + def format_display_name(account, **options) + html = encode(account.display_name.presence || account.username) + html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify] + html.html_safe # rubocop:disable Rails/OutputSafety + end + + def format_field(account, str, **options) return reformat(str).html_safe unless account.local? # rubocop:disable Rails/OutputSafety - encode_and_link_urls(str, me: true).html_safe # rubocop:disable Rails/OutputSafety + html = encode_and_link_urls(str, me: true) + html = encode_custom_emojis(html, account.emojis) if options[:custom_emojify] + html.html_safe # rubocop:disable Rails/OutputSafety end def linkify(text) diff --git a/app/models/account.rb b/app/models/account.rb index 72ba0398ef..4467d1512a 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -398,7 +398,7 @@ class Account < ApplicationRecord end def emojis - @emojis ||= CustomEmoji.from_text(note, domain) + @emojis ||= CustomEmoji.from_text(emojifiable_text, domain) end before_create :generate_keys @@ -425,4 +425,8 @@ class Account < ApplicationRecord self.domain = TagManager.instance.normalize_domain(domain) end + + def emojifiable_text + [note, display_name, fields.map(&:value)].join(' ') + end end diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 863238eb74..8761bbb5e7 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -8,6 +8,7 @@ class REST::AccountSerializer < ActiveModel::Serializer :followers_count, :following_count, :statuses_count has_one :moved_to_account, key: :moved, serializer: REST::AccountSerializer, if: :moved_and_not_nested? + has_many :emojis, serializer: REST::CustomEmojiSerializer class FieldSerializer < ActiveModel::Serializer attributes :name, :value diff --git a/app/views/about/_administration.html.haml b/app/views/about/_administration.html.haml index ec5834f9cb..02286d68b7 100644 --- a/app/views/about/_administration.html.haml +++ b/app/views/about/_administration.html.haml @@ -6,7 +6,7 @@ .account__avatar{ style: "background-image: url(#{@instance_presenter.contact_account.avatar.url})" } %span.display-name %bdi - %strong.display-name__html.emojify= display_name(@instance_presenter.contact_account) + %strong.display-name__html.emojify= display_name(@instance_presenter.contact_account, custom_emojify: true) %span.display-name__account @#{@instance_presenter.contact_account.acct} - else .account__display-name diff --git a/app/views/about/_contact.html.haml b/app/views/about/_contact.html.haml index cf21ad5a3c..3215d50b53 100644 --- a/app/views/about/_contact.html.haml +++ b/app/views/about/_contact.html.haml @@ -12,7 +12,7 @@ .avatar= image_tag contact.contact_account.avatar.url .name = link_to TagManager.instance.url_for(contact.contact_account) do - %span.display_name.emojify= display_name(contact.contact_account) + %span.display_name.emojify= display_name(contact.contact_account, custom_emojify: true) %span.username @#{contact.contact_account.acct} - else .owner diff --git a/app/views/accounts/_grid_card.html.haml b/app/views/accounts/_grid_card.html.haml index 95acbd581e..a59ed128e6 100644 --- a/app/views/accounts/_grid_card.html.haml +++ b/app/views/accounts/_grid_card.html.haml @@ -5,7 +5,7 @@ .avatar= image_tag account.avatar.url(:original) .name = link_to TagManager.instance.url_for(account) do - %span.display_name.emojify= display_name(account) + %span.display_name.emojify= display_name(account, custom_emojify: true) %span.username @#{account.local? ? account.local_username_and_domain : account.acct} = fa_icon('lock') if account.locked? diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 41315f0393..13dcaf616a 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -5,7 +5,7 @@ .card__bio %h1.name - %span.p-name.emojify= display_name(account) + %span.p-name.emojify= display_name(account, custom_emojify: true) %small< %span>< @#{account.local_username_and_domain} = fa_icon('lock') if account.locked? @@ -28,7 +28,7 @@ - account.fields.each do |field| %dl %dt.emojify{ title: field.name }= field.name - %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value) + %dd.emojify{ title: field.value }= Formatter.instance.format_field(account, field.value, custom_emojify: true) .details-counters .counter{ class: active_nav_class(short_account_url(account)) } diff --git a/app/views/accounts/_moved_strip.html.haml b/app/views/accounts/_moved_strip.html.haml index 6a14a5dd30..ae18c6dc70 100644 --- a/app/views/accounts/_moved_strip.html.haml +++ b/app/views/accounts/_moved_strip.html.haml @@ -3,7 +3,7 @@ .moved-strip .moved-strip__message = fa_icon 'suitcase' - = t('accounts.moved_html', name: content_tag(:strong, display_name(account), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention')) + = t('accounts.moved_html', name: content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), TagManager.instance.url_for(moved_to_account), class: 'mention')) .moved-strip__card = link_to TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do @@ -13,5 +13,5 @@ .account__avatar-overlay-overlay{ style: "background-image: url('#{account.avatar.url(:original)}')" } %span.display-name - %strong.emojify= display_name(moved_to_account) + %strong.emojify= display_name(moved_to_account, custom_emojify: true) %span @#{moved_to_account.acct} diff --git a/app/views/admin/reports/_account.html.haml b/app/views/admin/reports/_account.html.haml index 22b7a08618..9ac161c9c6 100644 --- a/app/views/admin/reports/_account.html.haml +++ b/app/views/admin/reports/_account.html.haml @@ -15,5 +15,5 @@ .account__avatar{ style: "background-image: url(#{account.avatar.url}); width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px" } %span.display-name %bdi - %strong.display-name__html.emojify= display_name(account) + %strong.display-name__html.emojify= display_name(account, custom_emojify: true) %span.display-name__account @#{account.acct} diff --git a/app/views/authorize_follows/_card.html.haml b/app/views/authorize_follows/_card.html.haml index e81e292ba6..9abcfd37e1 100644 --- a/app/views/authorize_follows/_card.html.haml +++ b/app/views/authorize_follows/_card.html.haml @@ -6,7 +6,7 @@ %span.display-name - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account) = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do - %strong.emojify= display_name(account) + %strong.emojify= display_name(account, custom_emojify: true) %span @#{account.acct} - if account.note? diff --git a/app/views/remote_unfollows/_card.html.haml b/app/views/remote_unfollows/_card.html.haml index e81e292ba6..9abcfd37e1 100644 --- a/app/views/remote_unfollows/_card.html.haml +++ b/app/views/remote_unfollows/_card.html.haml @@ -6,7 +6,7 @@ %span.display-name - account_url = local_assigns[:admin] ? admin_account_path(account.id) : TagManager.instance.url_for(account) = link_to account_url, class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'noopener' do - %strong.emojify= display_name(account) + %strong.emojify= display_name(account, custom_emojify: true) %span @#{account.acct} - if account.note? diff --git a/app/views/shared/_landing_strip.html.haml b/app/views/shared/_landing_strip.html.haml index ae26fc1fff..78f5ed4bcc 100644 --- a/app/views/shared/_landing_strip.html.haml +++ b/app/views/shared/_landing_strip.html.haml @@ -2,7 +2,7 @@ = image_tag asset_pack_path('logo.svg'), class: 'logo' %div - = t('landing_strip_html', name: content_tag(:span, display_name(account), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path)) + = t('landing_strip_html', name: content_tag(:span, display_name(account, custom_emojify: true), class: :emojify), link_to_root_path: link_to(content_tag(:strong, site_hostname), root_path)) - if open_registrations? = t('landing_strip_signup_html', sign_up_path: new_user_registration_path) diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml index afc66d1487..c0f1e4f0f5 100644 --- a/app/views/stream_entries/_detailed_status.html.haml +++ b/app/views/stream_entries/_detailed_status.html.haml @@ -4,7 +4,7 @@ .avatar = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '', class: 'u-photo' %span.display-name - %strong.p-name.emojify= display_name(status.account) + %strong.p-name.emojify= display_name(status.account, custom_emojify: true) %span= acct(status.account) - if embedded_view? diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml index a6f5120fb1..b89860ad90 100644 --- a/app/views/stream_entries/_simple_status.html.haml +++ b/app/views/stream_entries/_simple_status.html.haml @@ -10,7 +10,7 @@ %div = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '', class: 'u-photo' %span.display-name - %strong.p-name.emojify= display_name(status.account) + %strong.p-name.emojify= display_name(status.account, custom_emojify: true) %span= acct(status.account) .status__content.p-name.emojify< diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml index 9764bc74da..b87ca21771 100644 --- a/app/views/stream_entries/_status.html.haml +++ b/app/views/stream_entries/_status.html.haml @@ -28,7 +28,7 @@ = fa_icon('retweet fw') %span = link_to TagManager.instance.url_for(status.account), class: 'status__display-name muted' do - %strong.emojify= display_name(status.account) + %strong.emojify= display_name(status.account, custom_emojify: true) = t('stream_entries.reblogged') - elsif pinned .pre-header From 0dcb01855c7eddd3c15e2e7044df634138d200bd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 6 May 2018 11:50:00 +0200 Subject: [PATCH 019/239] Bump version to 2.4.0rc1 (#7283) --- lib/mastodon/version.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index a6927eec31..2c643dcd7a 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -9,11 +9,11 @@ module Mastodon end def minor - 3 + 4 end def patch - 3 + 0 end def pre @@ -21,7 +21,7 @@ module Mastodon end def flags - '' + 'rc1' end def to_a From a14525d3df930036591e9a1cc33b26c2f6c5f0a4 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 6 May 2018 20:19:56 +0900 Subject: [PATCH 020/239] Weblate translations (2018-05-06) (#7381) * Translated using Weblate (Dutch) Currently translated at 100.0% (627 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Catalan) Currently translated at 100.0% (627 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Greek) Currently translated at 28.2% (177 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Occitan) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/oc/ * Translated using Weblate (Chinese (Hong Kong)) Currently translated at 98.2% (615 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/ * Translated using Weblate (Occitan) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/oc/ * Translated using Weblate (Occitan) Currently translated at 97.9% (613 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/oc/ * Translated using Weblate (Galician) Currently translated at 100.0% (626 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Galician) Currently translated at 100.0% (627 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 28.5% (179 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 28.5% (179 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.0% (182 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.0% (182 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.2% (183 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.3% (184 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.5% (185 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.7% (186 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.7% (186 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Slovak) Currently translated at 95.3% (597 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Slovak) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/ * Translated using Weblate (Slovak) Currently translated at 95.2% (597 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Chinese (Hong Kong)) Currently translated at 97.6% (612 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/ * Translated using Weblate (Chinese (Hong Kong)) Currently translated at 99.3% (623 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/zh_Hant_HK/ * Translated using Weblate (Polish) Currently translated at 99.8% (626 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/ * Translated using Weblate (Slovak) Currently translated at 100.0% (75 of 75 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/sk/ * Translated using Weblate (Arabic) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/ * Translated using Weblate (Arabic) Currently translated at 83.7% (525 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Spanish) Currently translated at 99.8% (626 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/es/ * Translated using Weblate (Italian) Currently translated at 54.7% (343 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/ * Translated using Weblate (Italian) Currently translated at 78.9% (495 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/it/ * Translated using Weblate (Esperanto) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/ * Translated using Weblate (Japanese) Currently translated at 99.8% (626 of 627 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * i18n-tasks normalize && i18n-tasks remove-unused && yarn manage:translations --- app/javascript/mastodon/locales/ar.json | 2 +- app/javascript/mastodon/locales/el.json | 128 ++++++++-------- app/javascript/mastodon/locales/eo.json | 28 ++-- app/javascript/mastodon/locales/oc.json | 4 +- app/javascript/mastodon/locales/sk.json | 2 +- config/locales/ar.yml | 10 ++ config/locales/ca.yml | 1 + config/locales/doorkeeper.sk.yml | 8 +- config/locales/el.yml | 167 +++++++++++++++++++++ config/locales/es.yml | 1 + config/locales/gl.yml | 5 +- config/locales/it.yml | 188 +++++++++++++++++++++++- config/locales/ja.yml | 1 + config/locales/nl.yml | 1 + config/locales/oc.yml | 24 +-- config/locales/pl.yml | 1 + config/locales/simple_form.oc.yml | 2 +- config/locales/sk.yml | 8 +- config/locales/zh-HK.yml | 21 ++- 19 files changed, 493 insertions(+), 109 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 947348f701..d531d8fd5a 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -258,7 +258,7 @@ "status.pin": "تدبيس على الملف الشخصي", "status.pinned": "تبويق مثبَّت", "status.reblog": "رَقِّي", - "status.reblog_private": "Boost to original audience", + "status.reblog_private": "القيام بالترقية إلى الجمهور الأصلي", "status.reblogged_by": "{name} رقى", "status.reply": "ردّ", "status.replyAll": "رُد على الخيط", diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index a7e1c408f8..5b36348eb8 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -2,9 +2,9 @@ "account.block": "Απόκλεισε τον/την @{name}", "account.block_domain": "Απόκρυψε τα πάντα από τον/την", "account.blocked": "Αποκλεισμένος/η", - "account.direct": "Απευθείας μήνυμα προς @{name}", + "account.direct": "Άμεσο μήνυμα προς @{name}", "account.disclaimer_full": "Οι παρακάτω πληροφορίες μπορει να μην αντανακλούν το προφίλ του χρήστη επαρκως.", - "account.domain_blocked": "Domain hidden", + "account.domain_blocked": "Κρυμμένος τομέας", "account.edit_profile": "Επεξεργάσου το προφίλ", "account.follow": "Ακολούθησε", "account.followers": "Ακόλουθοι", @@ -23,15 +23,15 @@ "account.requested": "Εκκρεμεί έγκριση. Κάνε κλικ για να ακυρώσεις το αίτημα ακολούθησης", "account.share": "Μοιράσου το προφίλ του/της @{name}", "account.show_reblogs": "Δείξε τις προωθήσεις του/της @{name}", - "account.unblock": "Unblock @{name}", + "account.unblock": "Ξεμπλόκαρε τον/την @{name}", "account.unblock_domain": "Αποκάλυψε το {domain}", - "account.unfollow": "Unfollow", - "account.unmute": "Unmute @{name}", - "account.unmute_notifications": "Unmute notifications from @{name}", + "account.unfollow": "Διακοπή παρακολούθησης", + "account.unmute": "Διακοπή αποσιώπησης του/της @{name}", + "account.unmute_notifications": "Διακοπή αποσιώπησης ειδοποιήσεων του/της @{name}", "account.view_full_profile": "Δες το πλήρες προφίλ", "alert.unexpected.message": "Προέκυψε απροσδόκητο σφάλμα.", "alert.unexpected.title": "Εεπ!", - "boost_modal.combo": "You can press {combo} to skip this next time", + "boost_modal.combo": "Μπορείς να πατήσεις {combo} για να το προσπεράσεις αυτό την επόμενη φορά", "bundle_column_error.body": "Κάτι πήγε στραβά ενώ φορτωνόταν αυτό το στοιχείο.", "bundle_column_error.retry": "Δοκίμασε ξανά", "bundle_column_error.title": "Σφάλμα δικτύου", @@ -41,7 +41,7 @@ "column.blocks": "Αποκλεισμένοι χρήστες", "column.community": "Τοπική ροή", "column.direct": "Απευθείας μηνύματα", - "column.domain_blocks": "Hidden domains", + "column.domain_blocks": "Κρυμμένοι τομείς", "column.favourites": "Αγαπημένα", "column.follow_requests": "Αιτήματα παρακολούθησης", "column.home": "Αρχική", @@ -60,7 +60,7 @@ "column_subheading.navigation": "Πλοήγηση", "column_subheading.settings": "Ρυθμίσεις", "compose_form.direct_message_warning": "Αυτό το τουτ θα εμφανίζεται μόνο σε όλους τους αναφερόμενους χρήστες.", - "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.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από καμία ταμπέλα καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά ταμπέλα.", "compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.", "compose_form.lock_disclaimer.lock": "κλειδωμένος", "compose_form.placeholder": "Τι σκέφτεσαι;", @@ -78,65 +78,65 @@ "confirmations.delete.message": "Σίγουρα θες να διαγράψεις αυτή την κατάσταση;", "confirmations.delete_list.confirm": "Διέγραψε", "confirmations.delete_list.message": "Σίγουρα θες να διαγράψεις οριστικά αυτή τη λίστα;", - "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.mute.confirm": "Mute", - "confirmations.mute.message": "Are you sure you want to mute {name}?", - "confirmations.unfollow.confirm": "Unfollow", - "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", - "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.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.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.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 instances to fill it up", - "follow_request.authorize": "Authorize", - "follow_request.reject": "Reject", - "getting_started.appsshort": "Apps", + "confirmations.domain_block.confirm": "Απόκρυψη ολόκληρου του τομέα", + "confirmations.domain_block.message": "Σίγουρα θες να μπλοκάρεις ολόκληρο το {domain}; Συνήθως μερικά εστιασμένα μπλοκ ή αποσιωπήσεις επαρκούν και προτιμούνται.", + "confirmations.mute.confirm": "Αποσιώπηση", + "confirmations.mute.message": "Σίγουρα θες να αποσιωπήσεις τον/την {name};", + "confirmations.unfollow.confirm": "Διακοπή παρακολούθησης", + "confirmations.unfollow.message": "Σίγουρα θες να πάψεις να ακολουθείς τον/την {name};", + "embed.instructions": "Ενσωματώστε αυτή την κατάσταση στην ιστοσελίδα σας αντιγράφοντας τον παρακάτω κώδικα.", + "embed.preview": "Ορίστε πως θα φαίνεται:", + "emoji_button.activity": "Δραστηριότητα", + "emoji_button.custom": "Προσαρμοσμένα", + "emoji_button.flags": "Σημαίες", + "emoji_button.food": "Φαγητά & Ποτά", + "emoji_button.label": "Εισάγετε emoji", + "emoji_button.nature": "Φύση", + "emoji_button.not_found": "Ουδέν emojo!! (╯°□°)╯︵ ┻━┻", + "emoji_button.objects": "Αντικείμενα", + "emoji_button.people": "Άνθρωποι", + "emoji_button.recent": "Δημοφιλή", + "emoji_button.search": "Αναζήτηση…", + "emoji_button.search_results": "Αποτελέσματα αναζήτησης", + "emoji_button.symbols": "Σύμβολα", + "emoji_button.travel": "Ταξίδια & Τοποθεσίες", + "empty_column.community": "Η τοπική ροή είναι κενή. Γράψε κάτι δημόσιο παραμύθι ν' αρχινίσει!", + "empty_column.direct": "Δεν έχεις απευθείας μηνύματα ακόμα. Όταν στείλεις ή λάβεις κανένα, θα εμφανιστεί εδώ.", + "empty_column.hashtag": "Δεν υπάρχει ακόμα κάτι για αυτή την ταμπέλα.", + "empty_column.home": "Η τοπική σου ροή είναι κενή! Πήγαινε στο {public} ή κάνε αναζήτηση για να ξεκινήσεις και να γνωρίσεις άλλους χρήστες.", + "empty_column.home.public_timeline": "η δημόσια ροή", + "empty_column.list": "Δεν υπάρχει τίποτα σε αυτή τη λίστα ακόμα. Όταν τα μέλη της δημοσιεύσουν νέες καταστάσεις, θα εμφανιστούν εδώ", + "empty_column.notifications": "Δεν έχεις ειδοποιήσεις ακόμα. Αλληλεπίδρασε με άλλους χρήστες για να ξεκινήσεις την κουβέντα.", + "empty_column.public": "Δεν υπάρχει τίποτα εδώ! Γράψε κάτι δημόσιο, ή ακολούθησε χειροκίνητα χρήστες από άλλα instances για να το γεμίσεις", + "follow_request.authorize": "Ενέκρινε", + "follow_request.reject": "Απέρριψε", + "getting_started.appsshort": "Εφαρμογές", "getting_started.faq": "FAQ", - "getting_started.heading": "Getting started", - "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", - "getting_started.userguide": "User Guide", - "home.column_settings.advanced": "Advanced", - "home.column_settings.basic": "Basic", - "home.column_settings.filter_regex": "Filter out by regular expressions", - "home.column_settings.show_reblogs": "Show boosts", - "home.column_settings.show_replies": "Show replies", - "home.settings": "Column settings", - "keyboard_shortcuts.back": "to navigate back", - "keyboard_shortcuts.boost": "to boost", - "keyboard_shortcuts.column": "to focus a status in one of the columns", - "keyboard_shortcuts.compose": "to focus the compose textarea", + "getting_started.heading": "Ξεκινώντας", + "getting_started.open_source_notice": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να συνεισφέρεις ή να αναφέρεις ζητήματα στο GitHub στο {github}.", + "getting_started.userguide": "Οδηγός Χρηστών", + "home.column_settings.advanced": "Προχωρημένα", + "home.column_settings.basic": "Βασικά", + "home.column_settings.filter_regex": "Φιλτράρετε μέσω regular expressions", + "home.column_settings.show_reblogs": "Εμφάνιση προωθήσεων", + "home.column_settings.show_replies": "Εμφάνιση απαντήσεων", + "home.settings": "Ρυθμίσεις στηλών", + "keyboard_shortcuts.back": "για επιστροφή πίσω", + "keyboard_shortcuts.boost": "για προώθηση", + "keyboard_shortcuts.column": "για εστίαση μιας κατάστασης σε μια από τις στήλες", + "keyboard_shortcuts.compose": "για εστίαση στην περιοχή κειμένου συγγραφής", "keyboard_shortcuts.description": "Description", - "keyboard_shortcuts.down": "to move down in the list", + "keyboard_shortcuts.down": "για κίνηση προς τα κάτω στη λίστα", "keyboard_shortcuts.enter": "to open status", - "keyboard_shortcuts.favourite": "to favourite", + "keyboard_shortcuts.favourite": "για σημείωση αγαπημένου", "keyboard_shortcuts.heading": "Keyboard Shortcuts", - "keyboard_shortcuts.hotkey": "Hotkey", - "keyboard_shortcuts.legend": "to display this legend", - "keyboard_shortcuts.mention": "to mention author", - "keyboard_shortcuts.reply": "to reply", - "keyboard_shortcuts.search": "to focus search", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", - "keyboard_shortcuts.toot": "to start a brand new toot", + "keyboard_shortcuts.hotkey": "Συντόμευση", + "keyboard_shortcuts.legend": "για να εμφανίσεις αυτόν τον οδηγό", + "keyboard_shortcuts.mention": "για να αναφέρεις το συγγραφέα", + "keyboard_shortcuts.reply": "για απάντηση", + "keyboard_shortcuts.search": "για εστίαση αναζήτησης", + "keyboard_shortcuts.toggle_hidden": "για εμφάνιση/απόκρυψη κειμένου πίσω από την προειδοποίηση", + "keyboard_shortcuts.toot": "για δημιουργία ολοκαίνουριου τουτ", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.up": "to move up in the list", "lightbox.close": "Close", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 37587c14c6..1ab6d2aa09 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -2,7 +2,7 @@ "account.block": "Bloki @{name}", "account.block_domain": "Kaŝi ĉion de {domain}", "account.blocked": "Blokita", - "account.direct": "Direct message @{name}", + "account.direct": "Rekte mesaĝi @{name}", "account.disclaimer_full": "Subaj informoj povas reflekti la profilon de la uzanto nekomplete.", "account.domain_blocked": "Domajno kaŝita", "account.edit_profile": "Redakti profilon", @@ -29,8 +29,8 @@ "account.unmute": "Malsilentigi @{name}", "account.unmute_notifications": "Malsilentigi sciigojn de @{name}", "account.view_full_profile": "Vidi plenan profilon", - "alert.unexpected.message": "An unexpected error occurred.", - "alert.unexpected.title": "Oops!", + "alert.unexpected.message": "Neatendita eraro okazis.", + "alert.unexpected.title": "Ups!", "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", @@ -40,8 +40,8 @@ "bundle_modal_error.retry": "Bonvolu reprovi", "column.blocks": "Blokitaj uzantoj", "column.community": "Loka tempolinio", - "column.direct": "Direct messages", - "column.domain_blocks": "Hidden domains", + "column.direct": "Rektaj mesaĝoj", + "column.domain_blocks": "Kaŝitaj domajnoj", "column.favourites": "Stelumoj", "column.follow_requests": "Petoj de sekvado", "column.home": "Hejmo", @@ -59,7 +59,7 @@ "column_header.unpin": "Depingli", "column_subheading.navigation": "Navigado", "column_subheading.settings": "Agordado", - "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", + "compose_form.direct_message_warning": "Tiu mesaĝo videblos nur por ĉiuj menciitaj uzantoj.", "compose_form.hashtag_warning": "Ĉi tiu mesaĝo ne estos listigita per ajna kradvorto. Nur publikaj mesaĝoj estas serĉeblaj per kradvortoj.", "compose_form.lock_disclaimer": "Via konta ne estas {locked}. Iu ajn povas sekvi vin por vidi viajn mesaĝojn, kiuj estas nur por sekvantoj.", "compose_form.lock_disclaimer.lock": "ŝlosita", @@ -101,7 +101,7 @@ "emoji_button.symbols": "Simboloj", "emoji_button.travel": "Vojaĝoj kaj lokoj", "empty_column.community": "La loka tempolinio estas malplena. Skribu ion por plenigi ĝin!", - "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.direct": "Vi ankoraŭ ne havas rektan mesaĝon. Kiam vi sendos aŭ ricevos iun, ĝi aperos ĉi tie.", "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.", "empty_column.home": "Via hejma tempolinio estas malplena! Vizitu {public} aŭ uzu la serĉilon por renkonti aliajn uzantojn.", "empty_column.home.public_timeline": "la publikan tempolinion", @@ -135,7 +135,7 @@ "keyboard_shortcuts.mention": "por mencii la aŭtoron", "keyboard_shortcuts.reply": "por respondi", "keyboard_shortcuts.search": "por fokusigi la serĉilon", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_hidden": "por montri/kaŝi tekston malantaŭ enhava averto", "keyboard_shortcuts.toot": "por komenci tute novan mesaĝon", "keyboard_shortcuts.unfocus": "por malfokusigi la tekstujon aŭ la serĉilon", "keyboard_shortcuts.up": "por iri supren en la listo", @@ -157,8 +157,8 @@ "mute_modal.hide_notifications": "Ĉu vi volas kaŝi la sciigojn el ĉi tiu uzanto?", "navigation_bar.blocks": "Blokitaj uzantoj", "navigation_bar.community_timeline": "Loka tempolinio", - "navigation_bar.direct": "Direct messages", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.direct": "Rektaj mesaĝoj", + "navigation_bar.domain_blocks": "Kaŝitaj domajnoj", "navigation_bar.edit_profile": "Redakti profilon", "navigation_bar.favourites": "Stelumoj", "navigation_bar.follow_requests": "Petoj de sekvado", @@ -242,10 +242,10 @@ "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}", "standalone.public_title": "Enrigardo…", "status.block": "Bloki @{name}", - "status.cancel_reblog_private": "Unboost", + "status.cancel_reblog_private": "Eksdiskonigi", "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas", "status.delete": "Forigi", - "status.direct": "Direct message @{name}", + "status.direct": "Rekte mesaĝi @{name}", "status.embed": "Enkorpigi", "status.favourite": "Stelumi", "status.load_more": "Ŝargi pli", @@ -258,7 +258,7 @@ "status.pin": "Alpingli profile", "status.pinned": "Alpinglita mesaĝo", "status.reblog": "Diskonigi", - "status.reblog_private": "Boost to original audience", + "status.reblog_private": "Diskonigi al la originala atentaro", "status.reblogged_by": "{name} diskonigis", "status.reply": "Respondi", "status.replyAll": "Respondi al la fadeno", @@ -276,7 +276,7 @@ "tabs_bar.home": "Hejmo", "tabs_bar.local_timeline": "Loka tempolinio", "tabs_bar.notifications": "Sciigoj", - "tabs_bar.search": "Search", + "tabs_bar.search": "Serĉi", "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", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index d4836e9fe0..c4cb996cf3 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -110,7 +110,7 @@ "empty_column.public": "I a pas res aquí ! Escrivètz quicòm de public, o seguètz de personas d’autras instàncias per garnir lo flux public", "follow_request.authorize": "Autorizar", "follow_request.reject": "Regetar", - "getting_started.appsshort": "Apps", + "getting_started.appsshort": "Aplicacions", "getting_started.faq": "FAQ", "getting_started.heading": "Per començar", "getting_started.open_source_notice": "Mastodon es un logicial liure. Podètz contribuir e mandar vòstres comentaris e rapòrt de bug via {github} sus GitHub.", @@ -158,7 +158,7 @@ "navigation_bar.blocks": "Personas blocadas", "navigation_bar.community_timeline": "Flux public local", "navigation_bar.direct": "Messatges dirèctes", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.domain_blocks": "Domenis amagats", "navigation_bar.edit_profile": "Modificar lo perfil", "navigation_bar.favourites": "Favorits", "navigation_bar.follow_requests": "Demandas d’abonament", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index e5e826c964..d69648ccff 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -231,7 +231,7 @@ "report.target": "Nahlásenie {target}", "search.placeholder": "Hľadaj", "search_popout.search_format": "Pokročilé vyhľadávanie", - "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.full_text": "Jednoduchý textový výpis statusov ktoré si napísal/a, ktoré si obľúbil/a, povýšil/a, alebo aj tých, v ktorých si bol/a spomenutý/á, a potom všetky zadaniu odpovedajúce prezívky, mená a haštagy.", "search_popout.tips.hashtag": "haštag", "search_popout.tips.status": "status", "search_popout.tips.text": "Jednoduchý text vráti zhodujúce sa mená, prezývky a hashtagy", diff --git a/config/locales/ar.yml b/config/locales/ar.yml index eb0127eb51..632bd03b03 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -4,6 +4,7 @@ ar: about_hashtag_html: هذه هي الرسائل العامة مع الكلمات الدلالية 1#%{hashtag}. يمكنك التفاعل معهم إذا كان لديك حساب في أي مكان على الإنترنت المتحد. about_mastodon_html: ماستدون شبكة إجتماعية حرة و مفتوحة المصدر. هو بديل لامركزي لمنصات تجارية ، يمكنك من تجنب احتكار شركة واحدة للإتصالات الخاصة بك. يمكنك اختيار أي خادم تثق فيه. أيهما تختار، يمكنك التفاعل مع أي شخص آخر على الشبكة. يمكن لأي شخص تنصيب و تشغيل خادم ماستدون خاص به والمشاركة في الشبكات الاجتماعية بكل شفافية. about_this: عن مثيل الخادوم هذا + administered_by: 'يديره :' closed_registrations: التسجيلات في مثيل الخادوم هذا مُغلقة حاليًا. contact: للتواصل معنا contact_missing: غير محدد @@ -58,7 +59,15 @@ ar: destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح ! accounts: are_you_sure: متأكد ؟ + avatar: الصورة الرمزية by_domain: النطاق + change_email: + changed_msg: تم تعديل عنوان البريد الإلكتروني الخاص بالحساب بنجاح ! + current_email: عنوان البريد الإلكتروني الحالي + label: تعديل عنوان البريد الإلكتروني + new_email: عنوان البريد الإلكتروني الجديد + submit: تعديل عنوان البريد الإلكتروني + title: تعديل عنوان البريد الإلكتروني الخاص بـ %{username} confirm: تأكيد confirmed: مؤكَّد confirming: التأكد @@ -108,6 +117,7 @@ ar: public: عمومي push_subscription_expires: انتهاء الاشتراك ”PuSH“ redownload: تحديث الصورة الرمزية + remove_avatar: حذف الصورة الرمزية resend_confirmation: already_confirmed: هذا المستخدم مؤكد بالفعل send: أعد إرسال رسالة البريد الالكتروني الخاصة بالتأكيد diff --git a/config/locales/ca.yml b/config/locales/ca.yml index bdc3f74844..9956c00988 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -373,6 +373,7 @@ ca: admin_mailer: new_report: body: "%{reporter} ha informat de %{target}" + body_remote: Algú des de el domini %{domain} ha informat sobre %{target} subject: Informe nou per a %{instance} (#%{id}) application_mailer: notification_preferences: Canvia les preferències de correu diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index bda26429e8..65b3b496ee 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -33,14 +33,14 @@ sk: help: native_redirect_uri: Použite %{native_redirect_uri} pre lokálne testy redirect_uri: Iba jedna URI na riadok - scopes: Rozsahy oddeľujte medzerami. Nechajte prázdne pre štandardné rozsahy. + scopes: Oprávnenia oddeľujte medzerami. Nechajte prázdne pre štandardné oprávnenia. index: application: Aplikácia callback_url: Návratová URL delete: Zmazať name: Názov new: Nová aplikácia - scopes: Rozsahy + scopes: Oprávnenia show: Ukázať title: Vaše aplikácie new: @@ -49,7 +49,7 @@ sk: actions: Akcie application_id: Kľúč klienta callback_urls: Návratové URL adresy - scopes: Rozsahy + scopes: Oprávnenia secret: Tajné slovo klienta title: 'Aplikácia: %{name}' authorizations: @@ -73,7 +73,7 @@ sk: application: Aplikácia created_at: Autorizované date_format: "%Y-%m-%d %H:%M:%S" - scopes: Rozsahy + scopes: Oprávnenia title: Vaše autorizované aplikácie errors: messages: diff --git a/config/locales/el.yml b/config/locales/el.yml index 8741635e1d..da2b7a64a8 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1,12 +1,15 @@ --- el: about: + about_hashtag_html: Αυτά είναι δημόσια τουτ σημειωμένα με #%{hashtag}. Μπορείς να αλληλεπιδράσεις με αυτά αν έχεις λογαριασμό οπουδήποτε στο fediverse. about_mastodon_html: Το Mastodon είναι ένα κοινωνικό δίκτυο που βασίζεται σε ανοιχτά δικτυακά πρωτόκολλα και ελεύθερο λογισμικό ανοιχτού κώδικα. Είναι αποκεντρωμένο όπως το e-mail. about_this: Σχετικά administered_by: 'Διαχειρίζεται από:' closed_registrations: Αυτή τη στιγμή οι εγγραφές σε αυτό τον διακομιστή είναι κλειστές. Αλλά! Μπορείς να βρεις έναν άλλο διακομιστή για να ανοίξεις λογαριασμό και να έχεις πρόσβαση από εκεί στο ίδιο ακριβώς δίκτυο. contact: Επικοινωνία contact_missing: Δεν έχει οριστεί + contact_unavailable: Μ/Δ + description_headline: Τι είναι το %{domain}; domain_count_after: άλλοι διακομιστές domain_count_before: Συνδέεται με extended_description_html: | @@ -15,9 +18,12 @@ el: features: humane_approach_body: Μαθαίνοντας από τις αποτυχίες άλλων δικτύων, το Mastodon στοχεύει να κάνει σχεδιαστικά ηθικές επιλογές για να καταπολεμήσει την κακόβουλη χρήση των κοινωνικών δικτύων. humane_approach_title: Μια πιο ανθρώπινη προσέγγιση + not_a_product_body: Το Mastodon δεν είναι εμπορικό δίκτυο. Χωρίς διαφημίσεις, χωρίς εξόρυξη δεδομένων, χωρίς φραγμένες περιοχές. Δεν έχει κεντρική αρχή. not_a_product_title: Είσαι άτομο, όχι προϊόν + real_conversation_body: Με 500 χαρακτήρες στη διάθεσή σου και υποστήριξη για λεπτομερή έλεγχο και προειδοποιήσεις πολυμέσων, μπορείς να εκφραστείς με τον τρόπο που θέλεις. real_conversation_title: Φτιαγμένο για αληθινή συζήτηση within_reach_body: Οι πολλαπλές εφαρμογές για το iOS, το Android και τις υπόλοιπες πλατφόρμες, χάρη σε ένα φιλικό προς τους προγραμματιστές οικοσύστημα API, σου επιτρέπουν να κρατάς επαφή με τους φίλους και τις φίλες σου οπουδήποτε. + within_reach_title: Πάντα προσβάσιμο generic_description: "%{domain} είναι ένας εξυπηρετητής στο δίκτυο" hosted_on: Το Mastodon φιλοξενείται στο %{domain} learn_more: Μάθε περισσότερα @@ -26,6 +32,7 @@ el: status_count_after: καταστάσεις status_count_before: Ποιός συνέγραψε user_count_after: χρήστες + user_count_before: Σπίτι what_is_mastodon: Τι είναι το Mastodon; accounts: follow: Ακολούθησε @@ -38,3 +45,163 @@ el: people_who_follow: Χρήστες που ακολουθούν τον/την %{name} posts: Τουτ posts_with_replies: Τουτ και απαντήσεις + remote_follow: Απομακρυσμένη παρακολούθηση + reserved_username: Το όνομα χρήστη είναι κατειλημμένο + roles: + admin: Διαχειριστής + moderator: Μεσολαβητής + unfollow: Διακοπή παρακολούθησης + admin: + account_moderation_notes: + create: Δημιουργία + created_msg: Επιτυχής δημιουργία σημειώματος μεσολάβησης! + delete: Διαγραφή + destroyed_msg: Επιτυχής καταστροφή σημειώματος μεσολάβησης! + accounts: + are_you_sure: Σίγουρα; + avatar: Αβατάρ + by_domain: Τομέας + change_email: + changed_msg: Επιτυχής αλλαγή email λογαριασμού! + current_email: Τρέχον email + label: Αλλαγή email + new_email: Νέο email + submit: Αλλαγή email + title: Αλλαγή email για %{username} + confirm: Επιβεβαίωση + confirmed: Επιβεβαιώθηκε + demote: Υποβίβαση + disable: Απενεργοποίηση + disable_two_factor_authentication: Απενεργοποίηση 2FA + disabled: Απενεργοποιημένο + display_name: Όνομα εμφάνισης + domain: Τομέας + edit: Αλλαγή + email: Email + enable: Ενεργοποίηση + enabled: Ενεργοποιημένο + feed_url: URL ροής + followers: Ακόλουθοι + followers_url: URL ακολούθων + follows: Ακολουθεί + inbox_url: URL εισερχομένων + ip: IP + location: + all: Όλα + local: Τοπικά + remote: Απομακρυσμένα + title: Τοποθεσία + login_status: Κατάσταση εισόδου + media_attachments: Συνημμένα πολυμέσα + memorialize: Μετατροπή σε νεκρολογία + moderation: + all: Όλα + silenced: Αποσιωπημένα + suspended: Σε αναστολή + title: Μεσολάβηση + moderation_notes: Σημειώσεις μεσολάβησης + most_recent_activity: Πιο πρόσφατη δραστηριότητα + most_recent_ip: Πιο πρόσφατη IP + not_subscribed: Άνευ εγγραφής + order: + alphabetic: Αλφαβητικά + most_recent: Πιο πρόσφατα + title: Ταξινόμηση + outbox_url: URL εξερχομένων + perform_full_suspension: Πλήρης αναστολή + profile_url: URL προφίλ + promote: Προβίβασε + protocol: Πρωτόκολλο + public: Δημόσιο + push_subscription_expires: Η εγγραφή PuSH λήγει + redownload: Ανανέωση αβατάρ + remove_avatar: Απομακρυσμένο αβατάρ + reset: Επαναφορά + reset_password: Επαναφορά συνθηματικού + resubscribe: Επανεγγραφή + role: Δικαιώματα + roles: + admin: Διαχειριστής + moderator: Μεσολαβητής + staff: Προσωπικό + user: Χρήστης + salmon_url: URL Salmon + search: Αναζήτηση + shared_inbox_url: URL κοινόχρηστων εισερχομένων + show: + created_reports: Αναφορές από αυτόν το λογαριασμό + report: ανάφερε + targeted_reports: Αναφορές για αυτόν το λογαριασμό + silence: Αποσιώπησε + statuses: Καταστάσεις + subscribe: Εγγραφή + title: Λογαριασμοί + unconfirmed_email: Ανεπιβεβαίωτο email + undo_silenced: Αναίρεση αποσιώπησης + undo_suspension: Αναίρεση παύσης + unsubscribe: Κατάργηση εγγραφής + username: Όνομα χρήστη + web: Διαδίκτυο + action_logs: + actions: + assigned_to_self_report: Ο/Η %{name} ανάθεσε την αναφορά %{target} στον εαυτό του/της + change_email_user: Ο/Η %{name} άλλαξε τη διεύθυνση email του χρήστη %{target} + confirm_user: Ο/Η %{name} επιβεβαίωσε τη διεύθυνση email του χρήστη %{target} + create_custom_emoji: Ο/Η %{name} ανέβασε νέο emoji %{target} + create_domain_block: Ο/Η %{name} μπλόκαρε τον τομέα %{target} + create_email_domain_block: Ο/Η %{name} έβαλε τον τομέα email %{target} σε μαύρη λίστα + demote_user: Ο/Η %{name} υποβίβασε το χρήστη %{target} + destroy_domain_block: Ο/Η %{name} ξεμπλόκαρε τον τομέα %{target} + destroy_email_domain_block: Ο/Η %{name} έβαλε τον τομέα email %{target} σε λευκή λίστα + destroy_status: Ο/Η %{name} αφαίρεσε την κατάσταση του/της %{target} + disable_2fa_user: Ο/Η %{name} απενεργοποίησε την απαίτηση δύο παραγόντων για το χρήστη %{target} + disable_custom_emoji: Ο/Η %{name} απενεργοποίησε το emoji %{target} + disable_user: Ο/Η %{name} απενεργοποίησε την είσοδο για το χρήστη %{target} + enable_custom_emoji: Ο/Η %{name} ενεργοποίησε το emoji %{target} + enable_user: Ο/Η %{name} ενεργοποίησε την είσοδο του χρήστη %{target} + memorialize_account: Ο/Η %{name} μετέτρεψε το λογαριασμό του/της %{target} σε σελίδα νεκρολογίας + promote_user: Ο/Η %{name} προβίβασε το χρήστη %{target} + remove_avatar_user: Ο/Η %{name} αφαίρεσε το αβατάρ του/της %{target} + reopen_report: Ο/Η %{name} ξανάνοιξε την αναφορά %{target} + reset_password_user: Ο/Η %{name} επανέφερε το συνθηματικό του χρήστη %{target} + resolve_report: Ο/Η %{name} επέλυσε την αναφορά %{target} + silence_account: Ο/Η %{name} αποσιώπησε το λογαριασμό του/της %{target} + suspend_account: Ο/Η %{name} έπαυσε το λογαριασμό του/της %{target} + unassigned_report: Ο/Η %{name} αποδέσμευσε την αναφορά %{target} + unsilence_account: Ο/Η %{name} ήρε την αποσιώπηση του λογαριασμού του/της %{target} + unsuspend_account: Ο/Η %{name} ήρε την παύση του λογαριασμού του χρήστη %{target} + update_custom_emoji: Ο/Η %{name} ενημέρωσε το emoji %{target} + update_status: Ο/Η %{name} ενημέρωσε την κατάσταση του/της %{target} + title: Αρχείο ελέγχου + custom_emojis: + by_domain: Τομέας + copied_msg: Επιτυχής δημιουργία τοπικού αντίγραφου του emoji + copy: Αντιγραφή + copy_failed_msg: Αδυναμία δημιουργίας τοπικού αντίγραφου αυτού του emoji + created_msg: Επιτυχής δημιουργία του emoji! + delete: Διαγραφή + destroyed_msg: Επιτυχής καταστροφή του emojo! + disable: Απενεργοποίηση + disabled_msg: Επιτυχής απενεργοποίηση αυτού του emoji + emoji: Emoji + enable: Ενεργοποίηση + enabled_msg: Επιτυχής ενεργοποίηση αυτού του emoji + image_hint: PNG έως 50KB + listed: Αναφερθέντα + new: + title: Προσθήκη νέου προσαρμοσμένου emoji + overwrite: Αντικατάσταση + shortcode: Σύντομος κωδικός + shortcode_hint: Τουλάχιστον 2 χαρακτήρες, μόνο αλφαριθμητικοί και κάτω παύλες + title: Προσαρμοσμένα emoji + update_failed_msg: Αδυναμία ενημέρωσης του emoji + updated_msg: Επιτυχής ενημέρωση του Emoji! + upload: Ανέβασμα + domain_blocks: + add_new: Προσθήκη νέου + created_msg: Ο αποκλεισμός τομέα είναι υπό επεξεργασία + destroyed_msg: Ο αποκλεισμός τομέα άρθηκε + domain: Τομέας + new: + create: Δημιουργία αποκλεισμού + hint: Ο αποκλεισμός τομέα δεν θα αποτρέψει νέες καταχωρίσεις λογαριασμών στην βάση δεδομένων, αλλά θα εφαρμόσει αναδρομικά και αυτόματα συγκεκριμένες πολιτικές μεσολάβησης σε αυτούς τους λογαριασμούς. diff --git a/config/locales/es.yml b/config/locales/es.yml index 11bee3239b..593716b169 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -373,6 +373,7 @@ es: admin_mailer: new_report: body: "%{reporter} ha reportado a %{target}" + body_remote: Alguien de %{domain} a reportado a %{target} subject: Nuevo reporte para la %{instance} (#%{id}) application_mailer: notification_preferences: Cambiar preferencias de correo electrónico diff --git a/config/locales/gl.yml b/config/locales/gl.yml index e00c4b4333..e676fe8374 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -19,8 +19,8 @@ gl: humane_approach_body: Aprendendo dos erros de outras redes, Mastodon intenta tomar decisións éticas de deseño para loitar contra os usos incorrectos da rede. humane_approach_title: Unha aproximación máis humana not_a_product_body: Mastodon non é unha rede comercial. Sen anuncios, sen minería de datos, sen xardíns privados. Non hai autoridade centralizada. - not_a_product_title: Vostede é unha persona, non un producto - real_conversation_body: Con 500 caracteres a súa disposición e soporte para contido ao por menor e avisos sobre o contido, pode expresarse vostede do xeito que queira. + not_a_product_title: Vostede é unha persoa, non un producto + real_conversation_body: Con 500 caracteres a súa disposición, soporte para contido polo miúdo e avisos sobre o contido, pode expresarse vostede con libertade. real_conversation_title: Construído para conversacións reais within_reach_body: Existen múltiples aplicativos para iOS, Android e outras plataformas grazas a un entorno API amigable para o desenvolvedor que lle permite estar ao tanto cos seus amigos en calquer lugar. within_reach_title: Sempre en contacto @@ -373,6 +373,7 @@ gl: admin_mailer: new_report: body: "%{reporter} informou sobre %{target}" + body_remote: Alguén desde %{domain} informou sobre %{target} subject: Novo informe sobre %{instance} (#%{id}) application_mailer: notification_preferences: Cambiar os axustes de correo-e diff --git a/config/locales/it.yml b/config/locales/it.yml index eafe6b2a17..b53645c9fd 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -143,6 +143,17 @@ it: confirm_user: "%{name} ha confermato l'indirizzo email per l'utente %{target}" create_custom_emoji: "%{name} ha caricato un nuovo emoji %{target}" create_domain_block: "%{name} ha bloccato il dominio %{target}" + disable_custom_emoji: "%{name} ha disabilitato l'emoji %{target}" + disable_user: "%{name} ha disabilitato il login per l'utente %{target}" + enable_custom_emoji: "%{name} ha abilitato l'emoji %{target}" + enable_user: "%{name} ha abilitato il login per l'utente %{target}" + remove_avatar_user: "%{name} ha eliminato l'avatar di %{target}" + reset_password_user: "%{name} ha reimpostato la password dell'utente %{target}" + silence_account: "%{name} ha silenziato l'account di %{target}" + suspend_account: "%{name} ha sospeso l'account di %{target}" + unsilence_account: "%{name} ha de-silenziato l'account di %{target}" + unsuspend_account: "%{name} ha annullato la sospensione dell'account di %{target}" + update_custom_emoji: "%{name} ha aggiornato l'emoji %{target}" custom_emojis: by_domain: Dominio copied_msg: Creata con successo una copia locale dell'emoji @@ -162,6 +173,7 @@ it: title: Aggiungi nuovo emoji personalizzato overwrite: Sovrascrivi shortcode: Shortcode + shortcode_hint: Almeno due caratteri, solo caratteri alfanumerici e trattino basso title: Emoji personalizzate unlisted: Non elencato update_failed_msg: Impossibile aggiornare questa emojii @@ -185,6 +197,13 @@ it: suspend: Sospendi severity: Severità show: + affected_accounts: + one: Interessato un solo account nel database + other: Interessati %{count} account nel database + retroactive: + silence: De-silenzia tutti gli account esistenti da questo dominio + suspend: Annulla la sospensione di tutti gli account esistenti da questo dominio + title: Annulla il blocco del dominio per %{domain} undo: Annulla title: Blocchi dominio undo: Annulla @@ -238,12 +257,19 @@ it: view: Mostra settings: activity_api_enabled: + desc_html: Conteggi degli status pubblicati localmente, degli utenti attivi e delle nuove registrazioni in gruppi settimanali title: Pubblica statistiche aggregate circa l'attività dell'utente + bootstrap_timeline_accounts: + title: Seguiti predefiniti per i nuovi utenti contact_information: username: Nome utente del contatto peers_api_enabled: + desc_html: Nomi di dominio che questa istanza ha incontrato nella fediverse title: Pubblica elenco di istanze scoperte registrations: + closed_message: + desc_html: Mostrato nella pagina iniziale quando le registrazioni sono chiuse. Puoi usare tag HTML + title: Messaggio per registrazioni chiuse deletion: desc_html: Consenti a chiunque di cancellare il proprio account title: Apri la cancellazione dell'account @@ -251,6 +277,9 @@ it: disabled: Nessuno open: desc_html: Consenti a chiunque di creare un account + title: Apri registrazioni + show_known_fediverse_at_about_page: + desc_html: Quando attivato, mostra nell'anteprima i toot da tutte le istanze conosciute. Altrimenti mostra solo i toot locali. show_staff_badge: title: Mostra badge staff site_description: @@ -262,6 +291,7 @@ it: title: Anteprima timeline title: Impostazioni sito statuses: + back_to_account: Torna alla pagina dell'account batch: delete: Elimina nsfw_off: NSFW OFF @@ -270,6 +300,7 @@ it: media: title: Media no_media: Nessun media + title: Gli status dell'account with_media: con media subscriptions: callback_url: URL Callback @@ -288,16 +319,23 @@ it: created: Applicazione creata con successo destroyed: Applicazione eliminata con successo invalid_url: L'URL fornito non è valido + regenerate_token: Rigenera token di accesso + token_regenerated: Token di accesso rigenerato + warning: Fa' molta attenzione con questi dati. Non fornirli mai a nessun altro! auth: + agreement_html: Iscrivendoti, accetti di seguire le regole dell'istanza e le nostre condizioni di servizio. change_password: Password confirm_email: Conferma email delete_account: Elimina account + delete_account_html: Se desideri cancellare il tuo account, puoi farlo qui. Ti sarà chiesta conferma. didnt_get_confirmation: Non hai ricevuto le istruzioni di conferma? forgot_password: Hai dimenticato la tua password? login: Entra logout: Logout migrate_account: Sposta ad un account differente + migrate_account_html: Se vuoi che questo account sia reindirizzato a uno diverso, puoi configurarlo qui. or: o + or_log_in_with: Oppure accedi con register: Iscriviti register_elsewhere: Iscriviti su un altro server resend_confirmation: Invia di nuovo le istruzioni di conferma @@ -308,6 +346,11 @@ it: already_following: Stai già seguendo questo account error: Sfortunatamente c'è stato un errore nel consultare l'account remoto follow: Segui + follow_request: 'Hai mandato una richiesta di diventare seguace a:' + following: 'Accettato! Ora stai seguendo:' + post_follow: + close: Oppure puoi chiudere questa finestra. + return: Torna al profilo dell'utente title: Segui %{acct} datetime: distance_in_words: @@ -323,11 +366,41 @@ it: x_minutes: "%{count} minuti" x_months: "%{count} mesi" x_seconds: "%{count} secondi" + deletes: + bad_password_msg: Ci avete provato, hacker! Password errata + confirm_password: Inserisci la tua password attuale per verificare la tua identità + description_html: Questa azione eliminerà in modo permanente e irreversibile tutto il contenuto del tuo account e lo disattiverà. Il tuo nome utente resterà riservato per prevenire che qualcuno in futuro assuma la tua identità. + proceed: Cancella l'account + success_msg: Il tuo account è stato cancellato + warning_html: È garantita solo la cancellazione del contenuto solo da questa istanza. I contenuti che sono stati ampiamente condivisi probabilmente lasceranno delle tracce. I server offline e quelli che non ricevono più i tuoi aggiornamenti non aggiorneranno i loro database. + errors: + '403': Non sei autorizzato a visualizzare questa pagina. + '404': La pagina che stavi cercando non esiste. + '410': La pagina che stavi cercando non esiste più. + '422': + content: Verifica di sicurezza non riuscita. Stai bloccando i cookies? + title: Verifica di sicurezza non riuscita + noscript_html: Per usare l'interfaccia web di Mastodon dovi abilitare JavaScript. In alternativa puoi provare una delle app native per Mastodon per la tua piattaforma. exports: + archive_takeout: + date: Data + download: Scarica il tuo archivio + hint_html: Puoi richiedere un archivio dei tuoi toot e media caricati. I dati esportati sono in formato ActivityPub, leggibili da qualunque software che segue questo standard. + in_progress: Creazione archivio... + request: Richiedi il tuo archivio + size: Dimensioni blocks: Stai bloccando csv: CSV follows: Stai seguendo + mutes: Stai silenziando storage: Archiviazione media + followers: + domain: Dominio + explanation_html: Se vuoi garantire la privacy dei tuoi status, devi sapere chi ti sta seguendo. I tuoi status privati vengono inviati a tutte le istanze su cui hai dei seguaci. Puoi controllare chi sono i tuoi seguaci, ed eliminarli se non hai fiducia che la tua privacy venga rispettata dallo staff o dal software di quelle istanze. + followers_count: Numero di seguaci + purge: Elimina dai seguaci + true_privacy_html: Tieni presente che l'effettiva riservatezza si può ottenere solo con la crittografia end-to-end. + unlocked_warning_html: Chiunque può seguirti per vedere immediatamente i tuoi status privati. %{lock_link} per poter esaminare e respingere gli utenti che vogliono seguirti. generic: changes_saved_msg: Modifiche effettuate con successo! powered_by: offerto da %{link} @@ -341,38 +414,76 @@ it: types: blocking: Lista dei bloccati following: Lista dei seguaci + muting: Lista dei silenziati upload: Carica + in_memoriam_html: In Memoriam. + invites: + delete: Disattiva + expired: Scaduto + expires_in: + '1800': 30 minuti + '21600': 6 ore + '3600': 1 ora + '43200': 12 ore + '604800': 1 settimana + '86400': 1 giorno + expires_in_prompt: Mai + generate: Genera + max_uses_prompt: Nessun limite + prompt: Genera dei link e forniscili ad altri per concedere l'accesso a questa istanza + table: + expires_at: Scade + title: Invita persone landing_strip_html: "%{name} è un utente su %{link_to_root_path}. Puoi seguirlo o interagire con lui se possiedi un account ovunque nel fediverse." landing_strip_signup_html: Se non possiedi un account, puoi iscriverti qui. + lists: + errors: + limit: Hai raggiunto il numero massimo di liste media_attachments: validations: images_and_video: Impossibile allegare video a un post che contiene già immagini too_many: Impossibile allegare più di 4 file + migrations: + acct: utente@dominio del nuovo account + currently_redirecting: 'Il tuo profilo sarà ridirezionato a:' + proceed: Salva + updated_msg: L'impostazione per la migrazione dell'account è sta aggiornata! + moderation: + title: Moderazione notification_mailer: digest: + action: Vedi tutte le notifiche body: 'Ecco un breve riassunto di quello che ti sei perso su %{instance} dalla tua ultima visita del %{since}:' mention: "%{name} ti ha menzionato:" new_followers_summary: - one: Hai ricevuto un nuovo seguace! Urrà! - other: Hai ricevuto %{count} nuovi seguaci! Incredibile! + one: E inoltre hai ricevuto un nuovo seguace mentre eri assente! Urrà! + other: Inoltre, hai acquisito %{count} nuovi seguaci mentre eri assente! Incredibile! subject: one: "1 nuova notifica dalla tua ultima visita \U0001F418" other: "%{count} nuove notifiche dalla tua ultima visita \U0001F418" + title: In tua assenza… favourite: body: 'Il tuo status è stato apprezzato da %{name}:' subject: "%{name} ha apprezzato il tuo status" + title: Nuovo preferito follow: body: "%{name} ti sta seguendo!" subject: "%{name} ti sta seguendo" + title: Nuovo seguace follow_request: + action: Gestisci richieste di essere seguito body: "%{name} ha chiesto di seguirti" subject: 'Seguace in sospeso: %{name}' + title: Nuova richiesta di essere seguito mention: + action: Rispondi body: 'Sei stato menzionato da %{name} su:' subject: Sei stato menzionato da %{name} + title: Nuova menzione reblog: body: 'Il tuo status è stato condiviso da %{name}:' subject: "%{name} ha condiviso il tuo status" + title: Nuova condivisione number: human: decimal_units: @@ -385,35 +496,82 @@ it: trillion: T unit: '' pagination: + newer: Più recente next: Avanti + older: Più vecchio prev: Indietro truncate: "…" + preferences: + languages: Lingue + other: Altro + publishing: Pubblicazione + web: Web + push_notifications: + favourite: + title: "%{name} ha segnato il tuo status come apprezzato" + follow: + title: "%{name} ha iniziato a seguirti" + group: + title: "%{count} notifiche" + mention: + action_expand: Mostra altro + action_favourite: Apprezzato + reblog: + title: "%{name} ha condiviso il tuo status" remote_follow: acct: Inserisci il tuo username@dominio da cui vuoi seguire questo utente missing_resource: Impossibile trovare l'URL di reindirizzamento richiesto per il tuo account proceed: Conferma prompt: 'Stai per seguire:' + remote_unfollow: + error: Errore + title: Titolo + sessions: + browser: Browser + browsers: + blackberry: Blackberry + current_session: Sessione corrente + description: "%{browser} su %{platform}" + platforms: + other: piattaforma sconosciuta settings: authorized_apps: Applicazioni autorizzate back: Torna a Mastodon + delete: Cancellazione account + development: Sviluppo edit_profile: Modifica profilo export: Esporta impostazioni + followers: Seguaci autorizzati import: Importa + migrate: Migrazione dell'account + notifications: Notifiche preferences: Preferenze settings: Impostazioni - two_factor_authentication: Autenticazione a Due Fattori + two_factor_authentication: Autenticazione a due fattori + your_apps: Le tue applicazioni statuses: open_in_web: Apri sul Web over_character_limit: Limite caratteri superato di %{max} + pin_errors: + limit: Hai già fissato in cima il massimo numero di toot + ownership: Non puoi fissare in cima un toot di qualcun altro + private: Un toot non pubblico non può essere fissato in cima + reblog: Un toot condiviso non può essere fissato in cima show_more: Mostra di più visibilities: private: Mostra solo ai tuoi seguaci + private_long: Mostra solo ai seguaci public: Pubblico + public_long: Tutti lo possono vedere unlisted: Pubblico, ma non visibile sulla timeline pubblica + unlisted_long: Tutti lo possono vedere, ma non compare nelle timeline pubbliche stream_entries: click_to_show: Clicca per mostrare + pinned: Toot fissato in cima reblogged: condiviso sensitive_content: Materiale sensibile + themes: + contrast: Contrasto elevato time: formats: default: "%b %d, %Y, %H:%M" @@ -422,15 +580,39 @@ it: description_html: Se abiliti l'autorizzazione a due fattori, entrare nel tuo account ti richiederà di avere vicino il tuo telefono, il quale ti genererà un codice per eseguire l'accesso. disable: Disabilita enable: Abilita + enabled: È abilitata l'autenticazione a due fattori enabled_success: Autenticazione a due fattori attivata con successo + generate_recovery_codes: Genera codici di recupero instructions_html: "Scannerizza questo QR code con Google Authenticator o un'app TOTP simile sul tuo telefono. Da ora in poi, quell'applicazione genererà codici da inserire necessariamente per eseguire l'accesso." + lost_recovery_codes: I codici di recupero ti permettono di accedere al tuo account se perdi il telefono. Se hai perso i tuoi codici di recupero, puoi rigenerarli qui. Quelli vecchi saranno annullati. manual_instructions: 'Se non puoi scannerizzare il QR code e hai bisogno di inserirlo manualmente, questo è il codice segreto in chiaro:' + recovery_codes_regenerated: I codici di recupero sono stati rigenerati + recovery_instructions_html: Se perdi il telefono, puoi usare uno dei codici di recupero qui sotto per riottenere l'accesso al tuo account. Conserva i codici di recupero in un posto sicuro. Ad esempio puoi stamparli e conservarli insieme ad altri documenti importanti. setup: Configura wrong_code: Il codice inserito non è corretto! Assicurati che l'orario del server e l'orario del telefono siano corretti. user_mailer: + backup_ready: + explanation: Hai richiesto un backup completo del tuo account Mastodon. È pronto per essere scaricato! + subject: Il tuo archivio è pronto per essere scaricato + title: Esportazione archivio welcome: + edit_profile_step: Puoi personalizzare il tuo profilo caricando un avatar, un'intestazione, modificando il tuo nome visualizzato e così via. Se vuoi controllare i tuoi nuovi seguaci prima di autorizzarli a seguirti, puoi bloccare il tuo account. + explanation: Ecco alcuni suggerimenti per iniziare + final_action: Inizia a postare + final_step: 'Inizia a postare! Anche se non hai seguaci, i tuoi messaggi pubblici possono essere visti da altri, ad esempio nelle timeline locali e negli hashtag. Se vuoi puoi presentarti con l''hashtag #introductions.' + full_handle: Il tuo nome utente completo + full_handle_hint: Questo è ciò che diresti ai tuoi amici in modo che possano seguirti o contattarti da un'altra istanza. + review_preferences_action: Cambia preferenze + review_preferences_step: Dovresti impostare le tue preferenze, ad esempio quali email vuoi ricevere oppure il livello predefinito di privacy per i tuoi post. Se le immagini in movimento non ti danno fastidio, puoi abilitare l'animazione automatica delle GIF. + subject: Benvenuto/a su Mastodon + tip_bridge_html: Se vieni da Twitter, puoi trovare i tuoi amici su Mastodon usando laapp bridge. Ma funziona solo se anche loro la usano! + tip_federated_timeline: La timeline federata visualizza uno dopo l'altro i messaggi pubblicati su Mastodon. Ma comprende solo gli utenti seguiti dai tuoi vicini, quindi non è completa. + tip_following: Per impostazione predefinita, segui l'amministratore/i del tuo server. Per trovare utenti più interessanti, dà un'occhiata alle timeline locale e federata. + tip_local_timeline: La timeline locale visualizza uno dopo l'altro i messaggi degli utenti di %{instance}. Questi sono i tuoi vicini! + tip_mobile_webapp: Se il tuo browser mobile ti dà la possibilità di aggiungere Mastodon allo schermo, puoi ricevere le notifiche. Funziona un po' come un'app natova! tips: Suggerimenti title: Benvenuto a bordo, %{name}! users: invalid_email: L'indirizzo email inserito non è valido invalid_otp_token: Codice d'accesso non valido + seamless_external_login: Ti sei collegato per mezzo di un servizio esterno, quindi le impostazioni di email e password non sono disponibili. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index c7025fc186..83283a3771 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -373,6 +373,7 @@ ja: admin_mailer: new_report: body: "%{reporter} が %{target} を通報しました" + body_remote: "%{domain} の誰かが %{target} を通報しました" subject: "%{instance} の新しい通報 (#%{id})" application_mailer: notification_preferences: メール設定の変更 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 6ca81b3757..44ad1ed6d8 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -373,6 +373,7 @@ nl: admin_mailer: new_report: body: "%{reporter} heeft %{target} gerapporteerd" + body_remote: Iemand van %{domain} heeft %{target} gerapporteerd subject: Nieuwe toots gerapporteerd op %{instance} (#%{id}) application_mailer: notification_preferences: E-mailvoorkeuren wijzigen diff --git a/config/locales/oc.yml b/config/locales/oc.yml index e61f7ebd00..82c8eacbb2 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -49,7 +49,7 @@ oc: reserved_username: Aqueste nom d’utilizaire es reservat roles: admin: Admin - moderator: Mod + moderator: Moderador unfollow: Quitar de sègre admin: account_moderation_notes: @@ -128,7 +128,7 @@ oc: role: Permissions roles: admin: Administrator - moderator: Moderator + moderator: Moderador staff: Personnal user: Uitlizaire salmon_url: URL Salmon @@ -168,10 +168,12 @@ oc: memorialize_account: "%{name} transformèt en memorial la pagina de perfil a %{target}" promote_user: "%{name} promoguèt %{target}" remove_avatar_user: "%{name} suprimèt l’avatar a %{target}" + reopen_report: "%{name} tornèt dobrir lo rapòrt %{target}" reset_password_user: "%{name} reïnicializèt lo senhal a %{target}" - resolve_report: "%{name} anullèt lo rapòrt de %{target}" + resolve_report: "%{name} anullèt lo rapòrt %{target}" silence_account: "%{name} metèt en silenci lo compte a %{target}" suspend_account: "%{name} susprenguèt lo compte a %{target}" + unassigned_report: "%{name} daissèt de tractar lo rapòrt %{target}" unsilence_account: "%{name} levèt lo silenci del compte a %{target}" unsuspend_account: "%{name} restabliguèt lo compte a %{target}" update_custom_emoji: "%{name} metèt a jorn l’emoji %{target}" @@ -266,6 +268,8 @@ oc: report: rapòrt action_taken_by: Mesura menada per are_you_sure: Es segur ? + assign_to_self: Me l’assignar + assigned: Moderador assignat comment: none: Pas cap created_at: Creacion @@ -283,12 +287,15 @@ oc: reported_account: Compte senhalat reported_by: Senhalat per resolved: Resolgut + resolved_msg: Rapòrt corrèctament resolgut  ! silence_account: Metre lo compte en silenci status: Estatut suspend_account: Suspendre lo compte target: Cibla title: Senhalament + unassign: Levar unresolved: Pas resolguts + updated_at: Actualizat view: Veire settings: activity_api_enabled: @@ -346,8 +353,8 @@ oc: back_to_account: Tornar a la pagina Compte batch: delete: Suprimir - nsfw_off: NSFW OFF - nsfw_on: NSFW ON + nsfw_off: Marcar coma pas sensible + nsfw_on: Marcar coma sensible failed_to_execute: Fracàs media: title: Mèdia @@ -487,9 +494,7 @@ oc: less_than_x_minutes: one: Fa mens d’una minuta other: Fa mens de %{count} minutas - less_than_x_seconds: - one: Fa mens d’una segonda - other: Fa mens de %{count} segondas + less_than_x_seconds: Ara meteis over_x_years: one: Fa mai d’un an other: Fa mai de %{count} ans @@ -700,7 +705,7 @@ oc: micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser opera: Opera - otter: Otter + otter: Autre phantom_js: PhantomJS qq: QQ Browser safari: Safari @@ -750,6 +755,7 @@ oc: video: one: "%{count} vidèo" other: "%{count} vidèos" + content_warning: 'Avertiment de contengut : %{warning}' disallowed_hashtags: one: 'conten una etiqueta desactivada : %{tags}' other: 'conten las etiquetas desactivadas : %{tags}' diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 1fbe0d5c8f..0d107ed53a 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -374,6 +374,7 @@ pl: admin_mailer: new_report: body: Użytkownik %{reporter} zgłosił %{target} + body_remote: Ktoś z %{domain} zgłosił %{target} subject: Nowe zgłoszenie na %{instance} (#%{id}) application_mailer: notification_preferences: Zmień ustawienia e-maili diff --git a/config/locales/simple_form.oc.yml b/config/locales/simple_form.oc.yml index 4ca58c1023..c80f85cce2 100644 --- a/config/locales/simple_form.oc.yml +++ b/config/locales/simple_form.oc.yml @@ -41,7 +41,7 @@ oc: header: Bandièra locale: Lenga locked: Far venir lo compte privat - max_uses: Limit d’utilizacion + max_uses: Limit d’utilizacions new_password: Nòu senhal note: Bio otp_attempt: Còdi Two-factor diff --git a/config/locales/sk.yml b/config/locales/sk.yml index ef756b474e..033019e0b4 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -1,7 +1,7 @@ --- sk: about: - about_hashtag_html: Toto sú verejné toot príspevky otagované #%{tagom}. Ak máš účet niekde vo fediverse, môžeš ich používať. + about_hashtag_html: Toto sú verejné toot príspevky otagované #%{hashtag}. Ak máš účet niekde vo fediverse, môžeš ich používať. about_mastodon_html: Mastodon je sociálna sieť založená na otvorených webových protokoloch. Jej zrojový kód je otvorený a je decentralizovaná podobne ako email. about_this: O tejto instancii administered_by: 'Správca je:' @@ -635,10 +635,10 @@ sk: title: Sezóna settings: authorized_apps: Autorizované aplikácie - back: Späť do Mastodonu - delete: Zmazanie účtu + back: Späť na Mastodon + delete: Vymazanie účtu development: Vývoj - edit_profile: Upraviť profil + edit_profile: Uprav profil export: Exportovať dáta followers: Povolení sledovatelia import: Importovať diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index c5d8c86968..a5f6a960a5 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -227,6 +227,7 @@ zh-HK: severity: 阻隔分級 show: affected_accounts: + one: 資料庫中有 %{count} 個用戶受影響 other: 資料庫中有%{count}個用戶受影響 retroactive: silence: 對此域名的所有用戶取消靜音 @@ -372,6 +373,7 @@ zh-HK: admin_mailer: new_report: body: "%{reporter} 舉報了用戶 %{target}。" + body_remote: 來自 %{domain} 的用戶舉報了用戶 %{target} subject: 來自 %{instance} 的用戶舉報(#%{id}) application_mailer: notification_preferences: 更改電郵首選項 @@ -510,7 +512,9 @@ zh-HK: '86400': 1 天後 expires_in_prompt: 永不過期 generate: 生成邀請連結 - max_uses: "%{count} 次" + max_uses: + one: 1 次 + other: "%{count} 次" max_uses_prompt: 無限制 prompt: 生成分享連結,邀請他人在本服務站註冊 table: @@ -577,7 +581,6 @@ zh-HK: quadrillion: Q thousand: K trillion: T - unit: '' pagination: newer: 較新 next: 下一頁 @@ -669,9 +672,16 @@ zh-HK: statuses: attached: description: 附件: %{attached} - image: "%{count} 張圖片" - video: "%{count} 段影片" + image: + one: "%{count} 幅圖片" + other: "%{count} 幅圖片" + video: + one: "%{count} 段影片" + other: "%{count} 段影片" content_warning: 'Content warning: %{warning}' + disallowed_hashtags: + one: 包含不允許的標籤: %{tags} + other: 包含不允許的標籤: %{tags} open_in_web: 開啟網頁 over_character_limit: 超過了 %{max} 字的限制 pin_errors: @@ -695,6 +705,9 @@ zh-HK: sensitive_content: 敏感內容 terms: title: "%{instance} 使用條款和隱私權政策" + themes: + contrast: 高對比 + default: 萬象 time: formats: default: "%Y年%-m月%d日 %H:%M" From 520f3a28fc4acb540a7840121d380aad9f96629a Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 6 May 2018 20:38:17 +0200 Subject: [PATCH 021/239] Various improvements to the report UI (#7342) * Also display replies in report modal * Allow report modal to be up to 80% of viewport height * Use narrow no-break space where needed in the French translation --- .../features/ui/components/report_modal.js | 6 ++--- app/javascript/mastodon/locales/fr.json | 24 +++++++++---------- .../styles/mastodon/components.scss | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js index 8a55c553c1..8616f0315c 100644 --- a/app/javascript/mastodon/features/ui/components/report_modal.js +++ b/app/javascript/mastodon/features/ui/components/report_modal.js @@ -30,7 +30,7 @@ const makeMapStateToProps = () => { account: getAccount(state, accountId), comment: state.getIn(['reports', 'new', 'comment']), forward: state.getIn(['reports', 'new', 'forward']), - statusIds: OrderedSet(state.getIn(['timelines', `account:${accountId}`, 'items'])).union(state.getIn(['reports', 'new', 'status_ids'])), + statusIds: OrderedSet(state.getIn(['timelines', `account:${accountId}:with_replies`, 'items'])).union(state.getIn(['reports', 'new', 'status_ids'])), }; }; @@ -64,12 +64,12 @@ export default class ReportModal extends ImmutablePureComponent { } componentDidMount () { - this.props.dispatch(expandAccountTimeline(this.props.account.get('id'))); + this.props.dispatch(expandAccountTimeline(this.props.account.get('id'), { withReplies: true })); } componentWillReceiveProps (nextProps) { if (this.props.account !== nextProps.account && nextProps.account) { - this.props.dispatch(expandAccountTimeline(nextProps.account.get('id'))); + this.props.dispatch(expandAccountTimeline(nextProps.account.get('id'), { withReplies: true })); } } diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index a4af97ddab..16bf4033c2 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -13,7 +13,7 @@ "account.hide_reblogs": "Masquer les partages de @{name}", "account.media": "Média", "account.mention": "Mentionner", - "account.moved_to": "{name} a déménagé vers :", + "account.moved_to": "{name} a déménagé vers :", "account.mute": "Masquer @{name}", "account.mute_notifications": "Ignorer les notifications de @{name}", "account.muted": "Silencé", @@ -30,7 +30,7 @@ "account.unmute_notifications": "Réactiver les notifications de @{name}", "account.view_full_profile": "Afficher le profil complet", "alert.unexpected.message": "Une erreur non-attendue s'est produite.", - "alert.unexpected.title": "Oups !", + "alert.unexpected.title": "Oups !", "boost_modal.combo": "Vous pouvez appuyer sur {combo} pour pouvoir 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", @@ -77,7 +77,7 @@ "confirmations.delete.confirm": "Supprimer", "confirmations.delete.message": "Confirmez-vous la suppression de ce pouet ?", "confirmations.delete_list.confirm": "Supprimer", - "confirmations.delete_list.message": "Êtes-vous sûr de vouloir supprimer définitivement cette liste ?", + "confirmations.delete_list.message": "Êtes-vous sûr 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.", "confirmations.mute.confirm": "Masquer", @@ -85,14 +85,14 @@ "confirmations.unfollow.confirm": "Ne plus suivre", "confirmations.unfollow.message": "Voulez-vous arrêter de suivre {name} ?", "embed.instructions": "Intégrez ce statut à votre site en copiant le code ci-dessous.", - "embed.preview": "Il apparaîtra comme cela :", + "embed.preview": "Il apparaîtra comme cela :", "emoji_button.activity": "Activités", "emoji_button.custom": "Personnalisés", "emoji_button.flags": "Drapeaux", "emoji_button.food": "Nourriture & Boisson", "emoji_button.label": "Insérer un émoji", "emoji_button.nature": "Nature", - "emoji_button.not_found": "Pas d'emojis !! (╯°□°)╯︵ ┻━┻", + "emoji_button.not_found": "Pas d'emojis !! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "Objets", "emoji_button.people": "Personnages", "emoji_button.recent": "Fréquemment utilisés", @@ -154,7 +154,7 @@ "media_gallery.toggle_visible": "Modifier la visibilité", "missing_indicator.label": "Non trouvé", "missing_indicator.sublabel": "Ressource introuvable", - "mute_modal.hide_notifications": "Masquer les notifications de cette personne ?", + "mute_modal.hide_notifications": "Masquer les notifications de cette personne ?", "navigation_bar.blocks": "Comptes bloqués", "navigation_bar.community_timeline": "Fil public local", "navigation_bar.direct": "Messages directs", @@ -177,9 +177,9 @@ "notifications.clear": "Nettoyer les notifications", "notifications.clear_confirmation": "Voulez-vous vraiment supprimer toutes vos notifications ?", "notifications.column_settings.alert": "Notifications locales", - "notifications.column_settings.favourite": "Favoris :", - "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :", - "notifications.column_settings.mention": "Mentions :", + "notifications.column_settings.favourite": "Favoris :", + "notifications.column_settings.follow": "Nouveaux⋅elles abonné⋅e·s :", + "notifications.column_settings.mention": "Mentions :", "notifications.column_settings.push": "Notifications push", "notifications.column_settings.push_meta": "Cet appareil", "notifications.column_settings.reblog": "Partages :", @@ -216,7 +216,7 @@ "privacy.unlisted.long": "Ne pas afficher dans les fils publics", "privacy.unlisted.short": "Non-listé", "regeneration_indicator.label": "Chargement…", - "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !", + "regeneration_indicator.sublabel": "Le flux de votre page principale est en cours de préparation !", "relative_time.days": "{number} j", "relative_time.hours": "{number} h", "relative_time.just_now": "à l’instant", @@ -224,8 +224,8 @@ "relative_time.seconds": "{number} s", "reply_indicator.cancel": "Annuler", "report.forward": "Transférer à {target}", - "report.forward_hint": "Le compte provient d'un autre serveur. Envoyez également une copie anonyme du rapport ?", - "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez ce compte ci-dessous :", + "report.forward_hint": "Le compte provient d'un autre serveur. Envoyez également une copie anonyme du rapport ?", + "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez ce compte ci-dessous :", "report.placeholder": "Commentaires additionnels", "report.submit": "Envoyer", "report.target": "Signalement", diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 7cf6f4b769..3e2a1ae104 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4033,7 +4033,7 @@ a.status-card { .report-modal__statuses { flex: 1 1 auto; min-height: 20vh; - max-height: 40vh; + max-height: 80vh; overflow-y: auto; overflow-x: hidden; From 796fe4c3614a7fd531ef8bada99e2fe2a37da74b Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 6 May 2018 22:26:39 +0200 Subject: [PATCH 022/239] Fixes/rollback scroll changes (#7387) * Revert "Do not re-position scroll when loading more (inserting items from below) (#7344)" This reverts commit 554653a4233c94fdf1e294ef9ed2a8b1b1742c13. * Revert "Prevent timeline from moving when cursor is hovering over it (fixes #7278) (#7327)" This reverts commit 9188537f5f10f9b6960857cd1292ef5db8d5a411. --- .../mastodon/components/scrollable_list.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 7cdd63910e..fd6858d05b 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -35,7 +35,6 @@ export default class ScrollableList extends PureComponent { state = { fullscreen: null, - mouseOver: false, }; intersectionObserverWrapper = new IntersectionObserverWrapper(); @@ -72,7 +71,7 @@ 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.state.mouseOver && !prevProps.isLoading)) { + if (someItemInserted && this.node.scrollTop > 0) { return this.node.scrollHeight - this.node.scrollTop; } else { return null; @@ -140,14 +139,6 @@ export default class ScrollableList extends PureComponent { this.props.onLoadMore(); } - handleMouseEnter = () => { - this.setState({ mouseOver: true }); - } - - handleMouseLeave = () => { - this.setState({ mouseOver: false }); - } - render () { const { children, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, emptyMessage, onLoadMore } = this.props; const { fullscreen } = this.state; @@ -158,7 +149,7 @@ export default class ScrollableList extends PureComponent { if (isLoading || childrenCount > 0 || !emptyMessage) { scrollableArea = ( -

    +
    {prepend} From 93553c17c8ed9fc8a092efc553f3ee43f7071875 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 May 2018 01:34:19 +0200 Subject: [PATCH 023/239] Add Corsican localization (#7390) * Added Corsican localization * Declaring Corsican localization * Fixed activerecord locale * Added a missing translation and switched to French-style apostrophes * Fixed a (predictable) mistake made while bulk-replacing apostrophes * More fixing * i18n-tasks normalize --- app/helpers/settings_helper.rb | 1 + app/javascript/mastodon/locales/co.json | 296 +++++++ .../mastodon/locales/whitelist_co.json | 2 + config/application.rb | 1 + config/locales/activerecord.co.yml | 13 + config/locales/co.yml | 831 ++++++++++++++++++ config/locales/devise.co.yml | 82 ++ config/locales/doorkeeper.co.yml | 119 +++ config/locales/simple_form.co.yml | 79 ++ 9 files changed, 1424 insertions(+) create mode 100644 app/javascript/mastodon/locales/co.json create mode 100644 app/javascript/mastodon/locales/whitelist_co.json create mode 100644 config/locales/activerecord.co.yml create mode 100644 config/locales/co.yml create mode 100644 config/locales/devise.co.yml create mode 100644 config/locales/doorkeeper.co.yml create mode 100644 config/locales/simple_form.co.yml diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index f78e5fbc3f..f6d86a18e8 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -6,6 +6,7 @@ module SettingsHelper ar: 'العربية', bg: 'Български', ca: 'Català', + co: 'Corsu', de: 'Deutsch', el: 'Ελληνικά', eo: 'Esperanto', diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json new file mode 100644 index 0000000000..2d7427c55d --- /dev/null +++ b/app/javascript/mastodon/locales/co.json @@ -0,0 +1,296 @@ +{ + "account.block": "Bluccà @{name}", + "account.block_domain": "Piattà tuttu da {domain}", + "account.blocked": "Bluccatu", + "account.direct": "Missaghju direttu @{name}", + "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Duminiu piattatu", + "account.edit_profile": "Mudificà u prufile", + "account.follow": "Siguità", + "account.followers": "Abbunati", + "account.follows": "Abbunamenti", + "account.follows_you": "Vi seguita", + "account.hide_reblogs": "Piattà spartere da @{name}", + "account.media": "Media", + "account.mention": "Mintuvà @{name}", + "account.moved_to": "{name} hè partutu nant'à:", + "account.mute": "Piattà @{name}", + "account.mute_notifications": "Piattà nutificazione da @{name}", + "account.muted": "Piattatu", + "account.posts": "Statuti", + "account.posts_with_replies": "Statuti è risposte", + "account.report": "Palisà @{name}", + "account.requested": "In attesa d'apprubazione. Cliccate per annullà a dumanda", + "account.share": "Sparte u prufile di @{name}", + "account.show_reblogs": "Vede spartere da @{name}", + "account.unblock": "Sbluccà @{name}", + "account.unblock_domain": "Ùn piattà più {domain}", + "account.unfollow": "Ùn siguità più", + "account.unmute": "Ùn piattà più @{name}", + "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}", + "account.view_full_profile": "View full profile", + "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.", + "alert.unexpected.title": "Uups!", + "boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta", + "bundle_column_error.body": "C'hè statu un prublemu caricandu st'elementu.", + "bundle_column_error.retry": "Pruvà torna", + "bundle_column_error.title": "Errore di cunnessione", + "bundle_modal_error.close": "Chjudà", + "bundle_modal_error.message": "C'hè statu un prublemu caricandu st'elementu.", + "bundle_modal_error.retry": "Pruvà torna", + "column.blocks": "Utilizatori bluccati", + "column.community": "Linea pubblica lucale", + "column.direct": "Missaghji diretti", + "column.domain_blocks": "Duminii piattati", + "column.favourites": "Favuriti", + "column.follow_requests": "Dumande d'abbunamentu", + "column.home": "Accolta", + "column.lists": "Liste", + "column.mutes": "Utilizatori piattati", + "column.notifications": "Nutificazione", + "column.pins": "Statuti puntarulati", + "column.public": "Linea pubblica glubale", + "column_back_button.label": "Ritornu", + "column_header.hide_settings": "Piattà i parametri", + "column_header.moveLeft_settings": "Spiazzà à manca", + "column_header.moveRight_settings": "Spiazzà à diritta", + "column_header.pin": "Puntarulà", + "column_header.show_settings": "Mustrà i parametri", + "column_header.unpin": "Spuntarulà", + "column_subheading.navigation": "Navigazione", + "column_subheading.settings": "Parametri", + "compose_form.direct_message_warning": "Solu l'utilizatori mintuvati puderenu vede stu statutu.", + "compose_form.hashtag_warning": "Stu statutu ùn hè \"Micca listatu\" è ùn sarà micca listatu indè e circate da hashtag. Per esse vistu in quesse, u statutu deve esse \"Pubblicu\".", + "compose_form.lock_disclaimer": "U vostru contu ùn hè micca {locked}. Tuttu u mondu pò seguitavi è vede i vostri statuti privati.", + "compose_form.lock_disclaimer.lock": "privatu", + "compose_form.placeholder": "À chè pensate?", + "compose_form.publish": "Toot", + "compose_form.publish_loud": "{publish}!", + "compose_form.sensitive.marked": "Media indicatu cum'è sensibile", + "compose_form.sensitive.unmarked": "Media micca indicatu cum'è sensibile", + "compose_form.spoiler.marked": "Testu piattatu daret'à un'avertimentu", + "compose_form.spoiler.unmarked": "Testu micca piattatu", + "compose_form.spoiler_placeholder": "Scrive u vostr'avertimentu quì", + "confirmation_modal.cancel": "Annullà", + "confirmations.block.confirm": "Bluccà", + "confirmations.block.message": "Site sicuru·a che vulete bluccà @{name}?", + "confirmations.delete.confirm": "Toglie", + "confirmations.delete.message": "Site sicuru·a che vulete supprime stu statutu?", + "confirmations.delete_list.confirm": "Toglie", + "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à.", + "confirmations.mute.confirm": "Piattà", + "confirmations.mute.message": "Site sicuru·a che vulete piattà @{name}?", + "confirmations.unfollow.confirm": "Disabbunassi", + "confirmations.unfollow.message": "Site sicuru·a ch'ùn vulete più siguità @{name}?", + "embed.instructions": "Integrà stu statutu à u vostru situ cù u codice quì sottu.", + "embed.preview": "Assumiglierà à qualcosa cusì:", + "emoji_button.activity": "Attività", + "emoji_button.custom": "Persunalizati", + "emoji_button.flags": "Bandere", + "emoji_button.food": "Manghjusca è Bienda", + "emoji_button.label": "Mette un'emoji", + "emoji_button.nature": "Natura", + "emoji_button.not_found": "Ùn c'hè nunda! (╯°□°)╯︵ ┻━┻", + "emoji_button.objects": "Oggetti", + "emoji_button.people": "Parsunaghji", + "emoji_button.recent": "Assai utilizati", + "emoji_button.search": "Cercà...", + "emoji_button.search_results": "Risultati di a cerca", + "emoji_button.symbols": "Simbuli", + "emoji_button.travel": "Lochi è Viaghju", + "empty_column.community": "Ùn c'hè nunda indè a linea lucale. Scrivete puru qualcosa!", + "empty_column.direct": "Ùn avete ancu nisun missaghju direttu. S'è voi mandate o ricevete unu, u vidarete quì.", + "empty_column.hashtag": "Ùn c'hè ancu nunda quì.", + "empty_column.home": "A vostr'accolta hè viota! Pudete andà nant'à {public} o pruvà a ricerca per truvà parsone da siguità.", + "empty_column.home.public_timeline": "a linea pubblica", + "empty_column.list": "Ùn c'hè ancu nunda quì. Quandu membri di sta lista manderanu novi statuti, i vidarete quì.", + "empty_column.notifications": "Ùn avete ancu nisuna nutificazione. Interact with others to start the conversation.", + "empty_column.public": "Ùn c'hè nunda quì! Scrivete qualcosa in pubblicu o seguitate utilizatori d'altre istanze per empie a linea pubblica.", + "follow_request.authorize": "Auturizà", + "follow_request.reject": "Righjittà", + "getting_started.appsshort": "Applicazione", + "getting_started.faq": "FAQ", + "getting_started.heading": "Per principià", + "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}", + "getting_started.userguide": "Guida d'utilizazione", + "home.column_settings.advanced": "Avanzati", + "home.column_settings.basic": "Bàsichi", + "home.column_settings.filter_regex": "Filtrà cù spressione regulare (regex)", + "home.column_settings.show_reblogs": "Vede e spartere", + "home.column_settings.show_replies": "Vede e risposte", + "home.settings": "Parametri di a colonna", + "keyboard_shortcuts.back": "rivultà", + "keyboard_shortcuts.boost": "sparte", + "keyboard_shortcuts.column": "fucalizà un statutu indè una colonna", + "keyboard_shortcuts.compose": "fucalizà nant'à l'area di ridazzione", + "keyboard_shortcuts.description": "Descrizzione", + "keyboard_shortcuts.down": "falà indè a lista", + "keyboard_shortcuts.enter": "apre u statutu", + "keyboard_shortcuts.favourite": "aghjunghje à i favuriti", + "keyboard_shortcuts.heading": "Accorte cù a tastera", + "keyboard_shortcuts.hotkey": "Accorta", + "keyboard_shortcuts.legend": "vede a legenda", + "keyboard_shortcuts.mention": "mintuvà l'autore", + "keyboard_shortcuts.reply": "risponde", + "keyboard_shortcuts.search": "fucalizà nant'à l'area di circata", + "keyboard_shortcuts.toggle_hidden": "vede/piattà u testu daretu à l'avertimentu CW", + "keyboard_shortcuts.toot": "scrive un novu statutu", + "keyboard_shortcuts.unfocus": "ùn fucalizà più l'area di testu", + "keyboard_shortcuts.up": "cullà indè a lista", + "lightbox.close": "Chjudà", + "lightbox.next": "Siguente", + "lightbox.previous": "Pricidente", + "lists.account.add": "Aghjunghje à a lista", + "lists.account.remove": "Toglie di a lista", + "lists.delete": "Supprime a lista", + "lists.edit": "Mudificà a lista", + "lists.new.create": "Aghjustà una lista", + "lists.new.title_placeholder": "Titulu di a lista", + "lists.search": "Circà indè i vostr'abbunamenti", + "lists.subheading": "E vo liste", + "loading_indicator.label": "Caricamentu...", + "media_gallery.toggle_visible": "Cambià a visibilità", + "missing_indicator.label": "Micca trovu", + "missing_indicator.sublabel": "Ùn era micca pussivule di truvà sta risorsa", + "mute_modal.hide_notifications": "Piattà nutificazione da st'utilizatore?", + "navigation_bar.blocks": "Utilizatori bluccati", + "navigation_bar.community_timeline": "Linea pubblica lucale", + "navigation_bar.direct": "Missaghji diretti", + "navigation_bar.domain_blocks": "Duminii piattati", + "navigation_bar.edit_profile": "Mudificà u prufile", + "navigation_bar.favourites": "Favuriti", + "navigation_bar.follow_requests": "Dumande d'abbunamentu", + "navigation_bar.info": "À prupositu di l'istanza", + "navigation_bar.keyboard_shortcuts": "Accorte cù a tastera", + "navigation_bar.lists": "Liste", + "navigation_bar.logout": "Scunnettassi", + "navigation_bar.mutes": "Utilizatori piattati", + "navigation_bar.pins": "Statuti puntarulati", + "navigation_bar.preferences": "Preferenze", + "navigation_bar.public_timeline": "Linea pubblica glubale", + "notification.favourite": "{name} hà aghjuntu u vostru statutu à i so favuriti", + "notification.follow": "{name} v'hà seguitatu", + "notification.mention": "{name} v'hà mintuvatu", + "notification.reblog": "{name} hà spartutu u vostru statutu", + "notifications.clear": "Purgà e nutificazione", + "notifications.clear_confirmation": "Site sicuru·a che vulete toglie tutte ste nutificazione?", + "notifications.column_settings.alert": "Nutificazione nant'à l'urdinatore", + "notifications.column_settings.favourite": "Favuriti:", + "notifications.column_settings.follow": "Abbunati novi:", + "notifications.column_settings.mention": "Minzione:", + "notifications.column_settings.push": "Nutificazione Push", + "notifications.column_settings.push_meta": "Quess'apparechju", + "notifications.column_settings.reblog": "Spartere:", + "notifications.column_settings.show": "Mustrà indè a colonna", + "notifications.column_settings.sound": "Sunà", + "onboarding.done": "Fatta", + "onboarding.next": "Siguente", + "onboarding.page_five.public_timelines": "A linea pubblica lucale mostra statuti pubblichi da tuttu u mondu nant'à {domain}. A linea pubblica glubale mostra ancu quelli di a ghjente seguitata da l'utilizatori di {domain}. Quesse sò una bona manera d'incuntrà nove parsone.", + "onboarding.page_four.home": "A linea d'accolta mostra i statuti di i vostr'abbunamenti.", + "onboarding.page_four.notifications": "A colonna di nutificazione mostra l'interazzione ch'altre parsone anu cù u vostru contu.", + "onboarding.page_one.federation": "Mastodon ghjè una rete di servori independenti, chjamati istanze, uniti indè una sola rete suciale.", + "onboarding.page_one.full_handle": "U vostru identificatore cumplettu", + "onboarding.page_one.handle_hint": "Quessu ghjè cio chì direte à i vostri amichi per circavi.", + "onboarding.page_one.welcome": "Benvenuti/a nant'à Mastodon!", + "onboarding.page_six.admin": "L'amministratore di a vostr'istanza hè {admin}.", + "onboarding.page_six.almost_done": "Quasgi finitu...", + "onboarding.page_six.appetoot": "Bon Appetoot!", + "onboarding.page_six.apps_available": "Ci sò {apps} dispunibule per iOS, Android è altre piattaforme.", + "onboarding.page_six.github": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un prublemu, nant'à {github}.", + "onboarding.page_six.guidelines": "regule di a cumunità", + "onboarding.page_six.read_guidelines": "Ùn vi scurdate di leghje e {guidelines} di {domain}", + "onboarding.page_six.various_app": "applicazione pè u telefuninu", + "onboarding.page_three.profile": "Pudete mudificà u prufile per cambia u ritrattu, a descrizzione è u nome affissatu. Ci sò ancu alcun'altre preferenze.", + "onboarding.page_three.search": "Fate usu di l'area di ricerca per truvà altre persone è vede hashtag cum'è {illustration} o {introductions}. Per vede qualcunu ch'ùn hè micca nant'à st'istanza, cercate u so identificatore complettu (pare un'email).", + "onboarding.page_two.compose": "I statuti è missaghji si scrivenu indè l'area di ridazzione. Pudete caricà imagine, cambià i parametri di pubblicazione, è mette avertimenti di cuntenuti cù i buttoni quì sottu.", + "onboarding.skip": "Passà", + "privacy.change": "Mudificà a cunfidenzialità di u statutu", + "privacy.direct.long": "Mandà solu à quelli chì so mintuvati", + "privacy.direct.short": "Direttu", + "privacy.private.long": "Mustrà solu à l'abbunati", + "privacy.private.short": "Privatu", + "privacy.public.long": "Mustrà à tuttu u mondu nant'a linea pubblica", + "privacy.public.short": "Pubblicu", + "privacy.unlisted.long": "Ùn mette micca nant'a linea pubblica (ma tutt'u mondu pò vede u statutu nant'à u vostru prufile)", + "privacy.unlisted.short": "Micca listatu", + "regeneration_indicator.label": "Caricamentu…", + "regeneration_indicator.sublabel": "Priparazione di a vostra pagina d'accolta", + "relative_time.days": "{number}d", + "relative_time.hours": "{number}h", + "relative_time.just_now": "avà", + "relative_time.minutes": "{number}m", + "relative_time.seconds": "{number}s", + "reply_indicator.cancel": "Annullà", + "report.forward": "Trasferisce à {target}", + "report.forward_hint": "U contu hè nant'à un'altru servore. Vulete ancu mandà una copia anonima di u signalamentu quallà?", + "report.hint": "U signalamentu sarà mandatu à i muderatori di l'istanza. Pudete spiegà perchè avete palisatu stu contu quì sottu:", + "report.placeholder": "Altri cummenti", + "report.submit": "Mandà", + "report.target": "Signalamentu", + "search.placeholder": "Circà", + "search_popout.search_format": "Ricerca avanzata", + "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": "statutu", + "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", + "search_popout.tips.user": "utilizatore", + "search_results.accounts": "Ghjente", + "search_results.hashtags": "Hashtags", + "search_results.statuses": "Statuti", + "search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}", + "standalone.public_title": "Una vista di...", + "status.block": "Bluccà @{name}", + "status.cancel_reblog_private": "Ùn sparte più", + "status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu", + "status.delete": "Toglie", + "status.direct": "Mandà un missaghju @{name}", + "status.embed": "Integrà", + "status.favourite": "Aghjunghje à i favuriti", + "status.load_more": "Vede di più", + "status.media_hidden": "Media piattata", + "status.mention": "Mintuvà @{name}", + "status.more": "Più", + "status.mute": "Piattà @{name}", + "status.mute_conversation": "Piattà a cunversazione", + "status.open": "Apre stu statutu", + "status.pin": "Puntarulà à u prufile", + "status.pinned": "Statutu puntarulatu", + "status.reblog": "Sparte", + "status.reblog_private": "Sparte à l'audienza uriginale", + "status.reblogged_by": "{name} hà spartutu", + "status.reply": "Risponde", + "status.replyAll": "Risponde à tutti", + "status.report": "Palisà @{name}", + "status.sensitive_toggle": "Cliccate per vede", + "status.sensitive_warning": "Cuntinutu sensibile", + "status.share": "Sparte", + "status.show_less": "Ripiegà", + "status.show_less_all": "Ripiegà tuttu", + "status.show_more": "Slibrà", + "status.show_more_all": "Slibrà tuttu", + "status.unmute_conversation": "Ùn piattà più a cunversazione", + "status.unpin": "Spuntarulà da u prufile", + "tabs_bar.federated_timeline": "Glubale", + "tabs_bar.home": "Accolta", + "tabs_bar.local_timeline": "Lucale", + "tabs_bar.notifications": "Nutificazione", + "tabs_bar.search": "Cercà", + "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", + "upload_form.description": "Discrive per i malvistosi", + "upload_form.focus": "Riquatrà", + "upload_form.undo": "Annullà", + "upload_progress.label": "Caricamentu...", + "video.close": "Chjudà a video", + "video.exit_fullscreen": "Caccià u pienu screnu", + "video.expand": "Ingrandà a video", + "video.fullscreen": "Pienu screnu", + "video.hide": "Piattà a video", + "video.mute": "Surdina", + "video.pause": "Pausa", + "video.play": "Lettura", + "video.unmute": "Caccià a surdina" +} diff --git a/app/javascript/mastodon/locales/whitelist_co.json b/app/javascript/mastodon/locales/whitelist_co.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/app/javascript/mastodon/locales/whitelist_co.json @@ -0,0 +1,2 @@ +[ +] diff --git a/config/application.rb b/config/application.rb index 25c926444e..b4871241a3 100644 --- a/config/application.rb +++ b/config/application.rb @@ -40,6 +40,7 @@ module Mastodon :ar, :bg, :ca, + :co, :de, :el, :eo, diff --git a/config/locales/activerecord.co.yml b/config/locales/activerecord.co.yml new file mode 100644 index 0000000000..af28d108fd --- /dev/null +++ b/config/locales/activerecord.co.yml @@ -0,0 +1,13 @@ +--- +co: + activerecord: + errors: + models: + account: + attributes: + username: + invalid: solu lettere, numeri è liniette basse + status: + attributes: + reblog: + taken: di u statutu esista digià diff --git a/config/locales/co.yml b/config/locales/co.yml new file mode 100644 index 0000000000..abef1d36bc --- /dev/null +++ b/config/locales/co.yml @@ -0,0 +1,831 @@ +--- +co: + about: + about_hashtag_html: Quessi sò statuti pubblichi taggati cù #%{hashtag}. Pudete interagisce cù elli sì voi avete un contu in qualche parte di u fediverse. + about_mastodon_html: Mastodon ghjè una rete suciale custruita incù prutucolli web aperti è lugiziali liberi. Hè decentralizatu cumu l’e-mail. + about_this: À prupositu + administered_by: 'Amministratu da:' + closed_registrations: Pè avà, l’arregistramenti sò chjosi nant’à st’istanza. Mà pudete truvà un’altr’istanza per fà un contu è avè accessu à listessa reta da quallà! + contact: Cuntattu + contact_missing: Mancante + contact_unavailable: Micca dispunibule + description_headline: Quale hè %{domain} ? + domain_count_after: altre istanze + domain_count_before: Cunnettati à + extended_description_html: | +

    Una bona piazza per e regule

    +

    A descrizzione stesa ùn hè micca stata riempiuta.

    + features: + humane_approach_body: Mastodon hà amparatu da i sbagli di l’altre rete suciale, è prova à fà scelte di cuncezzione più etiche per luttà contr’à l’abusu di i media suciali. + humane_approach_title: Una mentalità più umana + not_a_product_body: Mastodon ùn hè micca una rete cummerciale. Micca pubblicità, micca pruspizzione di dati, micca ambienti chjosi, è micca auturità centrale. + not_a_product_title: Site una parsona, micca un pruduttu + real_conversation_body: Cù 500 caratteri dispunibuli, diffusione persunalizata di u cuntinutu è avertimenti per media sensibili, pudete cumunicà cum’è voi vulete. + real_conversation_title: Fattu per una vera cunversazione + within_reach_body: Parechje app per iOS, Android è altre piattaforme, create cù un sistemu d’API accessibile à i prugrammatori, vi permettenu d’avè accessu à i vostri amichi senza prublemi. + within_reach_title: Sempre accessibile + generic_description: "%{domain} hè un servore di a rete" + hosted_on: Mastodon allughjatu nant’à %{domain} + learn_more: Amparà di più + other_instances: Lista di l’istanze + source_code: Codice di fonte + status_count_after: statuti + status_count_before: chì anu pubblicatu + user_count_after: parsone quì + user_count_before: Ci sò + what_is_mastodon: Quale hè Mastodon? + accounts: + follow: Siguità + followers: Abbunati + following: Abbunamenti + media: Media + moved_html: "%{name} hà cambiatu di contu, avà hè nant’à %{new_profile_link}:" + nothing_here: Ùn c’hè nunda quì! + people_followed_by: Seguitati da %{name} + people_who_follow: Seguitanu %{name} + posts: Statuti + posts_with_replies: Statuti è risposte + remote_follow: Siguità d’altrò + reserved_username: Stu cugnome hè riservatu + roles: + admin: Amministratore + moderator: Muderatore + unfollow: Ùn siguità più + admin: + account_moderation_notes: + create: Creà + created_msg: Nota di muderazione creata! + delete: Toglie + destroyed_msg: Nota di muderazione sguassata! + accounts: + are_you_sure: Site sicuru·a? + avatar: Ritrattu di prufile + by_domain: Duminiu + change_email: + changed_msg: Email di u contu cambiatu! + current_email: Email attuale + label: Mudificà l’Email + new_email: Novu Email + submit: Cambià Email + title: Mudificà l’Email di %{username} + confirm: Cunfirmà + confirmed: Cunfirmata + demote: Ritrugradà + disable: Disattivà + disable_two_factor_authentication: Disattivà l’identificazione à 2 fattori + disabled: Disattivatu + display_name: Nome pubblicu + domain: Duminiu + edit: Mudificà + email: E-mail + enable: Attivà + enabled: Attivatu + feed_url: URL di u flussu + followers: Abbunati + followers_url: URL di l’abbunati + follows: Abbunamenti + inbox_url: URL di l’inbox + ip: IP + location: + all: Tutti + local: Lucale + remote: D’altrò + title: Lucalizazione + login_status: Statutu di cunnessione + media_attachments: Media aghjunti + memorialize: Trasfurmà in mimuriale + moderation: + all: Tutti + silenced: Silenzati + suspended: Suspesi + title: Muderazione + moderation_notes: Note di muderazione + most_recent_activity: Attività più ricente + most_recent_ip: IP più ricente + not_subscribed: Micca abbunatu + order: + alphabetic: Alfabeticu + most_recent: Più ricente + title: Urdine + outbox_url: URL di l’outbox + perform_full_suspension: Fà una suspensione cumpleta + profile_url: URL di u prufile + promote: Prumove + protocol: Prutucollu + public: Pubblicu + push_subscription_expires: Spirata di l’abbunamentu PuSH + redownload: Mette à ghjornu i ritratti + remove_avatar: Toglie l’avatar + reset: Reset + reset_password: Riinizializà a chjave d’accessu + resubscribe: Riabbunassi + role: Auturizazione + roles: + admin: Amministratore + moderator: Muderatore + staff: Squadra + user: Utilizatore + salmon_url: URL di Salmon + search: Cercà + shared_inbox_url: URL di l’inbox spartuta + show: + created_reports: Signalamenti creati da stu contu + report: Signalamentu + targeted_reports: Signalamenti creati contr’à stu contu + silence: Silenzà + statuses: Statuti + subscribe: Abbunassi + title: Conti + unconfirmed_email: E-mail micca cunfirmatu + undo_silenced: Ùn silenzà più + undo_suspension: Ùn suspende più + unsubscribe: Disabbunassi + username: Cugnome + web: Web + action_logs: + actions: + assigned_to_self_report: "%{name} s’hè assignatu u signalamentu %{target}" + change_email_user: "%{name} hà cambiatu l’indirizzu e-mail di %{target}" + confirm_user: "%{name} hà cunfirmatu l’indirizzu e-mail di %{target}" + create_custom_emoji: "%{name} hà caricatu una nov’emoji %{target}" + create_domain_block: "%{name} hà bluccatu u duminiu %{target}" + create_email_domain_block: "%{name} hà messu u duminiu e-mail %{target} nant’a lista nera" + demote_user: "%{name} hà ritrugradatu l’utilizatore %{target}" + destroy_domain_block: "%{name} hà sbluccatu u duminiu %{target}" + destroy_email_domain_block: "%{name} hà messu u duminiu e-mail %{target} nant’a lista bianca" + destroy_status: "%{name} hà toltu u statutu di %{target}" + disable_2fa_user: "%{name} hà disattivatu l’identificazione à dui fattori per %{target}" + disable_custom_emoji: "%{name} hà disattivatu l’emoji %{target}" + disable_user: "%{name} hà disattivatu a cunnessione per %{target}" + enable_custom_emoji: "%{name} hà attivatu l’emoji %{target}" + enable_user: "%{name} hà attivatu a cunnessione per %{target}" + memorialize_account: "%{name} hà trasfurmatu u contu di %{target} in una pagina mimuriale" + promote_user: "%{name} hà prumossu %{target}" + remove_avatar_user: "%{name} hà toltu u ritrattu di %{target}" + reopen_report: "%{name} hà riapertu u signalamentu %{target}" + reset_password_user: "%{name} hà riinizializatu a chjave d’accessu di %{target}" + resolve_report: "%{name} hà chjosu u signalamentu %{target}" + silence_account: "%{name} hà silenzatu u contu di %{target}" + suspend_account: "%{name} hà suspesu u contu di %{target}" + unassigned_report: "%{name} hà disassignatu u signalamentu %{target}" + unsilence_account: "%{name} hà fattu che u contu di %{target} ùn hè più silenzatu" + unsuspend_account: "%{name} hà fattu che u contu di %{target} ùn hè più suspesu" + update_custom_emoji: "%{name} hà messu à ghjornu l’emoji %{target}" + update_status: "%{name} hà cambiatu u statutu di %{target}" + title: Ghjurnale d’audit + custom_emojis: + by_domain: Duminiu + copied_msg: Copia lucale di l’emoji creata! + copy: Cupià + copy_failed_msg: Ùn s’hè micca pussutu creà una copia di l’emoji + created_msg: L’emoji hè stata creata! + delete: Toglie + destroyed_msg: L’emoji hè stata tolta! + disable: Disattivà + disabled_msg: L’emoji hè stata disattivata! + emoji: Emoji + enable: Attivà + enabled_msg: L’emoji hè stata attivata! + image_hint: PNG di 50Ko o menu + listed: Listata + new: + title: Aghjustà una nov’emoji + overwrite: Soprascrive + shortcode: Accorta + shortcode_hint: 2 caratteri o più, solu lettere, numeri è liniette basse + title: Emoji parsunalizate + unlisted: Micca listata + update_failed_msg: Ùn s’hè micca pussutu mette à ghjornu l’emoji + updated_msg: L’emoji hè stata messa à ghjornu! + upload: Caricà + domain_blocks: + add_new: Aghjustà + created_msg: U blucchime di u duminiu hè attivu + destroyed_msg: U blucchime di u duminiu ùn hè più attivu + domain: Duminiu + new: + create: Creà un blucchime + hint: U blucchime di duminiu ùn impedirà micca a creazione di conti indè a database, mà metudi di muderazione specifiche saranu applicati. + severity: + desc_html: CùSilenzà, solu l’abbunati di u contu viderenu i so missaghji. Suspende sguassarà tutti i cuntenuti è dati di u contu. Utilizate Nisuna s’è voi vulete solu righjittà fugliali media. + noop: Nisuna + silence: Silenzà + suspend: Suspende + title: Novu blucchime di duminiu + reject_media: Righjittà i fugliali media + reject_media_hint: Sguassa tutti i media caricati è ricusa caricamenti futuri. Inutile per una suspensione + severities: + noop: Nisuna + silence: Silenzà + suspend: Suspende + severity: Severità + show: + affected_accounts: + one: Un contu tuccatu indè a database + other: "%{count} conti tuccati indè a database" + retroactive: + silence: Ùn silenzà più i conti nant’à stu duminiu + suspend: Ùn suspende più i conti nant’à stu duminiu + title: Ùn bluccà più u duminiu %{domain} + undo: Annullà + title: Blucchimi di duminiu + undo: Annullà + email_domain_blocks: + add_new: Aghjustà + created_msg: U blucchime di u duminiu d’e-mail hè attivu + delete: Toglie + destroyed_msg: U blucchime di u duminiu d’e-mail ùn hè più attivu + domain: Duminiu + new: + create: Creà un blucchime + title: Nova iscrizzione nant’a lista nera e-mail + title: Lista nera e-mail + instances: + account_count: Conti cunnisciuti + domain_name: Duminiu + reset: Riinizializà + search: Cercà + title: Istanze cunnisciute + invites: + filter: + all: Tuttu + available: Dispunibuli + expired: Spirati + title: Filtrà + title: Invitazione + report_notes: + created_msg: Nota di signalamentu creata! + destroyed_msg: Nota di signalamentu sguassata! + reports: + account: + note: nota + report: palisà + action_taken_by: Intervenzione di + are_you_sure: Site sicuru·a? + assign_to_self: Assignallu à mè + assigned: Muderatore assignatu + comment: + none: Nisunu + created_at: Palisatu + id: ID + mark_as_resolved: Indicà cum’è chjosu + mark_as_unresolved: Indicà cum’è sempre apertu + notes: + create: Aghjunghje una nota + create_and_resolve: Chjude cù una nota + create_and_unresolve: Riapre cù una nota + delete: Toglie + placeholder: Per parlà di l’azzione piglate, o altre messe à ghjornu nant’à u signalamentu… + reopen: Riapre u signalamentu + report: 'Signalamente #%{id}' + report_contents: Cuntenuti + reported_account: Contu palisatu + reported_by: Palisatu da + resolved: Scioltu è chjosu + resolved_msg: Signalamentu scioltu! + silence_account: Silenzà u contu + status: Statutu + suspend_account: Suspende u contu + target: Oggettu + title: Signalamenti + unassign: Disassignà + unresolved: Micca sciolti + updated_at: Messi à ghjornu + view: Vede + settings: + activity_api_enabled: + desc_html: Numeri di statuti creati quì, utilizatori attivi, è arregistramenti novi tutte e settimane + title: Pubblicà statistiche nant’à l’attività di l’utilizatori + bootstrap_timeline_accounts: + desc_html: Cugnomi separati cù virgule. Solu pussibule cù conti lucali è pubblichi. Quandu a lista hè viota, tutti l’amministratori lucali saranu selezziunati. + title: Abbunamenti predefiniti per l’utilizatori novi + contact_information: + email: E-mail prufissiunale + username: Identificatore di cuntattu + hero: + desc_html: Affissatu nant’a pagina d’accolta. Ricumandemu almenu 600x100px. S’ellu ùn hè micca definiti, a vignetta di l’istanza sarà usata + title: Ritrattu di cuprendula + peers_api_enabled: + desc_html: Indirizzi st’istanza hà vistu indè u fediverse + title: Pubblicà a lista d’istanza cunnisciute + registrations: + closed_message: + desc_html: Affissatu nant’a pagina d’accolta quandu l’arregistramenti sò chjosi. Pudete fà usu di u furmattu HTML + title: Missaghju per l’arregistramenti chjosi + deletion: + desc_html: Auturizà tuttu u mondu di sguassà u so propiu contu + title: Auturizà à sguassà i conti + min_invite_role: + disabled: Nisunu + title: Auturizà l’invitazione da + open: + desc_html: Auturizà tuttu u mondu à creà un contu quì + title: Apre l’arregistramenti + show_known_fediverse_at_about_page: + desc_html: Quandu ghjè selezziunatu, statuti di tuttu l’istanze cunnisciute saranu affissati indè a vista di e linee. Altrimente soli i statuti lucali saranu mustrati. + title: Vedde tuttu u fediverse cunnisciutu nant’a vista di e linee + show_staff_badge: + desc_html: Mustrerà un badge Squadra nant’à un prufile d’utilizatore + title: Mustrà un badge staff + site_description: + desc_html: Paragrafu di prisentazione nant’a pagina d’accolta è i marchi meta. Pudete fà usu di marchi HTML, in particulare <a> è <em>. + title: Discrizzione di l’istanza + site_description_extended: + desc_html: Una bona piazza per e regule, infurmazione è altre cose chì l’utilizatori duverìanu sapè. Pudete fà usu di marchi HTML + title: Discrizzione stesa di u situ + site_terms: + desc_html: Quì pudete scrive e vostre regule di cunfidenzialità, cundizione d’usu o altre menzione legale. Pudete fà usu di marchi HTML + title: Termini persunalizati + site_title: Nome di l’istanza + thumbnail: + desc_html: Utilizatu per viste cù OpenGraph è l’API. Ricumandemu 1200x630px + title: Vignetta di l’istanza + timeline_preview: + desc_html: Vede a linea pubblica nant’a pagina d’accolta + title: Vista di e linee + title: Parametri di u situ + statuses: + back_to_account: Ritornu à a pagina di u contu + batch: + delete: Toglie + nsfw_off: Indicà cum’è micca sensibile + nsfw_on: Indicà cum’è sensibile + failed_to_execute: Esecuzione impussibule + media: + title: Media + no_media: Nisun media + title: Statutu di u contu + with_media: Cù media + subscriptions: + callback_url: URL di richjama + confirmed: Cunfirmatu + expires_in: Spira in + last_delivery: Ultima arricata + title: WebSub + topic: Sughjettu + title: Amministrazione + admin_mailer: + new_report: + body: "%{reporter} hà palisatu %{target}" + body_remote: Qualch’unu da %{domain} hà palisatu %{target} + subject: Novu signalamentu nant’à %{instance} (#%{id}) + application_mailer: + notification_preferences: Cambià e priferenze e-mail + salutation: "%{name}," + settings: 'Cambià e priferenze e-mail: %{link}' + view: 'Vede:' + view_profile: Vede u prufile + view_status: Vede u statutu + applications: + created: Applicazione creata + destroyed: Applicazione sguassata + invalid_url: L’URL ch’è stata pruvista ùn hè valida + regenerate_token: Regenerate access token + token_regenerated: Access token successfully regenerated + warning: Be very careful with this data. Never share it with anyone! + your_token: Rigenerà a fiscia d’accessu + auth: + agreement_html: Arregistrassi vole dì chì site d’accunsentu per siguità e regule di l’istanza è e cundizione d’usu. + change_password: Chjave d’accessu + confirm_email: Cunfirmà l’e-mail + delete_account: Sguassà u contu + delete_account_html: S’è voi vulete toglie u vostru contu ghjè quì. Duverete cunfirmà a vostra scelta. + didnt_get_confirmation: Ùn avete micca ricevutu l’istruzione di cunfirmazione? + forgot_password: Chjave scurdata? + invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. + login: Cunnettassi + logout: Scunnettassi + migrate_account: Cambià di contu + migrate_account_html: S’è voi vulete riindirizà stu contu versu un’altru, ghjè pussibule quì. + or: o + or_log_in_with: O cunnettatevi cù + providers: + cas: CAS + saml: SAML + register: Arregistrassi + register_elsewhere: Arregistrassi altrò + resend_confirmation: Rimandà l’istruzzioni di cunfirmazione + reset_password: Cambià a chjave d’accessu + security: Sicurità + set_new_password: Creà una nova chjave d’accessu + authorize_follow: + already_following: You are already following this account + error: Peccatu, c’hè statu un prublemu ricercandu u contu. + follow: Siguità + follow_request: 'Avete dumandatu di siguità:' + following: 'Eccu! Avà seguitate:' + post_follow: + close: Or, you can just close this window. + return: Rivultà à u prufile di l’utilizatore + web: Andà à l’interfaccia web + title: Siguità %{acct} + datetime: + distance_in_words: + about_x_hours: "%{count}h" + about_x_months: "%{count}mo" + about_x_years: "%{count}y" + almost_x_years: "%{count}y" + half_a_minute: Avà + less_than_x_minutes: "%{count}m" + less_than_x_seconds: Avà + over_x_years: "%{count}y" + x_days: "%{count}d" + x_minutes: "%{count}m" + x_months: "%{count}mo" + x_seconds: "%{count}s" + deletes: + bad_password_msg: È nò! Sta chjave ùn hè curretta + confirm_password: Entrate a vostra chjave d’accessu attuale per verificà a vostra identità + description_html: U contu sarà deattivatu è u cuntenutu sarà sguassatu di manera permanente è irreversibile. Ùn sarà micca pussibule piglià stu cugnome torna per evità l’impusture. + proceed: Sguassà u contu + success_msg: U vostru contu hè statu sguassatu + warning_html: Pudete esse sicuru·a solu chì u cuntenutu sarà sguassatu di st’istanza. S’ellu hè statu spartutu in altrò, sarà forse sempre quallà. + warning_title: Dispunibilità di i cuntenuti sparsi + errors: + '403': Ùn site micca auturizatu·a à vede sta pagina. + '404': Sta pagina ùn esiste micca. + '410': Sta pagina ùn esiste più. + '422': + content: C’hè statu un prublemu cù a verificazione di sicurità. Forse bluccate cookies? + title: Fiascu di verificazione + '429': Limitatu dop’à troppu richieste + '500': + content: Scusate, mà c’hè statu un prublemu cù u nostru servore. + title: Sta pagina ùn hè curretta + noscript_html: Mastodon nant’à u web hà bisognu di JavaScript per funziunà. Pudete ancu pruvà l’applicazione native per a vostra piattaforma. + exports: + archive_takeout: + date: Data + download: Scaricà l’archiviu + hint_html: Pudete dumandà un’archiviu di i vostri statuti è media caricati. I dati saranu in u furmattu ActivityPub è pudarenu esse letti da tutti i lugiziali chì u supportanu. + in_progress: Cumpilazione di l’archiviu... + request: Dumandà u vostr’archiviu + size: Pesu + blocks: Bluccate + csv: CSV + follows: Seguitate + mutes: Piattate + storage: I vostri media + followers: + domain: Duminiu + explanation_html: Per assicuravi di a cunfidenzialità di i vostri statuti, duvete avè primura di quale vi seguita. I vostri statuti privati sò mandati à tutte l’istanze induve avete abbunati. Pensate à u vostru livellu di cunfidenza in i so amministratori. + followers_count: Numeru d’abbunati + lock_link: Rendete u contu privatu + purge: Toglie di a lista d’abbunati + success: + one: Suppressione di l’abbunati d’un duminiu... + other: Suppressione di l’abbunati da %{count} duminii... + true_privacy_html: Ùn vi scurdate chì una vera cunfidenzialità pò solu esse ottenuta cù crittografia da un capu à l’altru. + unlocked_warning_html: Tuttu u mondu pò seguitavi è vede i vostri statuti privati. %{lock_link} per pudè cunfirmà o righjittà abbunamenti. + unlocked_warning_title: U vostru contu hè pubblicu + generic: + changes_saved_msg: Cambiamenti salvati! + powered_by: mossu da %{link} + save_changes: Salvà e mudificazione + validation_errors: + one: Qualcosa ùn và bè! Verificate un prublemu quì sottu. + other: Qualcosa ùn và bè! Verificate %{count} prublemi quì sottu. + imports: + preface: Pudete impurtà certi dati cumu e persone chì seguitate o bluccate nant’à u vostru contu nant’à st’istanza à partesi di fugliali creati nant’à un’altr’istanza. + success: I vostri dati sò stati impurtati è saranu trattati da quì à pocu. + types: + blocking: Persone chì bluccate + following: Persone chì seguitate + muting: Persone chì piattate + upload: Impurtà + in_memoriam_html: In mimoria. + invites: + delete: Disattivà + expired: Spirata + expires_in: + '1800': 30 minuti + '21600': 6 ore + '3600': 1 ora + '43200': 12 ore + '604800': 1 settimana + '86400': 1 ghjornu + expires_in_prompt: Mai + generate: Creà + max_uses: + one: 1 usu + other: "%{count} usi" + max_uses_prompt: Micca limita + prompt: Create è spartete ligami cù altre parsone per dà accessu à l’istanza + table: + expires_at: Spira + uses: Utiliza + title: Invità ghjente + landing_strip_html: "%{name} hè nant’à %{link_to_root_path}. Pudete seguitallu·a o cumunicà cù ellu·a cù un contu in qualche parte di u fediverse." + landing_strip_signup_html: Pudete ancu arrigistravi quì. + lists: + errors: + limit: Ùn pudete più creà altre liste. + media_attachments: + validations: + images_and_video: Ùn si pò micca aghjunghje un filmettu à un statutu chì hà digià ritratti + too_many: Ùn si pò micca aghjunghje più di 4 fugliali + migrations: + acct: cugnome@duminiu di u novu contu + currently_redirecting: "’U vostru prufile riindiriza tuttu versu à:’" + proceed: Salvà + updated_msg: I paramettri di migrazione sò stati messi à ghjornu! + moderation: + title: Muderazione + notification_mailer: + digest: + action: Vede tutte e nutificazione + body: Eccu cio ch’avete mancatu dapoi à a vostr’ultima visita u %{since} + mention: "%{name} v’hà mintuvatu·a in:" + new_followers_summary: + one: Avete ancu un’abbunatu novu! + other: Avete ancu %{count} abbunati novi! + subject: + one: "Una nutificazione nova dapoi à a vostr’ultima visita \U0001F418" + other: "%{count} nutificazione nove dapoi à a vostr’ultima visita \U0001F418" + title: Dapoi l’ultima volta… + favourite: + body: "%{name} hà aghjuntu u vostru statutu à i so favuriti :" + subject: "%{name} hà messu u vostru post in i so favuriti" + title: Novu favuritu + follow: + body: "%{name} s’hè abbunatu à u vostru contu !" + subject: "%{name} vi seguita" + title: Abbunatu novu + follow_request: + action: Vede e dumande d’abbunamentu + body: "%{name} vole abbunassi à u vostru contu" + subject: 'Dumanda d’abbunamentu: %{name}' + title: Nova dumanda d’abbunamentu + mention: + action: Risposta + body: "%{name} v’hà mintuvatu·a indè :" + subject: "%{name} v’hà mintuvatu·a" + title: Nova menzione + reblog: + body: 'U vostru statutu hè statu spartutu da %{name}:' + subject: "%{name} hà spartutu u vostru statutu" + title: Nova spartera + number: + human: + decimal_units: + format: "%n%u" + units: + billion: G + million: M + quadrillion: P + thousand: K + trillion: T + unit: '' + pagination: + newer: Più ricente + next: Dopu + older: Più vechju + prev: Nanzu + truncate: "…" + preferences: + languages: Lingue + other: Altre + publishing: Pubblicazione + web: Web + push_notifications: + favourite: + title: "%{name} hà aghjuntu u vostru statutu à i so favuriti" + follow: + title: "%{name} vi seguita" + group: + title: "%{count} nutificazioni" + mention: + action_boost: Sparte + action_expand: Vede di più + action_favourite: Aghjunghje à i favuriti + title: "%{name} v’hà mintuvatu·a" + reblog: + title: "%{name} hà spartutu u vostru statutu" + remote_follow: + acct: Entrate u vostru cugnome@istanza da induve vulete siguità stu contu. + missing_resource: Ùn avemu pussutu à truvà l’indirizzu di ridirezzione + proceed: Cuntinuà per siguità + prompt: 'Avete da siguità:' + remote_unfollow: + error: Errore + title: Titulu + unfollowed: Disabbunatu + sessions: + activity: Ultima attività + browser: Navigatore + browsers: + alipay: Alipay + blackberry: Blackberry + chrome: Chrome + edge: Microsoft Edge + electron: Electron + firefox: Firefox + generic: Navigatore scunnisciutu + ie: Internet Explorer + micro_messenger: MicroMessenger + nokia: Nokia S40 Ovi Browser + opera: Opera + otter: Otter + phantom_js: PhantomJS + qq: QQ Browser + safari: Safari + uc_browser: UCBrowser + weibo: Weibo + current_session: Sessione attuale + description: "%{browser} nant’à %{platform}" + explanation: Quessi sò i navigatori cunnettati à u vostru contu Mastodon. + ip: IP + platforms: + adobe_air: Adobe Air + android: Android + blackberry: Blackberry + chrome_os: ChromeOS + firefox_os: Firefox OS + ios: iOS + linux: Linux + mac: Mac + other: piattaforma scunnisciuta + windows: Windows + windows_mobile: Windows Mobile + windows_phone: Windows Phone + revoke: Rivucà + revoke_success: Sessione rivucata + title: Sessioni + settings: + authorized_apps: Applicazione auturizate + back: Ritornu nant’à Mastodon + delete: Suppressione di u contu + development: Sviluppu + edit_profile: Mudificà u prufile + export: Spurtazione d’infurmazione + followers: Abbunati auturizati + import: Impurtazione + migrate: Migrazione di u contu + notifications: Nutificazione + preferences: Priferenze + settings: Parametri + two_factor_authentication: Identificazione à dui fattori + your_apps: E vostre applicazione + statuses: + attached: + description: 'Aghjuntu: %{attached}' + image: + one: "%{count} ritrattu" + other: "%{count} ritratti" + video: + one: "%{count} filmettu" + other: "%{count} filmetti" + content_warning: 'Avertimentu: %{warning}' + disallowed_hashtags: + one: 'cuntene l’hashtag disattivatu: %{tags}' + other: 'cuntene l’hashtag disattivati: %{tags}' + open_in_web: Apre nant’à u web + over_character_limit: Site sopr’à a limita di %{max} caratteri + pin_errors: + limit: Avete digià puntarulatu u numeru massimale di statuti + ownership: Pudete puntarulà solu unu di i vostri propii statuti + private: Ùn pudete micca puntarulà un statutu ch’ùn hè micca pubblicu + reblog: Ùn pudete micca puntarulà una spartera + show_more: Vede di più + title: '%{name}: "%{quote}"' + visibilities: + private: Solu per l’abbunati + private_long: Mustrà solu à l’abbunati + public: Pubblicu + public_long: Tuttu u mondu pò vede + unlisted: Micca listatu + unlisted_long: Tuttu u mondu pò vede, mà micca indè e linee pubbliche + stream_entries: + click_to_show: Cliccà per vede + pinned: Statutu puntarulatu + reblogged: spartutu + sensitive_content: Cuntenutu sensibile + terms: + body_html: | +

    Privacy Policy

    +

    What information do we collect?

    + +
      +
    • Basic account information: If you register on this server, you may be asked to enter a username, an e-mail address and a password. You may also enter additional profile information such as a display name and biography, and upload a profile picture and header image. The username, display name, biography, profile picture and header image are always listed publicly.
    • +
    • Posts, following and other public information: The list of people you follow is listed publicly, the same is true for your followers. When you submit a message, the date and time is stored as well as the application you submitted the message from. Messages may contain media attachments, such as pictures and videos. Public and unlisted posts are available publicly. When you feature a post on your profile, that is also publicly available information. Your posts are delivered to your followers, in some cases it means they are delivered to different servers and copies are stored there. When you delete posts, this is likewise delivered to your followers. The action of reblogging or favouriting another post is always public.
    • +
    • Direct and followers-only posts: All posts are stored and processed on the server. Followers-only posts are delivered to your followers and users who are mentioned in them, and direct posts are delivered only to users mentioned in them. In some cases it means they are delivered to different servers and copies are stored there. We make a good faith effort to limit the access to those posts only to authorized persons, but other servers may fail to do so. Therefore it’s important to review servers your followers belong to. You may toggle an option to approve and reject new followers manually in the settings. Please keep in mind that the operators of the server and any receiving server may view such messages, and that recipients may screenshot, copy or otherwise re-share them. Do not share any dangerous information over Mastodon.
    • +
    • IPs and other metadata: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.
    • +
    + +
    + +

    What do we use your information for?

    + +

    Any of the information we collect from you may be used in the following ways:

    + +
      +
    • To provide the core functionality of Mastodon. You can only interact with other people’s content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.
    • +
    • To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.
    • +
    • The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.
    • +
    + +
    + +

    How do we protect your information?

    + +

    We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.

    + +
    + +

    What is our data retention policy?

    + +

    We will make a good faith effort to:

    + +
      +
    • Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.
    • +
    • Retain the IP addresses associated with registered users no more than 12 months.
    • +
    + +

    You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.

    + +

    You may irreversibly delete your account at any time.

    + +
    + +

    Do we use cookies?

    + +

    Yes. Cookies are small files that a site or its service provider transfers to your computer’s hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.

    + +

    We use cookies to understand and save your preferences for future visits.

    + +
    + +

    Do we disclose any information to outside parties?

    + +

    We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.

    + +

    Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.

    + +

    When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.

    + +
    + +

    Children’s Online Privacy Protection Act Compliance

    + +

    Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (Children’s Online Privacy Protection Act) do not use this site.

    + +
    + +

    Changes to our Privacy Policy

    + +

    If we decide to change our privacy policy, we will post those changes on this page.

    + +

    This document is CC-BY-SA. It was last updated March 7, 2018.

    + +

    Originally adapted from the Discourse privacy policy.

    + title: Termini d’usu è di cunfidenzialità per %{instance} + themes: + contrast: Cuntrastu altu + default: Mastodon + time: + formats: + default: "%d %b %Y, %H:%M" + two_factor_authentication: + code_hint: Entrate u codice generatu da l’applicazione per cunfirmà + description_html: S’ella hè attivata l’identificazione à dui fattori, duvete avè u vostru telefuninu pè ottene un codice di cunnezzione. + disable: Disattivà + enable: Attivà + enabled: Identificazione à dui fattori attivata + enabled_success: L’identificazione à dui fattori hè stata attivata. + generate_recovery_codes: Creà codici di ricuperazione + instructions_html: "Scanate stu QR code cù Google Authenticator, Authy o qualcosa cusì nant’à u vostru telefuninu. St’applicazione hà da creà codici da entrà ogni volta chì vi cunnettate." + lost_recovery_codes: I codici di ricuperazione à usu unicu vi permettenu di sempre avè accessu à u vostru contu s’è voi avete persu u vostru telefuninu. S’elli sò ancu persi, pudete creà codici novi quì. I vechji codici ùn marchjeranu più. + manual_instructions: S’ellu ùn hè micca pussibule scanà u QR code, pudete entre sta chjave sicreta:’ + recovery_codes: Codici di ricuperazione + recovery_codes_regenerated: Codici di ricuperazione ricreati + recovery_instructions_html: Pudete fà usu di i codici quì sottu per sempre avè accessu à u vostru contu s’ellu hè statu persu u vostru telefuninu. Guardateli in una piazza sicura. Per esempiu, stampati è cunservati cù altri ducumenti impurtanti. + setup: Installà + wrong_code: U codice ùn hè micca currettu! Site sicuru che l’ora di u telefuninu è di u servore sò esatte? + user_mailer: + backup_ready: + explanation: Avete dumandatu un’archiviu cumpletu di u vostru contu Mastodon. Avà hè prontu per scaricà! + subject: U vostru archiviu hè prontu à scaricà + title: Archiviu prontu + welcome: + edit_profile_action: Cunfigurazione di u prufile + edit_profile_step: Pudete persunalizà u vostru prufile cù un ritrattu di prufile o di cuprendula, un nome pubblicu persunalizatu, etc. Pudete ancu rende u contu privatu per duvè cunfirmà ogni dumanda d’abbunamentu. + explanation: Eccu alcune idee per principià + final_action: Principià à pustà + final_step: 'Andemu! Ancu senza abbunati i vostri missaghji pubblichi puderanu esse visti da altre persone, per esempiu nant’a linea lucale è l’hashtag. Pudete ancu prisintavi nant’à u hashtag #introductions!' + full_handle: U vostru identificatore cumplettu + full_handle_hint: Quessu ghjè cio chì direte à i vostri amichi per circavi, abbunassi à u vostru contu da altrò, o mandà missaghji. + review_preferences_action: Mudificà e priferenze + review_preferences_step: Quì pudete adattà u cumpurtamentu di Mastodon à e vostre priferenze, cum’è l’email che vulete riceve, u nivellu di cunfidenzialità predefinitu di i vostri statuti, o u cumpurtamentu di i GIF animati. + subject: Benvenutu·a nant’à Mastodon + tip_bridge_html: S’è voi venite di Twitter, pudete truvà i vostri amichi da quallà chì sò nant’à Mastodon cù a bridge app. Mà ùn marchja chè s’elli l’anu ancu usata! + tip_federated_timeline: A linea pubblica glubale mostra i statuti da altre istanze nant’a rete Mastodon, mà ùn hè micca cumpleta perchè ci sò soli i conti à quelli sò abbunati membri di a vostr’istanza. + tip_following: Site digià abbunatu·a à l’amministratori di u vostru servore. Per truvà d’altre parsone da siguità, pudete pruvà e linee pubbliche. + tip_local_timeline: A linea pubblica lucale ghjè una vista crunulogica di i statuti di a ghjente nant’à %{instance}. + tip_mobile_webapp: Pudete aghjunghje Mastodon à a pagina d’accolta di u vostru navigatore di telefuninu per riceve nutificazione, cum’un applicazione. + tips: Cunsiglii + title: Benvenutu·a, %{name}! + users: + invalid_email: L’indirizzu e-mail ùn hè currettu. + invalid_otp_token: U codice d’identificazione ùn hè currettu. + seamless_external_login: Site cunnettatu·a dapoi un serviziu esternu, allora i parametri di chjave d’accessu è d’indirizzu e-mail ùn so micca dispunibili. + signed_in_as: 'Cunnettatu·a cum’è:' diff --git a/config/locales/devise.co.yml b/config/locales/devise.co.yml new file mode 100644 index 0000000000..d5bb708876 --- /dev/null +++ b/config/locales/devise.co.yml @@ -0,0 +1,82 @@ +--- +co: + devise: + confirmations: + confirmed: U vostru indirizzu email hè statu cunfirmatu. + send_instructions: Avete da riceve un’email cù l’istruzzione di cunfirmazione in qualchì minuta. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda. + send_paranoid_instructions: S’ellu esiste u vostru indirizzu email in a database, avete da riceve l’istruzzione pè cunfirmà u vostru contu in qualchì minuta. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda. + failure: + already_authenticated: Site digià cunnettatu·a. + inactive: U vostru contu ùn hè ancu attivatu. + invalid: L’ %{authentication_keys} o a chjave d’accessu ùn sò curretti. + last_attempt: Avete un’ultimu tintativu nanzu chì u vostru contu sia chjosu. + locked: U vostru contu hè chjosu. + not_found_in_database: L’ %{authentication_keys} o a chjave d’accessu ùn sò curretti. + timeout: A vostra sezzione hè spirata. Ricunnettatevi pè cuntinuà. + unauthenticated: Cunnettatevi o arregistratevi pè cuntinuà. + unconfirmed: Duvete cunfirmà u vostru contu pè cuntinuà. + mailer: + confirmation_instructions: + action: Verificà l’indirizzu email + explanation: Avete creatu un contu nant’à %{host} cù st’indirizzu email. Pudete attivallu cù un clic, o ignurà quessu missaghji s’ellu un era micca voi. + extra_html: Pensate à leghje e regule di l’istanza è i termini d’usu. + subject: 'Mastodon: Istruzzione di cunfirmazione per %{instance}' + title: Verificà l’indirizzu email + email_changed: + explanation: 'L’indirizzu email di u vostru contu hè stata cambiata per:' + extra: S’ellu un era micca voi ch’avete cambiatu u vostru email, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di l’istanza s’ellu ùn hè più pussibule di cunnettavi. + subject: 'Mastodon: Email cambiatu' + title: Novu indirizzu email + password_change: + explanation: A chjave d’accessu per u vostru contu hè stata cambiata. + extra: S’ellu un era micca voi ch’avete cambiatu a vostra chjave d’accessu, qualch’un’altru hà accessu à u vostru contu. Duvete cambià a vostra chjave d’accessu o cuntattà l’amministratore di l’istanza s’ellu ùn hè più pussibule di cunnettavi. + subject: 'Mastodon: Chjave d’accessu cambiata' + title: Chjave cambiata + reconfirmation_instructions: + explanation: Cunfirmà u novu indirizzu per cambià l’email. + extra: S’ellu ùn era micca voi, ignurate stu missaghju. L’email ùn cambiarà micca s’è voi ùn cliccate micca u ligame. + subject: 'Mastodon: Cunfirmà l’email per %{instance}' + title: Verificà indirizzu email + reset_password_instructions: + action: Cambià a chjave d’accessu + explanation: Avete dumandatu una nova chjave d’accessu per u vostru contu. + extra: S’ellu ùn era micca voi, ignurate stu missaghju. A chjave d’accessu ùn cambiarà micca s’è voi ùn cliccate micca u ligame. + subject: 'Mastodon: Cambià a chjave d’accessu' + title: Cambià a chjave + unlock_instructions: + subject: 'Mastodon: Riapre u contu' + omniauth_callbacks: + failure: Ùn pudemu micca cunnettavi da %{kind} perchè "%{reason}". + success: Vi site cunnettatu·a da %{kind}. + passwords: + no_token: Ùn pudete micca vede sta pagina senza vene d’un e-mail di cambiamentu di chjave d’accessu. S’è voi venite quì dapoi st’e-mail, assicuratevi ch’avete utilizatu l’indirizzu URL cumpletu. + send_instructions: Avete da riceve l’istruzzione di cambiamentu di a chjave d’accessu in qualchì minuta. + send_paranoid_instructions: S’ellu esiste u vostr’e-mail in a database, avete da riceve un ligame di reinizialisazione. + updated: A vostra chjave d’accessu hè stata cambiata, è site cunnettatu·a. + updated_not_active: A vostra chjave d’accessu hè stata cambiata. + registrations: + destroyed: U vostru contu hè statu sguassatu. Avvedeci! + signed_up: Benvinutu! Site cunnettatu·a. + signed_up_but_inactive: Site arregistratu·a, mà ùn pudete micca cunnettavi perchè u vostru contu deve esse attivatu. + signed_up_but_locked: Site arregistratu·a, mà ùn pudete micca cunnettavi perchè u vostru contu hè chjosu. + signed_up_but_unconfirmed: Un missaghju cù un ligame di cunfirmazione hè statu mandatu à u vostru indirizzu e-mail. Aprite stu ligame pè attivà u vostru contu. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda. + update_needs_confirmation: U vostru contu hè statu messu à ghjornu mà duvemu verificà u vostru novu e-mail. Un missaghju cù un ligame di cunfirmazione hè statu mandatu. Pensate à verificà u cartulare di spam s’ellu ùn c’hè nunda. + updated: U vostru contu hè statu messu à ghjornu. + sessions: + already_signed_out: Scunnettatu·a. + signed_in: Cunnettatu·a. + signed_out: Scunnettatu·a. + unlocks: + send_instructions: Avete da riceve un’e-mail cù l’istruzzione pè riapre u vostru contu in qualchì minuta. + send_paranoid_instructions: S’ellu esiste u vostru contu, avete da riceve un’e-mail dù l’istruzzione pè riapre u vostru contu. + unlocked: U vostru contu hè statu riapertu, pudete cunnettavi pè cuntinuà. + errors: + messages: + already_confirmed: hè digià cunfirmatu, pudete pruvà à cunnettà vi + confirmation_period_expired: deve esse cunfirmatu nanz’à %{period}, duvete fà un’altra dumanda + expired: hè spiratu, duvete fà un’altra dumanda + not_found: ùn hè micca statu trovu + not_locked: ùn era micca chjosu + not_saved: + one: Un prublemu hà impeditu a cunservazione di stu (sta) %{resource} + other: "%{count} prublemi anu impeditu a cunservazione di stu (sta) %{resource} :" diff --git a/config/locales/doorkeeper.co.yml b/config/locales/doorkeeper.co.yml new file mode 100644 index 0000000000..01b082e401 --- /dev/null +++ b/config/locales/doorkeeper.co.yml @@ -0,0 +1,119 @@ +--- +co: + activerecord: + attributes: + doorkeeper/application: + name: Nome di l’applicazione + redirect_uri: URI di ridirezzione + scopes: Scopi + website: Situ di l’applicazione + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ùn pò cuntene un pezzu. + invalid_uri: duve esse un’URI curretta. + relative_uri: duve esse un’URI assoluta. + secured_uri: duve esse un’URL HTTPS/SSL. + doorkeeper: + applications: + buttons: + authorize: Appruvà + cancel: Sguassà + destroy: Strughje + edit: Mudificà + submit: Mandà + confirmations: + destroy: Site sicuru·a? + edit: + title: Mudificà l’applicazione + form: + error: Uups! V’invitemu à verificà u vostru formulariu per vede s’elli ùn ci sò sbaglii. + help: + native_redirect_uri: Utilizate %{native_redirect_uri} pè e prove lucale + redirect_uri: Utilizzate una linea per ogni URI + scopes: Separate i scopi cù spazii. Lasciate viotu per utilizzà i scopi predefiniti. + index: + application: Applicazione + callback_url: URL di richjama + delete: Toglie + name: Nome + new: Applicazione nova + scopes: Scopi + show: Vede + title: E vostre applicazione + new: + title: Applicazione nova + show: + actions: Azzioni + application_id: Chjave di u clientu + callback_urls: URL di richjama + scopes: Scopi + secret: Sicretu di u clientu + title: 'Applicazione : %{name}' + authorizations: + buttons: + authorize: Appruvà + deny: Ricusà + error: + title: C’hè statu un prublemu + new: + able_to: St’applicazione puderà + prompt: Parmette %{client_name} d’utilizzà u vostru contu? + title: Permessu riquestu + show: + title: Codice d’auturizazione da cupià indè l’applicazione + authorized_applications: + buttons: + revoke: Sguassà + confirmations: + revoke: Site sicuru·a? + index: + application: Applicazione + created_at: Auturizata u + date_format: "%d-%m-%Y %H:%M:%S" + scopes: Scopi + title: E vostre applicazione auturizate + errors: + messages: + access_denied: U pruprietariu di a risorsa o u servore d’autitinficazione hà ricusatu a dumanda. + credential_flow_not_configured: U flussu di l’identificazione di u pruprietariu di a risorsa hà fiascatu perchè Doorkeeper.configure.resource_owner_from_credentials ùn hè micca cunfiguratu. + invalid_client: L’autintificazione di u cliente hà fiascatu perchè u cliente ùn hè micca cunnisciutu, l’identificazione di u cliente ùn hè cumpresa, o u modu d’identificazione ùn marchja micca. + invalid_grant: L’accunsentu d’auturizazione furnitu ùn hè currettu, hè spiratu, sguassatu, ùn và micca cù l’indirizzu di ridirezzione usatu in a dumanda d’auturizazione, o hè statu emessu per un’altru cliente. + invalid_redirect_uri: L’URI di ridirezzione ùn hè curretta. + invalid_request: Ci manca un parametru riquestu indè a dumanda, cuntene un parametru ch’ùn esiste micca, o altru sbagliu di forma. + invalid_resource_owner: L’idintificanti di u pruprietariu di a risorsa ùn sò curretti, o u pruprietariu ùn pò micca esse trovu. + invalid_scope: U scopu dumandatu ùn hè currettu, hè scunnisciutu, o altru sbagliu di forma. + invalid_token: + expired: A marca d’accessu hè spirata + revoked: A marca d’accessu hè stata rivucata + unknown: A marca d’accessu ùn hè curretta + resource_owner_authenticator_not_configured: Ùn c’hè micca pussutu ricercà u pruprietariu di a risorsa perchè Doorkeeper.configure.resource_owner_authenticator ùn hè micca cunfiguratu. + server_error: C’hè statu un prublemu cù u servore d’auturizazione. + temporarily_unavailable: U servore d’auturizazione ùn pò micca trattà a dumanda avà perchè hè sopraccaricatu o in mantenimentu. + unauthorized_client: U cliente ùn pò micca fà sta dumanda cusì. + unsupported_grant_type: Stu tippu d’accunsentu ùn marchja micca nant’à stu servore d’auturizazione. + unsupported_response_type: Sta risposta ùn marchja micca nant’à stu servore d’auturizazione. + flash: + applications: + create: + notice: Applicazione creata. + destroy: + notice: Applicazione sguassata. + update: + notice: Applicazione messa à ghjornu. + authorized_applications: + destroy: + notice: Applicazione sguassata. + layouts: + admin: + nav: + applications: Applicazione + oauth2_provider: Furnitore OAuth2 + application: + title: Auturizazione OAuth riquestata. + scopes: + follow: bluccà, sbluccà, è reghje l’abbunamenti + read: leghje l’infurmazione di u vostru contu + write: mandà missaghji per voi diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml new file mode 100644 index 0000000000..21404897b3 --- /dev/null +++ b/config/locales/simple_form.co.yml @@ -0,0 +1,79 @@ +--- +co: + simple_form: + hints: + defaults: + avatar: Furmatu PNG, GIF o JPG. 2Mo o menu. Sarà ridottu à 400x400px + digest: Solu mandatu dopu à una longa perioda d’inattività, è solu s’elli ci sò novi missaghji diretti + display_name: + one: Ci ferma 1 caratteru + other: Ci fermanu %{count} caratteri + fields: Pudete avè fin’à 4 elementi mustrati cum’un tavulone nant’à u vostru prufile + header: Furmatu PNG, GIF o JPG. 2Mo o menu. Sarà ridottu à 700x335px + locked: Duvarete appruvà e dumande d’abbunamentu + note: + one: Ci ferma 1 caratteru + other: Ci fermanu %{count} caratteri + setting_noindex: Tocca à u vostru prufile pubblicu è i vostri statuti + setting_theme: Tocca à l’apparenza di Mastodon quandu site cunnettatu·a da qualch’apparechju. + imports: + data: Un fugliale CSV da un’altr’istanza di Mastodon + sessions: + otp: Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione. + user: + filtered_languages: Ùn viderete micca e lingue selezziunate nant’à e linee pubbliche. + labels: + account: + fields: + name: Label + value: Content + defaults: + avatar: Ritrattu di prufile + confirm_new_password: Cunfirmà a nova chjave d’accessu + confirm_password: Cunfirmà a chjave d’accessu + current_password: Chjave d’accessu attuale + data: Dati + display_name: Nome pubblicu + email: Indirizzu e-mail + expires_in: Spira dopu à + fields: Metadata di u prufile + filtered_languages: Lingue filtrate + header: Ritrattu di cuprendula + locale: Lingua + locked: Privatizà u contu + max_uses: Numeru massimale d’utilizazione + new_password: Nova chjave d’accessu + note: Descrizzione + otp_attempt: Codice d’identificazione à dui fattori + password: Chjave d’accessu + setting_auto_play_gif: Lettura autumatica di i GIF animati + setting_boost_modal: Mustrà una cunfirmazione per sparte un statutu + setting_default_privacy: Cunfidenzialità di i statuti + setting_default_sensitive: Sempre cunsiderà media cum’è sensibili + setting_delete_modal: Mustrà une cunfirmazione per toglie un statutu + setting_display_sensitive_media: Sempre mustrà media marcati cum’è sensibili + setting_noindex: Dumandà à i motori di ricerca internet d’un pudè micca esse truvatu·a cusì + setting_reduce_motion: Fà chì l’animazione vanu più pianu + setting_system_font_ui: Pulizza di caratteri di u sistemu + setting_theme: Tema di u situ + setting_unfollow_modal: Mustrà una cunfirmazione per siguità qualch’unu + severity: Severità + type: Tippu d’impurtazione + username: Cugnome + username_or_email: Cugnome o Email + interactions: + must_be_follower: Piattà e nutificazione di quelli·e ch’ùn vi seguitanu + must_be_following: Piattà e nutificazione di quelli·e ch’ùn seguitate + must_be_following_dm: Bluccà e missaghji diretti di quelli·e ch’ùn seguitate + notification_emails: + digest: Mandà e-mail di ricapitulazione + favourite: Mandà un’e-mail quandu qualch’unu aghjunghje i mo statuti à i so favuriti + follow: Mandà un’e-mail quandu qualch’unu mi seguita + follow_request: Mandà un’e-mail quandu qualch’unu vole seguitami + mention: Mandà un’e-mail quandu qualch’unu mi mintuva + reblog: Mandà un’e-mail quandu qualch’unu sparte i mo statuti + 'no': Nò + required: + mark: "*" + text: riquisiti + 'yes': Ié From 27cfb13b836753023bdcca8660e1fefa3b64640e Mon Sep 17 00:00:00 2001 From: Hugo Gameiro Date: Mon, 7 May 2018 01:28:28 +0100 Subject: [PATCH 024/239] Improve OpenStack v3 compatibility (#7392) * Update paperclip.rb * Update .env.production.sample * Update paperclip.rb --- .env.production.sample | 2 ++ config/initializers/paperclip.rb | 1 + 2 files changed, 3 insertions(+) diff --git a/.env.production.sample b/.env.production.sample index c936546da8..24b6b01439 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -113,6 +113,8 @@ SMTP_FROM_ADDRESS=notifications@example.com # For Keystone V3, the value for SWIFT_TENANT should be the project name # SWIFT_TENANT= # SWIFT_PASSWORD= +# Some OpenStack V3 providers require PROJECT_ID (optional) +# SWIFT_PROJECT_ID= # Keystone V2 and V3 URLs are supported. Use a V3 URL if possible to avoid # issues with token rate-limiting during high load. # SWIFT_AUTH_URL= diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index 17a520aa20..c134bc5b8f 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -60,6 +60,7 @@ elsif ENV['SWIFT_ENABLED'] == 'true' fog_credentials: { provider: 'OpenStack', openstack_username: ENV['SWIFT_USERNAME'], + openstack_project_id: ENV['SWIFT_PROJECT_ID'], openstack_project_name: ENV['SWIFT_TENANT'], openstack_tenant: ENV['SWIFT_TENANT'], # Some OpenStack-v2 ignores project_name but needs tenant openstack_api_key: ENV['SWIFT_PASSWORD'], From b9c17c6580f8335b227b65842be129959796f6ee Mon Sep 17 00:00:00 2001 From: abcang Date: Mon, 7 May 2018 16:30:18 +0900 Subject: [PATCH 025/239] Fix distribute_add_activity and distribute_remove_activity (#7393) --- app/controllers/api/v1/statuses/pins_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/statuses/pins_controller.rb b/app/controllers/api/v1/statuses/pins_controller.rb index bba6a6f480..54f8be667d 100644 --- a/app/controllers/api/v1/statuses/pins_controller.rb +++ b/app/controllers/api/v1/statuses/pins_controller.rb @@ -39,7 +39,7 @@ class Api::V1::Statuses::PinsController < Api::BaseController adapter: ActivityPub::Adapter ).as_json - ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account) + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account.id) end def distribute_remove_activity! @@ -49,6 +49,6 @@ class Api::V1::Statuses::PinsController < Api::BaseController adapter: ActivityPub::Adapter ).as_json - ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account) + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account.id) end end From 8b63d3942795e2837384c8045da950a24c53779f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 May 2018 09:30:38 +0200 Subject: [PATCH 026/239] Use plaintext value for field value tooltips in web UI (#7388) Fix #7383 --- app/javascript/mastodon/actions/importer/normalizer.js | 2 ++ app/javascript/mastodon/actions/notifications.js | 8 +------- .../mastodon/features/account/components/header.js | 2 +- app/javascript/mastodon/utils/html.js | 6 ++++++ 4 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 app/javascript/mastodon/utils/html.js diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 057bff58bd..c015d3a994 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -1,5 +1,6 @@ import escapeTextContentForBrowser from 'escape-html'; import emojify from '../../features/emoji/emoji'; +import { unescapeHTML } from '../../utils/html'; const domParser = new DOMParser(); @@ -22,6 +23,7 @@ export function normalizeAccount(account) { ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), value_emojified: emojify(pair.value, emojiMap), + value_plain: unescapeHTML(pair.value), })); } diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js index 7aa070f569..393268811e 100644 --- a/app/javascript/mastodon/actions/notifications.js +++ b/app/javascript/mastodon/actions/notifications.js @@ -8,6 +8,7 @@ import { importFetchedStatuses, } from './importer'; import { defineMessages } from 'react-intl'; +import { unescapeHTML } from '../utils/html'; export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE'; export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP'; @@ -31,13 +32,6 @@ const fetchRelatedRelationships = (dispatch, notifications) => { } }; -const unescapeHTML = (html) => { - const wrapper = document.createElement('div'); - html = html.replace(/
    |
    |\n/g, ' '); - wrapper.innerHTML = html; - return wrapper.textContent; -}; - export function updateNotifications(notification, intlMessages, intlLocale) { return (dispatch, getState) => { const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true); diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index def6257956..47915e6fb8 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -146,7 +146,7 @@ export default class Header extends ImmutablePureComponent { {fields.map((pair, i) => (
    -
    +
    ))}
    diff --git a/app/javascript/mastodon/utils/html.js b/app/javascript/mastodon/utils/html.js new file mode 100644 index 0000000000..0b646ce58f --- /dev/null +++ b/app/javascript/mastodon/utils/html.js @@ -0,0 +1,6 @@ +export const unescapeHTML = (html) => { + const wrapper = document.createElement('div'); + html = html.replace(/
    |
    |\n/g, ' '); + wrapper.innerHTML = html; + return wrapper.textContent; +}; From b890e5830c3933d8356c0d787ae2fef246505ae5 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 May 2018 09:30:53 +0200 Subject: [PATCH 027/239] Support explicitly supplying language code for status via REST API (#7389) --- app/services/post_status_service.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 9d2c7a4dc5..3080fb2447 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -31,7 +31,7 @@ class PostStatusService < BaseService sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]), spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, - language: LanguageDetector.instance.detect(text, account), + language: language_from_option(options[:language]) || LanguageDetector.instance.detect(text, account), application: options[:application]) end @@ -65,6 +65,10 @@ class PostStatusService < BaseService media end + def language_from_option(str) + ISO_639.find(str)&.alpha2 + end + def process_mentions_service ProcessMentionsService.new end From 7ff3c849d109d2c9960521db9b9bccf1d391a387 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 May 2018 09:31:07 +0200 Subject: [PATCH 028/239] Bot nameplates (#7391) * Store actor type in database * Add bot nameplate to web UI, add setting to preferences, API, AP Fix #7365 * Fix code style issues --- .../api/v1/accounts/credentials_controller.rb | 2 +- app/controllers/settings/profiles_controller.rb | 2 +- .../mastodon/features/account/components/header.js | 4 ++++ app/javascript/styles/mastodon/components.scss | 6 ++++++ app/javascript/styles/mastodon/forms.scss | 4 ++++ app/models/account.rb | 11 +++++++++++ app/serializers/activitypub/actor_serializer.rb | 2 +- app/serializers/rest/account_serializer.rb | 2 +- app/services/activitypub/process_account_service.rb | 1 + app/views/accounts/_header.html.haml | 6 +++++- app/views/settings/profiles/show.html.haml | 3 +++ config/locales/en.yml | 1 + config/locales/simple_form.en.yml | 2 ++ .../20180506221944_add_actor_type_to_accounts.rb | 5 +++++ db/schema.rb | 3 ++- 15 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 db/migrate/20180506221944_add_actor_type_to_accounts.rb diff --git a/app/controllers/api/v1/accounts/credentials_controller.rb b/app/controllers/api/v1/accounts/credentials_controller.rb index a3c4008e64..259d07be87 100644 --- a/app/controllers/api/v1/accounts/credentials_controller.rb +++ b/app/controllers/api/v1/accounts/credentials_controller.rb @@ -21,7 +21,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController private def account_params - params.permit(:display_name, :note, :avatar, :header, :locked, fields_attributes: [:name, :value]) + params.permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value]) end def user_settings_params diff --git a/app/controllers/settings/profiles_controller.rb b/app/controllers/settings/profiles_controller.rb index 5d81668dea..1b01fc75f0 100644 --- a/app/controllers/settings/profiles_controller.rb +++ b/app/controllers/settings/profiles_controller.rb @@ -27,7 +27,7 @@ class Settings::ProfilesController < ApplicationController private def account_params - params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, fields_attributes: [:name, :value]) + params.require(:account).permit(:display_name, :note, :avatar, :header, :locked, :bot, fields_attributes: [:name, :value]) end def set_account diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 47915e6fb8..7358053da0 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -131,6 +131,7 @@ export default class Header extends ImmutablePureComponent { const content = { __html: account.get('note_emojified') }; const displayNameHtml = { __html: account.get('display_name_html') }; const fields = account.get('fields'); + const badge = account.get('bot') ? (
    ) : null; return (
    @@ -139,6 +140,9 @@ export default class Header extends ImmutablePureComponent { @{account.get('acct')} {lockedIcon} + + {badge} +
    {fields.size > 0 && ( diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 3e2a1ae104..158bf68511 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -5159,6 +5159,12 @@ noscript { } } +.account__header .roles { + margin-top: 20px; + margin-bottom: 20px; + padding: 0 15px; +} + .account__header .account__header__fields { font-size: 14px; line-height: 20px; diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index f978901870..de16784a87 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -87,6 +87,10 @@ code { align-items: flex-start; } + &.file .label_input { + flex-wrap: nowrap; + } + &.select .label_input { align-items: initial; } diff --git a/app/models/account.rb b/app/models/account.rb index 4467d1512a..2b3ef5cdc1 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -45,6 +45,7 @@ # moved_to_account_id :bigint(8) # featured_collection_url :string # fields :jsonb +# actor_type :string # class Account < ApplicationRecord @@ -149,6 +150,16 @@ class Account < ApplicationRecord moved_to_account_id.present? end + def bot? + %w(Application Service).include? actor_type + end + + alias bot bot? + + def bot=(val) + self.actor_type = ActiveModel::Type::Boolean.new.cast(val) ? 'Service' : 'Person' + end + def acct local? ? username : "#{username}@#{domain}" end diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index fcf3bdf175..41c9aa44e8 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -37,7 +37,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer end def type - 'Person' + object.bot? ? 'Service' : 'Person' end def following diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb index 8761bbb5e7..6adcd70390 100644 --- a/app/serializers/rest/account_serializer.rb +++ b/app/serializers/rest/account_serializer.rb @@ -3,7 +3,7 @@ class REST::AccountSerializer < ActiveModel::Serializer include RoutingHelper - attributes :id, :username, :acct, :display_name, :locked, :created_at, + attributes :id, :username, :acct, :display_name, :locked, :bot, :created_at, :note, :url, :avatar, :avatar_static, :header, :header_static, :followers_count, :following_count, :statuses_count diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index f67ebb443a..cc416b6717 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -71,6 +71,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.note = @json['summary'] || '' @account.locked = @json['manuallyApprovesFollowers'] || false @account.fields = property_values || {} + @account.actor_type = @json['type'] end def set_fetchable_attributes! diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 13dcaf616a..4098d6778a 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -10,7 +10,11 @@ %span>< @#{account.local_username_and_domain} = fa_icon('lock') if account.locked? - - if Setting.show_staff_badge + - if account.bot? + .roles + .account-role.bot + = t 'accounts.roles.bot' + - elsif Setting.show_staff_badge - if account.user_admin? .roles .account-role.admin diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml index f28834d72e..a84f8a7da7 100644 --- a/app/views/settings/profiles/show.html.haml +++ b/app/views/settings/profiles/show.html.haml @@ -19,6 +19,9 @@ .fields-group = f.input :locked, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.locked') + .fields-group + = f.input :bot, as: :boolean, wrapper: :with_label, hint: t('simple_form.hints.defaults.bot') + .fields-group .input.with_block_label %label= t('simple_form.labels.defaults.fields') diff --git a/config/locales/en.yml b/config/locales/en.yml index e18354eac4..5369311ac5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -49,6 +49,7 @@ en: reserved_username: The username is reserved roles: admin: Admin + bot: Bot moderator: Mod unfollow: Unfollow admin: diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 7ba32906d4..495c6166b4 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -4,6 +4,7 @@ en: hints: defaults: avatar: PNG, GIF or JPG. At most 2MB. Will be downscaled to 400x400px + bot: Warns people that the account does not represent a person digest: Only sent after a long period of inactivity and only if you have received any personal messages in your absence display_name: one: 1 character left @@ -29,6 +30,7 @@ en: value: Content defaults: avatar: Avatar + bot: This is a bot account confirm_new_password: Confirm new password confirm_password: Confirm password current_password: Current password diff --git a/db/migrate/20180506221944_add_actor_type_to_accounts.rb b/db/migrate/20180506221944_add_actor_type_to_accounts.rb new file mode 100644 index 0000000000..7cfed640f7 --- /dev/null +++ b/db/migrate/20180506221944_add_actor_type_to_accounts.rb @@ -0,0 +1,5 @@ +class AddActorTypeToAccounts < ActiveRecord::Migration[5.2] + def change + add_column :accounts, :actor_type, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 566a320d87..f7fa24b835 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_04_16_210259) do +ActiveRecord::Schema.define(version: 2018_05_06_221944) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -75,6 +75,7 @@ ActiveRecord::Schema.define(version: 2018_04_16_210259) do t.bigint "moved_to_account_id" t.string "featured_collection_url" t.jsonb "fields" + t.string "actor_type" t.index "(((setweight(to_tsvector('simple'::regconfig, (display_name)::text), 'A'::\"char\") || setweight(to_tsvector('simple'::regconfig, (username)::text), 'B'::\"char\")) || setweight(to_tsvector('simple'::regconfig, (COALESCE(domain, ''::character varying))::text), 'C'::\"char\")))", name: "search_index", using: :gin t.index "lower((username)::text), lower((domain)::text)", name: "index_accounts_on_username_and_domain_lower" t.index ["uri"], name: "index_accounts_on_uri" From 244a270a8034bcf6bc1393f52bb76a0989e2119c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 May 2018 14:49:13 +0200 Subject: [PATCH 029/239] If an OStatus message contains nsfw hashtag, mark it as sensitive (#7398) * If an OStatus message contains nsfw hashtag, mark it as sensitive Undo parts of #7048 * Put nsfw hashtag on OStatus messages if they have any media * Fix code style issues --- app/lib/ostatus/activity/creation.rb | 8 +++++++- app/lib/ostatus/atom_serializer.rb | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb index 1e7f470299..dbccc83302 100644 --- a/app/lib/ostatus/activity/creation.rb +++ b/app/lib/ostatus/activity/creation.rb @@ -46,7 +46,8 @@ class OStatus::Activity::Creation < OStatus::Activity::Base visibility: visibility_scope, conversation: find_or_create_conversation, thread: thread? ? find_status(thread.first) || find_activitypub_status(thread.first, thread.second) : nil, - media_attachment_ids: media_attachments.map(&:id) + media_attachment_ids: media_attachments.map(&:id), + sensitive: sensitive? ) save_mentions(status) @@ -105,6 +106,11 @@ class OStatus::Activity::Creation < OStatus::Activity::Base private + def sensitive? + # OStatus-specific convention (not standard) + @xml.xpath('./xmlns:category', xmlns: OStatus::TagManager::XMLNS).any? { |category| category['term'] == 'nsfw' } + end + def find_or_create_conversation uri = @xml.at_xpath('./ostatus:conversation', ostatus: OStatus::TagManager::OS_XMLNS)&.attribute('ref')&.content return if uri.nil? diff --git a/app/lib/ostatus/atom_serializer.rb b/app/lib/ostatus/atom_serializer.rb index 7c66f2066e..698f2ee229 100644 --- a/app/lib/ostatus/atom_serializer.rb +++ b/app/lib/ostatus/atom_serializer.rb @@ -368,6 +368,7 @@ class OStatus::AtomSerializer append_element(entry, 'link', nil, rel: :enclosure, type: media.file_content_type, length: media.file_file_size, href: full_asset_url(media.file.url(:original, false))) end + append_element(entry, 'category', nil, term: 'nsfw') if status.sensitive? && status.media_attachments.any? append_element(entry, 'mastodon:scope', status.visibility) status.emojis.each do |emoji| From dc597005b385786dbecb00bdf01567e61f2689d9 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Mon, 7 May 2018 15:09:49 +0200 Subject: [PATCH 030/239] Port Sylvhem's mastodon-light to glitch flavour --- .../glitch/styles/mastodon-light.scss | 216 ++++++++++++++++++ .../skins/glitch/mastodon-light/common.scss | 1 + .../skins/glitch/mastodon-light/names.yml | 5 + 3 files changed, 222 insertions(+) create mode 100644 app/javascript/flavours/glitch/styles/mastodon-light.scss create mode 100644 app/javascript/skins/glitch/mastodon-light/common.scss create mode 100644 app/javascript/skins/glitch/mastodon-light/names.yml diff --git a/app/javascript/flavours/glitch/styles/mastodon-light.scss b/app/javascript/flavours/glitch/styles/mastodon-light.scss new file mode 100644 index 0000000000..46f88c9947 --- /dev/null +++ b/app/javascript/flavours/glitch/styles/mastodon-light.scss @@ -0,0 +1,216 @@ +// Set variables +$ui-base-color: #d9e1e8; +$ui-base-lighter-color: darken($ui-base-color, 57%); +$ui-highlight-color: #2b90d9; +$ui-primary-color: darken($ui-highlight-color, 28%); +$ui-secondary-color: #282c37; + +$primary-text-color: black; +$base-overlay-background: $ui-base-color; + +$login-button-color: white; +$account-background-color: white; + +// Import defaults +@import 'index'; + +// Change the color of the log in button +.button { + &.button-alternative-2 { + color: $login-button-color; + } +} + +// Change columns' default background colors +.column { + > .scrollable { + background: lighten($ui-base-color, 13%); + } +} + +.status.collapsed .status__content:after { + background: linear-gradient(rgba(lighten($ui-base-color, 13%), 0), rgba(lighten($ui-base-color, 13%), 1)); +} + +.drawer__inner { + background: $ui-base-color; +} + +.drawer > .contents { + background: $ui-base-color url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto !important; + + .mastodon { + filter: contrast(75%) brightness(75%) !important; + } +} + +// Change the default appearance of the content warning button +.status__content { + + .status__content__spoiler-link { + + background: darken($ui-base-color, 30%); + + &:hover { + background: darken($ui-base-color, 35%); + text-decoration: none; + } + + } + +} + +// Change the default appearance of the action buttons +.icon-button { + + &:hover, + &:active, + &:focus { + color: darken($ui-base-color, 40%); + transition: color 200ms ease-out; + } + + &.disabled { + color: darken($ui-base-color, 30%); + } + +} + +.status { + &.status-direct { + .icon-button.disabled { + color: darken($ui-base-color, 30%); + } + } +} + +// Change the colors used in the dropdown menu +.dropdown-menu { + background: $ui-base-color; +} + +.dropdown-menu__arrow { + + &.left { + border-left-color: $ui-base-color; + } + + &.top { + border-top-color: $ui-base-color; + } + + &.bottom { + border-bottom-color: $ui-base-color; + } + + &.right { + border-right-color: $ui-base-color; + } + +} + +.dropdown-menu__item { + a { + background: $ui-base-color; + color: $ui-secondary-color; + } +} + +// Change the default color of several parts of the compose form +.composer { + + .composer--spoiler input, .composer--textarea textarea { + color: darken($ui-base-color, 80%); + + &::placeholder { + color: darken($ui-base-color, 70%); + } + } + + strong { + color: lighten($ui-secondary-color, 65%); + } + + .composer--options { + background: darken($ui-base-color, 10%); + box-shadow: unset; + } + + .composer--options--dropdown--content--item { + color: $ui-primary-color; + + strong { + color: $ui-primary-color; + } + + } + +} + +// Change the default color used for the text in an empty column or on the error column +.empty-column-indicator, +.error-column { + color: darken($ui-base-color, 60%); +} + +// Change the default colors used on some parts of the profile pages +.activity-stream-tabs { + + background: $account-background-color; + + a { + &.active { + color: $ui-primary-color; + } + } + +} + +.activity-stream { + + .entry { + background: $account-background-color; + } + + .status.light { + + .status__content { + color: $primary-text-color; + } + + .display-name { + strong { + color: $primary-text-color; + } + } + + } + +} + +.accounts-grid { + .account-grid-card { + + .controls { + .icon-button { + color: $ui-secondary-color; + } + } + + .name { + a { + color: $primary-text-color; + } + } + + .username { + color: $ui-secondary-color; + } + + .account__header__content { + color: $primary-text-color; + } + + } +} + diff --git a/app/javascript/skins/glitch/mastodon-light/common.scss b/app/javascript/skins/glitch/mastodon-light/common.scss new file mode 100644 index 0000000000..c37f407b3e --- /dev/null +++ b/app/javascript/skins/glitch/mastodon-light/common.scss @@ -0,0 +1 @@ +@import 'flavours/glitch/styles/mastodon-light'; diff --git a/app/javascript/skins/glitch/mastodon-light/names.yml b/app/javascript/skins/glitch/mastodon-light/names.yml new file mode 100644 index 0000000000..f15424f2bb --- /dev/null +++ b/app/javascript/skins/glitch/mastodon-light/names.yml @@ -0,0 +1,5 @@ +en: + skins: + glitch: + mastodon-light: Mastodon (light) + From 10be4c496c12a4d6afda5a82ceae9d38f4016c37 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 8 May 2018 03:36:59 +0200 Subject: [PATCH 031/239] Fix hashtags not being federated on mentions (fixes #6900) (#7406) --- app/services/post_status_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 3080fb2447..8a1a120c38 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -35,8 +35,8 @@ class PostStatusService < BaseService application: options[:application]) end - process_mentions_service.call(status) process_hashtags_service.call(status) + process_mentions_service.call(status) LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text? DistributionWorker.perform_async(status.id) From 8ccc863ae8d05ff6c59e9c397b79ed70361ff163 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 8 May 2018 13:28:55 +0200 Subject: [PATCH 032/239] Do not crash in getStatusIds when there is a gap in the timeline (fixes #7400) (#7415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a crash occurring when the “gap” disconnection indicator is to be displayed in a filtered timeline. --- .../mastodon/features/ui/containers/status_list_container.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/mastodon/features/ui/containers/status_list_container.js b/app/javascript/mastodon/features/ui/containers/status_list_container.js index 4efacda65e..e5b1edc4a0 100644 --- a/app/javascript/mastodon/features/ui/containers/status_list_container.js +++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js @@ -21,6 +21,8 @@ const makeGetStatusIds = () => createSelector([ } return statusIds.filter(id => { + if (id === null) return true; + const statusForId = statuses.get(id); let showStatus = true; From a2b84b644ba416556609d16266ca7b83dcf8656b Mon Sep 17 00:00:00 2001 From: Surinna Curtis Date: Tue, 8 May 2018 06:30:04 -0500 Subject: [PATCH 033/239] Take the first recognized actor_type. (#7410) --- app/services/activitypub/process_account_service.rb | 10 +++++++++- spec/services/resolve_account_service_spec.rb | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index cc416b6717..721c9c9283 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -71,7 +71,7 @@ class ActivityPub::ProcessAccountService < BaseService @account.note = @json['summary'] || '' @account.locked = @json['manuallyApprovesFollowers'] || false @account.fields = property_values || {} - @account.actor_type = @json['type'] + @account.actor_type = actor_type end def set_fetchable_attributes! @@ -96,6 +96,14 @@ class ActivityPub::ProcessAccountService < BaseService ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id) end + def actor_type + if @json['type'].is_a?(Array) + @json['type'].find { |type| ActivityPub::FetchRemoteAccountService::SUPPORTED_TYPES.include?(type) } + else + @json['type'] + end + end + def image_url(key) value = first_of_value(@json[key]) diff --git a/spec/services/resolve_account_service_spec.rb b/spec/services/resolve_account_service_spec.rb index f4c810f758..dd7561587d 100644 --- a/spec/services/resolve_account_service_spec.rb +++ b/spec/services/resolve_account_service_spec.rb @@ -116,6 +116,7 @@ RSpec.describe ResolveAccountService, type: :service do expect(account.activitypub?).to eq true expect(account.domain).to eq 'ap.example.com' expect(account.inbox_url).to eq 'https://ap.example.com/users/foo/inbox' + expect(account.actor_type).to eq 'Person' end end From c1427f90f60ed37372a6f661e6e075354f2a96fd Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Tue, 8 May 2018 20:33:09 +0900 Subject: [PATCH 034/239] Show media modal on public timeline (#7413) --- app/javascript/mastodon/components/status.js | 2 +- .../mastodon/containers/timeline_container.js | 12 ++++++++++-- .../mastodon/features/ui/components/modal_root.js | 11 +++++++++++ app/views/about/show.html.haml | 2 ++ app/views/tags/show.html.haml | 2 ++ 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 402d558c4c..953d98c20d 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -206,7 +206,7 @@ export default class Status extends ImmutablePureComponent { ); } else { media = ( - + {Component => } ); diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js index 8719bb5c9e..a1a4bd024b 100644 --- a/app/javascript/mastodon/containers/timeline_container.js +++ b/app/javascript/mastodon/containers/timeline_container.js @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { Fragment } from 'react'; +import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import PropTypes from 'prop-types'; import configureStore from '../store/configureStore'; @@ -8,6 +9,7 @@ import { getLocale } from '../locales'; import PublicTimeline from '../features/standalone/public_timeline'; import CommunityTimeline from '../features/standalone/community_timeline'; import HashtagTimeline from '../features/standalone/hashtag_timeline'; +import ModalContainer from '../features/ui/containers/modal_container'; import initialState from '../initial_state'; const { localeData, messages } = getLocale(); @@ -47,7 +49,13 @@ export default class TimelineContainer extends React.PureComponent { return ( - {timeline} + + {timeline} + {ReactDOM.createPortal( + , + document.getElementById('modal-container'), + )} + ); diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js index 4185cba322..a334318ce5 100644 --- a/app/javascript/mastodon/features/ui/components/modal_root.js +++ b/app/javascript/mastodon/features/ui/components/modal_root.js @@ -40,6 +40,17 @@ export default class ModalRoot extends React.PureComponent { onClose: PropTypes.func.isRequired, }; + getSnapshotBeforeUpdate () { + const visible = !!this.props.type; + return { + overflowY: visible ? 'hidden' : null, + }; + } + + componentDidUpdate (prevProps, prevState, { overflowY }) { + document.body.style.overflowY = overflowY; + } + renderLoading = modalId => () => { return ['MEDIA', 'VIDEO', 'BOOST', 'CONFIRM', 'ACTIONS'].indexOf(modalId) === -1 ? : null; } diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml index 870dafdf52..fba46d54b7 100644 --- a/app/views/about/show.html.haml +++ b/app/views/about/show.html.haml @@ -142,3 +142,5 @@ %p = link_to t('about.source_code'), @instance_presenter.source_url = " (#{@instance_presenter.version_number})" + +#modal-container diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml index f8cdc99523..d46f359992 100644 --- a/app/views/tags/show.html.haml +++ b/app/views/tags/show.html.haml @@ -34,3 +34,5 @@ %p= t 'about.about_mastodon_html' = render 'features' + +#modal-container From 4fea89fe4ae0be64eab99f83c49bafeb3460bf10 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Tue, 8 May 2018 20:35:33 +0900 Subject: [PATCH 035/239] Multiple Issue templates (#7402) * Multiple Issue templates * Update bug_report.md --- .../bug_report.md} | 6 ++++++ .github/ISSUE_TEMPLATE/feature_request.md | 11 +++++++++++ 2 files changed, 17 insertions(+) rename .github/{ISSUE_TEMPLATE.md => ISSUE_TEMPLATE/bug_report.md} (80%) create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug_report.md similarity index 80% rename from .github/ISSUE_TEMPLATE.md rename to .github/ISSUE_TEMPLATE/bug_report.md index c78bcb492a..602530db0e 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,3 +1,9 @@ +--- +name: Bug Report +about: Create a report to help us improve + +--- + [Issue text goes here]. * * * * diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000000..46602fd2c0 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,11 @@ +--- +name: Feature Request +about: Suggest an idea for this project + +--- + +[Issue text goes here]. + +* * * * + +- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate. From 6092325a486b25e831b2c102df77a32f24c9de2c Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Wed, 9 May 2018 15:39:08 +0900 Subject: [PATCH 036/239] Rescue Mastodon::LengthValidationError in FetchLinkCardService (#7424) --- app/services/fetch_link_card_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/fetch_link_card_service.rb b/app/services/fetch_link_card_service.rb index 77d4aa5381..f9b1b2f0c6 100644 --- a/app/services/fetch_link_card_service.rb +++ b/app/services/fetch_link_card_service.rb @@ -27,7 +27,7 @@ class FetchLinkCardService < BaseService end attach_card if @card&.persisted? - rescue HTTP::Error, Addressable::URI::InvalidURIError => e + rescue HTTP::Error, Addressable::URI::InvalidURIError, Mastodon::LengthValidationError => e Rails.logger.debug "Error fetching link #{@url}: #{e}" nil end From e59fb1b96950f8dae2808298d70235cc5d19aade Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Wed, 9 May 2018 15:41:07 +0900 Subject: [PATCH 037/239] Correct rotate of image using EXIF (#7422) --- app/javascript/mastodon/utils/resize_image.js | 107 ++++++++++++++---- package.json | 1 + yarn.lock | 4 + 3 files changed, 89 insertions(+), 23 deletions(-) diff --git a/app/javascript/mastodon/utils/resize_image.js b/app/javascript/mastodon/utils/resize_image.js index 6442eda38c..54459de3ec 100644 --- a/app/javascript/mastodon/utils/resize_image.js +++ b/app/javascript/mastodon/utils/resize_image.js @@ -1,3 +1,5 @@ +import EXIF from 'exif-js'; + const MAX_IMAGE_DIMENSION = 1280; const getImageUrl = inputFile => new Promise((resolve, reject) => { @@ -28,6 +30,84 @@ const loadImage = inputFile => new Promise((resolve, reject) => { }).catch(reject); }); +const getOrientation = (img, type = 'image/png') => new Promise(resolve => { + if (type !== 'image/jpeg') { + resolve(1); + return; + } + + EXIF.getData(img, () => { + const orientation = EXIF.getTag(img, 'Orientation'); + resolve(orientation); + }); +}); + +const processImage = (img, { width, height, orientation, type = 'image/png' }) => new Promise(resolve => { + const canvas = document.createElement('canvas'); + [canvas.width, canvas.height] = orientation < 5 ? [width, height] : [height, width]; + + const context = canvas.getContext('2d'); + + switch (orientation) { + case 2: + context.translate(width, 0); + break; + case 3: + context.translate(width, height); + break; + case 4: + context.translate(0, height); + break; + case 5: + context.rotate(0.5 * Math.PI); + context.translate(1, -1); + break; + case 6: + context.rotate(0.5 * Math.PI); + context.translate(0, -height); + break; + case 7: + context.rotate(0.5, Math.PI); + context.translate(width, -height); + break; + case 8: + context.rotate(-0.5, Math.PI); + context.translate(-width, 0); + break; + } + + context.drawImage(img, 0, 0, width, height); + + canvas.toBlob(resolve, type); +}); + +const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) => { + const { width, height } = img; + + let newWidth, newHeight; + + if (width > height) { + newHeight = height * MAX_IMAGE_DIMENSION / width; + newWidth = MAX_IMAGE_DIMENSION; + } else if (height > width) { + newWidth = width * MAX_IMAGE_DIMENSION / height; + newHeight = MAX_IMAGE_DIMENSION; + } else { + newWidth = MAX_IMAGE_DIMENSION; + newHeight = MAX_IMAGE_DIMENSION; + } + + getOrientation(img, type) + .then(orientation => processImage(img, { + width: newWidth, + height: newHeight, + orientation, + type, + })) + .then(resolve) + .catch(reject); +}); + export default inputFile => new Promise((resolve, reject) => { if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') { resolve(inputFile); @@ -35,32 +115,13 @@ export default inputFile => new Promise((resolve, reject) => { } loadImage(inputFile).then(img => { - const canvas = document.createElement('canvas'); - const { width, height } = img; - - let newWidth, newHeight; - - if (width < MAX_IMAGE_DIMENSION && height < MAX_IMAGE_DIMENSION) { + if (img.width < MAX_IMAGE_DIMENSION && img.height < MAX_IMAGE_DIMENSION) { resolve(inputFile); return; } - if (width > height) { - newHeight = height * MAX_IMAGE_DIMENSION / width; - newWidth = MAX_IMAGE_DIMENSION; - } else if (height > width) { - newWidth = width * MAX_IMAGE_DIMENSION / height; - newHeight = MAX_IMAGE_DIMENSION; - } else { - newWidth = MAX_IMAGE_DIMENSION; - newHeight = MAX_IMAGE_DIMENSION; - } - - canvas.width = newWidth; - canvas.height = newHeight; - - canvas.getContext('2d').drawImage(img, 0, 0, newWidth, newHeight); - - canvas.toBlob(resolve, inputFile.type); + resizeImage(img, inputFile.type) + .then(resolve) + .catch(() => resolve(inputFile)); }).catch(reject); }); diff --git a/package.json b/package.json index 75e9e9f6dc..61f38409c0 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "emoji-mart": "Gargron/emoji-mart#build", "es6-symbol": "^3.1.1", "escape-html": "^1.0.3", + "exif-js": "^2.3.0", "express": "^4.16.2", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^0.11.2", diff --git a/yarn.lock b/yarn.lock index c5a49a497e..50c88557d2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2601,6 +2601,10 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exif-js@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/exif-js/-/exif-js-2.3.0.tgz#9d10819bf571f873813e7640241255ab9ce1a814" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" From db644968ceb67071ffea5513e8c1b35b245f2ee5 Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Wed, 9 May 2018 15:41:26 +0900 Subject: [PATCH 038/239] Add tests for admin/invites_controller (#7412) --- .../admin/invites_controller_spec.rb | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 spec/controllers/admin/invites_controller_spec.rb diff --git a/spec/controllers/admin/invites_controller_spec.rb b/spec/controllers/admin/invites_controller_spec.rb new file mode 100644 index 0000000000..e7d9954118 --- /dev/null +++ b/spec/controllers/admin/invites_controller_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +describe Admin::InvitesController do + render_views + + let(:user) { Fabricate(:user, admin: true) } + + before do + sign_in user, scope: :user + end + + describe 'GET #index' do + subject { get :index, params: { available: true } } + + let!(:invite) { Fabricate(:invite) } + + it 'renders index page' do + expect(subject).to render_template :index + expect(assigns(:invites)).to include invite + end + end + + describe 'POST #create' do + subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } } + + it 'succeeds to create a invite' do + expect{ subject }.to change { Invite.count }.by(1) + expect(subject).to redirect_to admin_invites_path + expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10) + end + end + + describe 'DELETE #destroy' do + let!(:invite) { Fabricate(:invite, expires_at: nil) } + + subject { delete :destroy, params: { id: invite.id } } + + it 'expires invite' do + expect(subject).to redirect_to admin_invites_path + expect(invite.reload).to be_expired + end + end +end From fcac2f1b60538c9c25a737e10b3f0e8318c11d3f Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Wed, 9 May 2018 15:41:46 +0900 Subject: [PATCH 039/239] Add tests for admin/roles_controller (#7421) --- .../admin/roles_controller_spec.rb | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 spec/controllers/admin/roles_controller_spec.rb diff --git a/spec/controllers/admin/roles_controller_spec.rb b/spec/controllers/admin/roles_controller_spec.rb new file mode 100644 index 0000000000..8e0de73cbd --- /dev/null +++ b/spec/controllers/admin/roles_controller_spec.rb @@ -0,0 +1,33 @@ +require 'rails_helper' + +describe Admin::RolesController do + render_views + + let(:admin) { Fabricate(:user, admin: true) } + + before do + sign_in admin, scope: :user + end + + describe 'POST #promote' do + subject { post :promote, params: { account_id: user.account_id } } + + let(:user) { Fabricate(:user, moderator: false, admin: false) } + + it 'promotes user' do + expect(subject).to redirect_to admin_account_path(user.account_id) + expect(user.reload).to be_moderator + end + end + + describe 'POST #demote' do + subject { post :demote, params: { account_id: user.account_id } } + + let(:user) { Fabricate(:user, moderator: true, admin: false) } + + it 'demotes user' do + expect(subject).to redirect_to admin_account_path(user.account_id) + expect(user.reload).not_to be_moderator + end + end +end From cbb7f330832aef0f3c4f75ade8c146883620fba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczak?= Date: Wed, 9 May 2018 12:20:49 +0200 Subject: [PATCH 040/239] =?UTF-8?q?=F0=9F=8C=8D:=20=F0=9F=87=B5?= =?UTF-8?q?=F0=9F=87=B1=E2=AC=86=EF=B8=8F=20(#7427)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Mikołajczak --- config/locales/pl.yml | 14 +++++++------- config/locales/simple_form.pl.yml | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 0d107ed53a..8133a41744 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -53,7 +53,7 @@ pl: unfollow: Przestań śledzić admin: account_moderation_notes: - create: Dodaj + create: Pozostaw notatkę created_msg: Pomyślnie dodano notatkę moderacyjną! delete: Usuń destroyed_msg: Pomyślnie usunięto notatkę moderacyjną! @@ -70,7 +70,7 @@ pl: title: Zmień adres e-mail dla %{username} confirm: Potwierdź confirmed: Potwierdzono - confirming: Potwierdzam + confirming: Potwierdzanie demote: Degraduj disable: Dezaktywuj disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuetapowe @@ -79,7 +79,7 @@ pl: domain: Domena edit: Edytuj email: Adres e-mail - email_status: Status e-maila + email_status: Stan e-maila enable: Aktywuj enabled: Aktywowano feed_url: Adres kanału @@ -119,8 +119,8 @@ pl: redownload: Odśwież awatar remove_avatar: Usun awatar resend_confirmation: - already_confirmed: Ten użytkownik jest już potwierdzony - send: Wyślij ponownie email potwierdzający + already_confirmed: To konto zostało już potwierdzone + send: Wyślij ponownie e-mail z potwierdzeniem success: E-mail z potwierdzeniem został wysłany! reset: Resetuj reset_password: Resetuj hasło @@ -374,7 +374,7 @@ pl: admin_mailer: new_report: body: Użytkownik %{reporter} zgłosił %{target} - body_remote: Ktoś z %{domain} zgłosił %{target} + body_remote: Użytkownik instancji %{domain} zgłosił %{target} subject: Nowe zgłoszenie na %{instance} (#%{id}) application_mailer: notification_preferences: Zmień ustawienia e-maili @@ -464,7 +464,7 @@ pl: archive_takeout: date: Data download: Pobierz swoje archiwum - hint_html: Możesz uzyskać archiwum swoich wpisów i wysłanej zawartości multimedialnej. Wyeksportowane dane będą dostępne w formacie ActivityPub, który możesz otworzyć w obsługujących go programach. + hint_html: Możesz uzyskać archiwum swoich wpisów i wysłanej zawartości multimedialnej. Wyeksportowane dane będą dostępne w formacie ActivityPub, który możesz otworzyć w obsługujących go programach. Możesz wyeksportować je po 7 dniach od poprzedniego eksportu. in_progress: Tworzenie archiwum… request: Uzyskaj archiwum size: Rozmiar diff --git a/config/locales/simple_form.pl.yml b/config/locales/simple_form.pl.yml index 4c1833b1ca..9341fc9e59 100644 --- a/config/locales/simple_form.pl.yml +++ b/config/locales/simple_form.pl.yml @@ -4,6 +4,7 @@ pl: hints: defaults: avatar: PNG, GIF lub JPG. Maksymalnie 2MB. Zostanie zmniejszony do 400x400px + bot: Informuje użytkowników, że konto nie jest prowadzone przez człowieka digest: Wysyłane tylko po długiej nieaktywności, jeżeli w tym czasie otrzymaleś jakąś wiadomość bezpośrednią display_name: few: Pozostały %{count} znaki. @@ -23,7 +24,7 @@ pl: imports: data: Plik CSV wyeksportowany z innej instancji Mastodona sessions: - otp: Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych. + otp: 'Wprowadź kod weryfikacji dwuetapowej z telefonu lub wykorzystaj jeden z kodów zapasowych:' user: filtered_languages: Wpisy w wybranych językach nie będą wyświetlać się na publicznych osiach czasu labels: @@ -33,6 +34,7 @@ pl: value: Zawartość defaults: avatar: Awatar + bot: To konto jest prowadzone przez bota confirm_new_password: Potwierdź nowe hasło confirm_password: Potwierdź hasło current_password: Obecne hasło From d0062715148206a5b14f247290537579a4187ccd Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Wed, 9 May 2018 23:22:52 +0900 Subject: [PATCH 041/239] Show card modal on public pages (#7428) --- .../mastodon/containers/card_container.js | 18 ------ .../mastodon/containers/cards_container.js | 59 +++++++++++++++++++ app/javascript/packs/public.js | 15 +++-- .../styles/mastodon/containers.scss | 1 + 4 files changed, 70 insertions(+), 23 deletions(-) delete mode 100644 app/javascript/mastodon/containers/card_container.js create mode 100644 app/javascript/mastodon/containers/cards_container.js diff --git a/app/javascript/mastodon/containers/card_container.js b/app/javascript/mastodon/containers/card_container.js deleted file mode 100644 index 11b9f88d4c..0000000000 --- a/app/javascript/mastodon/containers/card_container.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Card from '../features/status/components/card'; -import { fromJS } from 'immutable'; - -export default class CardContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string, - card: PropTypes.array.isRequired, - }; - - render () { - const { card, ...props } = this.props; - return ; - } - -} diff --git a/app/javascript/mastodon/containers/cards_container.js b/app/javascript/mastodon/containers/cards_container.js new file mode 100644 index 0000000000..894bf4ef99 --- /dev/null +++ b/app/javascript/mastodon/containers/cards_container.js @@ -0,0 +1,59 @@ +import React, { Fragment } from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import { IntlProvider, addLocaleData } from 'react-intl'; +import { getLocale } from '../locales'; +import Card from '../features/status/components/card'; +import ModalRoot from '../components/modal_root'; +import MediaModal from '../features/ui/components/media_modal'; +import { fromJS } from 'immutable'; + +const { localeData, messages } = getLocale(); +addLocaleData(localeData); + +export default class CardsContainer extends React.PureComponent { + + static propTypes = { + locale: PropTypes.string, + cards: PropTypes.object.isRequired, + }; + + state = { + media: null, + }; + + handleOpenCard = (media) => { + document.body.classList.add('card-standalone__body'); + this.setState({ media }); + } + + handleCloseCard = () => { + document.body.classList.remove('card-standalone__body'); + this.setState({ media: null }); + } + + render () { + const { locale, cards } = this.props; + + return ( + + + {[].map.call(cards, container => { + const { card, ...props } = JSON.parse(container.getAttribute('data-props')); + + return ReactDOM.createPortal( + , + container, + ); + })} + + {this.state.media && ( + + )} + + + + ); + } + +} diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js index 7096b9b4f2..3a1f1a16b4 100644 --- a/app/javascript/packs/public.js +++ b/app/javascript/packs/public.js @@ -25,7 +25,6 @@ function main() { const { getLocale } = require('../mastodon/locales'); const { localeData } = getLocale(); const VideoContainer = require('../mastodon/containers/video_container').default; - const CardContainer = require('../mastodon/containers/card_container').default; const React = require('react'); const ReactDOM = require('react-dom'); @@ -75,10 +74,16 @@ function main() { ReactDOM.render(, content); }); - [].forEach.call(document.querySelectorAll('[data-component="Card"]'), (content) => { - const props = JSON.parse(content.getAttribute('data-props')); - ReactDOM.render(, content); - }); + const cards = document.querySelectorAll('[data-component="Card"]'); + + if (cards.length > 0) { + import(/* webpackChunkName: "containers/cards_container" */ '../mastodon/containers/cards_container').then(({ default: CardsContainer }) => { + const content = document.createElement('div'); + + ReactDOM.render(, content); + document.body.appendChild(content); + }).catch(error => console.error(error)); + } const mediaGalleries = document.querySelectorAll('[data-component="MediaGallery"]'); diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss index 9d5ab66a48..c40b38a5a5 100644 --- a/app/javascript/styles/mastodon/containers.scss +++ b/app/javascript/styles/mastodon/containers.scss @@ -60,6 +60,7 @@ } } +.card-standalone__body, .media-gallery-standalone__body { overflow: hidden; } From 1b42ea9f2c754e373f4c11698796d2024c8ef37e Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Wed, 9 May 2018 23:59:39 +0900 Subject: [PATCH 042/239] Support gzip encoding on Request (#7425) --- app/lib/request.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index 00f94dacf5..fc7d398e04 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -51,7 +51,7 @@ class Request end def headers - (@account ? @headers.merge('Signature' => signature) : @headers).without(REQUEST_TARGET) + (@account ? @headers.merge('Signature' => signature) : @headers).reverse_merge('Accept-Encoding' => 'gzip').without(REQUEST_TARGET) end private @@ -100,7 +100,7 @@ class Request end def http_client - @http_client ||= HTTP.timeout(:per_operation, timeout).follow(max_hops: 2) + @http_client ||= HTTP.use(:auto_inflate).timeout(:per_operation, timeout).follow(max_hops: 2) end def use_proxy? From e60292c6164bae6d41cfe54b5e8be93d56c339b6 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Wed, 9 May 2018 23:59:58 +0900 Subject: [PATCH 043/239] Disable simplecov on CircleCI (#7416) * Disable simplecov on CircleCI * Remove --format progress --- .circleci/config.yml | 1 + spec/spec_helper.rb | 13 +++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index fc9c7e22b7..02b505457b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,7 @@ aliases: RAILS_ENV: test PARALLEL_TEST_PROCESSORS: 4 ALLOW_NOPAM: true + DISABLE_SIMPLECOV: true working_directory: ~/projects/mastodon/ - &attach_workspace diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index a0466dd4bf..0cd1f91d02 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,11 +1,12 @@ -require 'simplecov' - GC.disable -SimpleCov.start 'rails' do - add_group 'Services', 'app/services' - add_group 'Presenters', 'app/presenters' - add_group 'Validators', 'app/validators' +if ENV['DISABLE_SIMPLECOV'] != 'true' + require 'simplecov' + SimpleCov.start 'rails' do + add_group 'Services', 'app/services' + add_group 'Presenters', 'app/presenters' + add_group 'Validators', 'app/validators' + end end gc_counter = -1 From 5b46a6002f27ff3427867f9a3505a0f28afe0325 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 20:07:41 +0200 Subject: [PATCH 044/239] Ignore tootsuite-specific theme-related translation strings --- config/i18n-tasks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 0236fb8ccd..e9564692f9 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -62,5 +62,5 @@ ignore_unused: - 'errors.429' - 'admin.accounts.roles.*' - 'admin.action_logs.actions.*' - - 'themes.default' + - 'themes.*' - 'statuses.attached.*' From b8f8a3ea585ad0a7461c081829c92e425f67d9c9 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 22:11:59 +0200 Subject: [PATCH 045/239] Update glitch-soc style to match new bio fields markup --- .../glitch/styles/components/metadata.scss | 32 +++++------ .../flavours/glitch/styles/metadata.scss | 55 ++++++++++++------- 2 files changed, 50 insertions(+), 37 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/components/metadata.scss b/app/javascript/flavours/glitch/styles/components/metadata.scss index fa1a4bc342..29a6330e9c 100644 --- a/app/javascript/flavours/glitch/styles/components/metadata.scss +++ b/app/javascript/flavours/glitch/styles/components/metadata.scss @@ -2,7 +2,6 @@ font-size: 15px; line-height: 20px; overflow: hidden; - border-collapse: collapse; margin: 20px -10px -20px; border-bottom: 0; @@ -14,35 +13,36 @@ } } - tr { + dl { border-top: 1px solid lighten($ui-base-color, 8%); - text-align: center; + display: flex; } - th, td { + dt, + dd { + box-sizing: border-box; padding: 14px 20px; - vertical-align: middle; - - & > div { - max-height: 40px; - overflow-y: auto; - white-space: pre-wrap; - text-overflow: ellipsis; - } + text-align: center; + max-height: 48px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } - th { + dt { color: $darker-text-color; background: lighten($ui-base-color, 13%); - max-width: 120px; + width: 120px; + flex: 0 0 auto; + font-weight: 500; a { color: $primary-text-color; } } - td { - flex: auto; + dd { + flex: 1 1 auto; color: $primary-text-color; background: $ui-base-color; diff --git a/app/javascript/flavours/glitch/styles/metadata.scss b/app/javascript/flavours/glitch/styles/metadata.scss index b66cce3c1f..280848959e 100644 --- a/app/javascript/flavours/glitch/styles/metadata.scss +++ b/app/javascript/flavours/glitch/styles/metadata.scss @@ -1,43 +1,56 @@ .account__header__fields { $meta-table-border: lighten($ui-base-color, 8%); - - border-collapse: collapse; padding: 0; margin: 15px -15px -15px -15px; border: 0 none; border-top: 1px solid $meta-table-border; border-bottom: 1px solid $meta-table-border; + font-size: 14px; + line-height: 20px; - td, th { - padding: 15px; - border: 0 none; + dl { + display: flex; border-bottom: 1px solid $meta-table-border; - vertical-align: middle; } - tr:last-child { - td, th { - border-bottom: 0 none; - } - } - - td { - color: $ui-primary-color; + dt, + dd { + box-sizing: border-box; + padding: 14px; text-align: center; - width:100%; - padding-left: 0; + max-height: 48px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } - th { + dt { padding-left: 15px; - font-weight: bold; + font-weight: 500; text-align: center; - width: 94px; - color: $ui-secondary-color; + width: 120px; + flex: 0 0 auto; + color: $secondary-text-color; background: darken($ui-base-color, 8%); } + dd { + flex: 1 1 auto; + color: $darker-text-color; + } + a { - color: $classic-highlight-color; + color: $highlight-text-color; + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } + + dl:last-child { + border-bottom: 0; } } From 2e2758c25e838f344c884c47d36c8527b7660327 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 23:29:14 +0200 Subject: [PATCH 046/239] Adapt account fields rendering code in the WebUI to match upstream --- .../features/account/components/header.js | 42 +++++++------------ 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 7a0a2dfa96..044155cd88 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -102,35 +102,25 @@ export default class Header extends ImmutablePureComponent {
    {fields.size > 0 && ( - - - {fields.map((pair, i) => ( - - - ))} - -
    - -
    +
    + {fields.map((pair, i) => ( +
    +
    +
    +
    + ))} +
    )} {fields.size == 0 && metadata.length && ( - - - {(() => { - let data = []; - for (let i = 0; i < metadata.length; i++) { - data.push( - - - - - ); - } - return data; - })()} - -
    +
    + {metadata.map((pair, i) => ( +
    +
    +
    +
    + ))} +
    ) || null} {info} From 0033dbd11579bfd55d059379eb0c2ab3c3ba00f3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 22:19:10 +0200 Subject: [PATCH 047/239] Add bot badge to account headers in the WebUI --- .../flavours/glitch/features/account/components/header.js | 5 +++++ .../flavours/glitch/styles/components/accounts.scss | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 044155cd88..15bd6b3657 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -38,6 +38,8 @@ export default class Header extends ImmutablePureComponent { let displayName = account.get('display_name_html'); let fields = account.get('fields'); + let badge = account.get('bot') ? (
    ) : null; + let info = ''; let mutingInfo = ''; let actionBtn = ''; @@ -99,6 +101,9 @@ export default class Header extends ImmutablePureComponent { @{account.get('acct')} {account.get('locked') ? : null} + + {badge} +
    {fields.size > 0 && ( diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 84d3f6adef..5167a507ee 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -509,3 +509,9 @@ margin-bottom: 0; } } + +.account__header .roles { + margin-top: 20px; + margin-bottom: 20px; + padding: 0 15px; +} From 3c7d7ec2285b7e7830f129589f78cde5baf92aec Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 10 May 2018 13:04:55 +0200 Subject: [PATCH 048/239] [Glitch] Use plaintext value for field value tooltips in web UI Port 8b63d3942795e2837384c8045da950a24c53779f to glitch-soc This doesn't change anything for glitch-style fields, but those will go away eventually --- app/javascript/flavours/glitch/actions/notifications.js | 8 +------- .../flavours/glitch/features/account/components/header.js | 2 +- app/javascript/flavours/glitch/reducers/accounts.js | 2 ++ app/javascript/flavours/glitch/util/html.js | 6 ++++++ 4 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 app/javascript/flavours/glitch/util/html.js diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index cf27eff90e..0d52100b90 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -3,6 +3,7 @@ import { List as ImmutableList } from 'immutable'; import IntlMessageFormat from 'intl-messageformat'; import { fetchRelationships } from './accounts'; import { defineMessages } from 'react-intl'; +import { unescapeHTML } from 'flavours/glitch/util/html'; export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE'; @@ -40,13 +41,6 @@ const fetchRelatedRelationships = (dispatch, notifications) => { } }; -const unescapeHTML = (html) => { - const wrapper = document.createElement('div'); - html = html.replace(/
    |
    |\n/g, ' '); - wrapper.innerHTML = html; - return wrapper.textContent; -}; - export function updateNotifications(notification, intlMessages, intlLocale) { return (dispatch, getState) => { const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true); diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 15bd6b3657..464c73c9a2 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -111,7 +111,7 @@ export default class Header extends ImmutablePureComponent { {fields.map((pair, i) => (
    -
    +
    ))}
    diff --git a/app/javascript/flavours/glitch/reducers/accounts.js b/app/javascript/flavours/glitch/reducers/accounts.js index 23fbd999cd..e8127a8713 100644 --- a/app/javascript/flavours/glitch/reducers/accounts.js +++ b/app/javascript/flavours/glitch/reducers/accounts.js @@ -57,6 +57,7 @@ import { STORE_HYDRATE } from 'flavours/glitch/actions/store'; import emojify from 'flavours/glitch/util/emoji'; import { Map as ImmutableMap, fromJS } from 'immutable'; import escapeTextContentForBrowser from 'escape-html'; +import { unescapeHTML } from 'flavours/glitch/util/html'; const normalizeAccount = (state, account) => { account = { ...account }; @@ -74,6 +75,7 @@ const normalizeAccount = (state, account) => { ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), value_emojified: emojify(pair.value), + value_plain: unescapeHTML(pair.value), })); } diff --git a/app/javascript/flavours/glitch/util/html.js b/app/javascript/flavours/glitch/util/html.js new file mode 100644 index 0000000000..0b646ce58f --- /dev/null +++ b/app/javascript/flavours/glitch/util/html.js @@ -0,0 +1,6 @@ +export const unescapeHTML = (html) => { + const wrapper = document.createElement('div'); + html = html.replace(/
    |
    |\n/g, ' '); + wrapper.innerHTML = html; + return wrapper.textContent; +}; From 59b48b923d29db29f1abb17fd3023ca8a630e45a Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 10 May 2018 21:36:12 +0900 Subject: [PATCH 049/239] Disable inflate gzip on head method (#7432) --- app/lib/request.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index fc7d398e04..731bf76879 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -51,16 +51,17 @@ class Request end def headers - (@account ? @headers.merge('Signature' => signature) : @headers).reverse_merge('Accept-Encoding' => 'gzip').without(REQUEST_TARGET) + (@account ? @headers.merge('Signature' => signature) : @headers).without(REQUEST_TARGET) end private def set_common_headers! - @headers[REQUEST_TARGET] = "#{@verb} #{@url.path}" - @headers['User-Agent'] = user_agent - @headers['Host'] = @url.host - @headers['Date'] = Time.now.utc.httpdate + @headers[REQUEST_TARGET] = "#{@verb} #{@url.path}" + @headers['User-Agent'] = user_agent + @headers['Host'] = @url.host + @headers['Date'] = Time.now.utc.httpdate + @headers['Accept-Encoding'] = 'gzip' if @verb != :head end def set_digest! From f286c23900923c6da1b7b7032ced172604962520 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 10 May 2018 21:38:19 +0900 Subject: [PATCH 050/239] Add alternate for RSS (#7436) --- app/views/accounts/show.html.haml | 1 + app/views/tags/show.html.haml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml index bbf2139a5e..cfdd3a9452 100644 --- a/app/views/accounts/show.html.haml +++ b/app/views/accounts/show.html.haml @@ -8,6 +8,7 @@ %meta{ name: 'robots', content: 'noindex' }/ %link{ rel: 'salmon', href: api_salmon_url(@account.id) }/ + %link{ rel: 'alternate', type: 'application/rss+xml', href: account_url(@account, format: 'rss') }/ %link{ rel: 'alternate', type: 'application/atom+xml', href: account_url(@account, format: 'atom') }/ %link{ rel: 'alternate', type: 'application/activity+json', href: ActivityPub::TagManager.instance.uri_for(@account) }/ diff --git a/app/views/tags/show.html.haml b/app/views/tags/show.html.haml index d46f359992..f6e452f188 100644 --- a/app/views/tags/show.html.haml +++ b/app/views/tags/show.html.haml @@ -2,6 +2,8 @@ = "##{@tag.name}" - content_for :header_tags do + %link{ rel: 'alternate', type: 'application/rss+xml', href: tag_url(@tag, format: 'rss') }/ + %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous' = render 'og' From b91c131afad7be5065ff36c6cc1d546c61420a72 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 10 May 2018 21:38:40 +0900 Subject: [PATCH 051/239] Strip tags from og:description on public tag page (#7437) --- app/views/tags/_og.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/tags/_og.html.haml b/app/views/tags/_og.html.haml index 853a499aea..a7c289bcb0 100644 --- a/app/views/tags/_og.html.haml +++ b/app/views/tags/_og.html.haml @@ -2,5 +2,5 @@ = opengraph 'og:url', tag_url(@tag) = opengraph 'og:type', 'website' = opengraph 'og:title', "##{@tag.name}" -= opengraph 'og:description', t('about.about_hashtag_html', hashtag: @tag.name) += opengraph 'og:description', strip_tags(t('about.about_hashtag_html', hashtag: @tag.name)) = opengraph 'twitter:card', 'summary' From a6bdefe81129688e1be93026fcde58c3c51bf721 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 10 May 2018 21:48:26 +0900 Subject: [PATCH 052/239] Weblate translations (2018-05-10) (#7438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Translated using Weblate (Arabic) Currently translated at 83.6% (523 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Japanese) Currently translated at 99.5% (622 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (French) Currently translated at 99.6% (623 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (Korean) Currently translated at 99.8% (624 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ko/ * Translated using Weblate (Korean) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ko/ * Translated using Weblate (Catalan) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Persian) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/fa/ * Translated using Weblate (Finnish) Currently translated at 95.1% (59 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/ * Translated using Weblate (Finnish) Currently translated at 95.1% (59 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/ * Translated using Weblate (Finnish) Currently translated at 99.6% (293 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/ * Translated using Weblate (Finnish) Currently translated at 96.7% (60 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fi/ * Translated using Weblate (Finnish) Currently translated at 97.9% (612 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fi/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Arabic) Currently translated at 90.8% (568 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ in overeestemming met andere vertalingen * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (2 of 2 strings) Translation: Mastodon/Activerecord Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/activerecord/nl/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.2% (620 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Japanese) Currently translated at 99.6% (623 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Galician) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Galician) Currently translated at 98.3% (61 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (German) Currently translated at 99.2% (620 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (German) Currently translated at 99.2% (620 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (Esperanto) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/ * Translated using Weblate (Esperanto) Currently translated at 99.8% (624 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/ * Translated using Weblate (Russian) Currently translated at 93.5% (58 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/ * Translated using Weblate (Russian) Currently translated at 95.1% (59 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/ I’m not sure this is the best translation for custom fields, something like «Характеристика» might work better; hopefully someone will review this for second opinions * Translated using Weblate (Persian) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fa/ * Translated using Weblate (Persian) Currently translated at 99.6% (623 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fa/ * Translated using Weblate (Dutch) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/ * Translated using Weblate (Persian) Currently translated at 100.0% (75 of 75 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/fa/ * Translated using Weblate (Persian) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/ * Translated using Weblate (Dutch) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/ * Translated using Weblate (Slovak) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/ * Translated using Weblate (Russian) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ru/ * Translated using Weblate (Dutch) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/ * Translated using Weblate (German) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (Dutch) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (625 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Slovak) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.3% (621 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Dutch) Currently translated at 100.0% (626 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/nl/ * Translated using Weblate (Galician) Currently translated at 100.0% (626 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Galician) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/gl/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.2% (621 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Catalan) Currently translated at 100.0% (626 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Catalan) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ca/ * Translated using Weblate (Japanese) Currently translated at 92.1% (59 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/ * Translated using Weblate (Corsican) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/co/ * Translated using Weblate (Corsican) Currently translated at 99.8% (624 of 625 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (75 of 75 strings) Translation: Mastodon/Doorkeeper Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/doorkeeper/co/ * Translated using Weblate (Corsican) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/co/ * Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/ * Translated using Weblate (French) Currently translated at 99.6% (624 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (French) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/fr/ * Translated using Weblate (French) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Arabic) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/ * Translated using Weblate (Arabic) Currently translated at 90.8% (569 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Slovak) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/ * Translated using Weblate (Slovak) Currently translated at 95.2% (596 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Esperanto) Currently translated at 99.8% (625 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/ * Translated using Weblate (Japanese) Currently translated at 99.6% (624 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Esperanto) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/ * Translated using Weblate (Finnish) Currently translated at 99.6% (293 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fi/ * Translated using Weblate (Persian) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fa/ * Translated using Weblate (Japanese) Currently translated at 93.7% (60 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ja/ * Translated using Weblate (German) Currently translated at 99.6% (624 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Translated using Weblate (German) Currently translated at 100.0% (64 of 64 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/de/ * Translated using Weblate (German) Currently translated at 99.6% (624 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/de/ * Added translation using Weblate (Slovenian) * Translated using Weblate (Slovenian) Currently translated at 5.7% (36 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sl/ * Added translation using Weblate (Slovenian) * Translated using Weblate (Slovenian) Currently translated at 1.3% (4 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sl/ * Translated using Weblate (French) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Greek) Currently translated at 29.3% (184 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.3% (184 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.5% (185 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.5% (185 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.8% (187 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 29.8% (187 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.0% (188 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.0% (188 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.1% (189 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.3% (190 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.5% (191 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.5% (191 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 30.6% (192 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 100.0% (294 of 294 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/el/ * Translated using Weblate (Greek) Currently translated at 33.7% (211 of 626 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/el/ * yarn manage:translations && i18n-tasks normalize && i18n-tasks remove-unused --- app/javascript/mastodon/locales/ar.json | 1 + app/javascript/mastodon/locales/bg.json | 1 + app/javascript/mastodon/locales/ca.json | 1 + app/javascript/mastodon/locales/co.json | 19 +- app/javascript/mastodon/locales/de.json | 1 + .../mastodon/locales/defaultMessages.json | 4 + app/javascript/mastodon/locales/el.json | 11 +- app/javascript/mastodon/locales/en.json | 1 + app/javascript/mastodon/locales/eo.json | 1 + app/javascript/mastodon/locales/es.json | 1 + app/javascript/mastodon/locales/eu.json | 1 + app/javascript/mastodon/locales/fa.json | 11 +- app/javascript/mastodon/locales/fi.json | 21 +- app/javascript/mastodon/locales/fr.json | 5 +- app/javascript/mastodon/locales/gl.json | 1 + app/javascript/mastodon/locales/he.json | 1 + app/javascript/mastodon/locales/hr.json | 1 + app/javascript/mastodon/locales/hu.json | 1 + app/javascript/mastodon/locales/hy.json | 1 + app/javascript/mastodon/locales/id.json | 1 + app/javascript/mastodon/locales/io.json | 1 + app/javascript/mastodon/locales/it.json | 1 + app/javascript/mastodon/locales/ja.json | 1 + app/javascript/mastodon/locales/ko.json | 55 ++-- app/javascript/mastodon/locales/nl.json | 21 +- app/javascript/mastodon/locales/no.json | 1 + app/javascript/mastodon/locales/oc.json | 1 + app/javascript/mastodon/locales/pl.json | 1 + app/javascript/mastodon/locales/pt-BR.json | 1 + app/javascript/mastodon/locales/pt.json | 1 + app/javascript/mastodon/locales/ru.json | 1 + app/javascript/mastodon/locales/sk.json | 1 + app/javascript/mastodon/locales/sl.json | 297 ++++++++++++++++++ app/javascript/mastodon/locales/sr-Latn.json | 1 + app/javascript/mastodon/locales/sr.json | 1 + app/javascript/mastodon/locales/sv.json | 1 + app/javascript/mastodon/locales/te.json | 1 + app/javascript/mastodon/locales/th.json | 1 + app/javascript/mastodon/locales/tr.json | 1 + app/javascript/mastodon/locales/uk.json | 1 + .../mastodon/locales/whitelist_sl.json | 2 + app/javascript/mastodon/locales/zh-CN.json | 1 + app/javascript/mastodon/locales/zh-HK.json | 1 + app/javascript/mastodon/locales/zh-TW.json | 1 + config/locales/activerecord.nl.yml | 2 +- config/locales/ar.yml | 78 ++++- config/locales/ca.yml | 6 +- config/locales/co.yml | 57 ++-- config/locales/de.yml | 7 +- config/locales/devise.co.yml | 2 +- config/locales/devise.fa.yml | 13 +- config/locales/doorkeeper.co.yml | 10 +- config/locales/doorkeeper.fa.yml | 94 +++--- config/locales/el.yml | 51 ++- config/locales/eo.yml | 63 +++- config/locales/fa.yml | 150 ++++++++- config/locales/fi.yml | 70 ++++- config/locales/fr.yml | 9 +- config/locales/gl.yml | 6 +- config/locales/ja.yml | 5 +- config/locales/ko.yml | 28 +- config/locales/nl.yml | 38 +-- config/locales/pt-BR.yml | 60 ++-- config/locales/simple_form.ar.yml | 4 +- config/locales/simple_form.ca.yml | 4 +- config/locales/simple_form.co.yml | 8 +- config/locales/simple_form.de.yml | 4 +- config/locales/simple_form.eo.yml | 10 +- config/locales/simple_form.fa.yml | 14 +- config/locales/simple_form.fi.yml | 7 +- config/locales/simple_form.fr.yml | 4 +- config/locales/simple_form.gl.yml | 8 +- config/locales/simple_form.ja.yml | 4 +- config/locales/simple_form.nl.yml | 14 +- config/locales/simple_form.pt-BR.yml | 4 +- config/locales/simple_form.ru.yml | 10 +- config/locales/simple_form.sk.yml | 12 +- config/locales/sk.yml | 6 +- config/locales/sl.yml | 47 +++ 79 files changed, 1101 insertions(+), 288 deletions(-) create mode 100644 app/javascript/mastodon/locales/sl.json create mode 100644 app/javascript/mastodon/locales/whitelist_sl.json create mode 100644 config/locales/sl.yml diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index d531d8fd5a..a4f27cd318 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "حظر @{name}", "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}", "account.blocked": "محظور", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 9714751140..dd747ab3ba 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Блокирай", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index f2e3699d59..22c5453ca6 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloca @{name}", "account.block_domain": "Amaga-ho tot de {domain}", "account.blocked": "Bloquejat", diff --git a/app/javascript/mastodon/locales/co.json b/app/javascript/mastodon/locales/co.json index 2d7427c55d..9d8d950a89 100644 --- a/app/javascript/mastodon/locales/co.json +++ b/app/javascript/mastodon/locales/co.json @@ -1,9 +1,10 @@ { + "account.badges.bot": "Bot", "account.block": "Bluccà @{name}", "account.block_domain": "Piattà tuttu da {domain}", "account.blocked": "Bluccatu", "account.direct": "Missaghju direttu @{name}", - "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.disclaimer_full": "Ghjè pussibule chì l’infurmazione quì sottu ùn rifletta micca u prufile sanu di l’utilizatore.", "account.domain_blocked": "Duminiu piattatu", "account.edit_profile": "Mudificà u prufile", "account.follow": "Siguità", @@ -28,7 +29,7 @@ "account.unfollow": "Ùn siguità più", "account.unmute": "Ùn piattà più @{name}", "account.unmute_notifications": "Ùn piattà più nutificazione da @{name}", - "account.view_full_profile": "View full profile", + "account.view_full_profile": "Vede tuttu u prufile", "alert.unexpected.message": "Un prublemu inaspettatu hè accadutu.", "alert.unexpected.title": "Uups!", "boost_modal.combo": "Pudete appughjà nant'à {combo} per saltà quessa a prussima volta", @@ -78,7 +79,7 @@ "confirmations.delete.message": "Site sicuru·a che vulete supprime stu statutu?", "confirmations.delete_list.confirm": "Toglie", "confirmations.delete_list.message": "Site sicuru·a che vulete supprime sta lista?", - "confirmations.domain_block.confirm": "Piattà tuttu u duminiu?", + "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à.", "confirmations.mute.confirm": "Piattà", "confirmations.mute.message": "Site sicuru·a che vulete piattà @{name}?", @@ -107,13 +108,13 @@ "empty_column.home.public_timeline": "a linea pubblica", "empty_column.list": "Ùn c'hè ancu nunda quì. Quandu membri di sta lista manderanu novi statuti, i vidarete quì.", "empty_column.notifications": "Ùn avete ancu nisuna nutificazione. Interact with others to start the conversation.", - "empty_column.public": "Ùn c'hè nunda quì! Scrivete qualcosa in pubblicu o seguitate utilizatori d'altre istanze per empie a linea pubblica.", + "empty_column.public": "Ùn c'hè nunda quì! Scrivete qualcosa in pubblicu o seguitate utilizatori d'altre istanze per empie a linea pubblica", "follow_request.authorize": "Auturizà", "follow_request.reject": "Righjittà", "getting_started.appsshort": "Applicazione", "getting_started.faq": "FAQ", "getting_started.heading": "Per principià", - "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}", + "getting_started.open_source_notice": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un bug, nant'à GitHub: {github}.", "getting_started.userguide": "Guida d'utilizazione", "home.column_settings.advanced": "Avanzati", "home.column_settings.basic": "Bàsichi", @@ -200,7 +201,7 @@ "onboarding.page_six.apps_available": "Ci sò {apps} dispunibule per iOS, Android è altre piattaforme.", "onboarding.page_six.github": "Mastodon ghjè un lugiziale liberu. Pudete cuntribuisce à u codice o a traduzione, o palisà un prublemu, nant'à {github}.", "onboarding.page_six.guidelines": "regule di a cumunità", - "onboarding.page_six.read_guidelines": "Ùn vi scurdate di leghje e {guidelines} di {domain}", + "onboarding.page_six.read_guidelines": "Ùn vi scurdate di leghje e {guidelines} di {domain}!", "onboarding.page_six.various_app": "applicazione pè u telefuninu", "onboarding.page_three.profile": "Pudete mudificà u prufile per cambia u ritrattu, a descrizzione è u nome affissatu. Ci sò ancu alcun'altre preferenze.", "onboarding.page_three.search": "Fate usu di l'area di ricerca per truvà altre persone è vede hashtag cum'è {illustration} o {introductions}. Per vede qualcunu ch'ùn hè micca nant'à st'istanza, cercate u so identificatore complettu (pare un'email).", @@ -231,13 +232,13 @@ "report.target": "Signalamentu", "search.placeholder": "Circà", "search_popout.search_format": "Ricerca avanzata", - "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.full_text": "I testi simplici rimandanu i statuti ch'avete scritti, aghjunti à i vostri favuriti, spartuti o induve quelli site mintuvatu·a, è ancu i cugnomi, nomi pubblichi è hashtag chì currispondenu.", "search_popout.tips.hashtag": "hashtag", "search_popout.tips.status": "statutu", - "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", + "search_popout.tips.text": "Un testu simplice rimanda i nomi pubblichi, cugnomi è hashtag", "search_popout.tips.user": "utilizatore", "search_results.accounts": "Ghjente", - "search_results.hashtags": "Hashtags", + "search_results.hashtags": "Hashtag", "search_results.statuses": "Statuti", "search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}", "standalone.public_title": "Una vista di...", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index f442e06754..fe5bc44437 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "@{name} blocken", "account.block_domain": "Alles von {domain} verstecken", "account.blocked": "Blockiert", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 86cf839933..6cbe148de3 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -552,6 +552,10 @@ { "defaultMessage": "Domain hidden", "id": "account.domain_blocked" + }, + { + "defaultMessage": "Bot", + "id": "account.badges.bot" } ], "path": "app/javascript/mastodon/features/account/components/header.json" diff --git a/app/javascript/mastodon/locales/el.json b/app/javascript/mastodon/locales/el.json index 5b36348eb8..d1421be763 100644 --- a/app/javascript/mastodon/locales/el.json +++ b/app/javascript/mastodon/locales/el.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Απόκλεισε τον/την @{name}", "account.block_domain": "Απόκρυψε τα πάντα από τον/την", "account.blocked": "Αποκλεισμένος/η", @@ -111,7 +112,7 @@ "follow_request.authorize": "Ενέκρινε", "follow_request.reject": "Απέρριψε", "getting_started.appsshort": "Εφαρμογές", - "getting_started.faq": "FAQ", + "getting_started.faq": "Συχνές Ερωτήσεις", "getting_started.heading": "Ξεκινώντας", "getting_started.open_source_notice": "Το Mastodon είναι ελεύθερο λογισμικό. Μπορείς να συνεισφέρεις ή να αναφέρεις ζητήματα στο GitHub στο {github}.", "getting_started.userguide": "Οδηγός Χρηστών", @@ -174,7 +175,7 @@ "notification.follow": "{name} followed you", "notification.mention": "{name} mentioned you", "notification.reblog": "{name} boosted your status", - "notifications.clear": "Clear notifications", + "notifications.clear": "Καθαρισμός ειδοποιήσεων", "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:", @@ -194,7 +195,7 @@ "onboarding.page_one.full_handle": "Your full handle", "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.", "onboarding.page_one.welcome": "Welcome to Mastodon!", - "onboarding.page_six.admin": "Your instance's admin is {admin}.", + "onboarding.page_six.admin": "Ο διαχειριστής του κόμβου σου είναι ο/η {admin}.", "onboarding.page_six.almost_done": "Almost done...", "onboarding.page_six.appetoot": "Bon Appetoot!", "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.", @@ -248,13 +249,13 @@ "status.direct": "Direct message @{name}", "status.embed": "Embed", "status.favourite": "Favourite", - "status.load_more": "Load more", + "status.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.open": "Διεύρυνε αυτή την κατάσταση", "status.pin": "Pin on profile", "status.pinned": "Pinned toot", "status.reblog": "Boost", diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 98d6c0dd71..b796ba8f38 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 1ab6d2aa09..4aa3d80a3a 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloki @{name}", "account.block_domain": "Kaŝi ĉion de {domain}", "account.blocked": "Blokita", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 41d7db9da7..8aac2d77df 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloquear", "account.block_domain": "Ocultar todo de {domain}", "account.blocked": "Bloqueado", diff --git a/app/javascript/mastodon/locales/eu.json b/app/javascript/mastodon/locales/eu.json index 49cdf56301..e927547e39 100644 --- a/app/javascript/mastodon/locales/eu.json +++ b/app/javascript/mastodon/locales/eu.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokeatu @{name}", "account.block_domain": "{domain}(e)ko guztia ezkutatu", "account.blocked": "Blokeatuta", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 99aba00c35..e19b1cd859 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "مسدودسازی @{name}", "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}", "account.blocked": "مسدودشده", @@ -125,17 +126,17 @@ "keyboard_shortcuts.boost": "برای بازبوقیدن", "keyboard_shortcuts.column": "برای برجسته‌کردن یک نوشته در یکی از ستون‌ها", "keyboard_shortcuts.compose": "برای فعال‌کردن کادر نوشتهٔ تازه", - "keyboard_shortcuts.description": "Description", + "keyboard_shortcuts.description": "توضیح", "keyboard_shortcuts.down": "برای پایین‌رفتن در فهرست", - "keyboard_shortcuts.enter": "to open status", + "keyboard_shortcuts.enter": "برای گشودن نوشته", "keyboard_shortcuts.favourite": "برای پسندیدن", - "keyboard_shortcuts.heading": "Keyboard Shortcuts", + "keyboard_shortcuts.heading": "میان‌برهای صفحه‌کلید", "keyboard_shortcuts.hotkey": "میان‌بر", "keyboard_shortcuts.legend": "برای نمایش این راهنما", "keyboard_shortcuts.mention": "برای نام‌بردن از نویسنده", "keyboard_shortcuts.reply": "برای پاسخ‌دادن", "keyboard_shortcuts.search": "برای فعال‌کردن جستجو", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_hidden": "برای نمایش/نهفتن نوشتهٔ پشت هشدار محتوا", "keyboard_shortcuts.toot": "برای آغاز یک بوق تازه", "keyboard_shortcuts.unfocus": "برای برداشتن توجه از نوشتن/جستجو", "keyboard_shortcuts.up": "برای بالا رفتن در فهرست", @@ -211,7 +212,7 @@ "privacy.direct.short": "مستقیم", "privacy.private.long": "تنها به پیگیران نشان بده", "privacy.private.short": "خصوصی", - "privacy.public.long": "در فهرست عمومی نشان بده", + "privacy.public.long": "نمایش در فهرست عمومی", "privacy.public.short": "عمومی", "privacy.unlisted.long": "عمومی، ولی فهرست نکن", "privacy.unlisted.short": "فهرست‌نشده", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 07d4d9aa5c..cfe9c4f331 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Estä @{name}", "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}", "account.blocked": "Estetty", @@ -29,8 +30,8 @@ "account.unmute": "Poista käyttäjän @{name} mykistys", "account.unmute_notifications": "Poista mykistys käyttäjän @{name} ilmoituksilta", "account.view_full_profile": "Näytä koko profiili", - "alert.unexpected.message": "An unexpected error occurred.", - "alert.unexpected.title": "Oops!", + "alert.unexpected.message": "Tapahtui odottamaton virhe.", + "alert.unexpected.title": "Hups!", "boost_modal.combo": "Ensi kerralla voit ohittaa tämän painamalla {combo}", "bundle_column_error.body": "Jokin meni vikaan komponenttia ladattaessa.", "bundle_column_error.retry": "Yritä uudestaan", @@ -41,7 +42,7 @@ "column.blocks": "Estetyt käyttäjät", "column.community": "Paikallinen aikajana", "column.direct": "Direct messages", - "column.domain_blocks": "Hidden domains", + "column.domain_blocks": "Piilotetut verkkotunnukset", "column.favourites": "Suosikit", "column.follow_requests": "Seuraamispyynnöt", "column.home": "Koti", @@ -59,7 +60,7 @@ "column_header.unpin": "Poista kiinnitys", "column_subheading.navigation": "Navigaatio", "column_subheading.settings": "Asetukset", - "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", + "compose_form.direct_message_warning": "Tämä tuuttaus näkyy vain mainituille käyttäjille.", "compose_form.hashtag_warning": "Tämä tuuttaus ei näy hashtag-hauissa, koska se on listaamaton. Hashtagien avulla voi hakea vain julkisia tuuttauksia.", "compose_form.lock_disclaimer": "Tilisi ei ole {locked}. Kuka tahansa voi seurata tiliäsi ja nähdä vain seuraajille rajaamasi julkaisut.", "compose_form.lock_disclaimer.lock": "lukittu", @@ -135,7 +136,7 @@ "keyboard_shortcuts.mention": "mainitse julkaisija", "keyboard_shortcuts.reply": "vastaa", "keyboard_shortcuts.search": "siirry hakukenttään", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_hidden": "näytä/piilota sisältövaroituksella merkitty teksti", "keyboard_shortcuts.toot": "ala kirjoittaa uutta tuuttausta", "keyboard_shortcuts.unfocus": "siirry pois tekstikentästä tai hakukentästä", "keyboard_shortcuts.up": "siirry listassa ylöspäin", @@ -158,7 +159,7 @@ "navigation_bar.blocks": "Estetyt käyttäjät", "navigation_bar.community_timeline": "Paikallinen aikajana", "navigation_bar.direct": "Direct messages", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.domain_blocks": "Piilotetut verkkotunnukset", "navigation_bar.edit_profile": "Muokkaa profiilia", "navigation_bar.favourites": "Suosikit", "navigation_bar.follow_requests": "Seuraamispyynnöt", @@ -242,10 +243,10 @@ "search_results.total": "{count, number} {count, plural, one {result} other {results}}", "standalone.public_title": "Kurkistus sisälle...", "status.block": "Estä @{name}", - "status.cancel_reblog_private": "Unboost", + "status.cancel_reblog_private": "Peru buustaus", "status.cannot_reblog": "Tätä julkaisua ei voi buustata", "status.delete": "Poista", - "status.direct": "Direct message @{name}", + "status.direct": "Viesti käyttäjälle @{name}", "status.embed": "Upota", "status.favourite": "Tykkää", "status.load_more": "Lataa lisää", @@ -258,7 +259,7 @@ "status.pin": "Kiinnitä profiiliin", "status.pinned": "Kiinnitetty tuuttaus", "status.reblog": "Buustaa", - "status.reblog_private": "Boost to original audience", + "status.reblog_private": "Buustaa alkuperäiselle yleisölle", "status.reblogged_by": "{name} buustasi", "status.reply": "Vastaa", "status.replyAll": "Vastaa ketjuun", @@ -276,7 +277,7 @@ "tabs_bar.home": "Koti", "tabs_bar.local_timeline": "Paikallinen", "tabs_bar.notifications": "Ilmoitukset", - "tabs_bar.search": "Search", + "tabs_bar.search": "Hae", "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 16bf4033c2..b0bda275ce 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloquer @{name}", "account.block_domain": "Tout masquer venant de {domain}", "account.blocked": "Bloqué", @@ -187,7 +188,7 @@ "notifications.column_settings.sound": "Émettre un son", "onboarding.done": "Effectué", "onboarding.next": "Suivant", - "onboarding.page_five.public_timelines": "Le fil public global affiche les messages de toutes les personnes suivies par les membres de {domain}. Le fil public local est identique mais se limite aux membres de {domain}.", + "onboarding.page_five.public_timelines": "Le fil public global affiche les messages de toutes les personnes suivies par les membres de {domain}. Le fil public local est identique, mais se limite aux membres de {domain}.", "onboarding.page_four.home": "L’Accueil affiche les messages des personnes que vous suivez.", "onboarding.page_four.notifications": "La colonne de notification vous avertit lors d'une interaction avec vous.", "onboarding.page_one.federation": "Mastodon est un réseau de serveurs indépendants qui se joignent pour former un réseau social plus vaste. Nous appelons ces serveurs des instances.", @@ -225,7 +226,7 @@ "reply_indicator.cancel": "Annuler", "report.forward": "Transférer à {target}", "report.forward_hint": "Le compte provient d'un autre serveur. Envoyez également une copie anonyme du rapport ?", - "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez ce compte ci-dessous :", + "report.hint": "Le rapport sera envoyé aux modérateurs de votre instance. Vous pouvez expliquer pourquoi vous signalez le compte ci-dessous :", "report.placeholder": "Commentaires additionnels", "report.submit": "Envoyer", "report.target": "Signalement", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 652ca31d15..29885b8960 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloquear @{name}", "account.block_domain": "Ocultar calquer contido de {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 0ffbb14f31..a4bcba8ff1 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "חסימת @{name}", "account.block_domain": "להסתיר הכל מהקהילה {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index c41cc3ea10..bd1dfac4c0 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokiraj @{name}", "account.block_domain": "Sakrij sve sa {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index a0c1861845..5059a45d4a 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "@{name} letiltása", "account.block_domain": "Minden elrejtése innen: {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index a0442bad47..7fe723892c 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Արգելափակել @{name}֊ին", "account.block_domain": "Թաքցնել ամենը հետեւյալ տիրույթից՝ {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 2fd9225440..07b26a0a5a 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokir @{name}", "account.block_domain": "Sembunyikan segalanya dari {domain}", "account.blocked": "Terblokir", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index ed45ee11ec..a8ab72339e 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokusar @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index a7ca620156..9d3486152e 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blocca @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Bloccato", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index a5857c1153..7ac65c393d 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "@{name}さんをブロック", "account.block_domain": "{domain}全体を非表示", "account.blocked": "ブロック済み", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 2a27346736..e72a7dff9c 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "@{name}을 차단", "account.block_domain": "{domain} 전체를 숨김", "account.blocked": "차단 됨", @@ -29,9 +30,9 @@ "account.unmute": "뮤트 해제", "account.unmute_notifications": "@{name}의 알림 뮤트 해제", "account.view_full_profile": "전체 프로필 보기", - "alert.unexpected.message": "An unexpected error occurred.", - "alert.unexpected.title": "Oops!", - "boost_modal.combo": "다음부터 {combo}를 누르면 이 과정을 건너뛸 수 있습니다.", + "alert.unexpected.message": "예측하지 못한 에러가 발생했습니다.", + "alert.unexpected.title": "앗!", + "boost_modal.combo": "{combo}를 누르면 다음부터 이 과정을 건너뛸 수 있습니다", "bundle_column_error.body": "컴포넌트를 불러오는 과정에서 문제가 발생했습니다.", "bundle_column_error.retry": "다시 시도", "bundle_column_error.title": "네트워크 에러", @@ -40,8 +41,8 @@ "bundle_modal_error.retry": "다시 시도", "column.blocks": "차단 중인 사용자", "column.community": "로컬 타임라인", - "column.direct": "Direct messages", - "column.domain_blocks": "Hidden domains", + "column.direct": "다이렉트 메시지", + "column.domain_blocks": "숨겨진 도메인", "column.favourites": "즐겨찾기", "column.follow_requests": "팔로우 요청", "column.home": "홈", @@ -59,17 +60,17 @@ "column_header.unpin": "고정 해제", "column_subheading.navigation": "내비게이션", "column_subheading.settings": "설정", - "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", + "compose_form.direct_message_warning": "이 툿은 멘션 된 유저들에게만 보여집니다.", "compose_form.hashtag_warning": "이 툿은 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 툿만이 해시태그로 검색 될 수 있습니다.", "compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.", "compose_form.lock_disclaimer.lock": "비공개", "compose_form.placeholder": "지금 무엇을 하고 있나요?", "compose_form.publish": "툿", "compose_form.publish_loud": "{publish}!", - "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.sensitive.marked": "미디어가 열람주의로 설정되어 있습니다", + "compose_form.sensitive.unmarked": "미디어가 열람주의로 설정 되어 있지 않습니다", + "compose_form.spoiler.marked": "열람주의가 설정되어 있습니다", + "compose_form.spoiler.unmarked": "열람주의가 설정 되어 있지 않습니다", "compose_form.spoiler_placeholder": "경고", "confirmation_modal.cancel": "취소", "confirmations.block.confirm": "차단", @@ -101,13 +102,13 @@ "emoji_button.symbols": "기호", "emoji_button.travel": "여행과 장소", "empty_column.community": "로컬 타임라인에 아무 것도 없습니다. 아무거나 적어 보세요!", - "empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.", + "empty_column.direct": "아직 다이렉트 메시지가 없습니다. 다이렉트 메시지를 보내거나 받은 경우, 여기에 표시 됩니다.", "empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.", "empty_column.home": "아직 아무도 팔로우 하고 있지 않습니다. {public}를 보러 가거나, 검색하여 다른 사용자를 찾아 보세요.", "empty_column.home.public_timeline": "연합 타임라인", "empty_column.list": "리스트에 아직 아무 것도 없습니다.", - "empty_column.notifications": "아직 알림이 없습니다. 다른 사람과 대화를 시작해 보세요!", - "empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 인스턴스 유저를 팔로우 해서 가득 채워보세요!", + "empty_column.notifications": "아직 알림이 없습니다. 다른 사람과 대화를 시작해 보세요.", + "empty_column.public": "여기엔 아직 아무 것도 없습니다! 공개적으로 무언가 포스팅하거나, 다른 인스턴스의 유저를 팔로우 해서 채워보세요", "follow_request.authorize": "허가", "follow_request.reject": "거부", "getting_started.appsshort": "애플리케이션", @@ -135,7 +136,7 @@ "keyboard_shortcuts.mention": "멘션", "keyboard_shortcuts.reply": "답장", "keyboard_shortcuts.search": "검색창에 포커스", - "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "keyboard_shortcuts.toggle_hidden": "CW로 가려진 텍스트를 표시/비표시", "keyboard_shortcuts.toot": "새 툿 작성", "keyboard_shortcuts.unfocus": "작성창에서 포커스 해제", "keyboard_shortcuts.up": "리스트에서 위로 이동", @@ -157,8 +158,8 @@ "mute_modal.hide_notifications": "이 사용자로부터의 알림을 뮤트하시겠습니까?", "navigation_bar.blocks": "차단한 사용자", "navigation_bar.community_timeline": "로컬 타임라인", - "navigation_bar.direct": "Direct messages", - "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.direct": "다이렉트 메시지", + "navigation_bar.domain_blocks": "숨겨진 도메인", "navigation_bar.edit_profile": "프로필 편집", "navigation_bar.favourites": "즐겨찾기", "navigation_bar.follow_requests": "팔로우 요청", @@ -177,12 +178,12 @@ "notifications.clear": "알림 지우기", "notifications.clear_confirmation": "정말로 알림을 삭제하시겠습니까?", "notifications.column_settings.alert": "데스크탑 알림", - "notifications.column_settings.favourite": "즐겨찾기", - "notifications.column_settings.follow": "새 팔로워", - "notifications.column_settings.mention": "답글", + "notifications.column_settings.favourite": "즐겨찾기:", + "notifications.column_settings.follow": "새 팔로워:", + "notifications.column_settings.mention": "답글:", "notifications.column_settings.push": "푸시 알림", "notifications.column_settings.push_meta": "이 장치", - "notifications.column_settings.reblog": "부스트", + "notifications.column_settings.reblog": "부스트:", "notifications.column_settings.show": "컬럼에 표시", "notifications.column_settings.sound": "효과음 재생", "onboarding.done": "완료", @@ -200,7 +201,7 @@ "onboarding.page_six.apps_available": "iOS、Android 또는 다른 플랫폼에서 사용할 수 있는 {apps}이 있습니다.", "onboarding.page_six.github": "Mastodon는 오픈 소스 소프트웨어입니다. 버그 보고나 기능 추가 요청, 기여는 {github}에서 할 수 있습니다.", "onboarding.page_six.guidelines": "커뮤니티 가이드라인", - "onboarding.page_six.read_guidelines": "{guidelines}을 확인하는 것을 잊지 마세요.", + "onboarding.page_six.read_guidelines": "{domain}의 {guidelines}을 확인하는 것을 잊지 마세요!", "onboarding.page_six.various_app": "다양한 모바일 애플리케이션", "onboarding.page_three.profile": "[프로필 편집] 에서 자기 소개나 이름을 변경할 수 있습니다. 또한 다른 설정도 변경할 수 있습니다.", "onboarding.page_three.search": "검색 바에서 {illustration} 나 {introductions} 와 같이 특정 해시태그가 달린 포스트를 보거나, 사용자를 찾을 수 있습니다.", @@ -242,10 +243,10 @@ "search_results.total": "{count, number}건의 결과", "standalone.public_title": "지금 이런 이야기를 하고 있습니다…", "status.block": "@{name} 차단", - "status.cancel_reblog_private": "Unboost", + "status.cancel_reblog_private": "부스트 취소", "status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다", "status.delete": "삭제", - "status.direct": "Direct message @{name}", + "status.direct": "@{name}에게 다이렉트 메시지", "status.embed": "공유하기", "status.favourite": "즐겨찾기", "status.load_more": "더 보기", @@ -258,7 +259,7 @@ "status.pin": "고정", "status.pinned": "고정 된 툿", "status.reblog": "부스트", - "status.reblog_private": "Boost to original audience", + "status.reblog_private": "원래의 수신자들에게 부스트", "status.reblogged_by": "{name}님이 부스트 했습니다", "status.reply": "답장", "status.replyAll": "전원에게 답장", @@ -267,16 +268,16 @@ "status.sensitive_warning": "민감한 미디어", "status.share": "공유", "status.show_less": "숨기기", - "status.show_less_all": "Show less for all", + "status.show_less_all": "모두 접기", "status.show_more": "더 보기", - "status.show_more_all": "Show more for all", + "status.show_more_all": "모두 펼치기", "status.unmute_conversation": "이 대화의 뮤트 해제하기", "status.unpin": "고정 해제", "tabs_bar.federated_timeline": "연합", "tabs_bar.home": "홈", "tabs_bar.local_timeline": "로컬", "tabs_bar.notifications": "알림", - "tabs_bar.search": "Search", + "tabs_bar.search": "검색", "ui.beforeunload": "지금 나가면 저장되지 않은 항목을 잃게 됩니다.", "upload_area.title": "드래그 & 드롭으로 업로드", "upload_button.label": "미디어 추가", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index adc1d19a7c..a6bfe36f91 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokkeer @{name}", "account.block_domain": "Negeer alles van {domain}", "account.blocked": "Geblokkeerd", @@ -50,7 +51,7 @@ "column.notifications": "Meldingen", "column.pins": "Vastgezette toots", "column.public": "Globale tijdlijn", - "column_back_button.label": "terug", + "column_back_button.label": "Terug", "column_header.hide_settings": "Instellingen verbergen", "column_header.moveLeft_settings": "Kolom naar links verplaatsen", "column_header.moveRight_settings": "Kolom naar rechts verplaatsen", @@ -61,7 +62,7 @@ "column_subheading.settings": "Instellingen", "compose_form.direct_message_warning": "Deze toot zal alleen zichtbaar zijn voor alle vermelde gebruikers.", "compose_form.hashtag_warning": "Deze toot valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare toots kunnen via hashtags gevonden worden.", - "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en toots zien die je alleen aan volgers hebt gericht.", + "compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de toots zien die je alleen aan jouw volgers hebt gericht.", "compose_form.lock_disclaimer.lock": "besloten", "compose_form.placeholder": "Wat wil je kwijt?", "compose_form.publish": "Toot", @@ -76,10 +77,10 @@ "confirmations.block.message": "Weet je het zeker dat je {name} wilt blokkeren?", "confirmations.delete.confirm": "Verwijderen", "confirmations.delete.message": "Weet je het zeker dat je deze toot wilt verwijderen?", - "confirmations.delete_list.confirm": "Delete", + "confirmations.delete_list.confirm": "Verwijderen", "confirmations.delete_list.message": "Weet je zeker dat je deze lijst definitief wilt verwijderen?", "confirmations.domain_block.confirm": "Negeer alles van deze server", - "confirmations.domain_block.message": "Weet je het echt, echt zeker dat je alles van {domain} wil negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en gewenst.", + "confirmations.domain_block.message": "Weet je het echt heel erg zeker dat je alles van {domain} wil negeren? In de meeste gevallen is het blokkeren of negeren van een paar specifieke personen voldoende en gepaster.", "confirmations.mute.confirm": "Negeren", "confirmations.mute.message": "Weet je het zeker dat je {name} wilt negeren?", "confirmations.unfollow.confirm": "Ontvolgen", @@ -106,13 +107,13 @@ "empty_column.home": "Jij volgt nog niemand. Bezoek {public} of gebruik het zoekvenster om andere mensen te ontmoeten.", "empty_column.home.public_timeline": "de globale tijdlijn", "empty_column.list": "Er is nog niks in deze lijst. Wanneer lijstleden nieuwe toots publiceren, zijn deze hier te zien.", - "empty_column.notifications": "Je hebt nog geen meldingen. Heb interactie met andere mensen om het gesprek aan te gaan.", + "empty_column.notifications": "Je hebt nog geen meldingen. Begin met iemand een gesprek.", "empty_column.public": "Er is hier helemaal niks! Toot iets in het openbaar of volg mensen van andere servers om het te vullen", "follow_request.authorize": "Goedkeuren", "follow_request.reject": "Afkeuren", "getting_started.appsshort": "Apps", "getting_started.faq": "FAQ", - "getting_started.heading": "Beginnen", + "getting_started.heading": "Aan de slag", "getting_started.open_source_notice": "Mastodon is vrije software. Je kunt bijdragen of problemen melden op GitHub via {github}.", "getting_started.userguide": "Gebruikersgids", "home.column_settings.advanced": "Geavanceerd", @@ -131,7 +132,7 @@ "keyboard_shortcuts.favourite": "om als favoriet te markeren", "keyboard_shortcuts.heading": "Sneltoetsen", "keyboard_shortcuts.hotkey": "Sneltoets", - "keyboard_shortcuts.legend": "om deze legenda weer te geven", + "keyboard_shortcuts.legend": "om deze legenda te tonen", "keyboard_shortcuts.mention": "om de auteur te vermelden", "keyboard_shortcuts.reply": "om te reageren", "keyboard_shortcuts.search": "om het zoekvak te focussen", @@ -187,7 +188,7 @@ "notifications.column_settings.sound": "Geluid afspelen", "onboarding.done": "Klaar", "onboarding.next": "Volgende", - "onboarding.page_five.public_timelines": "De lokale tijdlijn toont openbare toots van iedereen op {domain}. De globale tijdlijn toont openbare toots van iedereen die door gebruikers van {domain} worden gevolgd, dus ook mensen van andere Mastodonservers. Dit zijn de openbare tijdlijnen en vormen een uitstekende manier om nieuwe mensen te ontdekken.", + "onboarding.page_five.public_timelines": "De lokale tijdlijn toont openbare toots van iedereen op {domain}. De globale tijdlijn toont openbare toots van iedereen die door gebruikers van {domain} worden gevolgd, dus ook mensen van andere Mastodonservers. Dit zijn de openbare tijdlijnen en vormen een uitstekende manier om nieuwe mensen te leren kennen.", "onboarding.page_four.home": "Deze tijdlijn laat toots zien van mensen die jij volgt.", "onboarding.page_four.notifications": "De kolom met meldingen toont alle interacties die je met andere Mastodongebruikers hebt.", "onboarding.page_one.federation": "Mastodon is een netwerk van onafhankelijke servers die samen een groot sociaal netwerk vormen.", @@ -231,7 +232,7 @@ "report.target": "Rapporteer {target}", "search.placeholder": "Zoeken", "search_popout.search_format": "Geavanceerd zoeken", - "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken naar jouw toots, gebooste toots, favorieten en naar toots waarin jij bent vermeldt, en naar gebruikersnamen, weergavenamen en hashtags.", + "search_popout.tips.full_text": "Gebruik gewone tekst om te zoeken in jouw toots, gebooste toots, favorieten en in toots waarin jij bent vermeldt, en tevens naar gebruikersnamen, weergavenamen en hashtags.", "search_popout.tips.hashtag": "hashtag", "search_popout.tips.status": "toot", "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags", @@ -253,7 +254,7 @@ "status.mention": "Vermeld @{name}", "status.more": "Meer", "status.mute": "Negeer @{name}", - "status.mute_conversation": "Negeer conversatie", + "status.mute_conversation": "Negeer gesprek", "status.open": "Toot volledig tonen", "status.pin": "Aan profielpagina vastmaken", "status.pinned": "Vastgemaakte toot", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index 0ee6d07229..05dae0630c 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokkér @{name}", "account.block_domain": "Skjul alt fra {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index c4cb996cf3..ead57d63fc 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blocar @{name}", "account.block_domain": "Tot amagar del domeni {domain}", "account.blocked": "Blocat", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 9dff9d1a3e..efebe69824 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokuj @{name}", "account.block_domain": "Blokuj wszystko z {domain}", "account.blocked": "Zablokowany", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 7f8690f913..2360c41e76 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloquear @{name}", "account.block_domain": "Esconder tudo de {domain}", "account.blocked": "Bloqueado", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json index ce816dc41c..3ac92dd577 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Bloquear @{name}", "account.block_domain": "Esconder tudo do domínio {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 8eeebaf736..5998734396 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Блокировать", "account.block_domain": "Блокировать все с {domain}", "account.blocked": "Заблокирован(а)", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index d69648ccff..1cf7dee809 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokovať @{name}", "account.block_domain": "Ukryť všetko z {domain}", "account.blocked": "Blokovaný/á", diff --git a/app/javascript/mastodon/locales/sl.json b/app/javascript/mastodon/locales/sl.json new file mode 100644 index 0000000000..202dc4bd03 --- /dev/null +++ b/app/javascript/mastodon/locales/sl.json @@ -0,0 +1,297 @@ +{ + "account.badges.bot": "Bot", + "account.block": "Blokiraj @{name}", + "account.block_domain": "Skrij vse iz {domain}", + "account.blocked": "Blokirano", + "account.direct": "Neposredno sporočilo @{name}", + "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", + "account.edit_profile": "Edit profile", + "account.follow": "Follow", + "account.followers": "Followers", + "account.follows": "Follows", + "account.follows_you": "Follows you", + "account.hide_reblogs": "Hide boosts from @{name}", + "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.posts": "Toots", + "account.posts_with_replies": "Toots and replies", + "account.report": "Report @{name}", + "account.requested": "Awaiting approval. Click to cancel follow request", + "account.share": "Share @{name}'s profile", + "account.show_reblogs": "Show boosts from @{name}", + "account.unblock": "Unblock @{name}", + "account.unblock_domain": "Unhide {domain}", + "account.unfollow": "Unfollow", + "account.unmute": "Unmute @{name}", + "account.unmute_notifications": "Unmute notifications from @{name}", + "account.view_full_profile": "View full profile", + "alert.unexpected.message": "An unexpected error occurred.", + "alert.unexpected.title": "Oops!", + "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.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_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.navigation": "Navigation", + "column_subheading.settings": "Settings", + "compose_form.direct_message_warning": "This toot will only be visible to all the mentioned users.", + "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.publish": "Toot", + "compose_form.publish_loud": "{publish}!", + "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.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.", + "confirmations.mute.confirm": "Mute", + "confirmations.mute.message": "Are you sure you want to mute {name}?", + "confirmations.unfollow.confirm": "Unfollow", + "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "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.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.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.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 instances to fill it up", + "follow_request.authorize": "Authorize", + "follow_request.reject": "Reject", + "getting_started.appsshort": "Apps", + "getting_started.faq": "FAQ", + "getting_started.heading": "Getting started", + "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", + "getting_started.userguide": "User Guide", + "home.column_settings.advanced": "Advanced", + "home.column_settings.basic": "Basic", + "home.column_settings.filter_regex": "Filter out by regular expressions", + "home.column_settings.show_reblogs": "Show boosts", + "home.column_settings.show_replies": "Show replies", + "home.settings": "Column settings", + "keyboard_shortcuts.back": "to navigate back", + "keyboard_shortcuts.boost": "to boost", + "keyboard_shortcuts.column": "to focus a status in one of the columns", + "keyboard_shortcuts.compose": "to focus the compose textarea", + "keyboard_shortcuts.description": "Description", + "keyboard_shortcuts.down": "to move down in the list", + "keyboard_shortcuts.enter": "to open status", + "keyboard_shortcuts.favourite": "to favourite", + "keyboard_shortcuts.heading": "Keyboard Shortcuts", + "keyboard_shortcuts.hotkey": "Hotkey", + "keyboard_shortcuts.legend": "to display this legend", + "keyboard_shortcuts.mention": "to mention author", + "keyboard_shortcuts.reply": "to reply", + "keyboard_shortcuts.search": "to focus search", + "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", + "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", + "lists.account.add": "Add to list", + "lists.account.remove": "Remove from list", + "lists.delete": "Delete list", + "lists.edit": "Edit list", + "lists.new.create": "Add list", + "lists.new.title_placeholder": "New list title", + "lists.search": "Search among people you follow", + "lists.subheading": "Your lists", + "loading_indicator.label": "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.blocks": "Blocked users", + "navigation_bar.community_timeline": "Local timeline", + "navigation_bar.direct": "Direct messages", + "navigation_bar.domain_blocks": "Hidden domains", + "navigation_bar.edit_profile": "Edit profile", + "navigation_bar.favourites": "Favourites", + "navigation_bar.follow_requests": "Follow requests", + "navigation_bar.info": "Extended information", + "navigation_bar.keyboard_shortcuts": "Keyboard shortcuts", + "navigation_bar.lists": "Lists", + "navigation_bar.logout": "Logout", + "navigation_bar.mutes": "Muted users", + "navigation_bar.pins": "Pinned toots", + "navigation_bar.preferences": "Preferences", + "navigation_bar.public_timeline": "Federated timeline", + "notification.favourite": "{name} favourited your status", + "notification.follow": "{name} followed you", + "notification.mention": "{name} mentioned you", + "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.follow": "New followers:", + "notifications.column_settings.mention": "Mentions:", + "notifications.column_settings.push": "Push notifications", + "notifications.column_settings.push_meta": "This device", + "notifications.column_settings.reblog": "Boosts:", + "notifications.column_settings.show": "Show in column", + "notifications.column_settings.sound": "Play sound", + "onboarding.done": "Done", + "onboarding.next": "Next", + "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.", + "onboarding.page_four.home": "The home timeline shows posts from people you follow.", + "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.", + "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.", + "onboarding.page_one.full_handle": "Your full handle", + "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.", + "onboarding.page_one.welcome": "Welcome to Mastodon!", + "onboarding.page_six.admin": "Your instance's admin is {admin}.", + "onboarding.page_six.almost_done": "Almost done...", + "onboarding.page_six.appetoot": "Bon Appetoot!", + "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.", + "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.", + "onboarding.page_six.guidelines": "community guidelines", + "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!", + "onboarding.page_six.various_app": "mobile apps", + "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.", + "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.", + "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.", + "onboarding.skip": "Skip", + "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 instance 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.total": "{count, number} {count, plural, one {result} other {results}}", + "standalone.public_title": "A look inside...", + "status.block": "Block @{name}", + "status.cancel_reblog_private": "Unboost", + "status.cannot_reblog": "This post cannot be boosted", + "status.delete": "Delete", + "status.direct": "Direct message @{name}", + "status.embed": "Embed", + "status.favourite": "Favourite", + "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.reblog": "Boost", + "status.reblog_private": "Boost to original audience", + "status.reblogged_by": "{name} boosted", + "status.reply": "Reply", + "status.replyAll": "Reply to thread", + "status.report": "Report @{name}", + "status.sensitive_toggle": "Click to view", + "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.unmute_conversation": "Unmute conversation", + "status.unpin": "Unpin from profile", + "tabs_bar.federated_timeline": "Federated", + "tabs_bar.home": "Home", + "tabs_bar.local_timeline": "Local", + "tabs_bar.notifications": "Notifications", + "tabs_bar.search": "Search", + "ui.beforeunload": "Your draft will be lost if you leave Mastodon.", + "upload_area.title": "Drag & drop to upload", + "upload_button.label": "Add media", + "upload_form.description": "Describe for the visually impaired", + "upload_form.focus": "Crop", + "upload_form.undo": "Undo", + "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/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index b1ea0d1795..490b3a51ac 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blokiraj korisnika @{name}", "account.block_domain": "Sakrij sve sa domena {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index aa978675fe..b331f9f48a 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Блокирај корисника @{name}", "account.block_domain": "Сакриј све са домена {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 4efe88a7e7..36b2007645 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Blockera @{name}", "account.block_domain": "Dölj allt från {domain}", "account.blocked": "Blockerad", diff --git a/app/javascript/mastodon/locales/te.json b/app/javascript/mastodon/locales/te.json index a56720fee3..038ac6abbd 100644 --- a/app/javascript/mastodon/locales/te.json +++ b/app/javascript/mastodon/locales/te.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 82b44fe307..8d24395af6 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 056fbfe8fe..a377e7b74a 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Engelle @{name}", "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 1a7b587893..613d1a00da 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "Заблокувати", "account.block_domain": "Заглушити {domain}", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/whitelist_sl.json b/app/javascript/mastodon/locales/whitelist_sl.json new file mode 100644 index 0000000000..0d4f101c7a --- /dev/null +++ b/app/javascript/mastodon/locales/whitelist_sl.json @@ -0,0 +1,2 @@ +[ +] diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index a3a4de0af4..073dbe6cb2 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "屏蔽 @{name}", "account.block_domain": "隐藏来自 {domain} 的内容", "account.blocked": "Blocked", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index 7719e08a64..0c012aa7d5 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "封鎖 @{name}", "account.block_domain": "隱藏來自 {domain} 的一切文章", "account.blocked": "封鎖", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 84ff25e037..0f4d04947b 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -1,4 +1,5 @@ { + "account.badges.bot": "Bot", "account.block": "封鎖 @{name}", "account.block_domain": "隱藏來自 {domain} 的一切貼文", "account.blocked": "已被封鎖的", diff --git a/config/locales/activerecord.nl.yml b/config/locales/activerecord.nl.yml index 7972096653..eeabab34aa 100644 --- a/config/locales/activerecord.nl.yml +++ b/config/locales/activerecord.nl.yml @@ -6,7 +6,7 @@ nl: account: attributes: username: - invalid: alleen letters, nummers en laag streepje + invalid: alleen letters, nummers en underscores status: attributes: reblog: diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 632bd03b03..194d91cb02 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -53,7 +53,7 @@ ar: unfollow: إلغاء المتابعة admin: account_moderation_notes: - create: إنشاء + create: إترك ملاحظة created_msg: تم إنشاء ملاحظة الإشراف بنجاح ! delete: حذف destroyed_msg: تم تدمير ملاحظة الإشراف بنجاح ! @@ -142,6 +142,7 @@ ar: statuses: المنشورات subscribe: اشترك title: الحسابات + unconfirmed_email: البريد الإلكتروني غير المؤكد undo_silenced: رفع الصمت undo_suspension: إلغاء تعليق الحساب unsubscribe: إلغاء الاشتراك @@ -149,6 +150,8 @@ ar: web: الويب action_logs: actions: + assigned_to_self_report: قام {name} بتعيين التقرير٪ {target} لأنفسهم + change_email_user: غيّر٪ {name} عنوان البريد الإلكتروني للمستخدم٪ {target} confirm_user: "%{name} قد قام بتأكيد عنوان البريد الإلكتروني لـ %{target}" create_custom_emoji: "%{name} قام برفع إيموجي جديد %{target}" create_domain_block: "%{name} قام بحجب نطاق %{target}" @@ -164,10 +167,13 @@ ar: enable_user: "%{name} لقد قام بتنشيط تسجيل الدخول للمستخدِم %{target}" memorialize_account: لقد قام %{name} بتحويل حساب %{target} إلى صفحة تذكارية promote_user: "%{name} قام بترقية المستخدم %{target}" + remove_avatar_user: تمت إزالة٪ {name} الصورة الرمزية٪ {target} + reopen_report: تمت إعادة فتح التقرير {name}٪ {target} reset_password_user: "%{name} لقد قام بإعادة تعيين الكلمة السرية الخاصة بـ %{target}" resolve_report: قام %{name} بحل التقرير %{target} silence_account: لقد قام %{name} بكتم حساب %{target} suspend_account: لقد قام %{name} بتعليق حساب %{target} + unassigned_report: "٪ {name} تقرير غير معتمد٪ {target}" unsilence_account: لقد قام %{name} بإلغاء الكتم عن حساب %{target} unsuspend_account: لقد قام %{name} بإلغاء التعليق المفروض على حساب %{target} update_custom_emoji: "%{name} قام بتحديث الإيموجي %{target}" @@ -205,12 +211,15 @@ ar: domain: النطاق new: create: إنشاء حظر + hint: لن تمنع كتلة المجال إنشاء إدخالات حساب في قاعدة البيانات ، ولكنها ستطبق طرق الإشراف المحددة بأثر رجعي وتلقائي على هذه الحسابات. severity: + desc_html: "Silence سيجعل مشاركات الحساب غير مرئية لأي شخص لا يتبعها. Suspend سيزيل كل محتوى الحساب ووسائطه وبيانات ملفه الشخصي. Use None إذا كنت تريد فقط رفض ملفات الوسائط." noop: لا شيء silence: كتم suspend: تعليق title: حجب نطاق جديد reject_media: رفض ملفات الوسائط + reject_media_hint: يزيل ملفات الوسائط المخزنة محليًا ويرفض تنزيل أي ملفات في المستقبل. غير ذي صلة للتعليق severities: noop: لا شيء silence: إخفاء أو كتم @@ -250,35 +259,59 @@ ar: expired: المنتهي صلاحيتها title: التصفية title: الدعوات + report_notes: + created_msg: |- + 41/5000 + تم إنشاء ملاحظة التقرير بنجاح! + destroyed_msg: تم حذف ملاحظة التقرير بنجاح! reports: + account: + note: ملحوظة + report: تقرير action_taken_by: تم اتخاذ الإجراء مِن طرف are_you_sure: هل أنت متأكد ؟ + assign_to_self: عين لي + assigned: تعين رئيس comment: none: لا شيء + created_at: ذكرت id: معرّف ID mark_as_resolved: إعتبار التقرير كمحلول + mark_as_unresolved: علام كغير محلولة + notes: + create: اضف ملاحظة + create_and_resolve: الحل مع ملاحظة + create_and_unresolve: إعادة فتح مع ملاحظة + delete: حذف + placeholder: وصف الإجراءات التي تم اتخاذها أو أي تحديثات أخرى لهذا التقرير … + reopen: إعادة فتح التقرير report: 'التقرير #%{id}' report_contents: المحتويات reported_account: حساب مُبلّغ عنه reported_by: أبلغ عنه من طرف resolved: معالجة + resolved_msg: تم حل تقرير بنجاح! silence_account: كتم و إخفاء الحساب status: الحالة suspend_account: فرض تعليق على الحساب target: الهدف title: التقارير + unassign: إلغاء تعيين unresolved: غير معالجة + updated_at: محدث view: عرض settings: activity_api_enabled: desc_html: عدد المنشورات المحلية و المستخدمين النشطين و التسجيلات الأسبوعية الجديدة title: نشر مُجمل الإحصائيات عن نشاط المستخدمين bootstrap_timeline_accounts: + desc_html: افصل بين أسماء المستخدمين المتعددة بواسطة الفاصلة. استعمل الحسابات المحلية والمفتوحة فقط. الافتراضي عندما تكون فارغة كل المسؤولين المحليين. title: الإشتراكات الإفتراضية للمستخدمين الجدد contact_information: email: البريد الإلكتروني المهني username: الإتصال بالمستخدِم hero: + desc_html: معروض على الصفحة الأولى. لا يقل عن 600 × 100 بكسل. عند عدم التعيين ، تعود الصورة إلى النسخة المصغرة على سبيل المثال title: الصورة الرأسية peers_api_enabled: desc_html: أسماء النطاقات التي إلتقى بها مثيل الخادوم على البيئة الموحَّدة فيديفرس @@ -297,15 +330,23 @@ ar: desc_html: السماح للجميع بإنشاء حساب title: فتح التسجيل show_known_fediverse_at_about_page: + desc_html: عند التثبت ، سوف تظهر toots من جميع fediverse المعروفة على عرض مسبق. وإلا فإنه سيعرض فقط toots المحلية. title: إظهار الفيديفرس الموحَّد في خيط المُعايَنة + show_staff_badge: + desc_html: عرض شارة الموظفين على صفحة المستخدم + title: إظهار شارة الموظفين site_description: + desc_html: فقرة تمهيدية على الصفحة الأولى وفي العلامات الوصفية. يمكنك استخدام علامات HTML ، ولا سيما <a> و <em>. title: وصف مثيل الخادوم site_description_extended: + desc_html: مكان جيد لمدونة قواعد السلوك والقواعد والإرشادات وغيرها من الأمور التي تحدد حالتك. يمكنك استخدام علامات HTML title: الوصف المُفصّل للموقع site_terms: + desc_html: يمكنك كتابة سياسة الخصوصية الخاصة بك ، شروط الخدمة أو غيرها من القوانين. يمكنك استخدام علامات HTML title: شروط الخدمة المخصصة site_title: إسم مثيل الخادم thumbnail: + desc_html: يستخدم للعروض السابقة عبر Open Graph و API. 1200x630px موصى به title: الصورة الرمزية المصغرة لمثيل الخادوم timeline_preview: desc_html: عرض الخيط العمومي على صفحة الإستقبال @@ -315,12 +356,16 @@ ar: back_to_account: العودة إلى صفحة الحساب batch: delete: حذف + nsfw_off: ضع علامة انها غير حساسة + nsfw_on: ضع علامة انها حساسة failed_to_execute: خطأ في التفعيل media: title: الوسائط + no_media: لا يوجد وسائط title: منشورات الحساب with_media: بالوسائط subscriptions: + callback_url: عاود الاتصال بالعنوان confirmed: مؤكَّد expires_in: تنتهي مدة صلاحيتها في last_delivery: آخر إيداع @@ -330,6 +375,8 @@ ar: admin_mailer: new_report: body: قام %{reporter} بالإبلاغ عن %{target} + body_remote: أبلغ شخص ما من٪ {domain} عن٪ {target} + subject: تقرير جديد ل%{instance} (#%{id}) application_mailer: notification_preferences: تعديل خيارات البريد الإلكتروني salutation: "%{name}،" @@ -342,6 +389,7 @@ ar: destroyed: تم حذف التطبيق بنجاح invalid_url: إن الرابط المقدم غير صالح regenerate_token: إعادة توليد رمز النفاذ + token_regenerated: تم إعادة إنشاء الرمز الوصول بنجاح warning: كن حذرا مع هذه البيانات. لا تقم أبدا بمشاركتها مع الآخَرين ! your_token: رمز نفاذك auth: @@ -352,6 +400,7 @@ ar: delete_account_html: إن كنت ترغب في حذف حسابك يُمكنك المواصلة هنا. سوف يُطلَبُ منك التأكيد قبل الحذف. didnt_get_confirmation: لم تتلق تعليمات التأكيد ؟ forgot_password: نسيت كلمة المرور ؟ + invalid_reset_password_token: رمز إعادة تعيين كلمة المرور غير صالح أو منتهي الصلاحية. يرجى طلب واحد جديد. login: تسجيل الدخول logout: خروج migrate_account: الإنتقال إلى حساب آخر @@ -368,6 +417,7 @@ ar: security: الهوية set_new_password: إدخال كلمة مرور جديدة authorize_follow: + already_following: أنت تتابع بالفعل هذا الحساب error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد follow: إتبع follow_request: 'لقد قمت بإرسال طلب متابعة إلى :' @@ -410,7 +460,7 @@ ar: archive_takeout: date: التاريخ download: تنزيل نسخة لحسابك - hint_html: بإمكانك طلب نسخة كاملة لـ كافة تبويقاتك و الوسائط التي قمت بنشرها. البيانات المُصدَّرة ستكون محفوظة على شكل نسق ActivityPub و باستطاعتك قراءتها بأي برنامج يدعم هذا النسق. + hint_html: بإمكانك طلب نسخة كاملة لـ كافة تبويقاتك و الوسائط التي قمت بنشرها. البيانات المُصدَّرة ستكون محفوظة على شكل نسق ActivityPub و باستطاعتك قراءتها بأي برنامج يدعم هذا النسق. يُمكنك طلب نسخة كل 7 أيام. in_progress: عملية جمع نسخة لبيانات حسابك جارية … request: طلب نسخة لحسابك size: الحجم @@ -544,6 +594,9 @@ ar: missing_resource: تعذر العثور على رابط التحويل المطلوب الخاص بحسابك proceed: أكمل المتابعة prompt: 'إنك بصدد متابعة :' + remote_unfollow: + error: '' + title: '' sessions: activity: آخر نشاط browser: المتصفح @@ -581,11 +634,13 @@ ar: windows: ويندوز windows_mobile: ويندوز موبايل windows_phone: ويندوز فون + revoke: '' revoke_success: تم إبطال الجلسة بنجاح title: الجلسات settings: authorized_apps: التطبيقات المرخص لها back: عودة إلى ماستدون + delete: '' development: التطوير edit_profile: تعديل الملف الشخصي export: تصدير البيانات @@ -598,9 +653,18 @@ ar: two_factor_authentication: إثبات الهويّة المزدوج your_apps: تطبيقاتك statuses: + attached: + image: + one: '' + other: '' + video: + one: '' + other: '' + content_warning: '' open_in_web: إفتح في الويب over_character_limit: تم تجاوز حد الـ %{max} حرف المسموح بها pin_errors: + limit: '' ownership: لا يمكن تدبيس تبويق نشره شخص آخر private: لا يمكن تثبيت تبويق لم يُنشر للعامة reblog: لا يمكن تثبيت ترقية @@ -641,9 +705,19 @@ ar: wrong_code: الرمز الذي أدخلته غير صالح ! تحقق من صحة الوقت على الخادم و الجهاز ؟ user_mailer: backup_ready: + explanation: '' subject: نسخة بيانات حسابك جاهزة للتنزيل title: المغادرة بأرشيف الحساب + welcome: + edit_profile_action: '' + explanation: '' + full_handle: '' + review_preferences_action: '' + subject: '' + tips: نصائح + title: أهلاً بك، %{name} ! users: invalid_email: عنوان البريد الإلكتروني غير صالح invalid_otp_token: الرمز الثنائي غير صالح seamless_external_login: لقد قمت بتسجيل الدخول عبر خدمة خارجية، إنّ إعدادات الكلمة السرية و البريد الإلكتروني غير متوفرة. + signed_in_as: 'تم تسجيل دخولك بصفة :' diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 9956c00988..e90b682304 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -49,11 +49,12 @@ ca: reserved_username: El nom d'usuari està reservat roles: admin: Administrador + bot: Bot moderator: Moderador unfollow: Deixa de seguir admin: account_moderation_notes: - create: Crea + create: Crea nota created_msg: La nota de moderació s'ha creat correctament! delete: Suprimeix destroyed_msg: Nota de moderació destruïda amb èxit! @@ -463,7 +464,7 @@ ca: archive_takeout: date: Data download: Descarrega l’arxiu - hint_html: Pots sol·licitar un arxiu dels teus toots i els fitxers multimèdia pujats. Les dades exportades tindran el format ActivityPub, llegible per qualsevol programari compatible. + hint_html: Pots sol·licitar un arxiu dels teus toots i els fitxers multimèdia pujats. Les dades exportades tindran el format ActivityPub, llegible per qualsevol programari compatible. Pots sol·licitar un arxiu cada 7 dies. in_progress: Compilant el teu arxiu... request: Sol·licita el teu arxiu size: Tamany @@ -833,5 +834,6 @@ ca: users: invalid_email: L'adreça de correu no és correcta invalid_otp_token: El codi de dos factors no és correcte + otp_lost_help_html: Si has perdut l'accés a tots dos pots contactar per %{email} seamless_external_login: Has iniciat sessió via un servei extern per tant els ajustos de contrasenya i correu electrònic no estan disponibles. signed_in_as: 'Sessió iniciada com a:' diff --git a/config/locales/co.yml b/config/locales/co.yml index abef1d36bc..637491d6b2 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -1,11 +1,11 @@ --- co: about: - about_hashtag_html: Quessi sò statuti pubblichi taggati cù #%{hashtag}. Pudete interagisce cù elli sì voi avete un contu in qualche parte di u fediverse. + about_hashtag_html: Quessi sò statuti pubblichi taggati cù #%{hashtag}. Pudete interagisce cù elli sì voi avete un contu in qualche parte di u fediverse. about_mastodon_html: Mastodon ghjè una rete suciale custruita incù prutucolli web aperti è lugiziali liberi. Hè decentralizatu cumu l’e-mail. about_this: À prupositu administered_by: 'Amministratu da:' - closed_registrations: Pè avà, l’arregistramenti sò chjosi nant’à st’istanza. Mà pudete truvà un’altr’istanza per fà un contu è avè accessu à listessa reta da quallà! + closed_registrations: Pè avà, l’arregistramenti sò chjosi nant’à st’istanza. Mà pudete truvà un’altr’istanza per fà un contu è avè accessu à listessa reta da quallà. contact: Cuntattu contact_missing: Mancante contact_unavailable: Micca dispunibule @@ -70,6 +70,7 @@ co: title: Mudificà l’Email di %{username} confirm: Cunfirmà confirmed: Cunfirmata + confirming: Cunfirmazione demote: Ritrugradà disable: Disattivà disable_two_factor_authentication: Disattivà l’identificazione à 2 fattori @@ -78,6 +79,7 @@ co: domain: Duminiu edit: Mudificà email: E-mail + email_status: Statu di l’e-mail enable: Attivà enabled: Attivatu feed_url: URL di u flussu @@ -116,6 +118,10 @@ co: push_subscription_expires: Spirata di l’abbunamentu PuSH redownload: Mette à ghjornu i ritratti remove_avatar: Toglie l’avatar + resend_confirmation: + already_confirmed: St’utilizatore hè digià cunfirmatu + send: Rimandà un’e-mail di cunfirmazione + success: L’e-mail di cunfirmazione hè statu mandatu! reset: Reset reset_password: Riinizializà a chjave d’accessu resubscribe: Riabbunassi @@ -175,17 +181,17 @@ co: title: Ghjurnale d’audit custom_emojis: by_domain: Duminiu - copied_msg: Copia lucale di l’emoji creata! + copied_msg: Copia lucale di l’emoji creata copy: Cupià copy_failed_msg: Ùn s’hè micca pussutu creà una copia di l’emoji created_msg: L’emoji hè stata creata! delete: Toglie destroyed_msg: L’emoji hè stata tolta! disable: Disattivà - disabled_msg: L’emoji hè stata disattivata! + disabled_msg: L’emoji hè stata disattivata emoji: Emoji enable: Attivà - enabled_msg: L’emoji hè stata attivata! + enabled_msg: L’emoji hè stata attivata image_hint: PNG di 50Ko o menu listed: Listata new: @@ -380,9 +386,9 @@ co: created: Applicazione creata destroyed: Applicazione sguassata invalid_url: L’URL ch’è stata pruvista ùn hè valida - regenerate_token: Regenerate access token - token_regenerated: Access token successfully regenerated - warning: Be very careful with this data. Never share it with anyone! + regenerate_token: Creà un’altra fiscia d’accessu + token_regenerated: A fiscia d’accessu hè stata rigenerata + warning: Abbadate à quessi dati. Ùn i date à nisunu! your_token: Rigenerà a fiscia d’accessu auth: agreement_html: Arregistrassi vole dì chì site d’accunsentu per siguità e regule di l’istanza è e cundizione d’usu. @@ -392,7 +398,7 @@ co: delete_account_html: S’è voi vulete toglie u vostru contu ghjè quì. Duverete cunfirmà a vostra scelta. didnt_get_confirmation: Ùn avete micca ricevutu l’istruzione di cunfirmazione? forgot_password: Chjave scurdata? - invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. + invalid_reset_password_token: U ligame di riinizializazione di a chjave d’accessu hè spiratu o ùn hè micca validu. Pudete dumandà un'altru ligame. login: Cunnettassi logout: Scunnettassi migrate_account: Cambià di contu @@ -409,13 +415,13 @@ co: security: Sicurità set_new_password: Creà una nova chjave d’accessu authorize_follow: - already_following: You are already following this account - error: Peccatu, c’hè statu un prublemu ricercandu u contu. + already_following: Site digià abbunatu·a à stu contu + error: Peccatu, c’hè statu un prublemu ricercandu u contu follow: Siguità follow_request: 'Avete dumandatu di siguità:' following: 'Eccu! Avà seguitate:' post_follow: - close: Or, you can just close this window. + close: O pudete ancu chjude sta finestra. return: Rivultà à u prufile di l’utilizatore web: Andà à l’interfaccia web title: Siguità %{acct} @@ -483,11 +489,11 @@ co: powered_by: mossu da %{link} save_changes: Salvà e mudificazione validation_errors: - one: Qualcosa ùn và bè! Verificate un prublemu quì sottu. - other: Qualcosa ùn và bè! Verificate %{count} prublemi quì sottu. + one: Qualcosa ùn và bè! Verificate u prublemu quì sottu + other: Qualcosa ùn và bè! Verificate %{count} prublemi quì sottu imports: preface: Pudete impurtà certi dati cumu e persone chì seguitate o bluccate nant’à u vostru contu nant’à st’istanza à partesi di fugliali creati nant’à un’altr’istanza. - success: I vostri dati sò stati impurtati è saranu trattati da quì à pocu. + success: I vostri dati sò stati impurtati è saranu trattati da quì à pocu types: blocking: Persone chì bluccate following: Persone chì seguitate @@ -519,14 +525,14 @@ co: landing_strip_signup_html: Pudete ancu arrigistravi quì. lists: errors: - limit: Ùn pudete più creà altre liste. + limit: Ùn pudete più creà altre liste media_attachments: validations: images_and_video: Ùn si pò micca aghjunghje un filmettu à un statutu chì hà digià ritratti too_many: Ùn si pò micca aghjunghje più di 4 fugliali migrations: acct: cugnome@duminiu di u novu contu - currently_redirecting: "’U vostru prufile riindiriza tuttu versu à:’" + currently_redirecting: 'U vostru prufile riindiriza tuttu versu à:' proceed: Salvà updated_msg: I paramettri di migrazione sò stati messi à ghjornu! moderation: @@ -602,7 +608,7 @@ co: reblog: title: "%{name} hà spartutu u vostru statutu" remote_follow: - acct: Entrate u vostru cugnome@istanza da induve vulete siguità stu contu. + acct: Entrate u vostru cugnome@istanza da induve vulete siguità stu contu missing_resource: Ùn avemu pussutu à truvà l’indirizzu di ridirezzione proceed: Cuntinuà per siguità prompt: 'Avete da siguità:' @@ -791,11 +797,11 @@ co: disable: Disattivà enable: Attivà enabled: Identificazione à dui fattori attivata - enabled_success: L’identificazione à dui fattori hè stata attivata. + enabled_success: L’identificazione à dui fattori hè stata attivata generate_recovery_codes: Creà codici di ricuperazione instructions_html: "Scanate stu QR code cù Google Authenticator, Authy o qualcosa cusì nant’à u vostru telefuninu. St’applicazione hà da creà codici da entrà ogni volta chì vi cunnettate." lost_recovery_codes: I codici di ricuperazione à usu unicu vi permettenu di sempre avè accessu à u vostru contu s’è voi avete persu u vostru telefuninu. S’elli sò ancu persi, pudete creà codici novi quì. I vechji codici ùn marchjeranu più. - manual_instructions: S’ellu ùn hè micca pussibule scanà u QR code, pudete entre sta chjave sicreta:’ + manual_instructions: 'S’ellu ùn hè micca pussibule scanà u QR code, pudete entre sta chjave sicreta:' recovery_codes: Codici di ricuperazione recovery_codes_regenerated: Codici di ricuperazione ricreati recovery_instructions_html: Pudete fà usu di i codici quì sottu per sempre avè accessu à u vostru contu s’ellu hè statu persu u vostru telefuninu. Guardateli in una piazza sicura. Per esempiu, stampati è cunservati cù altri ducumenti impurtanti. @@ -811,7 +817,7 @@ co: edit_profile_step: Pudete persunalizà u vostru prufile cù un ritrattu di prufile o di cuprendula, un nome pubblicu persunalizatu, etc. Pudete ancu rende u contu privatu per duvè cunfirmà ogni dumanda d’abbunamentu. explanation: Eccu alcune idee per principià final_action: Principià à pustà - final_step: 'Andemu! Ancu senza abbunati i vostri missaghji pubblichi puderanu esse visti da altre persone, per esempiu nant’a linea lucale è l’hashtag. Pudete ancu prisintavi nant’à u hashtag #introductions!' + final_step: 'Andemu! Ancu senza abbunati i vostri missaghji pubblichi puderanu esse visti da altre persone, per esempiu nant’a linea lucale è l’hashtag. Pudete ancu prisintavi nant’à u hashtag #introductions.' full_handle: U vostru identificatore cumplettu full_handle_hint: Quessu ghjè cio chì direte à i vostri amichi per circavi, abbunassi à u vostru contu da altrò, o mandà missaghji. review_preferences_action: Mudificà e priferenze @@ -820,12 +826,13 @@ co: tip_bridge_html: S’è voi venite di Twitter, pudete truvà i vostri amichi da quallà chì sò nant’à Mastodon cù a bridge app. Mà ùn marchja chè s’elli l’anu ancu usata! tip_federated_timeline: A linea pubblica glubale mostra i statuti da altre istanze nant’a rete Mastodon, mà ùn hè micca cumpleta perchè ci sò soli i conti à quelli sò abbunati membri di a vostr’istanza. tip_following: Site digià abbunatu·a à l’amministratori di u vostru servore. Per truvà d’altre parsone da siguità, pudete pruvà e linee pubbliche. - tip_local_timeline: A linea pubblica lucale ghjè una vista crunulogica di i statuti di a ghjente nant’à %{instance}. - tip_mobile_webapp: Pudete aghjunghje Mastodon à a pagina d’accolta di u vostru navigatore di telefuninu per riceve nutificazione, cum’un applicazione. + tip_local_timeline: A linea pubblica lucale ghjè una vista crunulogica di i statuti di a ghjente nant’à %{instance}. Quessi sò i vostri cunvicini! + tip_mobile_webapp: Pudete aghjunghje Mastodon à a pagina d’accolta di u vostru navigatore di telefuninu per riceve nutificazione, cum’un applicazione! tips: Cunsiglii title: Benvenutu·a, %{name}! users: - invalid_email: L’indirizzu e-mail ùn hè currettu. - invalid_otp_token: U codice d’identificazione ùn hè currettu. + invalid_email: L’indirizzu e-mail ùn hè currettu + invalid_otp_token: U codice d’identificazione ùn hè currettu + otp_lost_help_html: S’è voi avete persu i dui, pudete cuntattà %{email} seamless_external_login: Site cunnettatu·a dapoi un serviziu esternu, allora i parametri di chjave d’accessu è d’indirizzu e-mail ùn so micca dispunibili. signed_in_as: 'Cunnettatu·a cum’è:' diff --git a/config/locales/de.yml b/config/locales/de.yml index 05d7e01b38..c0254f73f3 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -49,11 +49,12 @@ de: reserved_username: Dieser Profilname ist belegt roles: admin: Admin + bot: Bot moderator: Moderator unfollow: Entfolgen admin: account_moderation_notes: - create: Erstellen + create: Notiz hinterlassen created_msg: Moderationsnotiz erfolgreich erstellt! delete: Löschen destroyed_msg: Moderationsnotiz erfolgreich gelöscht! @@ -373,6 +374,7 @@ de: admin_mailer: new_report: body: "%{reporter} hat %{target} gemeldet" + body_remote: Jemand von %{domain} hat %{target} gemeldet subject: Neue Meldung auf %{instance} (#%{id}) application_mailer: notification_preferences: Ändere E-Mail-Einstellungen @@ -462,7 +464,7 @@ de: archive_takeout: date: Datum download: Dein Archiv herunterladen - hint_html: Du kannst ein Archiv deiner Beiträge und hochgeladenen Medien anfragen. Die exportierten Daten werden im ActivityPub-Format gespeichert, welches mit jeder Software lesbar ist die das Format unterstützt. + hint_html: Du kannst ein Archiv deiner Beiträge und hochgeladenen Medien anfragen. Die exportierten Daten werden im ActivityPub-Format gespeichert, welches mit jeder Software lesbar ist, die das Format unterstützt. Du kannst alle 7 Tage ein neues Archiv anfordern. in_progress: Stelle dein Archiv zusammen... request: Dein Archiv anfragen size: Größe @@ -755,5 +757,6 @@ de: users: invalid_email: Ungültige E-Mail-Adresse invalid_otp_token: Ungültiger Zwei-Faktor-Authentisierungs-Code + otp_lost_help_html: Wenn Sie zu beidem keinen Zugriff mehr haben, kontaktieren sie %{email} seamless_external_login: Du bist angemeldet über einen Drittanbieter-Dienst, weswegen Passwort- und E-Maileinstellungen nicht verfügbar sind. signed_in_as: 'Angemeldet als:' diff --git a/config/locales/devise.co.yml b/config/locales/devise.co.yml index d5bb708876..2471f857be 100644 --- a/config/locales/devise.co.yml +++ b/config/locales/devise.co.yml @@ -78,5 +78,5 @@ co: not_found: ùn hè micca statu trovu not_locked: ùn era micca chjosu not_saved: - one: Un prublemu hà impeditu a cunservazione di stu (sta) %{resource} + one: 'Un prublemu hà impeditu a cunservazione di stu (sta) %{resource}:' other: "%{count} prublemi anu impeditu a cunservazione di stu (sta) %{resource} :" diff --git a/config/locales/devise.fa.yml b/config/locales/devise.fa.yml index f78412f91d..8e95a3d94e 100644 --- a/config/locales/devise.fa.yml +++ b/config/locales/devise.fa.yml @@ -20,8 +20,17 @@ fa: subject: 'ماستدون: راهنمایی برای تأیید %{instance}' password_change: subject: 'ماستدون: رمزتان عوض شد' + reconfirmation_instructions: + explanation: نشانی تازه را تأیید کنید تا ایمیل‌تان عوض شود. + extra: اگر شما باعث این تغییر نبودید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید، نشانی ایمیل مربوط به حساب شما عوض نخواهد شد. + subject: 'ماستدون: تأیید ایمیل برای %{instance}' + title: تأیید نشانی ایمیل reset_password_instructions: + action: تغییر رمز + explanation: شما رمز تازه‌ای برای حسابتان درخواست کردید. + extra: اگر شما چنین درخواستی نکردید، لطفاً این ایمیل را نادیده بگیرید. تا زمانی که شما پیوند بالا را باز نکنید و رمز تازه‌ای نسازید، رمز شما عوض نخواهد شد. subject: 'ماستدون: راهنمایی برای بازنشانی رمز' + title: بازنشانی رمز unlock_instructions: subject: 'ماستدون: راهنمایی برای بازکردن قفل' omniauth_callbacks: @@ -57,5 +66,5 @@ fa: not_found: پیدا نشد not_locked: قفل نبود not_saved: - one: خطایی نگذاشت که این %{resource} ذخیره شود - other: به خاطر %{count} خطا، این %{resource} ذخیره نشد + one: 'خطایی نگذاشت که این %{resource} ذخیره شود:' + other: 'به خاطر %{count} خطا، این %{resource} ذخیره نشد:' diff --git a/config/locales/doorkeeper.co.yml b/config/locales/doorkeeper.co.yml index 01b082e401..31080d1533 100644 --- a/config/locales/doorkeeper.co.yml +++ b/config/locales/doorkeeper.co.yml @@ -29,7 +29,7 @@ co: edit: title: Mudificà l’applicazione form: - error: Uups! V’invitemu à verificà u vostru formulariu per vede s’elli ùn ci sò sbaglii. + error: Uups! V’invitemu à verificà u vostru formulariu per vede s’elli ùn ci sò sbaglii help: native_redirect_uri: Utilizate %{native_redirect_uri} pè e prove lucale redirect_uri: Utilizzate una linea per ogni URI @@ -60,10 +60,10 @@ co: title: C’hè statu un prublemu new: able_to: St’applicazione puderà - prompt: Parmette %{client_name} d’utilizzà u vostru contu? + prompt: L’applicazione %{client_name} hà dumandatu d’avè accessu à u vostru contu title: Permessu riquestu show: - title: Codice d’auturizazione da cupià indè l’applicazione + title: Codice d’auturizazione da cupià indè l’applicazione. authorized_applications: buttons: revoke: Sguassà @@ -83,7 +83,7 @@ co: invalid_grant: L’accunsentu d’auturizazione furnitu ùn hè currettu, hè spiratu, sguassatu, ùn và micca cù l’indirizzu di ridirezzione usatu in a dumanda d’auturizazione, o hè statu emessu per un’altru cliente. invalid_redirect_uri: L’URI di ridirezzione ùn hè curretta. invalid_request: Ci manca un parametru riquestu indè a dumanda, cuntene un parametru ch’ùn esiste micca, o altru sbagliu di forma. - invalid_resource_owner: L’idintificanti di u pruprietariu di a risorsa ùn sò curretti, o u pruprietariu ùn pò micca esse trovu. + invalid_resource_owner: L’idintificanti di u pruprietariu di a risorsa ùn sò curretti, o u pruprietariu ùn pò micca esse trovu invalid_scope: U scopu dumandatu ùn hè currettu, hè scunnisciutu, o altru sbagliu di forma. invalid_token: expired: A marca d’accessu hè spirata @@ -112,7 +112,7 @@ co: applications: Applicazione oauth2_provider: Furnitore OAuth2 application: - title: Auturizazione OAuth riquestata. + title: Auturizazione OAuth riquestata scopes: follow: bluccà, sbluccà, è reghje l’abbunamenti read: leghje l’infurmazione di u vostru contu diff --git a/config/locales/doorkeeper.fa.yml b/config/locales/doorkeeper.fa.yml index f3db862ca1..7e6a04ea81 100644 --- a/config/locales/doorkeeper.fa.yml +++ b/config/locales/doorkeeper.fa.yml @@ -19,56 +19,56 @@ fa: doorkeeper: applications: buttons: - authorize: Authorize - cancel: Cancel - destroy: Destroy - edit: Edit + authorize: اجازه دادن + cancel: لغو + destroy: پاک کردن + edit: ویرایش submit: Submit confirmations: - destroy: Are you sure? + destroy: آیا مطمئن هستید؟ edit: - title: Edit application + title: ویرایش برنامه form: - error: Whoops! Check your form for possible errors + error: اوخ! ببینید چیزی را اشتباهی در فرم وارد نکرده‌اید؟ help: - native_redirect_uri: Use %{native_redirect_uri} for local tests - redirect_uri: Use one line per URI - scopes: Separate scopes with spaces. Leave blank to use the default scopes. + native_redirect_uri: برای آزمایش‌های محلی %{native_redirect_uri} را به کار ببرید + redirect_uri: هر URI را در یک سطر جدا بنویسید + scopes: دامنه‌ها را با فاصلهٔ خالی از هم جدا کنید. برای به‌کاربردن دامنهٔ پیش‌فرض خالی بگذارید. index: - application: Application - callback_url: Callback URL + application: برنامه + callback_url: نشانی Callback delete: Delete name: Name - new: New application - scopes: Scopes - show: Show - title: Your applications + new: برنامهٔ تازه + scopes: دامنه‌ها + show: نمایش + title: برنامه‌های شما new: - title: New application + title: برنامهٔ تازه show: actions: Actions - application_id: Client key - callback_urls: Callback URLs - scopes: Scopes - secret: Client secret - title: 'Application: %{name}' + application_id: کلید کلاینت + callback_urls: نشانی‌های Callabck + scopes: دامنه‌ها + secret: کد سری کلاینت + title: 'برنامه: %{name}' authorizations: buttons: - authorize: Authorize - deny: Deny + authorize: اجازه دادن + deny: لغو اجازه error: - title: An error has occurred + title: خطایی رخ داد new: - able_to: It will be able to - prompt: Application %{client_name} requests access to your account - title: Authorization required + able_to: اجازه خواهد داشت + prompt: برنامهٔ %{client_name} می‌خواهد به حساب شما دسترسی داشته باشد + title: نیاز به اجازه دادن show: - title: Copy this authorization code and paste it to the application. + title: این کد مجوز را کپی کرده و در برنامه وارد کنید. authorized_applications: buttons: - revoke: Revoke + revoke: فسخ confirmations: - revoke: Are you sure? + revoke: آیا مطمئن هستید؟ index: application: برنامه created_at: مجازشده از @@ -77,7 +77,7 @@ fa: title: برنامه‌های مجاز errors: messages: - access_denied: The resource owner or authorization server denied the request. + access_denied: دارندهٔ منبع یا سرور اجازه دهنده درخواست را نپذیرفت. credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured. invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method. invalid_grant: The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. @@ -86,34 +86,34 @@ fa: invalid_resource_owner: The provided resource owner credentials are not valid, or resource owner cannot be found invalid_scope: The requested scope is invalid, unknown, or malformed. invalid_token: - expired: The access token expired - revoked: The access token was revoked - unknown: The access token is invalid + expired: کد دسترسی منقضی شده است + revoked: کد دسترسی فسخ شده است + unknown: کد دسترسی معتبر نیست resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged. - server_error: The authorization server encountered an unexpected condition which prevented it from fulfilling the request. - temporarily_unavailable: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. + server_error: خطای پیش‌بینی‌نشده‌ای برای سرور اجازه‌دهنده رخ داد که جلوی اجرای این درخواست را گرفت. + temporarily_unavailable: سرور اجازه‌دهنده به دلیل بار زیاد یا تعمیرات سرور هم‌اینک نمی‌تواند درخواست شما را بررسی کند. unauthorized_client: The client is not authorized to perform this request using this method. unsupported_grant_type: The authorization grant type is not supported by the authorization server. unsupported_response_type: The authorization server does not support this response type. flash: applications: create: - notice: Application created. + notice: برنامه ساخته شد. destroy: - notice: Application deleted. + notice: برنامه حذف شد. update: - notice: Application updated. + notice: برنامه به‌روز شد. authorized_applications: destroy: - notice: Application revoked. + notice: برنامه فسخ شد. layouts: admin: nav: - applications: Applications - oauth2_provider: OAuth2 Provider + applications: برنامه‌ها + oauth2_provider: فراهم‌کنندهٔ ورود دومرحله‌ای application: - title: OAuth authorization required + title: درخواست اجازهٔ OAuth scopes: - follow: follow, block, unblock and unfollow accounts - read: read your account's data - write: post on your behalf + follow: پیگیری، مسدودسازی، لغو مسدودسازی، و لغو پیگیری حساب‌ها + read: خواندن اطلاعات حساب شما + write: انتشار مطالب از طرف شما diff --git a/config/locales/el.yml b/config/locales/el.yml index da2b7a64a8..823a6f5769 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -5,7 +5,7 @@ el: about_mastodon_html: Το Mastodon είναι ένα κοινωνικό δίκτυο που βασίζεται σε ανοιχτά δικτυακά πρωτόκολλα και ελεύθερο λογισμικό ανοιχτού κώδικα. Είναι αποκεντρωμένο όπως το e-mail. about_this: Σχετικά administered_by: 'Διαχειρίζεται από:' - closed_registrations: Αυτή τη στιγμή οι εγγραφές σε αυτό τον διακομιστή είναι κλειστές. Αλλά! Μπορείς να βρεις έναν άλλο διακομιστή για να ανοίξεις λογαριασμό και να έχεις πρόσβαση από εκεί στο ίδιο ακριβώς δίκτυο. + closed_registrations: Αυτή τη στιγμή οι εγγραφές σε αυτό τον κόμβο είναι κλειστές. Αλλά! Μπορείς να βρεις έναν άλλο κόμβο για να ανοίξεις λογαριασμό και να έχεις πρόσβαση από εκεί στο ίδιο ακριβώς δίκτυο. contact: Επικοινωνία contact_missing: Δεν έχει οριστεί contact_unavailable: Μ/Δ @@ -27,7 +27,7 @@ el: generic_description: "%{domain} είναι ένας εξυπηρετητής στο δίκτυο" hosted_on: Το Mastodon φιλοξενείται στο %{domain} learn_more: Μάθε περισσότερα - other_instances: Λίστα διακομιστών + other_instances: Λίστα κόμβων source_code: Πηγαίος κώδικας status_count_after: καταστάσεις status_count_before: Ποιός συνέγραψε @@ -49,6 +49,7 @@ el: reserved_username: Το όνομα χρήστη είναι κατειλημμένο roles: admin: Διαχειριστής + bot: Μποτ (αυτόματος λογαριασμός) moderator: Μεσολαβητής unfollow: Διακοπή παρακολούθησης admin: @@ -70,6 +71,7 @@ el: title: Αλλαγή email για %{username} confirm: Επιβεβαίωση confirmed: Επιβεβαιώθηκε + confirming: Προς επιβεβαίωση demote: Υποβίβαση disable: Απενεργοποίηση disable_two_factor_authentication: Απενεργοποίηση 2FA @@ -78,6 +80,7 @@ el: domain: Τομέας edit: Αλλαγή email: Email + email_status: Κατάσταση email enable: Ενεργοποίηση enabled: Ενεργοποιημένο feed_url: URL ροής @@ -116,6 +119,10 @@ el: push_subscription_expires: Η εγγραφή PuSH λήγει redownload: Ανανέωση αβατάρ remove_avatar: Απομακρυσμένο αβατάρ + resend_confirmation: + already_confirmed: Ήδη επιβεβαιωμένος χρήστης + send: Επανάληψη αποστολής email επιβεβαίωσης + success: Το email επιβεβαίωσης στάλθηκε επιτυχώς! reset: Επαναφορά reset_password: Επαναφορά συνθηματικού resubscribe: Επανεγγραφή @@ -194,6 +201,7 @@ el: shortcode: Σύντομος κωδικός shortcode_hint: Τουλάχιστον 2 χαρακτήρες, μόνο αλφαριθμητικοί και κάτω παύλες title: Προσαρμοσμένα emoji + unlisted: Μη καταχωρημένα update_failed_msg: Αδυναμία ενημέρωσης του emoji updated_msg: Επιτυχής ενημέρωση του Emoji! upload: Ανέβασμα @@ -205,3 +213,42 @@ el: new: create: Δημιουργία αποκλεισμού hint: Ο αποκλεισμός τομέα δεν θα αποτρέψει νέες καταχωρίσεις λογαριασμών στην βάση δεδομένων, αλλά θα εφαρμόσει αναδρομικά και αυτόματα συγκεκριμένες πολιτικές μεσολάβησης σε αυτούς τους λογαριασμούς. + severity: + noop: Κανένα + silence: Σίγαση + settings: + hero: + desc_html: Εμφανίζεται στην μπροστινή σελίδα. Συνίσταται τουλάχιστον 600x100px. Όταν λείπει, χρησιμοποιείται η μικρογραφία του κόμβου + peers_api_enabled: + desc_html: Ονόματα τομέων που αυτός ο κόμβος έχει πετύχει στο fediverse + show_known_fediverse_at_about_page: + title: Εμφάνιση του γνωστού fediverse στην προεπισκόπηση ροής + site_description: + title: Περιγραφή κόμβου + site_description_extended: + desc_html: Ένα καλό μέρος για τον κώδικα δεοντολογίας, τους κανόνες, τις οδηγίες και ό,τι άλλο διαφοροποιεί τον κόμβο σου. Δέχεται και κώδικα HTML + site_title: Όνομα κόμβου + thumbnail: + title: Μικρογραφία κόμβου + timeline_preview: + desc_html: Εμφάνισε τη δημόσια ροή στην αρχική σελίδα + title: Προεπισκόπιση ροής + admin_mailer: + new_report: + subject: Νέα αναφορά για %{instance} (#%{id}) + auth: + agreement_html: Με την εγγραφή σου, συμφωνείς να ακολουθείς τους κανόνες αυτού του κόμβου και τους όρους χρήσης του. + deletes: + warning_html: Μόνο η διαγραφή περιεχομένου από αυτό τον συγκεκριμένο κόμβο είναι εγγυημένη. Το περιεχόμενο που έχει διαμοιραστεί ευρέως είναι πιθανό να αφήσει ίχνη. Όσοι διακομιστές είναι εκτός σύνδεσης και όσοι έχουν διακόψει τη λήψη των ενημερώσεων του κόμβου σου, δε θα ενημερώσουν τις βάσεις δεδομένων τους. + imports: + preface: Μπορείς να εισάγεις τα δεδομένα που έχεις εξάγει από άλλο κόμβο, όπως τη λίστα των ανθρώπων που ακολουθείς ή μπλοκάρεις. + invites: + prompt: Φτιάξε και μοίρασε συνδέσμους με τρίτους για να δώσεις πρόσβαση σε αυτόν τον κόμβο + terms: + title: Όροι Χρήσης και Πολιτική Απορρήτου του κόμβου %{instance} + user_mailer: + welcome: + final_step: 'Ξεκίνα τις δημοσιεύσεις! Ακόμα και χωρίς ακόλουθους τα δημόσια μηνύματά σου μπορεί να τα δουν άλλοι, για παράδειγμα στην τοπική ροή και στις ετικέτες. Ίσως να θέλεις να κάνεις μια εισαγωγή του εαυτού σου με την ετικέτα #introductions.' + full_handle_hint: Αυτό θα εδώ θα πεις στους φίλους σου για να σου μιλήσουν ή να σε ακολουθήσουν από άλλο κόμβο. + tip_federated_timeline: Η συνδυασμένη ροή είναι μια όψη πραγματικού χρόνου στο δίκτυο του Mastodon. Παρόλα αυτά, περιλαμβάνει μόνο όσους ακολουθούν οι γείτονές σου, άρα δεν είναι πλήρης. + tip_local_timeline: Η τοπική ροή είναι η όψη πραγματικού χρόνου των ανθρώπων στον κόμβο %{instance}. Αυτοί είναι οι άμεσοι γείτονές σου! diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 47d591993b..0903e35176 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -4,6 +4,7 @@ eo: about_hashtag_html: Ĉi tiuj estas la publikaj mesaĝoj markitaj per #%{hashtag}. Vi povas interagi kun ili se vi havas konton ie ajn en la fediverse. about_mastodon_html: Mastodon estas socia reto bazita sur malfermitaj retaj protokoloj kaj sur libera malfermitkoda programo. Ĝi estas sencentra kiel retmesaĝoj. about_this: Pri + administered_by: 'Administrata de:' closed_registrations: Registriĝoj estas nuntempe fermitaj en ĉi tiu nodo. Tamen, vi povas trovi alian nodon por fari konton kaj aliri al la sama reto de tie. contact: Kontakti contact_missing: Ne elektita @@ -48,17 +49,26 @@ eo: reserved_username: La uzantnomo estas rezervita roles: admin: Administranto + bot: Roboto moderator: Kontrolanto unfollow: Ne plu sekvi admin: account_moderation_notes: - create: Krei + create: Lasi noton created_msg: Kontrola noto sukcese kreita! delete: Forigi destroyed_msg: Kontrola noto sukcese detruita! accounts: are_you_sure: Ĉu vi certas? + avatar: Profilbildo by_domain: Domajno + change_email: + changed_msg: Konta retadreso sukcese ŝanĝita! + current_email: Nuna retadreso + label: Ŝanĝi retadreson + new_email: Nova retadreso + submit: Ŝanĝi retadreson + title: Ŝanĝi retadreson por %{username} confirm: Konfirmi confirmed: Konfirmita confirming: Konfirmante @@ -108,10 +118,11 @@ eo: public: Publika push_subscription_expires: Eksvalidiĝo de la abono al PuSH redownload: Aktualigi profilbildon + remove_avatar: Forigi profilbildon resend_confirmation: already_confirmed: Ĉi tiu uzanto jam estas konfirmita send: Esend konfirmi retpoŝton - success: Konfirma retpoŝto sukcese sendis + success: Konfirma retmesaĝo sukcese sendita! reset: Restarigi reset_password: Restarigi pasvorton resubscribe: Reaboni @@ -132,6 +143,7 @@ eo: statuses: Mesaĝoj subscribe: Aboni title: Kontoj + unconfirmed_email: Nekonfirmita retadreso undo_silenced: Malfari kaŝon undo_suspension: Malfari haltigon unsubscribe: Malaboni @@ -139,6 +151,8 @@ eo: web: Reto action_logs: actions: + assigned_to_self_report: "%{name} asignis signalon %{target} al si mem" + change_email_user: "%{name} ŝanĝis retadreson de uzanto %{target}" confirm_user: "%{name} konfirmis retadreson de uzanto %{target}" create_custom_emoji: "%{name} alŝutis novan emoĝion %{target}" create_domain_block: "%{name} blokis domajnon %{target}" @@ -154,10 +168,13 @@ eo: enable_user: "%{name} ebligis ensaluton por uzanto %{target}" memorialize_account: "%{name} ŝanĝis la konton de %{target} al memora paĝo" promote_user: "%{name} plirangigis uzanton %{target}" + remove_avatar_user: "%{name} forigis profilbildon de %{target}" + reopen_report: "%{name} remalfermis signalon %{target}" reset_password_user: "%{name} restarigis pasvorton de uzanto %{target}" - resolve_report: "%{name} flankmetis signalon %{target}" + resolve_report: "%{name} solvis signalon %{target}" silence_account: "%{name} kaŝis la konton de %{target}" suspend_account: "%{name} haltigis la konton de %{target}" + unassigned_report: "%{name} malasignis signalon %{target}" unsilence_account: "%{name} malkaŝis la konton de %{target}" unsuspend_account: "%{name} malhaltigis la konton de %{target}" update_custom_emoji: "%{name} ĝisdatigis emoĝion %{target}" @@ -243,24 +260,44 @@ eo: expired: Eksvalida title: Filtri title: Invitoj + report_notes: + created_msg: Signala noto sukcese kreita! + destroyed_msg: Signala noto sukcese forigita! reports: + account: + note: noto + report: signalo action_taken_by: Ago farita de are_you_sure: Ĉu vi certas? + assign_to_self: Asigni al mi + assigned: Asignita kontrolanto comment: none: Nenio + created_at: Signalita id: ID - mark_as_resolved: Marki kiel solvita + mark_as_resolved: Marki solvita + mark_as_unresolved: Marki nesolvita + notes: + create: Aldoni noton + create_and_resolve: Solvi per noto + create_and_unresolve: Remalfermi per noto + delete: Forigi + placeholder: Priskribu faritajn agojn, aŭ ajnan novan informon pri tiu signalo… + reopen: Remalfermi signalon report: 'Signalo #%{id}' report_contents: Enhavo reported_account: Signalita konto reported_by: Signalita de resolved: Solvita + resolved_msg: Signalo sukcese solvita! silence_account: Kaŝi konton status: Mesaĝoj suspend_account: Haltigi konton target: Celo title: Signaloj + unassign: Malasigni unresolved: Nesolvita + updated_at: Ĝisdatigita view: Vidi settings: activity_api_enabled: @@ -318,8 +355,8 @@ eo: back_to_account: Reveni al konta paĝo batch: delete: Forigi - nsfw_off: Malŝalti NSFW - nsfw_on: Ŝalti NSFW + nsfw_off: Marki ne tikla + nsfw_on: Marki tikla failed_to_execute: Ekigo malsukcesa media: title: Aŭdovidaĵoj @@ -337,6 +374,7 @@ eo: admin_mailer: new_report: body: "%{reporter} signalis %{target}" + body_remote: Iu de %{domain} signalis %{target} subject: Nova signalo por %{instance} (#%{id}) application_mailer: notification_preferences: Ŝanĝi retmesaĝajn preferojn @@ -378,6 +416,7 @@ eo: security: Sekureco set_new_password: Elekti novan pasvorton authorize_follow: + already_following: Vi jam sekvas tiun konton error: Bedaŭrinde, estis eraro en la serĉado de la fora konto follow: Sekvi follow_request: 'Vi sendis peton de sekvado al:' @@ -427,7 +466,7 @@ eo: archive_takeout: date: Dato download: Elŝuti vian arkivon - hint_html: Vi povas peti arkivon de viaj mesaĝoj kaj alŝutitaj aŭdovidaĵoj. La eksportitaj datumoj estos en la formato ActivityPub, legebla de ajna konformema programo. + hint_html: Vi povas peti arkivon de viaj mesaĝoj kaj alŝutitaj aŭdovidaĵoj. La eksportitaj datumoj estos en la formato ActivityPub, legebla de ajna konformema programo. Vi povas peti arkivon ĉiuseptage. in_progress: Kunmetado de via arkivo… request: Peti vian arkivon size: Grandeco @@ -472,6 +511,7 @@ eo: '21600': 6 horoj '3600': 1 horo '43200': 12 horoj + '604800': 1 semajno '86400': 1 tago expires_in_prompt: Neniam generate: Krei @@ -575,6 +615,10 @@ eo: missing_resource: La URL de plusendado ne estis trovita proceed: Daŭrigi por eksekvi prompt: 'Vi eksekvos:' + remote_unfollow: + error: Eraro + title: Titolo + unfollowed: Ne plu sekvita sessions: activity: Lasta ago browser: Retumilo @@ -641,6 +685,9 @@ eo: one: "%{count} video" other: "%{count} videoj" content_warning: 'Enhava averto: %{warning}' + disallowed_hashtags: + one: 'enhavas malpermesitan kradvorton: %{tags}' + other: 'enhavis malpermesitan kradvorton: %{tags}' open_in_web: Malfermi retumile over_character_limit: limo de %{max} signoj transpasita pin_errors: @@ -665,6 +712,7 @@ eo: terms: title: Uzkondiĉoj kaj privateca politiko de %{instance} themes: + contrast: Forta kontrasto default: Mastodon time: formats: @@ -711,5 +759,6 @@ eo: users: invalid_email: La retadreso estas nevalida invalid_otp_token: Nevalida kodo de dufaktora aŭtentigo + otp_lost_help_html: Se vi perdas aliron al ambaŭ, vi povas kontakti %{email} seamless_external_login: Vi estas ensalutinta per ekstera servo, do pasvortaj kaj retadresaj agordoj ne estas disponeblaj. signed_in_as: 'Ensalutinta kiel:' diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 5255e0e38f..1a8372d634 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -4,6 +4,7 @@ fa: about_hashtag_html: این‌ها نوشته‌های عمومی هستند که برچسب (هشتگ) #%{hashtag} را دارند. اگر شما روی هر سروری حساب داشته باشید می‌توانید به این نوشته‌ها واکنش نشان دهید. about_mastodon_html: ماستدون (Mastodon) یک شبکهٔ اجتماعی است که بر اساس پروتکل‌های آزاد وب و نرم‌افزارهای آزاد و کدباز ساخته شده است. این شبکه مانند ایمیل غیرمتمرکز است. about_this: درباره + administered_by: 'با مدیریت:' closed_registrations: ثبت‌نام روی این سرور هم‌اینک فعال نیست. اما شما می‌توانید سرور دیگری بیابید و با حسابی که آن‌جا می‌سازید دقیقاً به همین شبکه دسترسی داشته باشید. contact: تماس contact_missing: تعیین نشده @@ -52,13 +53,21 @@ fa: unfollow: پایان پیگیری admin: account_moderation_notes: - create: نوشتن + create: افزودن یادداشت created_msg: یادداشت مدیر با موفقیت ساخته شد! delete: پاک کردن destroyed_msg: یادداشت مدیر با موفقیت پاک شد! accounts: are_you_sure: آیا مطمئن هستید؟ + avatar: تصویر نمایه by_domain: دامین + change_email: + changed_msg: نشانی ایمیل این حساب با موفقیت تغییر کرد! + current_email: ایمیل کنونی + label: تغییر نشانی ایمیل + new_email: ایمیل تازه + submit: تغییر ایمیل + title: تغییر ایمیل برای %{username} confirm: تأیید confirmed: تأیید شد confirming: تأیید @@ -91,7 +100,7 @@ fa: all: همه silenced: بی‌صدا شده suspended: معلق شده - title: مدیریت + title: وضعیت moderation_notes: یادداشت مدیر most_recent_activity: آخرین فعالیت‌ها most_recent_ip: آخرین IP ها @@ -108,10 +117,11 @@ fa: public: عمومی push_subscription_expires: عضویت از راه PuSH منقضی شد redownload: به‌روزرسانی تصویر نمایه + remove_avatar: حذف تصویر نمایه resend_confirmation: already_confirmed: این کاربر قبلا تایید شده است send: ایمیل تایید را دوباره بفرستید - success: ایمیل تایید با موفقیت ارسال شد + success: ایمیل تایید با موفقیت ارسال شد! reset: بازنشانی reset_password: بازنشانی رمز resubscribe: اشتراک دوباره @@ -132,6 +142,7 @@ fa: statuses: نوشته‌ها subscribe: اشتراک title: حساب‌ها + unconfirmed_email: ایمیل تأییدنشده undo_silenced: واگردانی بی‌صداکردن undo_suspension: واگردانی تعلیق unsubscribe: لغو اشتراک @@ -139,6 +150,8 @@ fa: web: وب action_logs: actions: + assigned_to_self_report: "%{name} رسیدگی به گزارش %{target} را به عهده گرفت" + change_email_user: "%{name} نشانی ایمیل کاربر %{target} را تغییر داد" confirm_user: "%{name} نشانی ایمیل کاربر %{target} را تأیید کرد" create_custom_emoji: "%{name} شکلک تازهٔ %{target} را بارگذاشت" create_domain_block: "%{name} دامین %{target} را مسدود کرد" @@ -154,10 +167,13 @@ fa: enable_user: "%{name} ورود را برای کاربر %{target} فعال کرد" memorialize_account: "%{name} حساب کاربر %{target} را تبدیل به صفحهٔ یادمان کرد" promote_user: "%{name} کاربر %{target} را ترفیع داد" + remove_avatar_user: "%{name} تصویر نمایهٔ کاربر %{target} را حذف کرد" + reopen_report: "%{name} گزارش %{target} را دوباره به جریان انداخت" reset_password_user: "%{name} رمز کاربر %{target} را بازنشاند" - resolve_report: "%{name} گزارش %{target} را نادیده گرفت" + resolve_report: "%{name} گزارش %{target} را رفع کرد" silence_account: "%{name} حساب کاربر %{target} را خاموش (بی‌صدا) کرد" suspend_account: "%{name} حساب کاربر %{target} را تعلیق کرد" + unassigned_report: "%{name} بررسی گزارش %{target} را متوقف کرد" unsilence_account: "%{name} حساب کاربر %{target} را روشن (باصدا) کرد" unsuspend_account: "%{name} حساب کاربر %{target} را از تعلیق خارج کرد" update_custom_emoji: "%{name} شکلک %{target} را به‌روز کرد" @@ -243,32 +259,61 @@ fa: expired: منقضی‌شده title: فیلتر title: دعوت‌ها + report_notes: + created_msg: یادداشت گزارش با موفقیت ساخته شد! + destroyed_msg: یادداشت گزارش با موفقیت حذف شد! reports: + account: + note: یادداشت + report: گزارش action_taken_by: انجام‌دهنده are_you_sure: آیا مطمئن هستید؟ + assign_to_self: به عهدهٔ من بگذار + assigned: مدیر عهده‌دار comment: none: خالی + created_at: گزارش‌شده id: شناسه mark_as_resolved: علامت‌گذاری به عنوان حل‌شده + mark_as_unresolved: علامت‌گذاری به عنوان حل‌نشده + notes: + create: افزودن یادداشت + create_and_resolve: حل کردن با یادداشت + create_and_unresolve: دوباره گشودن با یادداشت + delete: حذف + placeholder: کارهایی را که در این باره انجام شده، یا هر به‌روزرسانی دیگری را بنویسید… + reopen: دوباره به جریان بیندازید report: 'گزارش #%{id}' report_contents: محتوا reported_account: حساب گزارش‌شده reported_by: گزارش از طرف resolved: حل‌شده + resolved_msg: گزارش با موفقیت حل شد! silence_account: بی‌صدا کردن حساب status: نوشته suspend_account: معلق‌کردن حساب target: هدف title: گزارش‌ها + unassign: پس‌گرفتن مسئولیت unresolved: حل‌نشده + updated_at: به‌روز شد view: نمایش settings: + activity_api_enabled: + desc_html: تعداد بوق‌های محلی، کاربران فعال، و کاربران تازه در هر هفته + title: انتشار آمار تجمیعی دربارهٔ فعالیت کاربران bootstrap_timeline_accounts: desc_html: نام‌های کاربری را با ویرگول از هم جدا کنید. تنها حساب‌های محلی و قفل‌نشده کار می‌کنند. اگر این‌جا را خالی بگذارید، به طور پیش‌فرض همهٔ مدیرهای این سرور پی‌گرفته خواهند شد. title: پیگیری‌های پیش‌فرض برای کاربران تازه contact_information: email: ایمیل کاری username: نام کاربری + hero: + desc_html: در صفحهٔ آغازین نمایش می‌یابد. دست‌کم ۶۰۰×۱۰۰ پیکسل توصیه می‌شود. اگر تعیین نشود، با تصویر بندانگشتی سرور جایگزین خواهد شد + title: تصویر سربرگ + peers_api_enabled: + desc_html: دامین‌هایی که این سرور به آن‌ها برخورده است + title: انتشار فهرست سرورهای یافته‌شده registrations: closed_message: desc_html: وقتی امکان ثبت نام روی سرور فعال نباشد در صفحهٔ اصلی نمایش می‌یابد
    می‌توانید HTML بنویسید @@ -282,6 +327,9 @@ fa: open: desc_html: همه بتوانند حساب باز کنند title: امکان ثبت نام + show_known_fediverse_at_about_page: + desc_html: اگر انتخاب شود، بوق‌های همهٔ سرورهای دیگر نیز در پیش‌نمایش این سرور نمایش می‌یابد. وگرنه فقط بوق‌های محلی نشان داده می‌شوند. + title: نمایش سرورهای دیگر در پیش‌نمایش این سرور show_staff_badge: desc_html: نمایش علامت همکار روی صفحهٔ کاربر title: نمایش علامت همکار @@ -306,8 +354,8 @@ fa: back_to_account: بازگشت به صفحهٔ حساب batch: delete: پاک‌کردن - nsfw_off: NSFW خاموش - nsfw_on: NSFW روشن + nsfw_off: علامت‌زدن به عنوان غیرحساس + nsfw_on: علامت‌زدن به عنوان حساس failed_to_execute: اجرا نشد media: title: رسانه @@ -321,15 +369,19 @@ fa: last_delivery: آخرین ارسال title: WebSub topic: موضوع - title: مدیریت + title: مدیریت سرور admin_mailer: new_report: body: کاربر %{reporter} کاربر %{target} را گزارش داد + body_remote: کسی از %{domain} گزارش %{target} را فرستاده subject: گزارش تازه‌ای برای %{instance} (#%{id}) application_mailer: + notification_preferences: تغییر ترجیحات ایمیل salutation: "%{name}،" settings: 'تغییر تنظیمات ایمیل: %{link}' view: 'نمایش:' + view_profile: دیدن نمایه + view_status: دیدن نوشته‌ها applications: created: برنامه با موفقیت ساخته شد destroyed: برنامه با موفقیت پاک شد @@ -340,6 +392,8 @@ fa: your_token: کد دسترسی شما auth: agreement_html: پیش از عضو شدن باید قوانین این سرور و شرایط استفادهٔ ما را بپذیرید. + change_password: رمز + confirm_email: تأیید ایمیل delete_account: پاک‌کردن حساب delete_account_html: اگر می‌خواهید حساب خود را پاک کنید، از این‌جا پیش بروید. از شما درخواست تأیید خواهد شد. didnt_get_confirmation: راهنمایی برای تأیید را دریافت نکردید؟ @@ -349,12 +403,19 @@ fa: logout: خروج migrate_account: نقل مکان به یک حساب دیگر migrate_account_html: اگر می‌خواهید این حساب را به حساب دیگری منتقل کنید، این‌جا را کلیک کنید. + or: یا + or_log_in_with: یا ورود به وسیلهٔ + providers: + cas: CAS + saml: SAML register: عضو شوید + register_elsewhere: ثبت نام روی یک سرور دیگر resend_confirmation: راهنمایی برای تأیید را دوباره بفرست reset_password: بازنشانی رمز security: امنیت set_new_password: تعیین رمز تازه authorize_follow: + already_following: شما همین الان هم این حساب را پی‌می‌گیرید error: متأسفانه حین یافتن آن حساب خطایی رخ داد follow: پی بگیرید follow_request: 'شما درخواست پیگیری فرستاده‌اید به:' @@ -399,6 +460,13 @@ fa: title: این صفحه درست نیست noscript_html: برای استفاده از نسخهٔ تحت وب ماستدون، لطفاً جاوااسکریپت را فعال کنید. یا به جایش می‌توانید یک اپ ماستدون را به‌کار ببرید. exports: + archive_takeout: + date: تاریخ + download: بایگانی خود را باربگیرید + hint_html: شما می‌توانید بایگانی بوق‌ها و پرونده‌های بارگذاری‌شدهٔ خود را درخواست کنید. داده‌های برون‌بری‌شده در قالب ActivityPub خواهند بود و همهٔ نرم‌افزارهای سازگار خواهند توانست آن را بخوانند. شما هر ۷ روز می‌توانید یک بار برای چنین بایگانی‌ای درخواست دهید. + in_progress: در حال ساختن بایگانی شما... + request: درخواست بایگانی داده‌هایتان + size: اندازه blocks: حساب‌های مسدودشده csv: CSV follows: حساب‌های پی‌گرفته @@ -440,6 +508,7 @@ fa: '21600': ۶ ساعت '3600': ۱ ساعت '43200': ۱۲ ساعت + '604800': ۱ هفته '86400': ۱ روز expires_in_prompt: هیچ وقت generate: ساختن @@ -467,32 +536,41 @@ fa: proceed: ذخیره updated_msg: تنظیمات نقل مکان حساب شما با موفقیت به‌روز شد! moderation: - title: مدیریت + title: مدیریت کاربران notification_mailer: digest: - body: 'خلاصه‌ای از آن‌چه از زمان آخرین بازدید شما در %{since} روی %{instance} رخ داد :' + action: دیدن همهٔ اعلان‌ها + body: خلاصه‌ای از پیغام‌هایی که از زمان آخرین بازدید شما در %{since} فرستاده شد mention: "%{name} این‌جا از شما نام برد:" new_followers_summary: - one: شما یک پیگیر تازه دارید! ای ول! - other: شما %{count} پیگیر تازه دارید! چه عالی! + one: در ضمن، وقتی که نبودید یک پیگیر تازه پیدا کردید! ای ول! + other: در ضمن، وقتی که نبودید %{count} پیگیر تازه پیدا کردید! چه عالی! subject: one: "یک اعلان تازه از زمان آخرین بازدید شما \U0001F418" other: "%{count} اعلان تازه از زمان آخرین بازدید شما \U0001F418" + title: در مدتی که نبودید… favourite: body: "%{name} این نوشتهٔ شما را پسندید:" subject: "%{name} نوشتهٔ شما را پسندید" + title: پسندیده‌شدن تازه follow: body: "%{name} هم‌اینک پیگیر شماست!" subject: "%{name} هم‌اینک پیگیر شماست" + title: پیگیر تازه follow_request: + action: مدیریت درخواست‌های پیگیری body: "%{name} می‌خواهد پیگیر نوشته‌های شما باشد" subject: 'منتظر پیگیری: %{name}' + title: درخواست پیگیری تازه mention: + action: پاسخ body: "%{name} در این‌جا از شما نام برد:" subject: "%{name} از شما نام برد" + title: نام‌برده‌شدن تازه reblog: body: "%{name} نوشتهٔ شما را بازبوقید:" subject: "%{name} نوشتهٔ شما را بازبوقید" + title: بازبوق تازه number: human: decimal_units: @@ -505,7 +583,9 @@ fa: trillion: T unit: '' pagination: + newer: تازه‌تر next: بعدی + older: قدیمی‌تر prev: قبلی truncate: "…" preferences: @@ -532,6 +612,10 @@ fa: missing_resource: نشانی اینترنتی برای رسیدن به حساب شما پیدا نشد proceed: درخواست پیگیری prompt: 'شما قرار است این حساب را پیگیری کنید:' + remote_unfollow: + error: خطا + title: عنوان + unfollowed: پایان پیگیری sessions: activity: آخرین کنش browser: مرورگر @@ -540,12 +624,14 @@ fa: blackberry: Blackberry chrome: Chrome edge: Microsoft Edge + electron: Electron firefox: Firefox generic: مرورگر ناشناخته ie: Internet Explorer micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser opera: Opera + otter: Otter phantom_js: PhantomJS qq: QQ Browser safari: Safari @@ -575,7 +661,7 @@ fa: authorized_apps: برنامه‌های مجاز back: بازگشت به ماستدون delete: پاک‌کردن حساب - development: Development + development: فرابری edit_profile: ویرایش نمایه export: برون‌سپاری داده‌ها followers: پیگیران مورد تأیید @@ -587,6 +673,18 @@ fa: two_factor_authentication: ورود دومرحله‌ای your_apps: برنامهٔ شما statuses: + attached: + description: 'پیوست‌شده: %{attached}' + image: + one: "%{count} تصویر" + other: "%{count} تصویر" + video: + one: "%{count} ویدیو" + other: "%{count} ویدیو" + content_warning: 'هشدا محتوا: %{warning}' + disallowed_hashtags: + one: 'دارای هشتگ غیرمجاز: %{tags}' + other: 'دارای هشتگ‌های غیرمجاز: %{tags}' open_in_web: بازکردن در وب over_character_limit: از حد مجاز %{max} حرف فراتر رفتید pin_errors: @@ -611,6 +709,7 @@ fa: terms: title: شرایط استفاده و سیاست رازداری %{instance} themes: + contrast: کنتراست بالا default: ماستدون time: formats: @@ -628,10 +727,35 @@ fa: manual_instructions: 'اگر نمی‌توانید کدها را اسکن کنید و باید آن‌ها را دستی وارد کنید، متن کد امنیتی این‌جاست:' recovery_codes: پشتیبان‌گیری از کدهای بازیابی recovery_codes_regenerated: کدهای بازیابی با موفقیت ساخته شدند - recovery_instructions_html: اگر تلفن خود را گم کردید، می‌توانید با یکی از کدهای بازیابی زیر کنترل حساب خود را به دست بگیرید. این کدها را در جای امنی نگه دارید. مثلاً آن‌ها را چاپ کنید و کنار سایر مدارک مهم خود قرار دهید + recovery_instructions_html: اگر تلفن خود را گم کردید، می‌توانید با یکی از کدهای بازیابی زیر کنترل حساب خود را به دست بگیرید. این کدها را در جای امنی نگه دارید. مثلاً آن‌ها را چاپ کنید و کنار سایر مدارک مهم خود قرار دهید. setup: راه اندازی wrong_code: کدی که وارد کردید نامعتبر بود! آیا ساعت سرور و ساعت دستگاه شما درست تنظیم شده‌اند؟ + user_mailer: + backup_ready: + explanation: شما یک نسخهٔ پشتیبان کامل از حساب خود را درخواست کردید. این پشتیبان الان آمادهٔ بارگیری است! + subject: بایگانی شما آمادهٔ دریافت است + title: گرفتن بایگانی + welcome: + edit_profile_action: تنظیم نمایه + edit_profile_step: 'شما می‌توانید نمایهٔ خود را به دلخواه خود تغییر دهید: می‌توانید تصویر نمایه، تصویر پس‌زمینه، نام، و چیزهای دیگری را تعیین کنید. اگر بخواهید، می‌توانید حساب خود را خصوصی کنید تا فقط کسانی که شما اجازه می‌دهید بتوانند پیگیر حساب شما شوند.' + explanation: نکته‌هایی که برای آغاز کار به شما کمک می‌کنند + final_action: چیزی منتشر کنید + final_step: 'چیزی بنویسید! حتی اگر الان کسی پیگیر شما نباشد، دیگران نوشته‌های عمومی شما را می‌بینند، مثلاً در فهرست نوشته‌های محلی و در هشتگ‌ها. شاید بخواهید با هشتگ #آشنایی خودتان را معرفی کنید.' + full_handle: نام کاربری کامل شما + full_handle_hint: این چیزی است که باید به دوستان خود بگویید تا بتوانند به شما پیغام بفرستند یا از سرورهای دیگر پیگیر شما شوند. + review_preferences_action: تغییر ترجیحات + review_preferences_step: با رفتن به صفحهٔ ترجیحات می‌توانید چیزهای گوناگونی را تنظیم کنید. مثلاً این که چه ایمیل‌های آگاه‌سازی‌ای به شما فرستاده شود، یا حریم خصوصی پیش‌فرض نوشته‌هایتان چه باشد. اگر بیماری سفر (حالت تهوع بر اثر دیدن اجسام متحرک) ندارید، می‌توانید پخش خودکار ویدیوها را فعال کنید. + subject: به ماستدون خوش آمدید + tip_bridge_html: اگر پیش از این کاربر توییتر بودید، می‌توانید دوستان توییتری خود را که در ماستدون هستند به کمک bridge app پیدا کنید. البته این فقط وقتی کار می‌کند که آن‌ها هم این اپ را به کار برده باشند! + tip_federated_timeline: "«فهرست نوشته‌های همه‌جا» نمایی از کل شبکهٔ بزرگ ماستدون به شما می‌دهد. البته این فهرست فقط افردای را نشان می‌دهد که هم‌سروری‌های شما آن‌ها را پیگیری می‌کنند، و بنابراین ممکن است کامل نباشد." + tip_following: شما به طور پیش‌فرض مدیر(های) سرور خود را پی می‌گیرید. برای یافتن افراد جالب دیگر، فهرست «نوشته‌های محلی» و «نوشته‌های همه‌جا» را ببینید. + tip_local_timeline: فهرست نوشته‌های محلی نمایی کلی از کاربران روی %{instance} را ارائه می‌دهد. این‌ها همسایه‌های شما هستند! + tip_mobile_webapp: اگر مرورگر موبایل شما امکان گذاشتن ماستدون روی صفحهٔ اصلی موبایل را به شما می‌دهد، این یعنی می‌توانید اعلان‌های خودکار ماستدون را دریافت کنید. با این کار ماستدون خیلی شبیه یک اپ معمولی موبایل می‌شود! + tips: نکته‌ها + title: خوش آمدید، کاربر %{name}! users: invalid_email: نشانی ایمیل نامعتبر است invalid_otp_token: کد ورود دومرحله‌ای نامعتبر است + otp_lost_help_html: اگر شما دسترسی به هیچ‌کدامشان ندارید، باید با ایمیل %{email} تماس بگیرید + seamless_external_login: شما با یک سرویس خارج از مجموعه وارد شده‌اید، به همین دلیل تنظیمات ایمیل و رمز برای شما در دسترس نیست. signed_in_as: 'واردشده به نام:' diff --git a/config/locales/fi.yml b/config/locales/fi.yml index fca58cc0f1..68a239ba35 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -4,6 +4,7 @@ fi: about_hashtag_html: Nämä ovat hashtagilla #%{hashtag} merkittyjä julkisia tuuttauksia. Voit vastata niihin, jos sinulla on tili jossain päin fediversumia. about_mastodon_html: Mastodon on sosiaalinen verkosto. Se on toteutettu avoimilla verkkoprotokollilla ja vapailla, avoimen lähdekoodin ohjelmistoilla, ja se toimii hajautetusti samaan tapaan kuin sähköposti. about_this: Tietoja tästä palvelimesta + administered_by: 'Ylläpitäjä:' closed_registrations: Tähän instanssiin ei voi tällä hetkellä rekisteröityä. Voit kuitenkin luoda tilin johonkin toiseen instanssiin ja käyttää samaa verkostoa sitä kautta. contact: Ota yhteyttä contact_missing: Ei asetettu @@ -58,26 +59,34 @@ fi: destroyed_msg: Moderointimerkinnän poisto onnistui! accounts: are_you_sure: Oletko varma? - by_domain: Verkko-osoite + avatar: Profiilikuva + by_domain: Verkkotunnus + change_email: + changed_msg: Tilin sähköposti vaihdettu onnistuneesti! + current_email: Nykyinen sähköposti + label: Vaihda sähköposti + new_email: Uusi sähköposti + submit: Vaihda sähköposti + title: Vaihda sähköposti käyttäjälle %{username} confirm: Vahvista confirmed: Vahvistettu - confirming: Vahvistavat + confirming: Vahvistetaan demote: Alenna disable: Poista käytöstä disable_two_factor_authentication: Poista 2FA käytöstä disabled: Poistettu käytöstä - display_name: Näyttönimi - domain: Verkko-osoite + display_name: Nimimerkki + domain: Verkkotunnus edit: Muokkaa email: Sähköposti email_status: Sähköpostin tila enable: Ota käyttöön enabled: Käytössä - feed_url: Syötteen URL + feed_url: Syötteen osoite followers: Seuraajat - followers_url: Seuraajien URL + followers_url: Seuraajien osoite follows: Seuraa - inbox_url: Saapuvan postilaatikon URL + inbox_url: Saapuvan postilaatikon osoite ip: IP location: all: Kaikki @@ -100,18 +109,19 @@ fi: alphabetic: Aakkosjärjestys most_recent: Uusin title: Järjestys - outbox_url: Lähtevän postilaatikon URL + outbox_url: Lähtevän postilaatikon osoite perform_full_suspension: Siirrä kokonaan jäähylle - profile_url: Profiilin URL + profile_url: Profiilin osoite promote: Ylennä protocol: Protokolla public: Julkinen push_subscription_expires: PuSH-tilaus vanhenee redownload: Päivitä profiilikuva + remove_avatar: Poista profiilikuva resend_confirmation: already_confirmed: Tämä käyttäjä on jo vahvistettu send: Lähetä varmistusviesti uudelleen - success: Vahvistusviesti lähetettiin onnistuneesti + success: Vahvistusviesti onnistuneesti lähetetty! reset: Palauta reset_password: Palauta salasana resubscribe: Tilaa uudelleen @@ -122,16 +132,17 @@ fi: staff: Henkilöstö user: Käyttäjä salmon_url: Salmon-URL - search: Haku - shared_inbox_url: Jaetun saapuvan postilaatikon URL + search: Hae + shared_inbox_url: Jaetun saapuvan postilaatikon osoite show: - created_reports: Tilin luomat raportit + created_reports: Tämän tilin luomat raportit report: raportti targeted_reports: Tästä tilistä tehdyt raportit silence: Hiljennä statuses: Tilat subscribe: Tilaa title: Tilit + unconfirmed_email: Sähköpostia ei vahvistettu undo_silenced: Peru hiljennys undo_suspension: Peru jäähy unsubscribe: Lopeta tilaus @@ -139,6 +150,8 @@ fi: web: Web action_logs: actions: + assigned_to_self_report: "%{name} otti raportin %{target} tehtäväkseen" + change_email_user: "%{name} vaihtoi käyttäjän %{target} sähköpostiosoitteen" confirm_user: "%{name} vahvisti käyttäjän %{target} sähköpostiosoitteen" create_custom_emoji: "%{name} lähetti uuden emojin %{target}" create_domain_block: "%{name} esti verkkotunnuksen %{target}" @@ -154,6 +167,8 @@ fi: enable_user: "%{name} salli sisäänkirjautumisen käyttäjälle %{target}" memorialize_account: "%{name} muutti käyttäjän %{target} tilin muistosivuksi" promote_user: "%{name} ylensi käyttäjän %{target}" + remove_avatar_user: "%{name} poisti käyttäjän %{target} profiilikuvan" + reopen_report: "%{name} avasi uudelleen raportin %{target}" reset_password_user: "%{name} palautti käyttäjän %{target} salasanan" resolve_report: "%{name} hylkäsi raportin %{target}" silence_account: "%{name} hiljensi käyttäjän %{target}" @@ -172,7 +187,7 @@ fi: delete: Poista destroyed_msg: Emojon poisto onnistui! disable: Poista käytöstä - disabled_msg: Emojin käytöstäpoisto onnistui + disabled_msg: Emojin poisto käytöstä onnistui emoji: Emoji enable: Ota käyttöön enabled_msg: Emojin käyttöönotto onnistui @@ -243,24 +258,42 @@ fi: expired: Vanhentunut title: Suodata title: Kutsut + report_notes: + created_msg: Muistiinpano onnistuneesti lisätty raporttiin! + destroyed_msg: Muistiinpano onnistuneesti poistettu raportista! reports: + account: + note: muistiinpano + report: raportti action_taken_by: Toimenpiteen tekijä are_you_sure: Oletko varma? + assign_to_self: Ota tehtäväksi comment: none: Ei mitään + created_at: Raportoitu id: Tunniste mark_as_resolved: Merkitse ratkaistuksi + mark_as_unresolved: Merkitse ratkaisemattomaksi + notes: + create: Lisää muistiinpano + create_and_resolve: Ratkaise ja lisää muistiinpano + create_and_unresolve: Avaa uudelleen ja lisää muistiinpano + delete: Poista + placeholder: Kuvaile mitä toimia on tehty tai muita päivityksiä tähän raporttiin… + reopen: Avaa raportti uudestaan report: Raportti nro %{id} report_contents: Sisältö reported_account: Raportoitu tili reported_by: Raportoija resolved: Ratkaistut + resolved_msg: Raportti onnistuneesti ratkaistu! silence_account: Hiljennä tili status: Tila suspend_account: Siirrä tili jäähylle target: Kohde title: Raportit unresolved: Ratkaisemattomat + updated_at: Päivitetty view: Näytä settings: activity_api_enabled: @@ -337,6 +370,7 @@ fi: admin_mailer: new_report: body: "%{reporter} on raportoinut kohteen %{target}" + body_remote: Joku osoitteesta %{domain} on raportoinut kohteen %{target} subject: Uusi raportti instanssista %{instance} (nro %{id}) application_mailer: notification_preferences: Muuta sähköpostiasetuksia @@ -378,6 +412,7 @@ fi: security: Tunnukset set_new_password: Aseta uusi salasana authorize_follow: + already_following: Sinä seuraat jo tätä tiliä error: Valitettavasti etätilin haussa tapahtui virhe follow: Seuraa follow_request: 'Olet lähettänyt seuraamispyynnön käyttäjälle:' @@ -470,6 +505,7 @@ fi: '21600': 6 tuntia '3600': 1 tunti '43200': 12 tuntia + '604800': 1 viikko '86400': 1 vuorokausi expires_in_prompt: Ei koskaan generate: Luo @@ -573,6 +609,8 @@ fi: missing_resource: Vaadittavaa uudelleenohjaus-URL:ää tiliisi ei löytynyt proceed: Siirry seuraamaan prompt: 'Olet aikeissa seurata:' + remote_unfollow: + error: Virhe sessions: activity: Viimeisin toiminta browser: Selain @@ -639,6 +677,9 @@ fi: one: "%{count} video" other: "%{count} videota" content_warning: 'Sisältövaroitus: %{warning}' + disallowed_hashtags: + one: 'sisälsi aihetunnisteen jota ei sallita: %{tags}' + other: 'sisälsi aihetunnisteet joita ei sallita: %{tags}' open_in_web: Avaa selaimessa over_character_limit: merkkimäärän rajoitus %{max} ylitetty pin_errors: @@ -709,5 +750,6 @@ fi: users: invalid_email: Virheellinen sähköpostiosoite invalid_otp_token: Virheellinen kaksivaiheisen todentamisen koodi + otp_lost_help_html: Jos sinulla ei ole pääsyä kumpaankaan, voit ottaa yhteyttä osoitteeseen %{email} seamless_external_login: Olet kirjautunut ulkoisen palvelun kautta, joten salasana- ja sähköpostiasetukset eivät ole käytettävissä. signed_in_as: 'Kirjautunut henkilönä:' diff --git a/config/locales/fr.yml b/config/locales/fr.yml index e7142f3fdb..f8f9026c8a 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -49,11 +49,12 @@ fr: reserved_username: Ce nom d’utilisateur⋅ice est réservé roles: admin: Admin + bot: Robot moderator: Modérateur·trice unfollow: Ne plus suivre admin: account_moderation_notes: - create: Créer + create: Créer une note created_msg: Note de modération créée avec succès ! delete: Supprimer destroyed_msg: Note de modération supprimée avec succès ! @@ -373,6 +374,7 @@ fr: admin_mailer: new_report: body: "%{reporter} a signalé %{target}" + body_remote: Quelqu'un de %{domain} a signalé %{target} subject: Nouveau signalement sur %{instance} (#%{id}) application_mailer: notification_preferences: Modifier les préférences de courriel @@ -462,7 +464,7 @@ fr: archive_takeout: date: Date download: Télécharger votre archive - hint_html: Vous pouvez demander une archive de vos pouets et médias téléversés. Les données exportées seront au format ActivityPub, lisible par tout logiciel compatible. + hint_html: Vous pouvez demander une archive de vos pouets et médias téléversés. Les données exportées seront au format ActivityPub, lisible par tout logiciel compatible. Vous pouvez demander une archive tous les 7 jours. in_progress: Élaboration de votre archive.... request: Demandez vos archives size: Taille @@ -630,7 +632,7 @@ fr: micro_messenger: MicroMessenger nokia: Nokia S40 Ovi Browser opera: Opera - otter: Autre + otter: Otter phantom_js: PhantomJS qq: QQ Browser safari: Safari @@ -755,5 +757,6 @@ fr: users: invalid_email: L’adresse courriel est invalide invalid_otp_token: Le code d’authentification à deux facteurs est invalide + otp_lost_help_html: Si vous perdez accès aux deux, vous pouvez contacter %{email} seamless_external_login: Vous êtes connecté via un service externe, donc les paramètres concernant le mot de passe et le courriel ne sont pas disponibles. signed_in_as: 'Connecté·e en tant que :' diff --git a/config/locales/gl.yml b/config/locales/gl.yml index e676fe8374..99396df923 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -49,11 +49,12 @@ gl: reserved_username: O nome de usuaria está reservado roles: admin: Admin + bot: Bot moderator: Mod unfollow: Deixar de seguir admin: account_moderation_notes: - create: Crear + create: Deixar nota created_msg: Nota a moderación creada con éxito! delete: Eliminar destroyed_msg: Nota a moderación destruída con éxito! @@ -463,7 +464,7 @@ gl: archive_takeout: date: Data download: Descargue o seu ficheiro - hint_html: Pode solicitar un ficheiro cos seus toots ficheiros de medios. Os datos estarán en formato ActivityPub e son compatibles con calquer software que o cumpla. + hint_html: Pode solicitar un ficheiro cos seus toots ficheiros de medios. Os datos estarán en formato ActivityPub e son compatibles con calquer software que o cumpla. Pode solicitar un ficheiro cada 7 días. in_progress: Xerando o seu ficheiro... request: Solicite o ficheiro size: Tamaño @@ -833,5 +834,6 @@ gl: users: invalid_email: O enderezo de correo non é válido invalid_otp_token: Código de doble-factor non válido + otp_lost_help_html: Si perde o acceso a ambos, pode contactar con %{email} seamless_external_login: Está conectado a través de un servizo externo, polo que os axustes de contrasinal e correo-e non están dispoñibles. signed_in_as: 'Rexistrada como:' diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 83283a3771..1d538a1a16 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -119,7 +119,7 @@ ja: redownload: アバターの更新 remove_avatar: アイコンを削除 resend_confirmation: - already_confirmed: メールアドレスは確認済みです。 + already_confirmed: メールアドレスは確認済みです send: 確認メールを再送 success: 確認メールを再送信しました! reset: リセット @@ -463,7 +463,7 @@ ja: archive_takeout: date: 日時 download: ダウンロード - hint_html: "トゥートとメディアのアーカイブをリクエストできます。 データはActivityPub形式で、対応しているソフトウェアで読み込むことができます。" + hint_html: "トゥートとメディアのアーカイブをリクエストできます。 データはActivityPub形式で、対応しているソフトウェアで読み込むことができます。7日毎にアーカイブをリクエストできます。" in_progress: 準備中... request: アーカイブをリクエスト size: 容量 @@ -833,5 +833,6 @@ ja: users: invalid_email: メールアドレスが無効です invalid_otp_token: 二段階認証コードが間違っています + otp_lost_help_html: どちらも使用できない場合、%{email} に連絡を取ると解決できるかもしれません seamless_external_login: あなたは外部サービスを介してログインしているため、パスワードとメールアドレスの設定は利用できません。 signed_in_as: '下記でログイン中:' diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 92e99ce501..62ed72b7dc 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -19,12 +19,12 @@ ko: humane_approach_body: 다른 SNS의 실패를 교훈삼아, Mastodon은 소셜미디어가 잘못 사용되는 것을 막기 위하여 윤리적인 설계를 추구합니다. humane_approach_title: 보다 배려를 의식한 설계를 추구 not_a_product_body: Mastodon은 이익을 추구하는 SNS가 아닙니다. 그러므로 광고와 데이터의 수집 및 분석이 존재하지 않고, 유저를 구속하지도 않습니다. - not_a_product_title: 여러분은 사람이며, 상품이 아닙니다. + not_a_product_title: 여러분은 사람이며, 상품이 아닙니다 real_conversation_body: 자유롭게 사용할 수 있는 500문자의 메세지와 미디어 경고 내용을 바탕으로, 자기자신을 자유롭게 표현할 수 있습니다. real_conversation_title: 진정한 커뮤니케이션을 위하여 within_reach_body: 개발자 친화적인 API에 의해서 실현된 iOS나 Android, 그 외의 여러 Platform들 덕분에 어디서든 친구들과 자유롭게 메세지를 주고 받을 수 있습니다. within_reach_title: 언제나 유저의 곁에서 - generic_description: "%{domain} 은 Mastodon의 인스턴스 입니다." + generic_description: "%{domain} 은 네트워크에 있는 한 서버입니다" hosted_on: "%{domain}에서 호스팅 되는 마스토돈" learn_more: 자세히 other_instances: 다른 인스턴스 @@ -53,7 +53,7 @@ ko: unfollow: 팔로우 해제 admin: account_moderation_notes: - create: 작성하기 + create: 모더레이션 노트 작성하기 created_msg: 모더레이션 기록이 성공적으로 작성되었습니다! delete: 삭제 destroyed_msg: 모더레이션 기록이 성공적으로 삭제되었습니다! @@ -119,9 +119,9 @@ ko: redownload: 아바타 업데이트 remove_avatar: 아바타 지우기 resend_confirmation: - already_confirmed: 이 사용자는 이미 확인되었습니다. + already_confirmed: 이 사용자는 이미 확인되었습니다 send: 다시 확인 이메일 - success: 확인 이메일이 전송되었습니다. + success: 확인 이메일이 전송되었습니다! reset: 초기화 reset_password: 비밀번호 초기화 resubscribe: 다시 구독 @@ -279,9 +279,9 @@ ko: mark_as_resolved: 해결 완료 처리 mark_as_unresolved: 미해결로 표시 notes: - create: 노트 추가 - create_and_resolve: 노트를 작성하고 해결됨으로 표시 - create_and_unresolve: 노트 작성과 함께 미해결로 표시 + create: 기록 추가 + create_and_resolve: 기록을 작성하고 해결됨으로 표시 + create_and_unresolve: 기록 작성과 함께 미해결로 표시 delete: 삭제 placeholder: 이 리포트에 대한 조치, 다른 업데이트 사항에 대해 설명합니다… reopen: 리포트 다시 열기 @@ -375,6 +375,7 @@ ko: admin_mailer: new_report: body: "%{reporter} 가 %{target} 를 신고했습니다" + body_remote: "%{domain}의 누군가가 %{target}을 신고했습니다" subject: "%{instance} 에 새 신고 등록됨 (#%{id})" application_mailer: notification_preferences: 메일 설정 변경 @@ -464,7 +465,7 @@ ko: archive_takeout: date: 날짜 download: 아카이브 다운로드 - hint_html: 당신의 툿과 업로드 된 미디어의 아카이브를 요청할 수 있습니다. 내보내지는 데이터는 ActivityPub 포맷입니다. 호환 되는 모든 소프트웨어에서 읽을 수 있습니다. + hint_html: 당신의 툿과 업로드 된 미디어의 아카이브를 요청할 수 있습니다. 내보내지는 데이터는 ActivityPub 포맷입니다. 호환 되는 모든 소프트웨어에서 읽을 수 있습니다. 7일마다 새로운 아카이브를 요청할 수 있습니다. in_progress: 당신의 아카이브를 컴파일 중입니다… request: 아카이브 요청하기 size: 크기 @@ -683,6 +684,9 @@ ko: one: "%{count} 영상" other: "%{count} 영상" content_warning: '열람 주의: %{warning}' + disallowed_hashtags: + one: '허용 되지 않은 해시태그를 포함하고 있습니다: %{tags}' + other: '허용되지 않은 해시태그를 포함하고 있습니다: %{tags}' open_in_web: Web으로 열기 over_character_limit: 최대 %{max}자까지 입력할 수 있습니다 pin_errors: @@ -707,6 +711,7 @@ ko: terms: title: "%{instance} 이용약관과 개인정보 취급 방침" themes: + contrast: 고대비 default: 마스토돈 time: formats: @@ -726,10 +731,10 @@ ko: recovery_codes_regenerated: 복구 코드가 다시 생성되었습니다 recovery_instructions_html: 휴대전화를 분실한 경우, 아래 복구 코드 중 하나를 사용해 계정에 접근할 수 있습니다. 복구 코드는 안전하게 보관해 주십시오. 이 코드를 인쇄해 중요한 서류와 함께 보관하는 것도 좋습니다. setup: 초기 설정 - wrong_code: 코드가 올바르지 않습니다. 서버와 휴대전화 간의 시간이 일치하는지 확인해 주십시오. + wrong_code: 코드가 올바르지 않습니다. 서버와 휴대전화 간의 시각이 일치하나요? user_mailer: backup_ready: - explanation: 당신이 요청한 계정의 풀 백업이 이제 다운로드 가능합니다. + explanation: 당신이 요청한 계정의 풀 백업이 이제 다운로드 가능합니다! subject: 당신의 아카이브를 다운로드 가능합니다 title: 아카이브 테이크 아웃 welcome: @@ -753,5 +758,6 @@ ko: users: invalid_email: 메일 주소가 올바르지 않습니다 invalid_otp_token: 2단계 인증 코드가 올바르지 않습니다 + otp_lost_help_html: 만약 양쪽 모두를 잃어버렸다면 %{email}을 통해 복구할 수 있습니다 seamless_external_login: 외부 서비스를 이용해 로그인 했습니다, 패스워드와 이메일 설정을 할 수 없습니다. signed_in_as: '다음과 같이 로그인 중:' diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 44ad1ed6d8..ddec18f6db 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -5,10 +5,10 @@ nl: about_mastodon_html: Mastodon is een sociaal netwerk dat gebruikt maakt van open webprotocollen en vrije software. Het is net zoals e-mail gedecentraliseerd. about_this: Over deze server administered_by: 'Beheerd door:' - closed_registrations: Registreren op deze server is momenteel uitgeschakeld. + closed_registrations: Registreren op deze server is momenteel niet mogelijk. Je kunt echter een andere server vinden om zo toegang te krijgen tot het netwerk. contact: Contact contact_missing: Niet ingesteld - contact_unavailable: N/A + contact_unavailable: n.v.t description_headline: Wat is %{domain}? domain_count_after: andere servers domain_count_before: Verbonden met @@ -16,11 +16,11 @@ nl:

    Een goede plek voor richtlijnen

    De uitgebreide omschrijving is nog niet ingevuld.

    features: - humane_approach_body: Na van de fouten van andere netwerken te hebben geleerd, tracht Mastodon ethische ontwerpkeuzes te maken om misbruik van social media te voorkomen. + humane_approach_body: Mastodon heeft van de fouten van andere sociale netwerken geleerd en probeert aan de hand van ethische ontwerpkeuzes misbruik van sociale media te voorkomen. humane_approach_title: Een meer menselijke aanpak - not_a_product_body: Mastodon is geen commercieel netwerk. Dus geen advertenties, geen datamining en geen besloten systemen. Er is geen centrale organisatie die alles bepaald. + not_a_product_body: Mastodon is geen commercieel netwerk. Dus geen advertenties, geen datamining en geen besloten systemen. Er is geen centrale organisatie die alles bepaalt. not_a_product_title: Jij bent een persoon, geen product - real_conversation_body: Met 500 karakters tot jouw beschikking, en ondersteuning voor tekst- en media-waarschuwingen, kan je jezelf uiten zoals jij dat wil. + real_conversation_body: Met 500 tekens tot jouw beschikking en ondersteuning voor tekst- en media-waarschuwingen, kan je jezelf uiten zoals jij dat wil. real_conversation_title: Voor echte gesprekken gemaakt within_reach_body: Meerdere apps voor iOS, Android en andere platformen, met dank aan het ontwikkelaarsvriendelijke API-systeem, zorgen ervoor dat je overal op de hoogte blijft. within_reach_title: Altijd binnen bereik @@ -41,19 +41,20 @@ nl: media: Media moved_html: "%{name} is verhuisd naar %{new_profile_link}:" nothing_here: Hier is niets! - people_followed_by: Mensen die %{name} volgt + people_followed_by: Mensen die %{name} volgen people_who_follow: Mensen die %{name} volgen posts: Toots - posts_with_replies: Toots met reacties + posts_with_replies: Toots en reacties remote_follow: Extern volgen reserved_username: Deze gebruikersnaam is gereserveerd roles: admin: Beheerder - moderator: Mod + bot: Bot + moderator: Moderator unfollow: Ontvolgen admin: account_moderation_notes: - create: Aanmaken + create: Laat een opmerking achter created_msg: Aanmaken van opmerking voor moderatoren geslaagd! delete: Verwijderen destroyed_msg: Verwijderen van opmerking voor moderatoren geslaagd! @@ -64,10 +65,10 @@ nl: change_email: changed_msg: E-mailadres van account succesvol veranderd! current_email: Huidig e-mailadres - label: E-mailadres veranderen + label: E-mailadres wijzigen new_email: Nieuw e-mailadres submit: E-mailadres veranderen - title: E-mailadres veranderen voor %{username} + title: E-mailadres wijzigen voor %{username} confirm: Bevestigen confirmed: Bevestigd confirming: Bevestiging @@ -93,9 +94,9 @@ nl: local: Lokaal remote: Extern title: Locatie - login_status: Aanmeldstatus + login_status: Login status media_attachments: Mediabijlagen - memorialize: Verander naar in memoriam + memorialize: In gedenkpagina veranderen moderation: all: Alles silenced: Genegeerd @@ -112,7 +113,7 @@ nl: outbox_url: Outbox-URL perform_full_suspension: Volledig opschorten profile_url: Profiel-URL - promote: Promoten + promote: Promoveren protocol: Protocol public: Openbaar push_subscription_expires: PuSH-abonnement verloopt op @@ -125,7 +126,7 @@ nl: reset: Opnieuw reset_password: Wachtwoord opnieuw instellen resubscribe: Opnieuw abonneren - role: Permissies + role: Bevoegdheden roles: admin: Beheerder moderator: Moderator @@ -165,7 +166,7 @@ nl: disable_user: Aanmelden voor %{target} is door %{name} uitgeschakeld enable_custom_emoji: Emoji %{target} is door %{name} ingeschakeld enable_user: Inloggen voor %{target} is door %{name} ingeschakeld - memorialize_account: Account %{target} is door %{name} in een in-memoriampagina veranderd + memorialize_account: Account %{target} is door %{name} in een gedenkpagina veranderd promote_user: Gebruiker %{target} is door %{name} gepromoveerd remove_avatar_user: "%{name} verwijderde de avatar van %{target}" reopen_report: "%{name} heeft gerapporteerde toot %{target} heropend" @@ -224,7 +225,7 @@ nl: noop: Geen silence: Negeren suspend: Opschorten - severity: Strengheid + severity: Zwaarte show: affected_accounts: one: Eén account in de database aangepast @@ -463,7 +464,7 @@ nl: archive_takeout: date: Datum download: Jouw archief downloaden - hint_html: Je kunt een archief opvragen van jouw toots en geüploade media. De geëxporteerde gegevens zijn in ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. + hint_html: Je kunt een archief opvragen van jouw toots en geüploade media. De geëxporteerde gegevens zijn in ActivityPub-formaat, dat door hiervoor geschikte software valt uit te lezen. Je kunt elke 7 dagen een kopie van je archief aanvragen. in_progress: Jouw archief wordt samengesteld... request: Jouw archief opvragen size: Omvang @@ -833,5 +834,6 @@ nl: users: invalid_email: E-mailadres is ongeldig invalid_otp_token: Ongeldige tweestaps-aanmeldcode + otp_lost_help_html: Als je toegang tot beiden kwijt bent geraakt, neem dan contact op via %{email} seamless_external_login: Je bent ingelogd via een externe dienst, daarom zijn wachtwoorden en e-mailinstellingen niet beschikbaar. signed_in_as: 'Ingelogd als:' diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 37abeffd9f..702236198b 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -53,7 +53,7 @@ pt-BR: unfollow: Deixar de seguir admin: account_moderation_notes: - create: Criar + create: Criar uma advertência created_msg: Nota de moderação criada com sucesso! delete: Excluir destroyed_msg: Nota de moderação excluída com sucesso! @@ -373,6 +373,7 @@ pt-BR: admin_mailer: new_report: body: "%{reporter} denunciou %{target}" + body_remote: Alguém da instância %{domain} reportou %{target} subject: Nova denúncia sobre %{instance} (#%{id}) application_mailer: notification_preferences: Mudar preferências de e-mail @@ -462,7 +463,7 @@ pt-BR: archive_takeout: date: Data download: Baixe o seu arquivo - hint_html: Você pode pedir um arquivo dos seus toots e mídia enviada. Os dados exportados estarão no formato ActivityPub, que podem ser lidos por qualquer software compatível. + hint_html: Você pode pedir um arquivo dos seus toots e mídia enviada. Os dados exportados estarão no formato ActivityPub, que podem ser lidos por qualquer software compatível. Você pode pedir um arquivo a cada 7 dias. in_progress: Preparando seu arquivo... request: Solicitar o seu arquivo size: Tamanho @@ -713,75 +714,75 @@ pt-BR:
  • Informação básica de conta: Se você se registrar nesse servidor, podemos pedir que você utilize um nome de usuário, um e-mail e uma senha. Você também pode adicionar informações extras como um nome de exibição e biografia; enviar uma imagem de perfil e imagem de cabeçalho. O nome de usuário, nome de exibição, biografia, imagem de perfil e imagem de cabeçalho são sempre listadas publicamente.
  • Posts, informação de seguidores e outras informações públicas: A lista de pessoas que você segue é listada publicamente, o mesmo é verdade para quem te segue. Quando você envia uma mensagem, a data e o horário são armazenados, assim como a aplicação que você usou para enviar a mensagem. Mensagens podem conter mídias anexadas, como imagens e vídeos. Posts públicos e não-listados estão disponíveis publicamente. Quando você destaca um post no seu perfil, isso também é uma informação pública. Seus posts são entregues aos seus seguidores e em alguns casos isso significa que eles são enviados para servidores diferentes e cópias são armazenadas nesses servidores. Quando você remove posts, essa informação também é entregue aos seus seguidores. O ato de compartilhar ou favoritar um outro post é sempre público.
  • Mensagens diretas e posts somente para seguidores: Todos os posts são armazenados e processados no servidor. Posts somente para seguidores são entregues aos seus seguidores e usuários que são mencionados neles; mensagens diretas são entregues somente aos usuários mencionados nelas. Em alguns casos isso significa que as mensagens são entregues para servidores diferentes e cópias são armazenadas nesses servidores. Nós fazemos esforços substanciais para limitar o acesso dessas mensagens somente para as pessoas autorizadas, mas outros servidores podem não fazer o mesmo. É importante portanto revisar os servidores à qual seus seguidores pertencem. Você pode usar uma opção para aprovar ou rejeitar novos seguidores manualmente nas configurações. Por favor tenha em mente que os operadores do servidor e de qualquer servidores do destinatário podem ver tais mensagens, e que os destinatários podem fazer capturas de tela, copiar ou de outra maneira compartilhar as mensagens. Não compartilhe informação confidencial pelo Mastodon.
  • -
  • IPs and other metadata: When you log in, we record the IP address you log in from, as well as the name of your browser application. All the logged in sessions are available for your review and revocation in the settings. The latest IP address used is stored for up to 12 months. We also may retain server logs which include the IP address of every request to our server.
  • +
  • IPs e outros metadados: Quando você faz se autentica, nos guardamos o endereço de IP que você usou ao se autenticar e o nome do seu navegador da internet. Todas as sessões autenticadas são disponíveis para serem analisadas e revogadas nas configurações. O último endereço de IP usado é guardado por até 12 meses. Nós também podemos reter históricos do servidor que incluem o endereço de IP de todas as requisições ao nosso servidor.

  • -

    What do we use your information for?

    +

    Para que usamos os seus dados?

    -

    Any of the information we collect from you may be used in the following ways:

    +

    Toda informação que coletamos de você pode ser usada das seguintes maneiras:

      -
    • To provide the core functionality of Mastodon. You can only interact with other people's content and post your own content when you are logged in. For example, you may follow other people to view their combined posts in your own personalized home timeline.
    • -
    • To aid moderation of the community, for example comparing your IP address with other known ones to determine ban evasion or other violations.
    • -
    • The email address you provide may be used to send you information, notifications about other people interacting with your content or sending you messages, and to respond to inquiries, and/or other requests or questions.
    • +
    • Para prover a funcionalidade básica do Mastodon. Você só pode interagir com o conteúdo de outras pessoas e postar seu próprio conteúdo estando autenticado. Por exemplo, você pode seguir outras pessoas para ver seus posts combinados na sua linha do tempo personalizada.
    • +
    • Para auxiliar na moderação da comunidade, por exemplo ao comparar o seu endereço de IP com outros endereços de IP conhecidos para determinar evasão de banimento e outras violações.
    • +
    • O endereço de email que você prover pode ser usado para lhe enviar informação, notificação sobre outras pessoas interagindo com o seu conteúdo ou lhe enviando mensagens e para responder a questões ou outros pedidos.

    -

    How do we protect your information?

    +

    Como protegemos as suas informações?

    -

    We implement a variety of security measures to maintain the safety of your personal information when you enter, submit, or access your personal information. Among other things, your browser session, as well as the traffic between your applications and the API, are secured with SSL, and your password is hashed using a strong one-way algorithm. You may enable two-factor authentication to further secure access to your account.

    +

    Nós implementamos diversas medidas de segurança para manter a segurança das suas informações pessoais quando você as acessa ou as envia. Entre outras coisas, sua sessão do navegador, bem como o tráfego entre as aplicações e a API são asseguradas usando SSL e a sua senha é guardada usando um algoritmo forte de encriptação de mão única. Você pode ativar autenticação em dois fatores como forma de aumentar a segurança no acesso à sua conta.


    -

    What is our data retention policy?

    +

    Qual é a nossa política de retenção de dados?

    -

    We will make a good faith effort to:

    +

    Nós fazemos esforços substanciais para:

      -
    • Retain server logs containing the IP address of all requests to this server, in so far as such logs are kept, no more than 90 days.
    • -
    • Retain the IP addresses associated with registered users no more than 12 months.
    • +
    • Reter o histórico do servidor contendo os endereços de IP de todas as requisições feitas à esse servidor, e com respeito a quanto tempo esses logs são retidos, não mais que 90 dias.
    • +
    • Reter o endereço de IP associado com usuários registrados não mais que 12 meses.
    -

    You can request and download an archive of your content, including your posts, media attachments, profile picture, and header image.

    +

    Você pode pedir e fazer o download de um arquivo de todo o conteúdo da sua conta, incluindo as suas mensagens, suas mídias anexadas, imagem de perfil e imagem de topo.

    -

    You may irreversibly delete your account at any time.

    +

    Você pode remover irreversivelmente a sua conta a qualquer momento.


    -

    Do we use cookies?

    +

    Nós usamos cookies?

    -

    Yes. Cookies are small files that a site or its service provider transfers to your computer's hard drive through your Web browser (if you allow). These cookies enable the site to recognize your browser and, if you have a registered account, associate it with your registered account.

    +

    Sim. Cookies são pequenos arquivos que um site ou serviço transfere ao seu disco rígido do seu computador através do seu navegador da web (se você permitir). Esses cookies permitem ao site conhecer seu navegador e, se você tiver uma conta registrada, associá-lo a sua conta.

    -

    We use cookies to understand and save your preferences for future visits.

    +

    Nós usamos cookies para compreender e salvar suas preferências para visitas futuras.


    -

    Do we disclose any information to outside parties?

    +

    Nós compartilhamos qualquer informação para terceiros?

    -

    We do not sell, trade, or otherwise transfer to outside parties your personally identifiable information. This does not include trusted third parties who assist us in operating our site, conducting our business, or servicing you, so long as those parties agree to keep this information confidential. We may also release your information when we believe release is appropriate to comply with the law, enforce our site policies, or protect ours or others rights, property, or safety.

    +

    Nós não vendemos, trocamos ou transferimos de qualquer maneira informação que pode lhe identificar à terceiros. Isso não inclui terceiros que podemos nos auxiliam a operar o nosso site, realizar nossos negócios ou lhe prestar serviços, contanto que esses terceiros se comprometam a manter essa informação confidencial. Nós podemos também divulgar informação quando acreditamos que é apropriado para obedecer a lei, para fazer cumprir nossas políticas ou proteger nossos direitos, propriedade ou segurança ou o direito, propriedade e segurança de outrem.

    -

    Your public content may be downloaded by other servers in the network. Your public and followers-only posts are delivered to the servers where your followers reside, and direct messages are delivered to the servers of the recipients, in so far as those followers or recipients reside on a different server than this.

    +

    Seu conteúdo público pode ser descarregado por outros servidores na rede. Suas mensagens públicas e somente para seus seguidores são entregues aos servidores onde seus seguidores resides e as suas mensagens diretas são entregues ao servidor dos usuários mencionados nelas, contanto que esses seguidores ou usuários residam em um servidor diferente deste.

    -

    When you authorize an application to use your account, depending on the scope of permissions you approve, it may access your public profile information, your following list, your followers, your lists, all your posts, and your favourites. Applications can never access your e-mail address or password.

    +

    Quando você autoriza uma aplicação a usar sua conta, dependendo do escopo de permissões que você aprovar, a aplicação pode acessar sua informação pública, a lista de usuários que você segue, seus seguidores, suas listas, suas mensagens e suas mensagens favoritas. Aplicações nunca podem acessar o seu endereço de e-mail ou senha.


    -

    Children's Online Privacy Protection Act Compliance

    +

    Conformidade com a COPPA (Children's Online Privacy Protection Act)

    -

    Our site, products and services are all directed to people who are at least 13 years old. If this server is in the USA, and you are under the age of 13, per the requirements of COPPA (Children's Online Privacy Protection Act) do not use this site.

    +

    Nosso site, produto e serviços são direcionados à pessoas que tem ao menos 13 anos de idade. Se esse servidor está hospedado nos EUA e você tem menos de 13 anos, de acordo com os requerimentos da COPPA (Children's Online Privacy Protection Act) não use este site.


    -

    Changes to our Privacy Policy

    +

    Mudanças à nossa política de privacidade

    -

    If we decide to change our privacy policy, we will post those changes on this page.

    +

    Se decidirmos mudar nossa política de privacidade, nós iremos disponibilizar as mudanças nesta página.

    -

    This document is CC-BY-SA. It was last updated March 7, 2018.

    +

    Este documento é CC-BY-SA. Ele foi atualizado pela última vez em 7 de março de 2018.

    -

    Originally adapted from the Discourse privacy policy.

    +

    Adaptado originalmente a partir da política de privacidade Discourse.

    title: "%{instance} Termos de Serviço e Política de Privacidade" themes: contrast: Alto contraste @@ -831,5 +832,6 @@ pt-BR: users: invalid_email: O endereço de e-mail é inválido invalid_otp_token: Código de autenticação inválido + otp_lost_help_html: Se você perder o acesso à ambos, você pode entrar em contato com %{email} seamless_external_login: Você está logado usando um serviço externo, então configurações de e-mail e password não estão disponíveis. signed_in_as: 'Acesso como:' diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index 28cfa8ab74..ff0332c181 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -4,6 +4,7 @@ ar: hints: defaults: avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 400x400px + bot: يُعلِم أنّ هذا الحساب لا يمثل شخصًا digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة display_name: one: 1 حرف باقي @@ -19,7 +20,7 @@ ar: imports: data: ملف CSV تم تصديره مِن مثيل خادوم ماستدون آخر sessions: - otp: قم بإدخال رمز المصادقة بخطوتين مِن هاتفك أو إستخدم أحد رموز النفاذ الإحتياطية. + otp: 'قم بإدخال رمز المصادقة بخطوتين الذي قام بتوليده تطبيق جهازك أو إستخدم أحد رموز النفاذ الإحتياطية :' user: filtered_languages: سوف يتم تصفية و إخفاء اللغات المختارة من خيوطك العمومية labels: @@ -29,6 +30,7 @@ ar: value: المحتوى defaults: avatar: الصورة الرمزية + bot: إنّ هذا الحساب روبوت آلي confirm_new_password: تأكيد كلمة السر الجديدة confirm_password: تأكيد كلمة السر current_password: كلمة السر الحالية diff --git a/config/locales/simple_form.ca.yml b/config/locales/simple_form.ca.yml index 1b04da90ad..21d466918b 100644 --- a/config/locales/simple_form.ca.yml +++ b/config/locales/simple_form.ca.yml @@ -4,6 +4,7 @@ ca: hints: defaults: avatar: PNG, GIF o JPG. Màxim 2MB. S'escalarà a 400x400px + bot: Informa a tothom que el compte no representa a una persona digest: Només s'envia després d'un llarg període d'inactivitat amb un resum de les mencions que has rebut en la teva absència display_name: one: 1 càracter restant @@ -19,7 +20,7 @@ ca: imports: data: Fitxer CSV exportat des de una altra instància de Mastodon sessions: - otp: Introdueix el codi de dos factors des del teu telèfon o utilitza un dels teus codis de recuperació. + otp: 'Introdueix el codi de dos factors generat per el teu telèfon o utilitza un dels teus codis de recuperació:' user: filtered_languages: Les llengües seleccionades s'eliminaran de les línies de temps públiques labels: @@ -29,6 +30,7 @@ ca: value: Contingut defaults: avatar: Avatar + bot: Aquest compte és un bot confirm_new_password: Confirma la contrasenya nova confirm_password: Confirma la contrasenya current_password: Contrasenya actual diff --git a/config/locales/simple_form.co.yml b/config/locales/simple_form.co.yml index 21404897b3..8d24704359 100644 --- a/config/locales/simple_form.co.yml +++ b/config/locales/simple_form.co.yml @@ -4,6 +4,7 @@ co: hints: defaults: avatar: Furmatu PNG, GIF o JPG. 2Mo o menu. Sarà ridottu à 400x400px + bot: Avisa a ghjente chì stu contu ùn riprisenta micca una parsona digest: Solu mandatu dopu à una longa perioda d’inattività, è solu s’elli ci sò novi missaghji diretti display_name: one: Ci ferma 1 caratteru @@ -19,16 +20,17 @@ co: imports: data: Un fugliale CSV da un’altr’istanza di Mastodon sessions: - otp: Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione. + otp: 'Entrate u codice d’identificazione à dui fattori nant’à u vostru telefuninu, o unu di i vostri codici di ricuperazione:' user: - filtered_languages: Ùn viderete micca e lingue selezziunate nant’à e linee pubbliche. + filtered_languages: Ùn viderete micca e lingue selezziunate nant’à e linee pubbliche labels: account: fields: name: Label - value: Content + value: Cuntinutu defaults: avatar: Ritrattu di prufile + bot: Stu contu hè un bot confirm_new_password: Cunfirmà a nova chjave d’accessu confirm_password: Cunfirmà a chjave d’accessu current_password: Chjave d’accessu attuale diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index a9d650a268..1bf1cbf78c 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -4,6 +4,7 @@ de: hints: defaults: avatar: PNG, GIF oder JPG. Maximal 2 MB. Wird auf 400×400 px herunterskaliert + bot: Warnt Besucher das dieser Nutzer keine echte Person darstellt digest: Wenn du lange Zeit inaktiv bist, wird dir eine Zusammenfassung von Erwähnungen in deiner Abwesenheit zugeschickt display_name: one: 1 Zeichen verbleibt @@ -19,7 +20,7 @@ de: imports: data: CSV-Datei, die aus einer anderen Mastodon-Instanz exportiert wurde sessions: - otp: Gib den Zwei-Faktor-Authentisierungs-Code von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes. + otp: 'Gib den Zwei-Faktor-Authentisierungscode von deinem Telefon ein oder benutze einen deiner Wiederherstellungscodes:' user: filtered_languages: Ausgewählte Sprachen werden aus deinen öffentlichen Zeitleisten gefiltert labels: @@ -29,6 +30,7 @@ de: value: Inhalt defaults: avatar: Profilbild + bot: Dies ist ein bot Benutzer confirm_new_password: Neues Passwort bestätigen confirm_password: Passwort bestätigen current_password: Derzeitiges Passwort diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml index 41a0c26aab..9ff9ebad46 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -4,10 +4,12 @@ eo: hints: defaults: avatar: Formato PNG, GIF aŭ JPG. Ĝis 2MB. Estos malgrandigita al 400x400px + bot: Atentigas homojn, ke la konto ne reprezentas homon digest: Sendita nur post longa tempo de neaktiveco, kaj nur se vi ricevis personan mesaĝon en via foresto display_name: one: 1 signo restas other: %{count} signoj restas + fields: Vi povas havi ĝis 4 tabelajn elementojn en via profilo header: Formato PNG, GIF aŭ JPG. Ĝis 2MB. Estos malgrandigita al 700x335px locked: Vi devos aprobi ĉiun peton de sekvado mane note: @@ -18,12 +20,17 @@ eo: imports: data: CSV-dosiero el alia nodo de Mastodon sessions: - otp: Enmetu la kodon de dufaktora aŭtentigo el via telefono aŭ uzu unu el la realiraj kodoj. + otp: 'Enmetu la kodon de dufaktora aŭtentigo el via telefono aŭ uzu unu el viaj realiraj kodoj:' user: filtered_languages: Markitaj lingvoj estos elfiltritaj de publikaj tempolinioj por vi labels: + account: + fields: + name: Etikedo + value: Enhavo defaults: avatar: Profilbildo + bot: Tio estas robota konto confirm_new_password: Konfirmi novan pasvorton confirm_password: Konfirmi pasvorton current_password: Nuna pasvorto @@ -31,6 +38,7 @@ eo: display_name: Publika nomo email: Retadreso expires_in: Eksvalidiĝas post + fields: Profilaj metadatumoj filtered_languages: Filtritaj lingvoj header: Fonbildo locale: Lingvo diff --git a/config/locales/simple_form.fa.yml b/config/locales/simple_form.fa.yml index ddb13ae43a..c492e5d9a6 100644 --- a/config/locales/simple_form.fa.yml +++ b/config/locales/simple_form.fa.yml @@ -3,11 +3,12 @@ fa: simple_form: hints: defaults: - avatar: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۱۲۰×۱۲۰ پیکسل تبدیل خواهد شد - digest: پس از مدت طولانی عدم فعالیت فرستاده می‌شود، شامل خلاصه‌ای از مواردی که در نبودتان از شما نام برده شده + avatar: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۴۰۰×۴۰۰ پیکسل تبدیل خواهد شد + digest: تنها وقتی فرستاده می‌شود که مدتی طولانی فعالیتی نداشته باشید و در این مدت برای شما پیغام خصوصی‌ای نوشته شده باشد display_name: one: 1 حرف باقی مانده other: %{count} حرف باقی مانده + fields: شما می‌توانید تا چهار مورد را در یک جدول در نمایهٔ خود نمایش دهید header: یکی از قالب‌های PNG یا GIF یا JPG. بیشترین اندازه ۲ مگابایت. تصویر به اندازهٔ ۳۳۵×۷۰۰ پیکسل تبدیل خواهد شد locked: باید پیگیران تازه را خودتان تأیید کنید. حریم خصوصی پیش‌فرض نوشته‌ها را روی پیگیران تنظیم می‌کند note: @@ -18,10 +19,14 @@ fa: imports: data: پروندهٔ CSV که از سرور ماستدون دیگری برون‌سپاری شده sessions: - otp: کد تأیید دومرحله‌ای را از تلفن خود وارد کنید یا یکی از کدهای بازیابی را به کار ببرید. + otp: 'کد تأیید دومرحله‌ای که اپ روی تلفن شما ساخته را وارد کنید یا یکی از کدهای بازیابی را به کار ببرید:' user: filtered_languages: زبان‌های انتخاب‌شده از فهرست عمومی نوشته‌هایی که می‌بینید حذف می‌شوند labels: + account: + fields: + name: برچسب + value: محتوا defaults: avatar: تصویر نمایه confirm_new_password: تأیید رمز تازه @@ -31,6 +36,7 @@ fa: display_name: نمایش به نام email: نشانی ایمیل expires_in: تاریخ انقضا + fields: اطلاعات تکمیلی نمایه filtered_languages: زبان‌های فیلترشده header: تصویر زمینه locale: زبان @@ -45,6 +51,7 @@ fa: setting_default_privacy: حریم خصوصی نوشته‌ها setting_default_sensitive: همیشه تصاویر را به عنوان حساس علامت بزن setting_delete_modal: پیش از پاک کردن یک نوشته پیغام تأیید نشان بده + setting_display_sensitive_media: همیشه تصویرهای علامت‌زده‌شده به عنوان حساس را نمایش بده setting_noindex: درخواست از موتورهای جستجو برای لغو فهرست‌سازی setting_reduce_motion: کاستن از حرکت در پویانمایی‌ها setting_system_font_ui: به‌کاربردن قلم پیش‌فرض سیستم @@ -53,6 +60,7 @@ fa: severity: شدت type: نوع درون‌ریزی username: نام کاربری (تنها حروف انگلیسی) + username_or_email: نام کاربری یا ایمیل interactions: must_be_follower: مسدودکردن اعلان‌های همه به جز پیگیران must_be_following: مسدودکردن اعلان‌های کسانی که شما پی نمی‌گیرید diff --git a/config/locales/simple_form.fi.yml b/config/locales/simple_form.fi.yml index f48e9ab23d..b7b97395a3 100644 --- a/config/locales/simple_form.fi.yml +++ b/config/locales/simple_form.fi.yml @@ -8,6 +8,7 @@ fi: display_name: one: 1 merkki jäljellä other: %{count} merkkiä jäljellä + fields: Sinulla voi olla korkeintaan 4 asiaa profiilissasi taulukossa header: PNG, GIF tai JPG. Enintään 2 Mt. Skaalataan kokoon 700 x 335 px locked: Sinun täytyy hyväksyä seuraajat manuaalisesti note: @@ -22,6 +23,9 @@ fi: user: filtered_languages: Valitut kielet suodatetaan pois julkisilta aikajanoilta labels: + account: + fields: + value: Sisältö defaults: avatar: Profiilikuva confirm_new_password: Vahvista uusi salasana @@ -31,6 +35,7 @@ fi: display_name: Nimimerkki email: Sähköpostiosoite expires_in: Vanhenee + fields: Profiilin metadata filtered_languages: Suodatetut kielet header: Otsakekuva locale: Kieli @@ -38,7 +43,7 @@ fi: max_uses: Käyttökertoja enintään new_password: Uusi salasana note: Kuvaus - otp_attempt: Kaksivaiheisen tunnistautumisen koodi + otp_attempt: Kaksivaiheisen tunnistuksen koodi password: Salasana setting_auto_play_gif: Toista GIF-animaatiot automaattisesti setting_boost_modal: Kysy vahvistusta ennen buustausta diff --git a/config/locales/simple_form.fr.yml b/config/locales/simple_form.fr.yml index 88e1b88737..1c5a7b191a 100644 --- a/config/locales/simple_form.fr.yml +++ b/config/locales/simple_form.fr.yml @@ -4,6 +4,7 @@ fr: hints: defaults: avatar: Au format PNG, GIF ou JPG. 2 Mo maximum. Sera réduit à 400x400px + bot: Avertit que ce compte ne représente pas une personne digest: Uniquement envoyé après une longue période d’inactivité et uniquement si vous avez reçu des messages personnels pendant votre absence display_name: one: 1 caractère restant @@ -19,7 +20,7 @@ fr: imports: data: Un fichier CSV généré par une autre instance de Mastodon sessions: - otp: Entrez le code d’authentification à deux facteurs depuis votre téléphone ou utilisez un de vos codes de récupération. + otp: 'Entrez le code d’authentification à deux facteurs généré par votre téléphone ou utilisez un de vos codes de récupération :' user: filtered_languages: Les langues sélectionnées seront filtrées hors de vos fils publics pour vous labels: @@ -29,6 +30,7 @@ fr: value: Contenu defaults: avatar: Image de profil + bot: Ceci est un robot confirm_new_password: Confirmation du nouveau mot de passe confirm_password: Confirmation du mot de passe current_password: Mot de passe actuel diff --git a/config/locales/simple_form.gl.yml b/config/locales/simple_form.gl.yml index 72633c7590..461b8080d7 100644 --- a/config/locales/simple_form.gl.yml +++ b/config/locales/simple_form.gl.yml @@ -3,13 +3,14 @@ gl: simple_form: hints: defaults: - avatar: PNG, GIF ou JPG. Como moito 2MB. Será reducida ate 400x400px + avatar: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 400x400px + bot: Avisa as usuarias de que a conta non representa a unha persoa digest: Enviar só tras un longo período de inactividade e só si recibeu algunha mensaxe personal na súa ausencia display_name: one: 1 caracter restante other: %{count} caracteres restantes fields: Pode ter ate 4 elementos no seu perfil mostrados como unha táboa - header: PNG, GIF ou JPG. Como moito 2MB. Será reducida a 700x335px + header: PNG, GIF ou JPG. Máximo 2MB. Será reducida a 700x335px locked: Require que vostede aprove as seguidoras de xeito manual note: one: 1 caracter restante @@ -19,7 +20,7 @@ gl: imports: data: Ficheiro CSV exportado desde outra instancia Mastodon sessions: - otp: Introduza o código de Doble-Factor desde o seu teléfono ou utilice un dos seus códigos de recuperación. + otp: Introduza o código de doble-factor xerado no aplicativo do seu móbil ou utilice un dos seus códigos de recuperación. user: filtered_languages: Os idiomas marcados filtraranse das liñas temporais públicas para vostede labels: @@ -29,6 +30,7 @@ gl: value: Contido defaults: avatar: Avatar + bot: Esta conta é de un bot confirm_new_password: Confirme o novo contrasinal confirm_password: Confirme o contrasinal current_password: Contrasinal actual diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 6b2d93454d..64d6e397fa 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -4,6 +4,7 @@ ja: hints: defaults: avatar: 2MBまでのPNGやGIF、JPGが利用可能です。400x400pxまで縮小されます + bot: アカウントが個人を表すものではないことを表示します digest: 長期間使用していない場合と不在時に返信を受けた場合のみ送信されます display_name: あと%{count}文字入力できます。 fields: プロフィールに表として4つまでの項目を表示することができます @@ -15,7 +16,7 @@ ja: imports: data: 他の Mastodon インスタンスからエクスポートしたCSVファイルを選択して下さい sessions: - otp: 携帯電話に表示された2段階認証コードを入力するか、生成したリカバリーコードを使用してください。 + otp: '携帯電話のアプリで生成された二段階認証コードを入力するか、リカバリーコードを使用してください:' user: filtered_languages: 選択した言語があなたの公開タイムラインから取り除かれます labels: @@ -25,6 +26,7 @@ ja: value: 内容 defaults: avatar: アイコン + bot: これは BOT アカウントです confirm_new_password: 新しいパスワード(確認用) confirm_password: パスワード(確認用) current_password: 現在のパスワード diff --git a/config/locales/simple_form.nl.yml b/config/locales/simple_form.nl.yml index ec42adfd72..fec5e7ec40 100644 --- a/config/locales/simple_form.nl.yml +++ b/config/locales/simple_form.nl.yml @@ -4,7 +4,8 @@ nl: hints: defaults: avatar: PNG, GIF of JPG. Maximaal 2MB. Wordt teruggeschaald naar 400x400px - digest: Wordt alleen na een lange periode van inactiviteit verzonden en alleen wanneer je tijdens jouw afwezigheid persoonlijke berichten ontvangt + bot: Waarschuwt mensen dat dit account geen echt persoon is + digest: Wordt alleen na een lange periode van inactiviteit verzonden en alleen wanneer je tijdens jouw afwezigheid persoonlijke berichten hebt ontvangen display_name: one: 1 teken over other: %{count} tekens over @@ -19,9 +20,9 @@ nl: imports: data: CSV-bestand dat op een andere Mastodonserver werd geëxporteerd sessions: - otp: Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcode's. + otp: Voer de tweestaps-aanmeldcode vanaf jouw mobiele telefoon in of gebruik een van jouw herstelcodes. user: - filtered_languages: De geselecteerde talen worden uit de lokale en globale tijdlijn verwijderd + filtered_languages: Geselecteerde talen worden uit de lokale en globale tijdlijn verwijderd labels: account: fields: @@ -29,6 +30,7 @@ nl: value: Inhoud defaults: avatar: Avatar + bot: Dit is een bot-account confirm_new_password: Nieuw wachtwoord bevestigen confirm_password: Wachtwoord bevestigen current_password: Huidig wachtwoord @@ -37,11 +39,11 @@ nl: email: E-mailadres expires_in: Vervalt na fields: Metadata profiel - filtered_languages: Talen filteren + filtered_languages: Gefilterde talen header: Omslagfoto locale: Taal locked: Maak account besloten - max_uses: Max aantal keer te gebruiken + max_uses: Max. aantal keer te gebruiken new_password: Nieuwe wachtwoord note: Bio otp_attempt: Tweestaps-aanmeldcode @@ -59,7 +61,7 @@ nl: setting_unfollow_modal: Vraag voor het ontvolgen van iemand een bevestiging severity: Zwaarte type: Importtype - username: gebruikersnaam + username: Gebruikersnaam username_or_email: Gebruikersnaam of e-mailadres interactions: must_be_follower: Meldingen van mensen die jou niet volgen blokkeren diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index cae1f671dd..0479c4c728 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -4,6 +4,7 @@ pt-BR: hints: defaults: avatar: PNG, GIF or JPG. Arquivos de até 2MB. Eles serão diminuídos para 400x400px + bot: Informa usuários que a conta não representa uma pessoa digest: Enviado após um longo período de inatividade com um resumo das menções que você recebeu em sua ausência display_name: one: 1 caracter restante @@ -19,7 +20,7 @@ pt-BR: imports: data: Arquivo CSV exportado de outra instância do Mastodon sessions: - otp: Insira o código de autenticação do seu celular ou use um dos códigos de recuperação. + otp: 'Insira o código de autenticação gerado pelo app no seu celular ou use um dos códigos de recuperação:' user: filtered_languages: Selecione os idiomas que devem ser removidos de suas timelines públicas labels: @@ -29,6 +30,7 @@ pt-BR: value: Conteúdo defaults: avatar: Avatar + bot: Essa é a conta de um robô confirm_new_password: Confirmar nova senha confirm_password: Confirmar senha current_password: Senha atual diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml index b8ee5892d3..639e4fdd5c 100644 --- a/config/locales/simple_form.ru.yml +++ b/config/locales/simple_form.ru.yml @@ -4,12 +4,13 @@ ru: hints: defaults: avatar: PNG, GIF или JPG. Максимально 2MB. Будет уменьшено до 400x400px - digest: Отсылается после долгого периода неактивности с общей информацией упоминаний, полученных в Ваше отсутствие + digest: Отсылается лишь после длительной неактивности, если Вы в это время получали личные сообщения display_name: few: Осталось %{count} символа many: Осталось %{count} символов one: Остался 1 символ other: Осталось %{count} символов + fields: В профиле можно отобразить до 4 пунктов как таблицу header: PNG, GIF или JPG. Максимально 2MB. Будет уменьшено до 700x335px locked: Потребует от Вас ручного подтверждения подписчиков, изменит приватность постов по умолчанию на "только для подписчиков" note: @@ -22,10 +23,14 @@ ru: imports: data: Файл CSV, экспортированный с другого узла Mastodon sessions: - otp: Введите код двухфакторной аутентификации или используйте один из Ваших кодов восстановления. + otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из Ваших кодов восстановления:' user: filtered_languages: Выбранные языки будут убраны из Ваших публичных лет. labels: + account: + fields: + name: Пункт + value: Значение defaults: avatar: Аватар confirm_new_password: Повторите новый пароль @@ -35,6 +40,7 @@ ru: display_name: Показываемое имя email: Адрес e-mail expires_in: Срок действия + fields: Метаданные профиля filtered_languages: Фильтруемые языки header: Заголовок locale: Язык diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index 134e62ee37..9abbeb0e87 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -4,6 +4,7 @@ sk: hints: defaults: avatar: PNG, GIF alebo JPG. Maximálne 2MB. Bude zmenšený na 400x400px + bot: Varuje užívateľov, že daný účet nerepreyentuje ozajstného človeka digest: Odoslané iba v prípade dlhodobej neprítomnosti, a len ak ste obdŕžali nejaké osobné správy kým ste boli preč display_name: one: Ostáva ti 1 znak @@ -14,12 +15,12 @@ sk: note: one: Ostáva vám 1 znak other: Ostáva ti %{count} znakov - setting_noindex: Ovplyvňuje profil a správy tak, že ich nebude možné nájsť vyhľadávaním - setting_theme: Toto ovplyvní ako bude Mastodon vyzerať pri prihlásení z hociktorého zariadenia. + setting_noindex: Ovplyvňuje verejný profil a statusy + setting_theme: Toto ovplyvňuje ako Mastodon vyzerá pri prihlásení z hociakého zariadenia. imports: data: CSV súbor vyexportovaný z inej Mastodon inštancie sessions: - otp: Napíš sem dvoj-faktorový kód z telefónu, alebo použite jeden z vašich obnovovacích kódov. + otp: 'Napíš sem dvoj-faktorový kód z telefónu, alebo použi jeden z tvojích obnovovacích kódov:' user: filtered_languages: Zaškrtnuté jazyky budú pre teba vynechané nebudú z verejnej časovej osi labels: @@ -29,6 +30,7 @@ sk: value: Obsah defaults: avatar: Avatar + bot: Toto je automatizovaný bot účet confirm_new_password: Znovu tvoje nové heslo, pre potvrdenie confirm_password: Potvrď heslo current_password: Súčasné heslo @@ -55,11 +57,11 @@ sk: setting_noindex: Nezaraďuj príspevky do indexu pre vyhľadávče setting_reduce_motion: Redukovať pohyb v animáciách setting_system_font_ui: Použiť základné systémové písmo - setting_theme: Vzhľad + setting_theme: Vzhľad stránky setting_unfollow_modal: Zobrazovať potvrdzovacie okno pred skončením sledovania iného používateľa severity: Závažnosť type: Typ importu - username: Užívateľské meno + username: Užívateľská prezývka username_or_email: Prezívka, alebo Email interactions: must_be_follower: Blokovať notifikácie pod používateľov, ktorí ťa nesledujú diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 033019e0b4..e91dd9554a 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -53,7 +53,7 @@ sk: unfollow: Prestať sledovať admin: account_moderation_notes: - create: Vytvoriť + create: Zanechaj poznámku created_msg: Poznámka moderátora bola úspešne vytvorená! delete: Zmazať destroyed_msg: Poznámka moderátora bola úspešne zmazaná! @@ -173,6 +173,7 @@ sk: resolve_report: "%{name} vyriešili nahlásenie užívateľa %{target}" silence_account: "%{name} utíšil/a účet %{target}" suspend_account: "%{name} zablokoval/a účet používateľa %{target}" + unassigned_report: "%{name} odobral/a report od %{target}" unsilence_account: "%{name} zrušil/a utíšenie účtu používateľa %{target}" unsuspend_account: "%{name} zrušil/a blokovanie účtu používateľa %{target}" update_custom_emoji: "%{name} aktualizoval/a emoji %{target}" @@ -372,6 +373,7 @@ sk: admin_mailer: new_report: body: "%{reporter} nahlásil %{target}" + body_remote: Niekto z %{domain} nahlásil %{target} subject: Nový report pre %{instance} (#%{id}) application_mailer: notification_preferences: Zmeniť e-mailové voľby @@ -460,7 +462,7 @@ sk: archive_takeout: date: Dátum download: Stiahni si svoj archív - hint_html: Môžeš si opýtať archív svojích príspevkov a nahratých médií. Exportované dáta budú v ActivityPub formáte, čítateľné hociakým kompatibilným softvérom. + hint_html: Môžeš si opýtať archív svojích príspevkov a nahratých médií. Exportované dáta budú v ActivityPub formáte, čítateľné hociakým kompatibilným softvérom. Archív si je možné vyžiadať každých sedem dní. in_progress: Balím tvoj archív... request: Vyžiadaj si tvoj archív size: Veľkosť diff --git a/config/locales/sl.yml b/config/locales/sl.yml new file mode 100644 index 0000000000..9e84dfcb97 --- /dev/null +++ b/config/locales/sl.yml @@ -0,0 +1,47 @@ +--- +sl: + about: + about_mastodon_html: Mastodon je socialno omrežje, ki temelji na odprtih spletnih protokolih in prosti ter odprtokodni programski opremi. Je decentraliziran, kot e-pošta. + administered_by: 'Upravlja:' + closed_registrations: Registracije so trenutno zaprte na tem vozlišču. Vendar! Tukaj lahko najdete druga vozlišča, na katerih se prijavite in dostopate do istega omrežja od tam. + contact: Kontakt + contact_missing: Ni nastavljeno + contact_unavailable: Ni na voljo + description_headline: Kaj je %{domain}? + domain_count_after: ostala vozlišča + domain_count_before: Povezan z + extended_description_html: | +

    Dober prostor za pravila

    +

    Razširjen opis še ni bil nastavljen.

    + features: + humane_approach_title: Bolj human pristop + not_a_product_title: Ti si oseba, ne izdelek + real_conversation_title: Zgrajen za pravi pogovor + learn_more: Spoznaj več + other_instances: Seznam vozlišč + source_code: Izvorna koda + status_count_after: statusi + status_count_before: Kdo je avtor + user_count_after: uporabniki + user_count_before: Dom za + what_is_mastodon: Kaj je Mastodon? + accounts: + follow: Sledi + followers: Sledilci + media: Medij + moved_html: "%{name} se je prestavil na %{new_profile_link}:" + nothing_here: Nič ni tukaj! + people_followed_by: Ljudje, ki jim sledi %{name} + people_who_follow: Ljudje, ki sledijo %{name} + remote_follow: Oddaljeno sledenje + reserved_username: Uporabniško ime je zasedeno + roles: + admin: Skrbnik + admin: + account_moderation_notes: + create: Pusti sporočilo + delete: Izbriši + accounts: + are_you_sure: Ali si prepričan? + avatar: Avatar + by_domain: Domena From e86a4fe36b1234e99f5b586d0dad779e38a4c0f8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 11 May 2018 11:49:12 +0200 Subject: [PATCH 053/239] Add REST API for Web Push Notifications subscriptions (#7445) - POST /api/v1/push/subscription - PUT /api/v1/push/subscription - DELETE /api/v1/push/subscription - New OAuth scope: "push" (required for the above methods) --- .../api/v1/push/subscriptions_controller.rb | 50 +++++++++++ .../api/web/push_subscriptions_controller.rb | 11 +-- app/controllers/shares_controller.rb | 1 + app/models/user.rb | 2 +- app/models/web/push_subscription.rb | 47 +++++++---- app/serializers/initial_state_serializer.rb | 4 +- .../rest/web_push_subscription_serializer.rb | 13 +++ .../web/notification_serializer.rb | 2 +- app/services/notify_service.rb | 21 +++-- app/workers/web/push_notification_worker.rb | 18 ++++ app/workers/web_push_notification_worker.rb | 25 ------ config/initializers/doorkeeper.rb | 2 +- config/locales/doorkeeper.en.yml | 1 + config/routes.rb | 4 + ...cess_token_id_to_web_push_subscriptions.rb | 6 ++ ...10230049_migrate_web_push_subscriptions.rb | 13 +++ db/schema.rb | 8 +- .../v1/push/subscriptions_controller_spec.rb | 83 +++++++++++++++++++ .../web/push_subscriptions_controller_spec.rb | 16 ++-- spec/models/web/push_subscription_spec.rb | 12 --- 20 files changed, 258 insertions(+), 81 deletions(-) create mode 100644 app/controllers/api/v1/push/subscriptions_controller.rb create mode 100644 app/serializers/rest/web_push_subscription_serializer.rb create mode 100644 app/workers/web/push_notification_worker.rb delete mode 100644 app/workers/web_push_notification_worker.rb create mode 100644 db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb create mode 100644 db/migrate/20180510230049_migrate_web_push_subscriptions.rb create mode 100644 spec/controllers/api/v1/push/subscriptions_controller_spec.rb diff --git a/app/controllers/api/v1/push/subscriptions_controller.rb b/app/controllers/api/v1/push/subscriptions_controller.rb new file mode 100644 index 0000000000..5038cc03c7 --- /dev/null +++ b/app/controllers/api/v1/push/subscriptions_controller.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +class Api::V1::Push::SubscriptionsController < Api::BaseController + before_action -> { doorkeeper_authorize! :push } + before_action :require_user! + before_action :set_web_push_subscription + + def create + @web_subscription&.destroy! + + @web_subscription = ::Web::PushSubscription.create!( + endpoint: subscription_params[:endpoint], + key_p256dh: subscription_params[:keys][:p256dh], + key_auth: subscription_params[:keys][:auth], + data: data_params, + user_id: current_user.id, + access_token_id: doorkeeper_token.id + ) + + render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer + end + + def update + raise ActiveRecord::RecordNotFound if @web_subscription.nil? + + @web_subscription.update!(data: data_params) + + render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer + end + + def destroy + @web_subscription&.destroy! + render_empty + end + + private + + def set_web_push_subscription + @web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id) + end + + def subscription_params + params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh]) + end + + def data_params + return {} if params[:data].blank? + params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention]) + end +end diff --git a/app/controllers/api/web/push_subscriptions_controller.rb b/app/controllers/api/web/push_subscriptions_controller.rb index 249e7c1860..fe8e425808 100644 --- a/app/controllers/api/web/push_subscriptions_controller.rb +++ b/app/controllers/api/web/push_subscriptions_controller.rb @@ -31,22 +31,23 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController endpoint: subscription_params[:endpoint], key_p256dh: subscription_params[:keys][:p256dh], key_auth: subscription_params[:keys][:auth], - data: data + data: data, + user_id: active_session.user_id, + access_token_id: active_session.access_token_id ) active_session.update!(web_push_subscription: web_subscription) - render json: web_subscription.as_payload + render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer end def update params.require([:id]) web_subscription = ::Web::PushSubscription.find(params[:id]) - web_subscription.update!(data: data_params) - render json: web_subscription.as_payload + render json: web_subscription, serializer: REST::WebPushSubscriptionSerializer end private @@ -56,6 +57,6 @@ class Api::Web::PushSubscriptionsController < Api::Web::BaseController end def data_params - @data_params ||= params.require(:data).permit(:alerts) + @data_params ||= params.require(:data).permit(alerts: [:follow, :favourite, :reblog, :mention]) end end diff --git a/app/controllers/shares_controller.rb b/app/controllers/shares_controller.rb index 3ec831a72d..9ef1e07491 100644 --- a/app/controllers/shares_controller.rb +++ b/app/controllers/shares_controller.rb @@ -15,6 +15,7 @@ class SharesController < ApplicationController def initial_state_params text = [params[:title], params[:text], params[:url]].compact.join(' ') + { settings: Web::Setting.find_by(user: current_user)&.data || {}, push_subscription: current_account.user.web_push_subscription(current_session), diff --git a/app/models/user.rb b/app/models/user.rb index f5f542f07d..21c217e77d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -245,7 +245,7 @@ class User < ApplicationRecord end def web_push_subscription(session) - session.web_push_subscription.nil? ? nil : session.web_push_subscription.as_payload + session.web_push_subscription.nil? ? nil : session.web_push_subscription end def invite_code=(code) diff --git a/app/models/web/push_subscription.rb b/app/models/web/push_subscription.rb index 1736106f79..df549c6d3d 100644 --- a/app/models/web/push_subscription.rb +++ b/app/models/web/push_subscription.rb @@ -3,38 +3,51 @@ # # Table name: web_push_subscriptions # -# id :bigint(8) not null, primary key -# endpoint :string not null -# key_p256dh :string not null -# key_auth :string not null -# data :json -# created_at :datetime not null -# updated_at :datetime not null +# id :bigint(8) not null, primary key +# endpoint :string not null +# key_p256dh :string not null +# key_auth :string not null +# data :json +# created_at :datetime not null +# updated_at :datetime not null +# access_token_id :bigint(8) +# user_id :bigint(8) # -require 'webpush' - class Web::PushSubscription < ApplicationRecord + belongs_to :user, optional: true + belongs_to :access_token, class_name: 'Doorkeeper::AccessToken', optional: true + has_one :session_activation def push(notification) - I18n.with_locale(session_activation.user.locale || I18n.default_locale) do + I18n.with_locale(associated_user.locale || I18n.default_locale) do push_payload(message_from(notification), 48.hours.seconds) end end def pushable?(notification) - data&.key?('alerts') && data['alerts'][notification.type.to_s] + data&.key?('alerts') && ActiveModel::Type::Boolean.new.cast(data['alerts'][notification.type.to_s]) end - def as_payload - payload = { id: id, endpoint: endpoint } - payload[:alerts] = data['alerts'] if data&.key?('alerts') - payload + def associated_user + return @associated_user if defined?(@associated_user) + + @associated_user = if user_id.nil? + session_activation.user + else + user + end end - def access_token - find_or_create_access_token.token + def associated_access_token + return @associated_access_token if defined?(@associated_access_token) + + @associated_access_token = if access_token_id.nil? + find_or_create_access_token.token + else + access_token + end end private diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 3b908e224e..6c9fba2f5b 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -2,7 +2,9 @@ class InitialStateSerializer < ActiveModel::Serializer attributes :meta, :compose, :accounts, - :media_attachments, :settings, :push_subscription + :media_attachments, :settings + + has_one :push_subscription, serializer: REST::WebPushSubscriptionSerializer def meta store = { diff --git a/app/serializers/rest/web_push_subscription_serializer.rb b/app/serializers/rest/web_push_subscription_serializer.rb new file mode 100644 index 0000000000..7fd952a567 --- /dev/null +++ b/app/serializers/rest/web_push_subscription_serializer.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class REST::WebPushSubscriptionSerializer < ActiveModel::Serializer + attributes :id, :endpoint, :alerts, :server_key + + def alerts + object.data&.dig('alerts') || {} + end + + def server_key + Rails.configuration.x.vapid_public_key + end +end diff --git a/app/serializers/web/notification_serializer.rb b/app/serializers/web/notification_serializer.rb index e5524fe7a7..31c7038324 100644 --- a/app/serializers/web/notification_serializer.rb +++ b/app/serializers/web/notification_serializer.rb @@ -54,7 +54,7 @@ class Web::NotificationSerializer < ActiveModel::Serializer def access_token return if actions.empty? - current_push_subscription.access_token + current_push_subscription.associated_access_token end def message diff --git a/app/services/notify_service.rb b/app/services/notify_service.rb index ba086449cc..6490d2735b 100644 --- a/app/services/notify_service.rb +++ b/app/services/notify_service.rb @@ -9,6 +9,7 @@ class NotifyService < BaseService return if recipient.user.nil? || blocked? create_notification + push_notification if @notification.browserable? send_email if email_enabled? rescue ActiveRecord::RecordInvalid return @@ -101,25 +102,27 @@ class NotifyService < BaseService def create_notification @notification.save! - return unless @notification.browserable? + end + + def push_notification + return if @notification.activity.nil? + Redis.current.publish("timeline:#{@recipient.id}", Oj.dump(event: :notification, payload: InlineRenderer.render(@notification, @recipient, :notification))) send_push_notifications end def send_push_notifications - # HACK: Can be caused by quickly unfavouriting a status, since creating - # a favourite and creating a notification are not wrapped in a transaction. - return if @notification.activity.nil? + subscriptions_ids = ::Web::PushSubscription.where(user_id: @recipient.user.id) + .select { |subscription| subscription.pushable?(@notification) } + .map(&:id) - sessions_with_subscriptions = @recipient.user.session_activations.where.not(web_push_subscription: nil) - sessions_with_subscriptions_ids = sessions_with_subscriptions.select { |session| session.web_push_subscription.pushable? @notification }.map(&:id) - - WebPushNotificationWorker.push_bulk(sessions_with_subscriptions_ids) do |session_activation_id| - [session_activation_id, @notification.id] + ::Web::PushNotificationWorker.push_bulk(subscriptions_ids) do |subscription_id| + [subscription_id, @notification.id] end end def send_email + return if @notification.activity.nil? NotificationMailer.public_send(@notification.type, @recipient, @notification).deliver_later end diff --git a/app/workers/web/push_notification_worker.rb b/app/workers/web/push_notification_worker.rb new file mode 100644 index 0000000000..4a40e5c8bd --- /dev/null +++ b/app/workers/web/push_notification_worker.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class Web::PushNotificationWorker + include Sidekiq::Worker + + sidekiq_options backtrace: true + + def perform(subscription_id, notification_id) + subscription = ::Web::PushSubscription.find(subscription_id) + notification = Notification.find(notification_id) + + subscription.push(notification) unless notification.activity.nil? + rescue Webpush::InvalidSubscription, Webpush::ExpiredSubscription + subscription.destroy! + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/app/workers/web_push_notification_worker.rb b/app/workers/web_push_notification_worker.rb deleted file mode 100644 index eacea04c34..0000000000 --- a/app/workers/web_push_notification_worker.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -class WebPushNotificationWorker - include Sidekiq::Worker - - sidekiq_options backtrace: true - - def perform(session_activation_id, notification_id) - session_activation = SessionActivation.find(session_activation_id) - notification = Notification.find(notification_id) - - return if session_activation.web_push_subscription.nil? || notification.activity.nil? - - session_activation.web_push_subscription.push(notification) - rescue Webpush::InvalidSubscription, Webpush::ExpiredSubscription - # Subscription expiration is not currently implemented in any browser - - session_activation.web_push_subscription.destroy! - session_activation.update!(web_push_subscription: nil) - - true - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 074f8c410b..4695538030 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -55,7 +55,7 @@ Doorkeeper.configure do # For more information go to # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes default_scopes :read - optional_scopes :write, :follow + optional_scopes :write, :follow, :push # Change the way client credentials are retrieved from the request object. # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index 33d544bed5..eca1fc675f 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -115,5 +115,6 @@ en: title: OAuth authorization required scopes: follow: follow, block, unblock and unfollow accounts + push: receive push notifications for your account read: read your account's data write: post on your behalf diff --git a/config/routes.rb b/config/routes.rb index 4c920cf74f..b7bd1a7ed5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -306,6 +306,10 @@ Rails.application.routes.draw do resources :lists, only: [:index, :create, :show, :update, :destroy] do resource :accounts, only: [:show, :create, :destroy], controller: 'lists/accounts' end + + namespace :push do + resource :subscription, only: [:create, :update, :destroy] + end end namespace :web do diff --git a/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb b/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb new file mode 100644 index 0000000000..94ef8e0f59 --- /dev/null +++ b/db/migrate/20180510214435_add_access_token_id_to_web_push_subscriptions.rb @@ -0,0 +1,6 @@ +class AddAccessTokenIdToWebPushSubscriptions < ActiveRecord::Migration[5.2] + def change + add_reference :web_push_subscriptions, :access_token, null: true, default: nil, foreign_key: { on_delete: :cascade, to_table: :oauth_access_tokens }, index: false + add_reference :web_push_subscriptions, :user, null: true, default: nil, foreign_key: { on_delete: :cascade }, index: false + end +end diff --git a/db/migrate/20180510230049_migrate_web_push_subscriptions.rb b/db/migrate/20180510230049_migrate_web_push_subscriptions.rb new file mode 100644 index 0000000000..6de1bed795 --- /dev/null +++ b/db/migrate/20180510230049_migrate_web_push_subscriptions.rb @@ -0,0 +1,13 @@ +class MigrateWebPushSubscriptions < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def up + add_index :web_push_subscriptions, :user_id, algorithm: :concurrently + add_index :web_push_subscriptions, :access_token_id, algorithm: :concurrently + end + + def down + remove_index :web_push_subscriptions, :user_id + remove_index :web_push_subscriptions, :access_token_id + end +end diff --git a/db/schema.rb b/db/schema.rb index f7fa24b835..221c08d98e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2018_05_06_221944) do +ActiveRecord::Schema.define(version: 2018_05_10_230049) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -539,6 +539,10 @@ ActiveRecord::Schema.define(version: 2018_05_06_221944) do t.json "data" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.bigint "access_token_id" + t.bigint "user_id" + t.index ["access_token_id"], name: "index_web_push_subscriptions_on_access_token_id" + t.index ["user_id"], name: "index_web_push_subscriptions_on_user_id" end create_table "web_settings", force: :cascade do |t| @@ -605,5 +609,7 @@ ActiveRecord::Schema.define(version: 2018_05_06_221944) do add_foreign_key "subscriptions", "accounts", name: "fk_9847d1cbb5", on_delete: :cascade add_foreign_key "users", "accounts", name: "fk_50500f500d", on_delete: :cascade add_foreign_key "users", "invites", on_delete: :nullify + add_foreign_key "web_push_subscriptions", "oauth_access_tokens", column: "access_token_id", on_delete: :cascade + add_foreign_key "web_push_subscriptions", "users", on_delete: :cascade add_foreign_key "web_settings", "users", name: "fk_11910667b2", on_delete: :cascade end diff --git a/spec/controllers/api/v1/push/subscriptions_controller_spec.rb b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb new file mode 100644 index 0000000000..01146294f8 --- /dev/null +++ b/spec/controllers/api/v1/push/subscriptions_controller_spec.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe Api::V1::Push::SubscriptionsController do + render_views + + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'push') } + + before do + allow(controller).to receive(:doorkeeper_token) { token } + end + + let(:create_payload) do + { + subscription: { + endpoint: 'https://fcm.googleapis.com/fcm/send/fiuH06a27qE:APA91bHnSiGcLwdaxdyqVXNDR9w1NlztsHb6lyt5WDKOC_Z_Q8BlFxQoR8tWFSXUIDdkyw0EdvxTu63iqamSaqVSevW5LfoFwojws8XYDXv_NRRLH6vo2CdgiN4jgHv5VLt2A8ah6lUX', + keys: { + p256dh: 'BEm_a0bdPDhf0SOsrnB2-ategf1hHoCnpXgQsFj5JCkcoMrMt2WHoPfEYOYPzOIs9mZE8ZUaD7VA5vouy0kEkr8=', + auth: 'eH_C8rq2raXqlcBVDa1gLg==', + }, + } + }.with_indifferent_access + end + + let(:alerts_payload) do + { + data: { + alerts: { + follow: true, + favourite: false, + reblog: true, + mention: false, + } + } + }.with_indifferent_access + end + + describe 'POST #create' do + it 'saves push subscriptions' do + post :create, params: create_payload + + push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint]) + + expect(push_subscription.endpoint).to eq(create_payload[:subscription][:endpoint]) + expect(push_subscription.key_p256dh).to eq(create_payload[:subscription][:keys][:p256dh]) + expect(push_subscription.key_auth).to eq(create_payload[:subscription][:keys][:auth]) + expect(push_subscription.user_id).to eq user.id + expect(push_subscription.access_token_id).to eq token.id + end + + it 'replaces old subscription on repeat calls' do + post :create, params: create_payload + post :create, params: create_payload + + expect(Web::PushSubscription.where(endpoint: create_payload[:subscription][:endpoint]).count).to eq 1 + end + end + + describe 'PUT #update' do + it 'changes alert settings' do + post :create, params: create_payload + put :update, params: alerts_payload + + push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint]) + + expect(push_subscription.data.dig('alerts', 'follow')).to eq(alerts_payload[:data][:alerts][:follow].to_s) + expect(push_subscription.data.dig('alerts', 'favourite')).to eq(alerts_payload[:data][:alerts][:favourite].to_s) + expect(push_subscription.data.dig('alerts', 'reblog')).to eq(alerts_payload[:data][:alerts][:reblog].to_s) + expect(push_subscription.data.dig('alerts', 'mention')).to eq(alerts_payload[:data][:alerts][:mention].to_s) + end + end + + describe 'DELETE #destroy' do + it 'removes the subscription' do + post :create, params: create_payload + delete :destroy + + expect(Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint])).to be_nil + end + end +end diff --git a/spec/controllers/api/web/push_subscriptions_controller_spec.rb b/spec/controllers/api/web/push_subscriptions_controller_spec.rb index bbf94c5c66..381cdeab94 100644 --- a/spec/controllers/api/web/push_subscriptions_controller_spec.rb +++ b/spec/controllers/api/web/push_subscriptions_controller_spec.rb @@ -59,10 +59,10 @@ describe Api::Web::PushSubscriptionsController do push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint]) - expect(push_subscription.data['follow']).to eq(alerts_payload[:data][:follow]) - expect(push_subscription.data['favourite']).to eq(alerts_payload[:data][:favourite]) - expect(push_subscription.data['reblog']).to eq(alerts_payload[:data][:reblog]) - expect(push_subscription.data['mention']).to eq(alerts_payload[:data][:mention]) + expect(push_subscription.data['alerts']['follow']).to eq(alerts_payload[:data][:alerts][:follow].to_s) + expect(push_subscription.data['alerts']['favourite']).to eq(alerts_payload[:data][:alerts][:favourite].to_s) + expect(push_subscription.data['alerts']['reblog']).to eq(alerts_payload[:data][:alerts][:reblog].to_s) + expect(push_subscription.data['alerts']['mention']).to eq(alerts_payload[:data][:alerts][:mention].to_s) end end end @@ -81,10 +81,10 @@ describe Api::Web::PushSubscriptionsController do push_subscription = Web::PushSubscription.find_by(endpoint: create_payload[:subscription][:endpoint]) - expect(push_subscription.data['follow']).to eq(alerts_payload[:data][:follow]) - expect(push_subscription.data['favourite']).to eq(alerts_payload[:data][:favourite]) - expect(push_subscription.data['reblog']).to eq(alerts_payload[:data][:reblog]) - expect(push_subscription.data['mention']).to eq(alerts_payload[:data][:mention]) + expect(push_subscription.data['alerts']['follow']).to eq(alerts_payload[:data][:alerts][:follow].to_s) + expect(push_subscription.data['alerts']['favourite']).to eq(alerts_payload[:data][:alerts][:favourite].to_s) + expect(push_subscription.data['alerts']['reblog']).to eq(alerts_payload[:data][:alerts][:reblog].to_s) + expect(push_subscription.data['alerts']['mention']).to eq(alerts_payload[:data][:alerts][:mention].to_s) end end end diff --git a/spec/models/web/push_subscription_spec.rb b/spec/models/web/push_subscription_spec.rb index 574da55ac2..c6665611c6 100644 --- a/spec/models/web/push_subscription_spec.rb +++ b/spec/models/web/push_subscription_spec.rb @@ -2,20 +2,8 @@ require 'rails_helper' RSpec.describe Web::PushSubscription, type: :model do let(:alerts) { { mention: true, reblog: false, follow: true, follow_request: false, favourite: true } } - let(:payload_no_alerts) { Web::PushSubscription.new(id: 1, endpoint: 'a', key_p256dh: 'c', key_auth: 'd').as_payload } - let(:payload_alerts) { Web::PushSubscription.new(id: 1, endpoint: 'a', key_p256dh: 'c', key_auth: 'd', data: { alerts: alerts }).as_payload } let(:push_subscription) { Web::PushSubscription.new(data: { alerts: alerts }) } - describe '#as_payload' do - it 'only returns id and endpoint' do - expect(payload_no_alerts.keys).to eq [:id, :endpoint] - end - - it 'returns alerts if set' do - expect(payload_alerts.keys).to eq [:id, :endpoint, :alerts] - end - end - describe '#pushable?' do it 'obeys alert settings' do expect(push_subscription.send(:pushable?, Notification.new(activity_type: 'Mention'))).to eq true From d31b031214eff38cba635af8732cbbab94fb6d9f Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Fri, 11 May 2018 18:51:07 +0900 Subject: [PATCH 054/239] Add CONTINUOUS_INTEGRATION: true to .circleci/config.yml (#7447) --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 02b505457b..8791965f0e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -11,6 +11,7 @@ aliases: RAILS_ENV: test PARALLEL_TEST_PROCESSORS: 4 ALLOW_NOPAM: true + CONTINUOUS_INTEGRATION: true DISABLE_SIMPLECOV: true working_directory: ~/projects/mastodon/ From fd0f2b675e70d03278f96985de727aa88a8a74fe Mon Sep 17 00:00:00 2001 From: Shuhei Kitagawa Date: Fri, 11 May 2018 20:14:33 +0900 Subject: [PATCH 055/239] Add tests for invites controller (#7441) * Add tests for invites controller * Small refactoring and fix for invites controller --- app/controllers/invites_controller.rb | 12 ++-- spec/controllers/invites_controller_spec.rb | 67 +++++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 spec/controllers/invites_controller_spec.rb diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index 38d6c8d73e..8e87c63cfd 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -8,9 +8,9 @@ class InvitesController < ApplicationController before_action :authenticate_user! def index - authorize :invite, :create? + authorize :invite, :index? - @invites = Invite.where(user: current_user) + @invites = invites @invite = Invite.new(expires_in: 1.day.to_i) end @@ -23,13 +23,13 @@ class InvitesController < ApplicationController if @invite.save redirect_to invites_path else - @invites = Invite.where(user: current_user) + @invites = invites render :index end end def destroy - @invite = Invite.where(user: current_user).find(params[:id]) + @invite = invites.find(params[:id]) authorize @invite, :destroy? @invite.expire! redirect_to invites_path @@ -37,6 +37,10 @@ class InvitesController < ApplicationController private + def invites + Invite.where(user: current_user) + end + def resource_params params.require(:invite).permit(:max_uses, :expires_in) end diff --git a/spec/controllers/invites_controller_spec.rb b/spec/controllers/invites_controller_spec.rb new file mode 100644 index 0000000000..c5c6cb651a --- /dev/null +++ b/spec/controllers/invites_controller_spec.rb @@ -0,0 +1,67 @@ +require 'rails_helper' + +describe InvitesController do + render_views + + before do + sign_in user + end + + describe 'GET #index' do + subject { get :index } + + let!(:invite) { Fabricate(:invite, user: user) } + + context 'when user is a staff' do + let(:user) { Fabricate(:user, moderator: true, admin: false) } + + it 'renders index page' do + expect(subject).to render_template :index + expect(assigns(:invites)).to include invite + expect(assigns(:invites).count).to eq 1 + end + end + + context 'when user is not a staff' do + let(:user) { Fabricate(:user, moderator: false, admin: false) } + + it 'returns 403' do + expect(subject).to have_http_status 403 + end + end + end + + describe 'POST #create' do + subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } } + + context 'when user is an admin' do + let(:user) { Fabricate(:user, moderator: false, admin: true) } + + it 'succeeds to create a invite' do + expect{ subject }.to change { Invite.count }.by(1) + expect(subject).to redirect_to invites_path + expect(Invite.last).to have_attributes(user_id: user.id, max_uses: 10) + end + end + + context 'when user is not an admin' do + let(:user) { Fabricate(:user, moderator: true, admin: false) } + + it 'returns 403' do + expect(subject).to have_http_status 403 + end + end + end + + describe 'DELETE #create' do + subject { delete :destroy, params: { id: invite.id } } + + let!(:invite) { Fabricate(:invite, user: user, expires_at: nil) } + let(:user) { Fabricate(:user, moderator: false, admin: true) } + + it 'expires invite' do + expect(subject).to redirect_to invites_path + expect(invite.reload).to be_expired + end + end +end From b59416500ecf59b38ba3d6f062c6537814c38735 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 11 May 2018 13:14:50 +0200 Subject: [PATCH 056/239] Catch Paperclip processing failures (fixes #6378) (#7439) --- app/models/concerns/remotable.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 7f1ef5191b..20ddbca53c 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -41,6 +41,9 @@ module Remotable rescue HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError, Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" nil + rescue Paperclip::Error => e + Rails.logger.debug "Error processing remote #{attachment_name}: #{e}" + nil end end From 37457543c75dc1a1f12cea4051841a85f13cbf16 Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 11 May 2018 13:20:31 +0200 Subject: [PATCH 057/239] =?UTF-8?q?Change=20wording=20of=20the=20=E2=80=9C?= =?UTF-8?q?undo=E2=80=9D=20media=20upload=20button=20(fixes=20#6857)=20(#7?= =?UTF-8?q?417)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/features/compose/components/upload.js | 2 +- app/javascript/mastodon/locales/defaultMessages.json | 4 ++-- app/javascript/mastodon/locales/en.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js index 61b2d19e0d..bfa2b47271 100644 --- a/app/javascript/mastodon/features/compose/components/upload.js +++ b/app/javascript/mastodon/features/compose/components/upload.js @@ -77,7 +77,7 @@ export default class Upload extends ImmutablePureComponent { {({ scale }) => (
    - + {media.get('type') === 'image' && }
    diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 6cbe148de3..3592918740 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -819,7 +819,7 @@ "id": "upload_form.description" }, { - "defaultMessage": "Undo", + "defaultMessage": "Delete", "id": "upload_form.undo" }, { @@ -1857,4 +1857,4 @@ ], "path": "app/javascript/mastodon/features/video/index.json" } -] \ No newline at end of file +] diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index b796ba8f38..aaad4f69c9 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -283,7 +283,7 @@ "upload_button.label": "Add media", "upload_form.description": "Describe for the visually impaired", "upload_form.focus": "Crop", - "upload_form.undo": "Undo", + "upload_form.undo": "Delete", "upload_progress.label": "Uploading...", "video.close": "Close video", "video.exit_fullscreen": "Exit full screen", From 6222c7def7d92638c58480834d8279eb831784ba Mon Sep 17 00:00:00 2001 From: ThibG Date: Fri, 11 May 2018 13:20:58 +0200 Subject: [PATCH 058/239] Update session activation time (fixes #5605) (#7408) --- app/controllers/application_controller.rb | 1 + .../concerns/session_tracking_concern.rb | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 app/controllers/concerns/session_tracking_concern.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 5885264470..5b22f17c63 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base include Localized include UserTrackingConcern + include SessionTrackingConcern helper_method :current_account helper_method :current_session diff --git a/app/controllers/concerns/session_tracking_concern.rb b/app/controllers/concerns/session_tracking_concern.rb new file mode 100644 index 0000000000..45361b0190 --- /dev/null +++ b/app/controllers/concerns/session_tracking_concern.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module SessionTrackingConcern + extend ActiveSupport::Concern + + UPDATE_SIGN_IN_HOURS = 24 + + included do + before_action :set_session_activity + end + + private + + def set_session_activity + return unless session_needs_update? + current_session.touch + end + + def session_needs_update? + !current_session.nil? && current_session.updated_at < UPDATE_SIGN_IN_HOURS.hours.ago + end +end From 2a85b97eb6da5f39a433d842e265fe25c5c274ec Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:13:59 +0200 Subject: [PATCH 059/239] Update admin page SCSS from upstream --- .../flavours/glitch/styles/admin.scss | 120 +++++++++--------- 1 file changed, 62 insertions(+), 58 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index b077df1450..1948a2a231 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -141,14 +141,15 @@ } hr { - margin: 20px 0; + width: 100%; + height: 0; border: 0; - background: transparent; - border-bottom: 1px solid $ui-base-color; + border-bottom: 1px solid rgba($ui-base-lighter-color, .6); + margin: 20px 0; - &.section-break { - margin: 30px 0; - border-bottom: 2px solid $ui-base-lighter-color; + &.spacer { + height: 1px; + border: 0; } } @@ -273,22 +274,6 @@ } } -.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; @@ -351,34 +336,9 @@ } } -.report-note__comment { - margin-bottom: 20px; -} - -.report-note__form { - margin-bottom: 20px; - - .report-note__textarea { - box-sizing: border-box; - border: 0; - padding: 7px 4px; - margin-bottom: 10px; - font-size: 16px; - color: $inverted-text-color; - display: block; - width: 100%; - outline: 0; - font-family: inherit; - resize: vertical; - } - - .report-note__buttons { - text-align: right; - } - - .report-note__button { - margin: 0 0 5px 5px; - } +.simple_form.new_report_note, +.simple_form.new_account_moderation_note { + max-width: 100%; } .batch-form-box { @@ -406,13 +366,6 @@ } } -.batch-checkbox, -.batch-checkbox-all { - display: flex; - align-items: center; - margin-right: 5px; -} - .back-link { margin-bottom: 10px; font-size: 14px; @@ -432,7 +385,7 @@ } .log-entry { - margin-bottom: 8px; + margin-bottom: 20px; line-height: 20px; &__header { @@ -530,9 +483,12 @@ } } +a.name-tag, .name-tag { display: flex; align-items: center; + text-decoration: none; + color: $secondary-text-color; .avatar { display: block; @@ -544,4 +500,52 @@ .username { font-weight: 500; } + + &.suspended { + .username { + text-decoration: line-through; + color: lighten($error-red, 12%); + } + + .avatar { + filter: grayscale(100%); + opacity: 0.8; + } + } +} + +.speech-bubble { + margin-bottom: 20px; + border-left: 4px solid $ui-highlight-color; + + &.positive { + border-left-color: $success-green; + } + + &.negative { + border-left-color: lighten($error-red, 12%); + } + + &__bubble { + padding: 16px; + padding-left: 14px; + font-size: 15px; + line-height: 20px; + border-radius: 4px 4px 4px 0; + position: relative; + font-weight: 500; + + a { + color: $darker-text-color; + } + } + + &__owner { + padding: 8px; + padding-left: 12px; + } + + time { + color: $dark-text-color; + } } From d0641e77acfa985273702aaab188cb7e0e594f2f Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:18:52 +0200 Subject: [PATCH 060/239] Update SCSS for about/landing page --- .../flavours/glitch/styles/about.scss | 76 +++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/about.scss b/app/javascript/flavours/glitch/styles/about.scss index 55f31266f5..c9c0e3081a 100644 --- a/app/javascript/flavours/glitch/styles/about.scss +++ b/app/javascript/flavours/glitch/styles/about.scss @@ -322,6 +322,11 @@ $small-breakpoint: 960px; border: 0; border-bottom: 1px solid rgba($ui-base-lighter-color, .6); margin: 20px 0; + + &.spacer { + height: 1px; + border: 0; + } } .container-alt { @@ -681,6 +686,54 @@ $small-breakpoint: 960px; margin-bottom: 0; } + .account { + border-bottom: 0; + padding: 0; + + &__display-name { + align-items: center; + display: flex; + margin-right: 5px; + } + + div.account__display-name { + &:hover { + .display-name strong { + text-decoration: none; + } + } + + .account__avatar { + cursor: default; + } + } + + &__avatar-wrapper { + margin-left: 0; + flex: 0 0 auto; + } + + &__avatar { + width: 44px; + height: 44px; + background-size: 44px 44px; + } + + .display-name { + font-size: 15px; + + &__account { + font-size: 14px; + } + } + } + + @media screen and (max-width: $small-breakpoint) { + .contact { + margin-top: 30px; + } + } + @media screen and (max-width: $column-breakpoint) { padding: 25px 20px; } @@ -816,6 +869,8 @@ $small-breakpoint: 960px; font-size: 16px; line-height: inherit; font-weight: inherit; + margin: 0; + padding: 0; } .column { @@ -852,8 +907,13 @@ $small-breakpoint: 960px; } &__features { + & > p { + padding-right: 60px; + } + .features-list { - margin: 40px 0 !important; + margin: 40px 0; + margin-top: 30px; } &__action { @@ -862,17 +922,11 @@ $small-breakpoint: 960px; } .features-list { - margin-top: 20px; - .features-list__row { display: flex; padding: 10px 0; justify-content: space-between; - &:first-child { - padding-top: 0; - } - .visual { flex: 0 0 auto; display: flex; @@ -898,6 +952,14 @@ $small-breakpoint: 960px; } } } + + @media screen and (min-width: $small-breakpoint) { + display: grid; + grid-gap: 30px; + grid-template-columns: 1fr 1fr; + grid-auto-columns: 50%; + grid-auto-rows: max-content; + } } .extended-description { From 86c477df23c6ed17d0ddacb37b7c2c1221ab7eb4 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:20:46 +0200 Subject: [PATCH 061/239] =?UTF-8?q?Update=20SCSS=20to=20match=20=E2=80=9CS?= =?UTF-8?q?how=20card=20modal=20on=20public=20pages=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/flavours/glitch/styles/containers.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss index 9d5ab66a48..c40b38a5a5 100644 --- a/app/javascript/flavours/glitch/styles/containers.scss +++ b/app/javascript/flavours/glitch/styles/containers.scss @@ -60,6 +60,7 @@ } } +.card-standalone__body, .media-gallery-standalone__body { overflow: hidden; } From 5c96717144100f62a86763cef7cdfe5bd50e26fd Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:31:18 +0200 Subject: [PATCH 062/239] Update forms SCSS from upstream --- .../flavours/glitch/styles/forms.scss | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss index 0b12742a98..f978901870 100644 --- a/app/javascript/flavours/glitch/styles/forms.scss +++ b/app/javascript/flavours/glitch/styles/forms.scss @@ -280,6 +280,11 @@ code { .actions { margin-top: 30px; display: flex; + + &.actions--top { + margin-top: 0; + margin-bottom: 30px; + } } button, @@ -563,9 +568,27 @@ code { .post-follow-actions { text-align: center; - color: $ui-primary-color; + color: $darker-text-color; div { margin-bottom: 4px; } } + +.alternative-login { + margin-top: 20px; + margin-bottom: 20px; + + h4 { + font-size: 16px; + color: $primary-text-color; + text-align: center; + margin-bottom: 20px; + border: 0; + padding: 0; + } + + .button { + display: block; + } +} From 944bac0b41b7cec71de391dc561ee8a9b3935704 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:34:23 +0200 Subject: [PATCH 063/239] [Glitch] Adjust RTL styles for landing page Port aef3f2775eca1b1054836cbe94f7dd6492744514 to glitch-soc --- app/javascript/flavours/glitch/styles/rtl.scss | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/app/javascript/flavours/glitch/styles/rtl.scss b/app/javascript/flavours/glitch/styles/rtl.scss index 77420c84b9..e9099a9e97 100644 --- a/app/javascript/flavours/glitch/styles/rtl.scss +++ b/app/javascript/flavours/glitch/styles/rtl.scss @@ -1,6 +1,22 @@ body.rtl { direction: rtl; + .column-header > button { + text-align: right; + padding-left: 0; + padding-right: 15px; + } + + .landing-page__logo { + margin-right: 0; + margin-left: 20px; + } + + .landing-page .features-list .features-list__row .visual { + margin-left: 0; + margin-right: 15px; + } + .column-link__icon, .column-header__icon { margin-right: 0; From fe36fabef1fee0a01262909cf954e0469938f709 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:43:26 +0200 Subject: [PATCH 064/239] Update SCSS for statuses public view --- .../glitch/styles/stream_entries.scss | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/stream_entries.scss b/app/javascript/flavours/glitch/styles/stream_entries.scss index b505c15806..40963ae848 100644 --- a/app/javascript/flavours/glitch/styles/stream_entries.scss +++ b/app/javascript/flavours/glitch/styles/stream_entries.scss @@ -6,7 +6,8 @@ background: $simple-background-color; .detailed-status.light, - .status.light { + .status.light, + .more.light { border-bottom: 1px solid $ui-secondary-color; animation: none; } @@ -65,6 +66,10 @@ } } + .media-gallery__gifv__label { + bottom: 9px; + } + .status.light { padding: 14px 14px 14px (48px + 14px * 2); position: relative; @@ -145,10 +150,10 @@ a.status__content__spoiler-link { color: $primary-text-color; - background: $ui-primary-color; + background: $ui-base-color; &:hover { - background: lighten($ui-primary-color, 8%); + background: lighten($ui-base-color, 8%); } } } @@ -215,10 +220,10 @@ a.status__content__spoiler-link { color: $primary-text-color; - background: $ui-primary-color; + background: $ui-base-color; &:hover { - background: lighten($ui-primary-color, 8%); + background: lighten($ui-base-color, 8%); } } } @@ -261,16 +266,8 @@ } .media-spoiler { - background: $ui-primary-color; - color: $inverted-text-color; - transition: all 100ms linear; - - &:hover, - &:active, - &:focus { - background: darken($ui-primary-color, 5%); - color: unset; - } + background: $ui-base-color; + color: $darker-text-color; } .pre-header { @@ -299,6 +296,17 @@ text-decoration: underline; } } + + .more { + color: $darker-text-color; + display: block; + padding: 14px; + text-align: center; + + &:not(:hover) { + text-decoration: none; + } + } } .embed { From 951dee676db973bdf93e482f023db03e5c681fcd Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:48:19 +0200 Subject: [PATCH 065/239] Update SCSS for tables --- .../flavours/glitch/styles/tables.scss | 116 +++++++++++++++++- 1 file changed, 113 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/styles/tables.scss b/app/javascript/flavours/glitch/styles/tables.scss index c12d84f1c0..fa876e6031 100644 --- a/app/javascript/flavours/glitch/styles/tables.scss +++ b/app/javascript/flavours/glitch/styles/tables.scss @@ -11,6 +11,7 @@ vertical-align: top; border-top: 1px solid $ui-base-color; text-align: left; + background: darken($ui-base-color, 4%); } & > thead > tr > th { @@ -48,9 +49,38 @@ } } - &.inline-table > tbody > tr:nth-child(odd) > td, - &.inline-table > tbody > tr:nth-child(odd) > th { - background: transparent; + &.inline-table { + & > tbody > tr:nth-child(odd) { + & > td, + & > th { + background: transparent; + } + } + + & > tbody > tr:first-child { + & > td, + & > th { + border-top: 0; + } + } + } + + &.batch-table { + & > thead > tr > th { + background: $ui-base-color; + border-top: 1px solid darken($ui-base-color, 8%); + border-bottom: 1px solid darken($ui-base-color, 8%); + + &:first-child { + border-radius: 4px 0 0; + border-left: 1px solid darken($ui-base-color, 8%); + } + + &:last-child { + border-radius: 0 4px 0 0; + border-right: 1px solid darken($ui-base-color, 8%); + } + } } } @@ -63,6 +93,13 @@ samp { font-family: 'mastodon-font-monospace', monospace; } +button.table-action-link { + background: transparent; + border: 0; + font: inherit; +} + +button.table-action-link, a.table-action-link { text-decoration: none; display: inline-block; @@ -79,4 +116,77 @@ a.table-action-link { font-weight: 400; margin-right: 5px; } + + &:first-child { + padding-left: 0; + } +} + +.batch-table { + &__toolbar, + &__row { + display: flex; + + &__select { + box-sizing: border-box; + padding: 8px 16px; + cursor: pointer; + min-height: 100%; + + input { + margin-top: 8px; + } + } + + &__actions, + &__content { + padding: 8px 0; + padding-right: 16px; + flex: 1 1 auto; + } + } + + &__toolbar { + border: 1px solid darken($ui-base-color, 8%); + background: $ui-base-color; + border-radius: 4px 0 0; + height: 47px; + align-items: center; + + &__actions { + text-align: right; + padding-right: 16px - 5px; + } + } + + &__row { + border: 1px solid darken($ui-base-color, 8%); + border-top: 0; + background: darken($ui-base-color, 4%); + + &:hover { + background: darken($ui-base-color, 2%); + } + + &:nth-child(even) { + background: $ui-base-color; + + &:hover { + background: lighten($ui-base-color, 2%); + } + } + + &__content { + padding-top: 12px; + padding-bottom: 16px; + } + } + + .status__content { + padding-top: 0; + + strong { + font-weight: 700; + } + } } From eafdb65af9cf93c1f1d8b6f994ff9cff29c018b3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 16:05:47 +0200 Subject: [PATCH 066/239] [Glitch] Fix contact info styling on landing page --- app/javascript/flavours/glitch/styles/components/accounts.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 5167a507ee..dadfa6d573 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -32,7 +32,8 @@ .account__avatar-wrapper { float: left; - margin: 6px 16px 6px 6px; + margin-left: 12px; + margin-right: 12px; } .account__avatar { From 336d5fecdb219289278a20d2116e9f363ac8df60 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 22:42:32 +0200 Subject: [PATCH 067/239] Fix root modal's keyup handling (Fixes #478) --- app/javascript/flavours/glitch/components/modal_root.js | 3 ++- .../flavours/glitch/features/ui/components/modal_root.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/modal_root.js b/app/javascript/flavours/glitch/components/modal_root.js index 789e117c70..89f81f58ef 100644 --- a/app/javascript/flavours/glitch/components/modal_root.js +++ b/app/javascript/flavours/glitch/components/modal_root.js @@ -6,6 +6,7 @@ export default class ModalRoot extends React.PureComponent { static propTypes = { children: PropTypes.node, onClose: PropTypes.func.isRequired, + noEsc: PropTypes.bool, }; state = { @@ -16,7 +17,7 @@ export default class ModalRoot extends React.PureComponent { handleKeyUp = (e) => { if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27) - && !!this.props.children && !this.props.props.noEsc) { + && !!this.props.children && !this.props.noEsc) { this.props.onClose(); } } diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js index 320c039a4d..cdb6dc9d0a 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js @@ -59,7 +59,7 @@ export default class ModalRoot extends React.PureComponent { const visible = !!type; return ( - + {visible && ( {(SpecificComponent) => } From a846656008843cdf16f8e9ad0eba3da95477309f Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sat, 12 May 2018 19:08:12 +0900 Subject: [PATCH 068/239] Downgrade doorkeeper to version 4.2.6 (#7456) ref https://github.com/doorkeeper-gem/doorkeeper/pull/1060 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 2beac94d2c..5c2f33de43 100644 --- a/Gemfile +++ b/Gemfile @@ -41,7 +41,7 @@ gem 'omniauth-cas', '~> 1.1' gem 'omniauth-saml', '~> 1.10' gem 'omniauth', '~> 1.2' -gem 'doorkeeper', '~> 4.3' +gem 'doorkeeper', '~> 4.2', '< 4.3' gem 'fast_blank', '~> 1.0' gem 'fastimage' gem 'goldfinger', '~> 2.1' diff --git a/Gemfile.lock b/Gemfile.lock index 6a579d53bb..4507cc1468 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -167,7 +167,7 @@ GEM docile (1.3.0) domain_name (0.5.20180417) unf (>= 0.0.5, < 1.0.0) - doorkeeper (4.3.2) + doorkeeper (4.2.6) railties (>= 4.2) dotenv (2.2.2) dotenv-rails (2.2.2) @@ -659,7 +659,7 @@ DEPENDENCIES devise (~> 4.4) devise-two-factor (~> 3.0) devise_pam_authenticatable2 (~> 9.1) - doorkeeper (~> 4.3) + doorkeeper (~> 4.2, < 4.3) dotenv-rails (~> 2.2, < 2.3) fabrication (~> 2.20) faker (~> 1.8) From fa7cdbeb67b291ba27a2c5d6f8e714ed3110bc04 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sat, 12 May 2018 22:30:06 +0900 Subject: [PATCH 069/239] Combine similar components into one on public UI (#7458) --- .../mastodon/containers/cards_container.js | 59 ------------------- ...leries_container.js => media_container.js} | 39 +++++++----- .../mastodon/containers/video_container.js | 26 -------- app/javascript/packs/public.js | 33 +++-------- .../styles/mastodon/containers.scss | 3 +- 5 files changed, 33 insertions(+), 127 deletions(-) delete mode 100644 app/javascript/mastodon/containers/cards_container.js rename app/javascript/mastodon/containers/{media_galleries_container.js => media_container.js} (53%) delete mode 100644 app/javascript/mastodon/containers/video_container.js diff --git a/app/javascript/mastodon/containers/cards_container.js b/app/javascript/mastodon/containers/cards_container.js deleted file mode 100644 index 894bf4ef99..0000000000 --- a/app/javascript/mastodon/containers/cards_container.js +++ /dev/null @@ -1,59 +0,0 @@ -import React, { Fragment } from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from '../locales'; -import Card from '../features/status/components/card'; -import ModalRoot from '../components/modal_root'; -import MediaModal from '../features/ui/components/media_modal'; -import { fromJS } from 'immutable'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -export default class CardsContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string, - cards: PropTypes.object.isRequired, - }; - - state = { - media: null, - }; - - handleOpenCard = (media) => { - document.body.classList.add('card-standalone__body'); - this.setState({ media }); - } - - handleCloseCard = () => { - document.body.classList.remove('card-standalone__body'); - this.setState({ media: null }); - } - - render () { - const { locale, cards } = this.props; - - return ( - - - {[].map.call(cards, container => { - const { card, ...props } = JSON.parse(container.getAttribute('data-props')); - - return ReactDOM.createPortal( - , - container, - ); - })} - - {this.state.media && ( - - )} - - - - ); - } - -} diff --git a/app/javascript/mastodon/containers/media_galleries_container.js b/app/javascript/mastodon/containers/media_container.js similarity index 53% rename from app/javascript/mastodon/containers/media_galleries_container.js rename to app/javascript/mastodon/containers/media_container.js index d77bd688bf..eb2d540cb3 100644 --- a/app/javascript/mastodon/containers/media_galleries_container.js +++ b/app/javascript/mastodon/containers/media_container.js @@ -1,9 +1,11 @@ -import React from 'react'; +import React, { PureComponent, Fragment } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import { IntlProvider, addLocaleData } from 'react-intl'; import { getLocale } from '../locales'; import MediaGallery from '../components/media_gallery'; +import Video from '../features/video'; +import Card from '../features/status/components/card'; import ModalRoot from '../components/modal_root'; import MediaModal from '../features/ui/components/media_modal'; import { fromJS } from 'immutable'; @@ -11,11 +13,13 @@ import { fromJS } from 'immutable'; const { localeData, messages } = getLocale(); addLocaleData(localeData); -export default class MediaGalleriesContainer extends React.PureComponent { +const MEDIA_COMPONENTS = { MediaGallery, Video, Card }; + +export default class MediaContainer extends PureComponent { static propTypes = { locale: PropTypes.string.isRequired, - galleries: PropTypes.object.isRequired, + components: PropTypes.object.isRequired, }; state = { @@ -24,31 +28,34 @@ export default class MediaGalleriesContainer extends React.PureComponent { }; handleOpenMedia = (media, index) => { - document.body.classList.add('media-gallery-standalone__body'); + document.body.classList.add('media-standalone__body'); this.setState({ media, index }); } handleCloseMedia = () => { - document.body.classList.remove('media-gallery-standalone__body'); + document.body.classList.remove('media-standalone__body'); this.setState({ media: null, index: null }); } render () { - const { locale, galleries } = this.props; + const { locale, components } = this.props; return ( - - {[].map.call(galleries, gallery => { - const { media, ...props } = JSON.parse(gallery.getAttribute('data-props')); + + {[].map.call(components, (component, i) => { + const componentName = component.getAttribute('data-component'); + const Component = MEDIA_COMPONENTS[componentName]; + const { media, card, ...props } = JSON.parse(component.getAttribute('data-props')); + + Object.assign(props, { + ...(media ? { media: fromJS(media) } : {}), + ...(card ? { card: fromJS(card) } : {}), + }); return ReactDOM.createPortal( - , - gallery + , + component, ); })} @@ -60,7 +67,7 @@ export default class MediaGalleriesContainer extends React.PureComponent { /> )} - + ); } diff --git a/app/javascript/mastodon/containers/video_container.js b/app/javascript/mastodon/containers/video_container.js deleted file mode 100644 index 2fd353096d..0000000000 --- a/app/javascript/mastodon/containers/video_container.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from '../locales'; -import Video from '../features/video'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -export default class VideoContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string.isRequired, - }; - - render () { - const { locale, ...props } = this.props; - - return ( - - - ); - } - -} diff --git a/app/javascript/packs/public.js b/app/javascript/packs/public.js index 3a1f1a16b4..d5e5b7fe00 100644 --- a/app/javascript/packs/public.js +++ b/app/javascript/packs/public.js @@ -24,7 +24,6 @@ function main() { const emojify = require('../mastodon/features/emoji/emoji').default; const { getLocale } = require('../mastodon/locales'); const { localeData } = getLocale(); - const VideoContainer = require('../mastodon/containers/video_container').default; const React = require('react'); const ReactDOM = require('react-dom'); @@ -69,30 +68,16 @@ function main() { }); }); - [].forEach.call(document.querySelectorAll('[data-component="Video"]'), (content) => { - const props = JSON.parse(content.getAttribute('data-props')); - ReactDOM.render(, content); - }); + const reactComponents = document.querySelectorAll('[data-component]'); + if (reactComponents.length > 0) { + import(/* webpackChunkName: "containers/media_container" */ '../mastodon/containers/media_container') + .then(({ default: MediaContainer }) => { + const content = document.createElement('div'); - const cards = document.querySelectorAll('[data-component="Card"]'); - - if (cards.length > 0) { - import(/* webpackChunkName: "containers/cards_container" */ '../mastodon/containers/cards_container').then(({ default: CardsContainer }) => { - const content = document.createElement('div'); - - ReactDOM.render(, content); - document.body.appendChild(content); - }).catch(error => console.error(error)); - } - - const mediaGalleries = document.querySelectorAll('[data-component="MediaGallery"]'); - - if (mediaGalleries.length > 0) { - const MediaGalleriesContainer = require('../mastodon/containers/media_galleries_container').default; - const content = document.createElement('div'); - - ReactDOM.render(, content); - document.body.appendChild(content); + ReactDOM.render(, content); + document.body.appendChild(content); + }) + .catch(error => console.error(error)); } }); diff --git a/app/javascript/styles/mastodon/containers.scss b/app/javascript/styles/mastodon/containers.scss index c40b38a5a5..ac648c8680 100644 --- a/app/javascript/styles/mastodon/containers.scss +++ b/app/javascript/styles/mastodon/containers.scss @@ -60,8 +60,7 @@ } } -.card-standalone__body, -.media-gallery-standalone__body { +.media-standalone__body { overflow: hidden; } From 74c2a4642395e177a8ffea5ab120dd837a802ff9 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 12 May 2018 16:48:32 +0200 Subject: [PATCH 070/239] Fetch boosted statuses on behalf of a follower (fixes #7426) (#7459) When an ActivityPub Announce is processed and the boosted toot is not known, fetch it on behalf of one of the booster's followers. This is to allow fetching self-boosts of previously-unknown private toots. If fetching on behalf of a user fails, try fetching it anonymously: the selected follower of a boosting user may be banned by the boosted toot's author. --- app/helpers/jsonld_helper.rb | 15 ++++++++++----- app/lib/activitypub/activity/announce.rb | 2 +- .../activitypub/fetch_remote_status_service.rb | 4 ++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/helpers/jsonld_helper.rb b/app/helpers/jsonld_helper.rb index e9056166c1..9d2b6cf00d 100644 --- a/app/helpers/jsonld_helper.rb +++ b/app/helpers/jsonld_helper.rb @@ -52,18 +52,22 @@ module JsonLdHelper graph.dump(:normalize) end - def fetch_resource(uri, id) + def fetch_resource(uri, id, on_behalf_of = nil) unless id - json = fetch_resource_without_id_validation(uri) + json = fetch_resource_without_id_validation(uri, on_behalf_of) return unless json uri = json['id'] end - json = fetch_resource_without_id_validation(uri) + json = fetch_resource_without_id_validation(uri, on_behalf_of) json.present? && json['id'] == uri ? json : nil end - def fetch_resource_without_id_validation(uri) + def fetch_resource_without_id_validation(uri, on_behalf_of = nil) + build_request(uri, on_behalf_of).perform do |response| + return body_to_json(response.body_with_limit) if response.code == 200 + end + # If request failed, retry without doing it on behalf of a user build_request(uri).perform do |response| response.code == 200 ? body_to_json(response.body_with_limit) : nil end @@ -85,8 +89,9 @@ module JsonLdHelper private - def build_request(uri) + def build_request(uri, on_behalf_of = nil) request = Request.new(:get, uri) + request.on_behalf_of(on_behalf_of) if on_behalf_of request.add_headers('Accept' => 'application/activity+json, application/ld+json') request end diff --git a/app/lib/activitypub/activity/announce.rb b/app/lib/activitypub/activity/announce.rb index 7e146ea8c4..f810c88a27 100644 --- a/app/lib/activitypub/activity/announce.rb +++ b/app/lib/activitypub/activity/announce.rb @@ -30,7 +30,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity if object_uri.start_with?('http') return if ActivityPub::TagManager.instance.local_uri?(object_uri) - ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true) + ActivityPub::FetchRemoteStatusService.new.call(object_uri, id: true, on_behalf_of: @account.followers.local.first) elsif @object['url'].present? ::FetchRemoteStatusService.new.call(@object['url']) end diff --git a/app/services/activitypub/fetch_remote_status_service.rb b/app/services/activitypub/fetch_remote_status_service.rb index b6c00a9e7e..2b447abb32 100644 --- a/app/services/activitypub/fetch_remote_status_service.rb +++ b/app/services/activitypub/fetch_remote_status_service.rb @@ -4,9 +4,9 @@ class ActivityPub::FetchRemoteStatusService < BaseService include JsonLdHelper # Should be called when uri has already been checked for locality - def call(uri, id: true, prefetched_body: nil) + def call(uri, id: true, prefetched_body: nil, on_behalf_of: nil) @json = if prefetched_body.nil? - fetch_resource(uri, id) + fetch_resource(uri, id, on_behalf_of) else body_to_json(prefetched_body) end From 4072475241d12a10e7dbab1d634fb37278113c5d Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 12 May 2018 17:44:15 +0200 Subject: [PATCH 071/239] Improvements to toots display in admin view (#7452) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Distinguish boosts from original statuses in the admin panel (fixes #7449) * Show the “show more” button in admin view to make CWs clearer (fixes #7451) * Make content warnings swag --- .../admin/account_moderation_notes_helper.rb | 10 ++++-- app/javascript/styles/mastodon/admin.scss | 33 +++++++++++++------ app/javascript/styles/mastodon/tables.scss | 11 +++++++ app/views/admin/reports/_status.html.haml | 26 ++++++++------- config/locales/en.yml | 1 + 5 files changed, 58 insertions(+), 23 deletions(-) diff --git a/app/helpers/admin/account_moderation_notes_helper.rb b/app/helpers/admin/account_moderation_notes_helper.rb index fdfadef080..49e764cefd 100644 --- a/app/helpers/admin/account_moderation_notes_helper.rb +++ b/app/helpers/admin/account_moderation_notes_helper.rb @@ -10,10 +10,16 @@ module Admin::AccountModerationNotesHelper end end + def admin_account_inline_link_to(account) + link_to admin_account_path(account.id), class: name_tag_classes(account, true) do + content_tag(:span, account.acct, class: 'username') + end + end + private - def name_tag_classes(account) - classes = ['name-tag'] + def name_tag_classes(account, inline = false) + classes = [inline ? 'inline-name-tag' : 'name-tag'] classes << 'suspended' if account.suspended? classes.join(' ') end diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 1948a2a231..560b11ddf4 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -484,19 +484,12 @@ } a.name-tag, -.name-tag { - display: flex; - align-items: center; +.name-tag, +a.inline-name-tag, +.inline-name-tag { text-decoration: none; color: $secondary-text-color; - .avatar { - display: block; - margin: 0; - margin-right: 5px; - border-radius: 50%; - } - .username { font-weight: 500; } @@ -514,6 +507,26 @@ a.name-tag, } } +a.name-tag, +.name-tag { + display: flex; + align-items: center; + + .avatar { + display: block; + margin: 0; + margin-right: 5px; + border-radius: 50%; + } + + &.suspended { + .avatar { + filter: grayscale(100%); + opacity: 0.8; + } + } +} + .speech-bubble { margin-bottom: 20px; border-left: 4px solid $ui-highlight-color; diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index fa876e6031..982bfd9900 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -1,3 +1,9 @@ +@keyframes Swag { + 0% { background-position: 0% 0%; } + 50% { background-position: 100% 0%; } + 100% { background-position: 200% 0%; } +} + .table { width: 100%; max-width: 100%; @@ -187,6 +193,11 @@ a.table-action-link { strong { font-weight: 700; + background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet,orange , yellow, green, cyan, blue, violet); + background-size: 200% 100%; + background-clip: text; + color: transparent; + animation: Swag 2s linear 0s infinite; } } } diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index 9057e6048d..5e174f312e 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -3,26 +3,30 @@ = f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id .batch-table__row__content .status__content>< - - unless status.spoiler_text.blank? + - unless status.proper.spoiler_text.blank? %p>< - %strong= Formatter.instance.format_spoiler(status) + %strong> Content warning: #{Formatter.instance.format_spoiler(status.proper)} - = Formatter.instance.format(status, custom_emojify: true) + = Formatter.instance.format(status.proper, custom_emojify: true) - - unless status.media_attachments.empty? - - if status.media_attachments.first.video? - - video = status.media_attachments.first - = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true + - unless status.proper.media_attachments.empty? + - if status.proper.media_attachments.first.video? + - video = status.proper.media_attachments.first + = react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, width: 610, height: 343, inline: true - else - = react_component :media_gallery, height: 343, sensitive: status.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } + = react_component :media_gallery, height: 343, sensitive: status.proper.sensitive? && !current_account&.user&.setting_display_sensitive_media, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json } .detailed-status__meta = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) · - = fa_visibility_icon(status) - = t("statuses.visibilities.#{status.visibility}") - - if status.sensitive? + - if status.reblog? + = fa_icon('retweet fw') + = t('statuses.boosted_from_html', acct_link: admin_account_inline_link_to(status.proper.account)) + - else + = fa_visibility_icon(status) + = t("statuses.visibilities.#{status.visibility}") + - if status.proper.sensitive? · = fa_icon('eye-slash fw') = t('stream_entries.sensitive_content') diff --git a/config/locales/en.yml b/config/locales/en.yml index 5369311ac5..c074fa5b04 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -682,6 +682,7 @@ en: video: one: "%{count} video" other: "%{count} videos" + boosted_from_html: Boosted from %{acct_link} content_warning: 'Content warning: %{warning}' disallowed_hashtags: one: 'contained a disallowed hashtag: %{tags}' From c39d2279969725963767102dc66f2bf03d3bebd2 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 12 May 2018 17:45:30 +0200 Subject: [PATCH 072/239] Fix glitch-style bio fields incorrect HTML escaping in public profiles --- app/views/accounts/_header.html.haml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index 6522135266..b5653f1614 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -37,8 +37,8 @@ .account__header__fields - processed_bio[:metadata].each do |i| %dl - %dt.emojify{ title: i[0] }= i[0] - %dd.emojify{ title: i[1] }= i[1] + %dt.emojify{ title: i[0] }!= i[0] + %dd.emojify{ title: i[1] }!= i[1] .details-counters .counter{ class: active_nav_class(short_account_url(account)) } From 15a8a75117c4d1e11f7b9c02342a1d06ab60204d Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 13 May 2018 18:32:46 +0900 Subject: [PATCH 073/239] Update http_parser.rb to head version (#7467) --- Gemfile | 1 + Gemfile.lock | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 5c2f33de43..1799c2981c 100644 --- a/Gemfile +++ b/Gemfile @@ -50,6 +50,7 @@ gem 'redis-namespace', '~> 1.5' gem 'htmlentities', '~> 4.3' gem 'http', '~> 3.2' gem 'http_accept_language', '~> 2.1' +gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2' gem 'httplog', '~> 1.0' gem 'idn-ruby', require: 'idn' gem 'kaminari', '~> 1.1' diff --git a/Gemfile.lock b/Gemfile.lock index 4507cc1468..6b7651b773 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,10 @@ +GIT + remote: https://github.com/tmm1/http_parser.rb + revision: 54b17ba8c7d8d20a16dfc65d1775241833219cf2 + ref: 54b17ba8c7d8d20a16dfc65d1775241833219cf2 + specs: + http_parser.rb (0.6.1) + GEM remote: https://rubygems.org/ specs: @@ -252,7 +259,6 @@ GEM domain_name (~> 0.5) http-form_data (2.1.0) http_accept_language (2.1.1) - http_parser.rb (0.6.0) httplog (1.0.2) colorize (~> 0.8) rack (>= 1.0) @@ -675,6 +681,7 @@ DEPENDENCIES htmlentities (~> 4.3) http (~> 3.2) http_accept_language (~> 2.1) + http_parser.rb (~> 0.6)! httplog (~> 1.0) i18n-tasks (~> 0.9) idn-ruby From efc482361b5ffb43589eec50c452c97c92384cae Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sun, 13 May 2018 20:48:14 +0900 Subject: [PATCH 074/239] Open video modal on public UI (#7469) --- app/javascript/mastodon/components/status.js | 4 +-- .../mastodon/containers/media_container.js | 25 +++++++++++++++---- .../status/components/detailed_status.js | 4 +-- .../features/ui/components/media_modal.js | 17 +++++++++++++ .../mastodon/features/video/index.js | 25 +++++++++++++++++-- .../styles/mastodon/components.scss | 4 +++ 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 953d98c20d..fd08ff3b7c 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -84,8 +84,8 @@ export default class Status extends ImmutablePureComponent { return
    ; } - handleOpenVideo = startTime => { - this.props.onOpenVideo(this._properStatus().getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } handleHotkeyReply = e => { diff --git a/app/javascript/mastodon/containers/media_container.js b/app/javascript/mastodon/containers/media_container.js index eb2d540cb3..1700fba05a 100644 --- a/app/javascript/mastodon/containers/media_container.js +++ b/app/javascript/mastodon/containers/media_container.js @@ -8,7 +8,7 @@ import Video from '../features/video'; import Card from '../features/status/components/card'; import ModalRoot from '../components/modal_root'; import MediaModal from '../features/ui/components/media_modal'; -import { fromJS } from 'immutable'; +import { List as ImmutableList, fromJS } from 'immutable'; const { localeData, messages } = getLocale(); addLocaleData(localeData); @@ -25,6 +25,7 @@ export default class MediaContainer extends PureComponent { state = { media: null, index: null, + time: null, }; handleOpenMedia = (media, index) => { @@ -32,9 +33,16 @@ export default class MediaContainer extends PureComponent { this.setState({ media, index }); } + handleOpenVideo = (video, time) => { + const media = ImmutableList([video]); + + document.body.classList.add('media-standalone__body'); + this.setState({ media, time }); + } + handleCloseMedia = () => { document.body.classList.remove('media-standalone__body'); - this.setState({ media: null, index: null }); + this.setState({ media: null, index: null, time: null }); } render () { @@ -51,18 +59,25 @@ export default class MediaContainer extends PureComponent { Object.assign(props, { ...(media ? { media: fromJS(media) } : {}), ...(card ? { card: fromJS(card) } : {}), + + ...(componentName === 'Video' ? { + onOpenVideo: this.handleOpenVideo, + } : { + onOpenMedia: this.handleOpenMedia, + }), }); return ReactDOM.createPortal( - , + , component, ); })} - {this.state.media === null || this.state.index === null ? null : ( + {this.state.media && ( )} diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index b5f5160326..4177190044 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -34,8 +34,8 @@ export default class DetailedStatus extends ImmutablePureComponent { e.stopPropagation(); } - handleOpenVideo = startTime => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } handleExpandedToggle = () => { diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js index fb76270fad..f4d6b5c4e6 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactSwipeableViews from 'react-swipeable-views'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; +import Video from '../../video'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; import classNames from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; @@ -112,6 +113,22 @@ export default class MediaModal extends ImmutablePureComponent { onClick={this.toggleNavigation} /> ); + } else if (image.get('type') === 'video') { + const { time } = this.props; + + return ( +