From c82a2358bd051fb5313abd04de0722e12d4ebc07 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Sun, 4 Mar 2018 01:53:55 +0900 Subject: [PATCH 01/59] Translate Korean (#6608) --- .../mastodon/locales/defaultMessages.json | 29 ++++++++++++++----- app/javascript/mastodon/locales/ko.json | 2 +- config/locales/ko.yml | 21 ++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index bf1b12c6324..52b7ea2cd83 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -315,6 +315,15 @@ ], "path": "app/javascript/mastodon/containers/status_container.json" }, + { + "descriptors": [ + { + "defaultMessage": "Media", + "id": "account.media" + } + ], + "path": "app/javascript/mastodon/features/account_gallery/index.json" + }, { "descriptors": [ { @@ -683,6 +692,14 @@ "defaultMessage": "Search", "id": "search.placeholder" }, + { + "defaultMessage": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", + "id": "search_popout.tips.full_text" + }, + { + "defaultMessage": "Simple text returns matching display names, usernames and hashtags", + "id": "search_popout.tips.text" + }, { "defaultMessage": "Advanced search format", "id": "search_popout.search_format" @@ -698,10 +715,6 @@ { "defaultMessage": "status", "id": "search_popout.tips.status" - }, - { - "defaultMessage": "Simple text returns matching display names, usernames and hashtags", - "id": "search_popout.tips.text" } ], "path": "app/javascript/mastodon/features/compose/components/search.json" @@ -1576,6 +1589,10 @@ }, { "descriptors": [ + { + "defaultMessage": "Close", + "id": "lightbox.close" + }, { "defaultMessage": "Additional comments", "id": "report.placeholder" @@ -1605,10 +1622,6 @@ }, { "descriptors": [ - { - "defaultMessage": "Compose", - "id": "tabs_bar.compose" - }, { "defaultMessage": "Home", "id": "tabs_bar.home" diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 8e7c8268281..feb4ee90eb6 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -216,6 +216,7 @@ "report.target": "문제가 된 사용자", "search.placeholder": "검색", "search_popout.search_format": "고급 검색 방법", + "search_popout.tips.full_text": "단순한 텍스트 검색은 당신이 작성했거나, 관심글로 지정했거나, 부스트했거나, 멘션을 받은 게시글, 그리고 유저네임, 디스플레이네임, 해시태그를 반환합니다.", "search_popout.tips.hashtag": "해시태그", "search_popout.tips.status": "툿", "search_popout.tips.text": "단순한 텍스트 검색은 관계된 프로필 이름, 유저 이름 그리고 해시태그를 표시합니다", @@ -250,7 +251,6 @@ "status.show_more": "더 보기", "status.unmute_conversation": "이 대화의 뮤트 해제하기", "status.unpin": "고정 해제", - "tabs_bar.compose": "포스트", "tabs_bar.federated_timeline": "연합", "tabs_bar.home": "홈", "tabs_bar.local_timeline": "로컬", diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 8bc318d7bc3..4f26d87515a 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -275,6 +275,9 @@ ko: contact_information: email: 공개할 메일 주소를 입력 username: 아이디를 입력 + hero: + desc_html: 프론트페이지에 표시 됩니다. 최소 600x100픽셀을 권장합니다. 만약 설정되지 않았다면, 인스턴스의 썸네일이 사용 됩니다 + title: 히어로 이미지 peers_api_enabled: desc_html: 이 인스턴스가 페디버스에서 만났던 도메인 네임들 title: 발견 된 인스턴스들의 리스트 발행 @@ -291,6 +294,9 @@ ko: open: desc_html: 계정을 생성할 수 있도록 허용합니다 title: 신규 계정 등록을 받음 + show_known_fediverse_at_about_page: + desc_html: 활성화 되면 프리뷰 페이지에서 페디버스의 모든 툿을 표시합니다. 비활성화시 로컬에 있는 툿만 표시 됩니다. + title: 타임라인 프리뷰에 알려진 페디버스 표시하기 show_staff_badge: desc_html: 유저 페이지에 스태프 배지를 표시합니다 title: 스태프 배지 표시 @@ -356,6 +362,7 @@ ko: auth: agreement_html: 이 등록으로 이용규약약관에 동의하는 것으로 간주됩니다. change_password: 보안 + confirm_email: 확인 메일 승인 delete_account: 계정 삭제 delete_account_html: 계정을 삭제하고 싶은 경우, 여기서 삭제할 수 있습니다. 삭제 전 확인 화면이 표시됩니다. didnt_get_confirmation: 확인 메일을 받지 못하셨습니까? @@ -365,6 +372,8 @@ ko: logout: 로그아웃 migrate_account: 계정 옮기기 migrate_account_html: 이 계정을 다른 계정으로 리디렉션 하길 원하는 경우 여기에서 설정할 수 있습니다. + or: 또는 + or_log_in_with: 다른 방법으로 로그인 하려면 register: 등록하기 resend_confirmation: 확인 메일을 다시 보내기 reset_password: 비밀번호 재설정 @@ -414,6 +423,13 @@ ko: title: 이 페이지는 잘못되었습니다 noscript_html: 마스토돈을 사용하기 위해서는 자바스크립트를 켜 주십시오. 아니면 네이티브 앱 중 하나를 사용할 수 있습니다. exports: + archive_takeout: + date: 날짜 + download: 아카이브 다운로드 + hint_html: 당신의 툿과 업로드 된 미디어의 아카이브를 요청할 수 있습니다. 내보내지는 데이터는 ActivityPub 포맷입니다. 호환 되는 모든 소프트웨어에서 읽을 수 있습니다. + in_progress: 당신의 아카이브를 컴파일 중입니다… + request: 아카이브 요청하기 + size: 크기 blocks: 차단 csv: CSV follows: 팔로우 @@ -726,6 +742,10 @@ ko: setup: 초기 설정 wrong_code: 코드가 올바르지 않습니다. 서버와 휴대전화 간의 시간이 일치하는지 확인해 주십시오. user_mailer: + backup_ready: + explanation: 당신이 요청한 계정의 풀 백업이 이제 다운로드 가능합니다. + subject: 당신의 아카이브를 다운로드 가능합니다 + title: 아카이브 테이크 아웃 welcome: edit_profile_action: 프로필 설정 edit_profile_step: 아바타, 헤더를 업로드하고, 사람들에게 표시 될 이름을 바꾸는 것으로 당신의 프로필을 커스텀 할 수 있습니다. 사람들이 당신을 팔로우 하기 전에 리뷰를 거치게 하고 싶다면 계정을 잠그면 됩니다. @@ -747,4 +767,5 @@ ko: users: invalid_email: 메일 주소가 올바르지 않습니다 invalid_otp_token: 2단계 인증 코드가 올바르지 않습니다 + seamless_external_login: 외부 서비스를 이용해 로그인 했습니다, 패스워드와 이메일 설정을 할 수 없습니다. signed_in_as: '다음과 같이 로그인 중:' From 49092945ab86725180e202945ae1bec03a32a634 Mon Sep 17 00:00:00 2001 From: Aboobacker MK Date: Sun, 4 Mar 2018 00:15:06 +0530 Subject: [PATCH 02/59] Fix 500 while searching after deleting a post (#6604) Fixes #6602 --- app/services/search_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/search_service.rb b/app/services/search_service.rb index fe98566866d..00a8b3dd77d 100644 --- a/app/services/search_service.rb +++ b/app/services/search_service.rb @@ -29,7 +29,9 @@ class SearchService < BaseService def perform_statuses_search! statuses = StatusesIndex.filter(term: { searchable_by: account.id }) .query(multi_match: { type: 'most_fields', query: query, operator: 'and', fields: %w(text text.stemmed) }) - .limit(limit).objects + .limit(limit) + .objects + .compact statuses.reject { |status| StatusFilter.new(status, account).filtered? } end From 44829d8216001e3d8183dbd12cacc5a2f4826751 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Mar 2018 07:21:41 +0100 Subject: [PATCH 03/59] Fix missing focalPoint in ActivityPub JSON (#6609) --- .../activitypub/note_serializer.rb | 9 ++++++ spec/lib/activitypub/activity/create_spec.rb | 29 +++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 24c39f3c96d..d0e6290c182 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -90,6 +90,7 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer include RoutingHelper attributes :type, :media_type, :url, :name + attribute :focal_point, if: :focal_point? def type 'Document' @@ -106,6 +107,14 @@ class ActivityPub::NoteSerializer < ActiveModel::Serializer def url object.local? ? full_asset_url(object.file.url(:original, false)) : object.remote_url end + + def focal_point? + object.file.meta.is_a?(Hash) && object.file.meta['focus'].is_a?(Hash) + end + + def focal_point + [object.file.meta['focus']['x'], object.file.meta['focus']['y']] + end end class MentionSerializer < ActiveModel::Serializer diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index 51f54a398ee..62b9db8c24d 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -202,7 +202,7 @@ RSpec.describe ActivityPub::Activity::Create do attachment: [ { type: 'Document', - mime_type: 'image/png', + mediaType: 'image/png', url: 'http://example.com/attachment.png', }, ], @@ -217,6 +217,31 @@ RSpec.describe ActivityPub::Activity::Create do end end + context 'with media attachments with focal points' do + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + attachment: [ + { + type: 'Document', + mediaType: 'image/png', + url: 'http://example.com/attachment.png', + focalPoint: [0.5, -0.7], + }, + ], + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7') + end + end + context 'with media attachments missing url' do let(:object_json) do { @@ -226,7 +251,7 @@ RSpec.describe ActivityPub::Activity::Create do attachment: [ { type: 'Document', - mime_type: 'image/png', + mediaType: 'image/png', }, ], } From 45feb439bd22c0999b8531879461e8d18fabe8a5 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 4 Mar 2018 16:55:15 +0900 Subject: [PATCH 04/59] Finalize location on scrollable notifications when unmounting (#6614) The top of the scrollable notifications will be invisible after unmounting. The Redux state should be updated accordingly in such a case so that the unread notification counter will be updated later. --- app/javascript/mastodon/features/notifications/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index 35b430bfb51..77abfae25ae 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -50,6 +50,13 @@ export default class Notifications extends React.PureComponent { trackScroll: true, }; + componentWillUnmount () { + this.handleScrollToBottom.cancel(); + this.handleScrollToTop.cancel(); + this.handleScroll.cancel(); + this.props.dispatch(scrollTopNotifications(false)); + } + handleScrollToBottom = debounce(() => { this.props.dispatch(scrollTopNotifications(false)); this.props.dispatch(expandNotifications()); From 9110db41c53a2f3f22affc23b364362133997d3e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Mar 2018 09:19:11 +0100 Subject: [PATCH 05/59] Federate pinned statuses over ActivityPub (#6610) * Federate pinned statuses over ActivityPub * Display pinned toots in web UI Fix #6117 * Fix migration * Fix tests * Update outbox_serializer.rb * Update remove_serializer.rb * Update add_serializer.rb * Update fetch_featured_collection_service.rb --- .../activitypub/collections_controller.rb | 57 +++++++++++++++++++ .../activitypub/outboxes_controller.rb | 2 +- .../api/v1/statuses/pins_controller.rb | 28 ++++++++- app/javascript/mastodon/actions/timelines.js | 15 ++--- app/javascript/mastodon/components/status.js | 11 +++- .../mastodon/components/status_list.js | 19 ++++++- .../account_timeline/components/header.js | 15 +++-- .../features/account_timeline/index.js | 15 +++-- .../mastodon/features/followers/index.js | 2 +- .../mastodon/features/following/index.js | 2 +- app/lib/activitypub/activity.rb | 4 ++ app/lib/activitypub/activity/add.rb | 13 +++++ app/lib/activitypub/activity/remove.rb | 14 +++++ app/lib/activitypub/adapter.rb | 1 + app/models/account.rb | 1 + .../activitypub/actor_serializer.rb | 6 +- app/serializers/activitypub/add_serializer.rb | 24 ++++++++ .../activitypub/collection_serializer.rb | 2 +- .../activitypub/outbox_serializer.rb | 8 +++ .../activitypub/remove_serializer.rb | 24 ++++++++ .../fetch_featured_collection_service.rb | 52 +++++++++++++++++ .../activitypub/process_account_service.rb | 22 ++++--- .../synchronize_featured_collection_worker.rb | 13 +++++ config/routes.rb | 2 + ...add_featured_collection_url_to_accounts.rb | 5 ++ db/schema.rb | 3 +- spec/lib/activitypub/activity/add_spec.rb | 29 ++++++++++ spec/lib/activitypub/activity/remove_spec.rb | 30 ++++++++++ spec/lib/activitypub/activity/update_spec.rb | 1 + 29 files changed, 383 insertions(+), 37 deletions(-) create mode 100644 app/controllers/activitypub/collections_controller.rb create mode 100644 app/lib/activitypub/activity/add.rb create mode 100644 app/lib/activitypub/activity/remove.rb create mode 100644 app/serializers/activitypub/add_serializer.rb create mode 100644 app/serializers/activitypub/outbox_serializer.rb create mode 100644 app/serializers/activitypub/remove_serializer.rb create mode 100644 app/services/activitypub/fetch_featured_collection_service.rb create mode 100644 app/workers/activitypub/synchronize_featured_collection_worker.rb create mode 100644 db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb create mode 100644 spec/lib/activitypub/activity/add_spec.rb create mode 100644 spec/lib/activitypub/activity/remove_spec.rb diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb new file mode 100644 index 00000000000..081914016e4 --- /dev/null +++ b/app/controllers/activitypub/collections_controller.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +class ActivityPub::CollectionsController < Api::BaseController + include SignatureVerification + + before_action :set_account + before_action :set_size + before_action :set_statuses + + def show + render json: collection_presenter, + serializer: ActivityPub::CollectionSerializer, + adapter: ActivityPub::Adapter, + content_type: 'application/activity+json', + skip_activities: true + end + + private + + def set_account + @account = Account.find_local!(params[:account_username]) + end + + def set_statuses + @statuses = scope_for_collection.paginate_by_max_id(20, params[:max_id], params[:since_id]) + @statuses = cache_collection(@statuses, Status) + end + + def set_size + case params[:id] + when 'featured' + @account.pinned_statuses.count + else + raise ActiveRecord::NotFound + end + end + + def scope_for_collection + case params[:id] + when 'featured' + @account.statuses.permitted_for(@account, signed_request_account).tap do |scope| + scope.merge!(@account.pinned_statuses) + end + else + raise ActiveRecord::NotFound + end + end + + def collection_presenter + ActivityPub::CollectionPresenter.new( + id: account_collection_url(@account, params[:id]), + type: :ordered, + size: @size, + items: @statuses + ) + end +end diff --git a/app/controllers/activitypub/outboxes_controller.rb b/app/controllers/activitypub/outboxes_controller.rb index a431e355783..9ed700c1e23 100644 --- a/app/controllers/activitypub/outboxes_controller.rb +++ b/app/controllers/activitypub/outboxes_controller.rb @@ -9,7 +9,7 @@ class ActivityPub::OutboxesController < Api::BaseController @statuses = @account.statuses.permitted_for(@account, signed_request_account).paginate_by_max_id(20, params[:max_id], params[:since_id]) @statuses = cache_collection(@statuses, Status) - render json: outbox_presenter, serializer: ActivityPub::CollectionSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json' + render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json' end private diff --git a/app/controllers/api/v1/statuses/pins_controller.rb b/app/controllers/api/v1/statuses/pins_controller.rb index 3de1009b842..bba6a6f4802 100644 --- a/app/controllers/api/v1/statuses/pins_controller.rb +++ b/app/controllers/api/v1/statuses/pins_controller.rb @@ -11,12 +11,18 @@ class Api::V1::Statuses::PinsController < Api::BaseController def create StatusPin.create!(account: current_account, status: @status) + distribute_add_activity! render json: @status, serializer: REST::StatusSerializer end def destroy pin = StatusPin.find_by(account: current_account, status: @status) - pin&.destroy! + + if pin + pin.destroy! + distribute_remove_activity! + end + render json: @status, serializer: REST::StatusSerializer end @@ -25,4 +31,24 @@ class Api::V1::Statuses::PinsController < Api::BaseController def set_status @status = Status.find(params[:status_id]) end + + def distribute_add_activity! + json = ActiveModelSerializers::SerializableResource.new( + @status, + serializer: ActivityPub::AddSerializer, + adapter: ActivityPub::Adapter + ).as_json + + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account) + end + + def distribute_remove_activity! + json = ActiveModelSerializers::SerializableResource.new( + @status, + serializer: ActivityPub::RemoveSerializer, + adapter: ActivityPub::Adapter + ).as_json + + ActivityPub::RawDistributionWorker.perform_async(Oj.dump(json), current_account) + end end diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js index 858a12b1529..f0ab16a2d76 100644 --- a/app/javascript/mastodon/actions/timelines.js +++ b/app/javascript/mastodon/actions/timelines.js @@ -117,13 +117,14 @@ export function refreshTimeline(timelineId, path, params = {}) { }; }; -export const refreshHomeTimeline = () => refreshTimeline('home', '/api/v1/timelines/home'); -export const refreshPublicTimeline = () => refreshTimeline('public', '/api/v1/timelines/public'); -export const refreshCommunityTimeline = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true }); -export const refreshAccountTimeline = (accountId, withReplies) => refreshTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies }); -export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true }); -export const refreshHashtagTimeline = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`); -export const refreshListTimeline = id => refreshTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`); +export const refreshHomeTimeline = () => refreshTimeline('home', '/api/v1/timelines/home'); +export const refreshPublicTimeline = () => refreshTimeline('public', '/api/v1/timelines/public'); +export const refreshCommunityTimeline = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true }); +export const refreshAccountTimeline = (accountId, withReplies) => refreshTimeline(`account:${accountId}${withReplies ? ':with_replies' : ''}`, `/api/v1/accounts/${accountId}/statuses`, { exclude_replies: !withReplies }); +export const refreshAccountFeaturedTimeline = accountId => refreshTimeline(`account:${accountId}:pinned`, `/api/v1/accounts/${accountId}/statuses`, { pinned: true }); +export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true }); +export const refreshHashtagTimeline = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`); +export const refreshListTimeline = id => refreshTimeline(`list:${id}`, `/api/v1/timelines/list/${id}`); export function refreshTimelineFail(timeline, error, skipLoading) { return { diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index c52cd5f0908..85baeffca7d 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -138,7 +138,7 @@ export default class Status extends ImmutablePureComponent { let media = null; let statusAvatar, prepend; - const { hidden } = this.props; + const { hidden, featured } = this.props; const { isExpanded } = this.state; let { status, account, ...other } = this.props; @@ -156,7 +156,14 @@ export default class Status extends ImmutablePureComponent { ); } - if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') { + if (featured) { + prepend = ( +
+
+ +
+ ); + } else if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') { const display_name_html = { __html: status.getIn(['account', 'display_name_html']) }; prepend = ( diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js index 5acaf714ec6..eb65838cea2 100644 --- a/app/javascript/mastodon/components/status_list.js +++ b/app/javascript/mastodon/components/status_list.js @@ -11,6 +11,7 @@ export default class StatusList extends ImmutablePureComponent { static propTypes = { scrollKey: PropTypes.string.isRequired, statusIds: ImmutablePropTypes.list.isRequired, + featuredStatusIds: ImmutablePropTypes.list, onScrollToBottom: PropTypes.func, onScrollToTop: PropTypes.func, onScroll: PropTypes.func, @@ -50,7 +51,7 @@ export default class StatusList extends ImmutablePureComponent { } render () { - const { statusIds, ...other } = this.props; + const { statusIds, featuredStatusIds, ...other } = this.props; const { isLoading, isPartial } = other; if (isPartial) { @@ -68,8 +69,8 @@ export default class StatusList extends ImmutablePureComponent { ); } - const scrollableContent = (isLoading || statusIds.size > 0) ? ( - statusIds.map((statusId) => ( + let scrollableContent = (isLoading || statusIds.size > 0) ? ( + statusIds.map(statusId => ( ( + + )).concat(scrollableContent); + } + return ( {scrollableContent} diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index 5cd4af1d361..b143e1d366a 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -21,6 +21,7 @@ export default class Header extends ImmutablePureComponent { onMute: PropTypes.func.isRequired, onBlockDomain: PropTypes.func.isRequired, onUnblockDomain: PropTypes.func.isRequired, + hideTabs: PropTypes.bool, }; static contextTypes = { @@ -68,7 +69,7 @@ export default class Header extends ImmutablePureComponent { } render () { - const { account } = this.props; + const { account, hideTabs } = this.props; if (account === null) { return ; @@ -94,11 +95,13 @@ export default class Header extends ImmutablePureComponent { onUnblockDomain={this.handleUnblockDomain} /> -
- - - -
+ {!hideTabs && ( +
+ + + +
+ )} ); } diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js index aed009ef08b..95ae5fd0689 100644 --- a/app/javascript/mastodon/features/account_timeline/index.js +++ b/app/javascript/mastodon/features/account_timeline/index.js @@ -3,7 +3,7 @@ import { connect } from 'react-redux'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { fetchAccount } from '../../actions/accounts'; -import { refreshAccountTimeline, expandAccountTimeline } from '../../actions/timelines'; +import { refreshAccountTimeline, refreshAccountFeaturedTimeline, expandAccountTimeline } from '../../actions/timelines'; import StatusList from '../../components/status_list'; import LoadingIndicator from '../../components/loading_indicator'; import Column from '../ui/components/column'; @@ -17,6 +17,7 @@ const mapStateToProps = (state, { params: { accountId }, withReplies = false }) return { statusIds: state.getIn(['timelines', `account:${path}`, 'items'], ImmutableList()), + featuredStatusIds: state.getIn(['timelines', `account:${accountId}:pinned`, 'items'], ImmutableList()), isLoading: state.getIn(['timelines', `account:${path}`, 'isLoading']), hasMore: !!state.getIn(['timelines', `account:${path}`, 'next']), }; @@ -29,19 +30,24 @@ export default class AccountTimeline extends ImmutablePureComponent { params: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, statusIds: ImmutablePropTypes.list, + featuredStatusIds: ImmutablePropTypes.list, isLoading: PropTypes.bool, hasMore: PropTypes.bool, withReplies: PropTypes.bool, }; componentWillMount () { - this.props.dispatch(fetchAccount(this.props.params.accountId)); - this.props.dispatch(refreshAccountTimeline(this.props.params.accountId, this.props.withReplies)); + const { params: { accountId }, withReplies } = this.props; + + this.props.dispatch(fetchAccount(accountId)); + this.props.dispatch(refreshAccountFeaturedTimeline(accountId)); + this.props.dispatch(refreshAccountTimeline(accountId, withReplies)); } componentWillReceiveProps (nextProps) { if ((nextProps.params.accountId !== this.props.params.accountId && nextProps.params.accountId) || nextProps.withReplies !== this.props.withReplies) { this.props.dispatch(fetchAccount(nextProps.params.accountId)); + this.props.dispatch(refreshAccountFeaturedTimeline(nextProps.params.accountId)); this.props.dispatch(refreshAccountTimeline(nextProps.params.accountId, nextProps.params.withReplies)); } } @@ -53,7 +59,7 @@ export default class AccountTimeline extends ImmutablePureComponent { } render () { - const { statusIds, isLoading, hasMore } = this.props; + const { statusIds, featuredStatusIds, isLoading, hasMore } = this.props; if (!statusIds && isLoading) { return ( @@ -71,6 +77,7 @@ export default class AccountTimeline extends ImmutablePureComponent { prepend={} scrollKey='account_timeline' statusIds={statusIds} + featuredStatusIds={featuredStatusIds} isLoading={isLoading} hasMore={hasMore} onScrollToBottom={this.handleScrollToBottom} diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js index f64ed794837..919a89332b1 100644 --- a/app/javascript/mastodon/features/followers/index.js +++ b/app/javascript/mastodon/features/followers/index.js @@ -80,7 +80,7 @@ export default class Followers extends ImmutablePureComponent {
- + {accountIds.map(id => )} {loadMore}
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js index a0c0fac0512..5719259d111 100644 --- a/app/javascript/mastodon/features/following/index.js +++ b/app/javascript/mastodon/features/following/index.js @@ -80,7 +80,7 @@ export default class Following extends ImmutablePureComponent {
- + {accountIds.map(id => )} {loadMore}
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index 6f4a3b4911a..9b00f0f522e 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -46,6 +46,10 @@ class ActivityPub::Activity ActivityPub::Activity::Reject when 'Flag' ActivityPub::Activity::Flag + when 'Add' + ActivityPub::Activity::Add + when 'Remove' + ActivityPub::Activity::Remove end end end diff --git a/app/lib/activitypub/activity/add.rb b/app/lib/activitypub/activity/add.rb new file mode 100644 index 00000000000..ea94d2f983b --- /dev/null +++ b/app/lib/activitypub/activity/add.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Add < ActivityPub::Activity + def perform + return unless @json['target'].present? && value_or_id(@json['target']) == @account.featured_collection_url + + status = status_from_uri(object_uri) + + return unless status.account_id == @account.id && !@account.pinned?(status) + + StatusPin.create!(account: @account, status: status) + end +end diff --git a/app/lib/activitypub/activity/remove.rb b/app/lib/activitypub/activity/remove.rb new file mode 100644 index 00000000000..97cee511687 --- /dev/null +++ b/app/lib/activitypub/activity/remove.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class ActivityPub::Activity::Remove < ActivityPub::Activity + def perform + return unless @json['origin'].present? && value_or_id(@json['origin']) == @account.featured_collection_url + + status = status_from_uri(object_uri) + + return unless status.account_id == @account.id + + pin = StatusPin.find_by(account: @account, status: status) + pin&.destroy! + end +end diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 8198ac58019..f19b04ae642 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -18,6 +18,7 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base 'toot' => 'http://joinmastodon.org/ns#', 'Emoji' => 'toot:Emoji', 'focalPoint' => { '@container' => '@list', '@id' => 'toot:focalPoint' }, + 'featured' => 'toot:featured', }, ], }.freeze diff --git a/app/models/account.rb b/app/models/account.rb index 13692d0d7dd..c1347fe651a 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -43,6 +43,7 @@ # protocol :integer default("ostatus"), not null # memorial :boolean default(FALSE), not null # moved_to_account_id :integer +# featured_collection_url :string # class Account < ApplicationRecord diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 622bdde0c40..afcd3777119 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -4,7 +4,7 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer include RoutingHelper attributes :id, :type, :following, :followers, - :inbox, :outbox, + :inbox, :outbox, :featured, :preferred_username, :name, :summary, :url, :manually_approves_followers @@ -53,6 +53,10 @@ class ActivityPub::ActorSerializer < ActiveModel::Serializer account_outbox_url(object) end + def featured + account_collection_url(object, :featured) + end + def endpoints object end diff --git a/app/serializers/activitypub/add_serializer.rb b/app/serializers/activitypub/add_serializer.rb new file mode 100644 index 00000000000..a5f091e3792 --- /dev/null +++ b/app/serializers/activitypub/add_serializer.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class ActivityPub::AddSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :type, :actor, :target + attribute :proper_object, key: :object + + def type + 'Add' + end + + def actor + ActivityPub::TagManager.instance.uri_for(object.account) + end + + def proper_object + ActivityPub::TagManager.instance.uri_for(object) + end + + def target + account_collection_url(object, :featured) + end +end diff --git a/app/serializers/activitypub/collection_serializer.rb b/app/serializers/activitypub/collection_serializer.rb index d43af3f8e39..1ae49294576 100644 --- a/app/serializers/activitypub/collection_serializer.rb +++ b/app/serializers/activitypub/collection_serializer.rb @@ -2,7 +2,7 @@ class ActivityPub::CollectionSerializer < ActiveModel::Serializer def self.serializer_for(model, options) - return ActivityPub::ActivitySerializer if model.class.name == 'Status' + return ActivityPub::NoteSerializer if model.class.name == 'Status' return ActivityPub::CollectionSerializer if model.class.name == 'ActivityPub::CollectionPresenter' super end diff --git a/app/serializers/activitypub/outbox_serializer.rb b/app/serializers/activitypub/outbox_serializer.rb new file mode 100644 index 00000000000..48fbad0fde5 --- /dev/null +++ b/app/serializers/activitypub/outbox_serializer.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer + def self.serializer_for(model, options) + return ActivityPub::ActivitySerializer if model.is_a?(Status) + super + end +end diff --git a/app/serializers/activitypub/remove_serializer.rb b/app/serializers/activitypub/remove_serializer.rb new file mode 100644 index 00000000000..6da7e35d3d2 --- /dev/null +++ b/app/serializers/activitypub/remove_serializer.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class ActivityPub::RemoveSerializer < ActiveModel::Serializer + include RoutingHelper + + attributes :type, :actor, :origin + attribute :proper_object, key: :object + + def type + 'Remove' + end + + def actor + ActivityPub::TagManager.instance.uri_for(object.account) + end + + def proper_object + ActivityPub::TagManager.instance.uri_for(object) + end + + def origin + account_collection_url(object, :featured) + end +end diff --git a/app/services/activitypub/fetch_featured_collection_service.rb b/app/services/activitypub/fetch_featured_collection_service.rb new file mode 100644 index 00000000000..40714e98012 --- /dev/null +++ b/app/services/activitypub/fetch_featured_collection_service.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +class ActivityPub::FetchFeaturedCollectionService < BaseService + include JsonLdHelper + + def call(account) + @account = account + @json = fetch_resource(@account.featured_collection_url, true) + + return unless supported_context? + return if @account.suspended? || @account.local? + + case @json['type'] + when 'Collection', 'CollectionPage' + process_items @json['items'] + when 'OrderedCollection', 'OrderedCollectionPage' + process_items @json['orderedItems'] + end + end + + private + + def process_items(items) + status_ids = items.map { |item| value_or_id(item) } + .reject { |uri| ActivityPub::TagManager.instance.local_uri?(uri) } + .map { |uri| ActivityPub::FetchRemoteStatusService.new.call(uri) } + .compact + .select { |status| status.account_id == @account.id } + .map(&:id) + + to_remove = [] + to_add = status_ids + + StatusPin.where(account: @account).pluck(:status_id).each do |status_id| + if status_ids.include?(status_id) + to_add.delete(status_id) + else + to_remove << status_id + end + end + + StatusPin.where(account: @account, status_id: to_remove).delete_all unless to_remove.empty? + + to_add.each do |status_id| + StatusPin.create!(account: @account, status_id: status_id) + end + end + + def supported_context? + super(@json) + end +end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index f43edafe7b3..68e9db766c4 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -27,6 +27,7 @@ class ActivityPub::ProcessAccountService < BaseService after_protocol_change! if protocol_changed? after_key_change! if key_changed? + check_featured_collection! if @account.featured_collection_url.present? @account rescue Oj::ParseError @@ -57,14 +58,15 @@ class ActivityPub::ProcessAccountService < BaseService end def set_immediate_attributes! - @account.inbox_url = @json['inbox'] || '' - @account.outbox_url = @json['outbox'] || '' - @account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || '' - @account.followers_url = @json['followers'] || '' - @account.url = url || @uri - @account.display_name = @json['name'] || '' - @account.note = @json['summary'] || '' - @account.locked = @json['manuallyApprovesFollowers'] || false + @account.inbox_url = @json['inbox'] || '' + @account.outbox_url = @json['outbox'] || '' + @account.shared_inbox_url = (@json['endpoints'].is_a?(Hash) ? @json['endpoints']['sharedInbox'] : @json['sharedInbox']) || '' + @account.followers_url = @json['followers'] || '' + @account.featured_collection_url = @json['featured'] || '' + @account.url = url || @uri + @account.display_name = @json['name'] || '' + @account.note = @json['summary'] || '' + @account.locked = @json['manuallyApprovesFollowers'] || false end def set_fetchable_attributes! @@ -85,6 +87,10 @@ class ActivityPub::ProcessAccountService < BaseService RefollowWorker.perform_async(@account.id) end + def check_featured_collection! + ActivityPub::SynchronizeFeaturedCollectionWorker.perform_async(@account.id) + end + def image_url(key) value = first_of_value(@json[key]) diff --git a/app/workers/activitypub/synchronize_featured_collection_worker.rb b/app/workers/activitypub/synchronize_featured_collection_worker.rb new file mode 100644 index 00000000000..dd676a3ee11 --- /dev/null +++ b/app/workers/activitypub/synchronize_featured_collection_worker.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class ActivityPub::SynchronizeFeaturedCollectionWorker + include Sidekiq::Worker + + sidekiq_options queue: 'pull' + + def perform(account_id) + ActivityPub::FetchFeaturedCollectionService.new.call(Account.find(account_id)) + rescue ActiveRecord::RecordNotFound + true + end +end diff --git a/config/routes.rb b/config/routes.rb index 7ed2d61f1bf..0542cb68016 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -58,8 +58,10 @@ Rails.application.routes.draw do resources :following, only: [:index], controller: :following_accounts resource :follow, only: [:create], controller: :account_follow resource :unfollow, only: [:create], controller: :account_unfollow + resource :outbox, only: [:show], module: :activitypub resource :inbox, only: [:create], module: :activitypub + resources :collections, only: [:show], module: :activitypub end resource :inbox, only: [:create], module: :activitypub diff --git a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb new file mode 100644 index 00000000000..e0b8ed5cc19 --- /dev/null +++ b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb @@ -0,0 +1,5 @@ +class AddFeaturedCollectionUrlToAccounts < ActiveRecord::Migration[5.1] + def change + add_column :accounts, :featured_collection_url, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index c6b81df34ed..c52a6f0d4ba 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: 20180211015820) do +ActiveRecord::Schema.define(version: 20180304013859) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -73,6 +73,7 @@ ActiveRecord::Schema.define(version: 20180211015820) do t.integer "protocol", default: 0, null: false t.boolean "memorial", default: false, null: false t.bigint "moved_to_account_id" + t.string "featured_collection_url" 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" diff --git a/spec/lib/activitypub/activity/add_spec.rb b/spec/lib/activitypub/activity/add_spec.rb new file mode 100644 index 00000000000..3ebab4e3730 --- /dev/null +++ b/spec/lib/activitypub/activity/add_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +RSpec.describe ActivityPub::Activity::Add do + let(:sender) { Fabricate(:account, featured_collection_url: 'https://example.com/featured') } + let(:status) { Fabricate(:status, account: sender) } + + let(:json) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'foo', + type: 'Add', + actor: ActivityPub::TagManager.instance.uri_for(sender), + object: ActivityPub::TagManager.instance.uri_for(status), + target: sender.featured_collection_url, + }.with_indifferent_access + end + + describe '#perform' do + subject { described_class.new(json, sender) } + + before do + subject.perform + end + + it 'creates a pin' do + expect(sender.pinned?(status)).to be true + end + end +end diff --git a/spec/lib/activitypub/activity/remove_spec.rb b/spec/lib/activitypub/activity/remove_spec.rb new file mode 100644 index 00000000000..c3f015053d1 --- /dev/null +++ b/spec/lib/activitypub/activity/remove_spec.rb @@ -0,0 +1,30 @@ +require 'rails_helper' + +RSpec.describe ActivityPub::Activity::Remove do + let(:sender) { Fabricate(:account, featured_collection_url: 'https://example.com/featured') } + let(:status) { Fabricate(:status, account: sender) } + + let(:json) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'foo', + type: 'Add', + actor: ActivityPub::TagManager.instance.uri_for(sender), + object: ActivityPub::TagManager.instance.uri_for(status), + origin: sender.featured_collection_url, + }.with_indifferent_access + end + + describe '#perform' do + subject { described_class.new(json, sender) } + + before do + StatusPin.create!(account: sender, status: status) + subject.perform + end + + it 'removes a pin' do + expect(sender.pinned?(status)).to be false + end + end +end diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index ea308e35cd5..fbfc585cf97 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -7,6 +7,7 @@ RSpec.describe ActivityPub::Activity::Update do stub_request(:get, actor_json[:outbox]).to_return(status: 404) stub_request(:get, actor_json[:followers]).to_return(status: 404) stub_request(:get, actor_json[:following]).to_return(status: 404) + stub_request(:get, actor_json[:featured]).to_return(status: 404) sender.update!(uri: ActivityPub::TagManager.instance.uri_for(sender)) end From 51d760960ccf0866eba32944434ba08b2cbe5092 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 4 Mar 2018 17:21:35 +0900 Subject: [PATCH 06/59] Set the default locale in config (#6580) Previously the default locale was set by Localized concern for controllers, but it was not enforced for mailers. config is enforced throughout the application and an appropriate place to set the default locale. --- app/controllers/concerns/localized.rb | 12 ++--- config/application.rb | 9 +++- config/environments/test.rb | 3 ++ spec/controllers/concerns/localized_spec.rb | 55 ++++++--------------- 4 files changed, 28 insertions(+), 51 deletions(-) diff --git a/app/controllers/concerns/localized.rb b/app/controllers/concerns/localized.rb index a9ea60f7dc6..e697284a8c7 100644 --- a/app/controllers/concerns/localized.rb +++ b/app/controllers/concerns/localized.rb @@ -17,11 +17,7 @@ module Localized end def default_locale - request_locale || env_locale || I18n.default_locale - end - - def env_locale - ENV['DEFAULT_LOCALE'] + request_locale || I18n.default_locale end def request_locale @@ -29,12 +25,10 @@ module Localized end def preferred_locale - http_accept_language.preferred_language_from([env_locale]) || - http_accept_language.preferred_language_from(I18n.available_locales) + http_accept_language.preferred_language_from(I18n.available_locales) end def compatible_locale - http_accept_language.compatible_language_from([env_locale]) || - http_accept_language.compatible_language_from(I18n.available_locales) + http_accept_language.compatible_language_from(I18n.available_locales) end end diff --git a/config/application.rb b/config/application.rb index 34b9dcf48ee..097cbf56778 100644 --- a/config/application.rb +++ b/config/application.rb @@ -31,7 +31,7 @@ module Mastodon # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. # config.time_zone = 'Central Time (US & Canada)' - # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # All translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] config.i18n.available_locales = [ :en, @@ -73,7 +73,12 @@ module Mastodon :'zh-TW', ] - config.i18n.default_locale = :en + config.i18n.default_locale = ENV['DEFAULT_LOCALE']&.to_sym + if config.i18n.available_locales.include?(config.i18n.default_locale) + config.i18n.fallbacks = [:en] + else + config.i18n.default_locale = :en + end # config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb') # config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')] diff --git a/config/environments/test.rb b/config/environments/test.rb index 20fe5f81384..74e7fa694e4 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -51,6 +51,9 @@ Rails.application.configure do # Raises error for missing translations # config.action_view.raise_on_missing_translations = true + + config.i18n.default_locale = :en + config.i18n.fallbacks = true end Paperclip::Attachment.default_options[:path] = "#{Rails.root}/spec/test_files/:class/:id_partition/:style.:extension" diff --git a/spec/controllers/concerns/localized_spec.rb b/spec/controllers/concerns/localized_spec.rb index c917ce85e7d..f71c96aff95 100644 --- a/spec/controllers/concerns/localized_spec.rb +++ b/spec/controllers/concerns/localized_spec.rb @@ -16,49 +16,24 @@ describe ApplicationController, type: :controller do end shared_examples 'default locale' do - context 'when DEFAULT_LOCALE environment variable is set' do - around do |example| - ClimateControl.modify 'DEFAULT_LOCALE' => 'ca', &example.method(:run) - I18n.locale = I18n.default_locale - end + after { I18n.locale = I18n.default_locale } - it 'sets language specified by ENV if preferred' do - request.headers['Accept-Language'] = 'ca, fa' - get 'success' - expect(I18n.locale).to eq :ca - end - - it 'sets available and preferred language if language specified by ENV is not preferred' do - request.headers['Accept-Language'] = 'ca-ES, fa' - get 'success' - expect(I18n.locale).to eq :fa - end - - it 'sets language specified by ENV if it is compatible and none of available languages are preferred' do - request.headers['Accept-Language'] = 'ca-ES, fa-IR' - get 'success' - expect(I18n.locale).to eq :ca - end - - it 'sets available and compatible langauge if language specified by ENV is not compatible none of available languages are preferred' do - request.headers['Accept-Language'] = 'fa-IR' - get 'success' - expect(I18n.locale).to eq :fa - end - - it 'sets language specified by ENV if none of available languages are compatible' do - request.headers['Accept-Language'] = '' - get 'success' - expect(I18n.locale).to eq :ca - end + it 'sets available and preferred language' do + request.headers['Accept-Language'] = 'ca-ES, fa' + get 'success' + expect(I18n.locale).to eq :fa end - context 'when DEFAULT_LOCALE environment variable is not set' do - it 'sets default locale if none of available languages are compatible' do - request.headers['Accept-Language'] = '' - get 'success' - expect(I18n.locale).to eq :en - end + it 'sets available and compatible langauge if none of available languages are preferred' do + request.headers['Accept-Language'] = 'fa-IR' + get 'success' + expect(I18n.locale).to eq :fa + end + + it 'sets default locale if none of available languages are compatible' do + request.headers['Accept-Language'] = '' + get 'success' + expect(I18n.locale).to eq :en end end From b66ec3bf95fdb0c38d8472a4bd643ed81bc46100 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 4 Mar 2018 10:00:24 +0100 Subject: [PATCH 07/59] Fix #6611: Typo in change password template (#6616) --- app/views/auth/passwords/edit.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/auth/passwords/edit.html.haml b/app/views/auth/passwords/edit.html.haml index 12880c22771..53d1769d623 100644 --- a/app/views/auth/passwords/edit.html.haml +++ b/app/views/auth/passwords/edit.html.haml @@ -4,7 +4,7 @@ = simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| = render 'shared/error_messages', object: resource - - if !use_seamless_external_login?? || resource.encrypted_password.present? + - if !use_seamless_external_login? || resource.encrypted_password.present? = f.input :reset_password_token, as: :hidden = f.input :password, autofocus: true, placeholder: t('simple_form.labels.defaults.new_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.new_password'), :autocomplete => 'off' } From 778b37790b425debd16b73c21f0805ff2e9a4ce8 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Sun, 4 Mar 2018 18:00:46 +0900 Subject: [PATCH 08/59] Do not fetch environment variables to determine default locale (#6618) The default locale is now set by config. --- app/serializers/rest/instance_serializer.rb | 2 +- lib/tasks/assets.rake | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/serializers/rest/instance_serializer.rb b/app/serializers/rest/instance_serializer.rb index e903604b269..e3e64ea8767 100644 --- a/app/serializers/rest/instance_serializer.rb +++ b/app/serializers/rest/instance_serializer.rb @@ -48,7 +48,7 @@ class REST::InstanceSerializer < ActiveModel::Serializer end def languages - [ENV.fetch('DEFAULT_LOCALE', I18n.default_locale)] + [I18n.default_locale] end private diff --git a/lib/tasks/assets.rake b/lib/tasks/assets.rake index 0826f018641..b642510a162 100644 --- a/lib/tasks/assets.rake +++ b/lib/tasks/assets.rake @@ -1,10 +1,8 @@ # frozen_string_literal: true def render_static_page(action, dest:, **opts) - I18n.with_locale(ENV['DEFAULT_LOCALE'] || I18n.default_locale) do - html = ApplicationController.render(action, opts) - File.write(dest, html) - end + html = ApplicationController.render(action, opts) + File.write(dest, html) end namespace :assets do From 460e380d386367b6809d319859e13d17a6a2acea Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 5 Mar 2018 04:27:25 +0900 Subject: [PATCH 09/59] Implement tag auto-completion by history (#6621) This is a functionality similar to one implemented in Pawoo: https://github.com/pixiv/mastodon/commit/21a3c70f8083b1347d2b8420ed7001b78c2c9620 --- app/javascript/mastodon/actions/compose.js | 64 ++++++++++++++++++- app/javascript/mastodon/actions/store.js | 13 ++-- .../components/autosuggest_textarea.js | 5 +- app/javascript/mastodon/reducers/compose.js | 19 ++++++ app/javascript/mastodon/settings.js | 1 + 5 files changed, 95 insertions(+), 7 deletions(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 1732ff189ed..0fe4800227c 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -1,6 +1,7 @@ import api from '../api'; import { throttle } from 'lodash'; import { search as emojiSearch } from '../features/emoji/emoji_mart_search_light'; +import { tagHistory } from '../settings'; import { useEmoji } from './emojis'; import { @@ -27,6 +28,9 @@ export const COMPOSE_UPLOAD_UNDO = 'COMPOSE_UPLOAD_UNDO'; export const COMPOSE_SUGGESTIONS_CLEAR = 'COMPOSE_SUGGESTIONS_CLEAR'; export const COMPOSE_SUGGESTIONS_READY = 'COMPOSE_SUGGESTIONS_READY'; export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT'; +export const COMPOSE_SUGGESTION_TAGS_UPDATE = 'COMPOSE_SUGGESTION_TAGS_UPDATE'; + +export const COMPOSE_TAG_HISTORY_UPDATE = 'COMPOSE_TAG_HISTORY_UPDATE'; export const COMPOSE_MOUNT = 'COMPOSE_MOUNT'; export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT'; @@ -111,6 +115,7 @@ export function submitCompose() { 'Idempotency-Key': getState().getIn(['compose', 'idempotencyKey']), }, }).then(function (response) { + dispatch(insertIntoTagHistory(response.data.tags)); dispatch(submitComposeSuccess({ ...response.data })); // To make the app more responsive, immediately get the status into the columns @@ -273,12 +278,22 @@ const fetchComposeSuggestionsEmojis = (dispatch, getState, token) => { dispatch(readyComposeSuggestionsEmojis(token, results)); }; +const fetchComposeSuggestionsTags = (dispatch, getState, token) => { + dispatch(updateSuggestionTags(token)); +}; + export function fetchComposeSuggestions(token) { return (dispatch, getState) => { - if (token[0] === ':') { + switch (token[0]) { + case ':': fetchComposeSuggestionsEmojis(dispatch, getState, token); - } else { + break; + case '#': + fetchComposeSuggestionsTags(dispatch, getState, token); + break; + default: fetchComposeSuggestionsAccounts(dispatch, getState, token); + break; } }; }; @@ -308,6 +323,9 @@ export function selectComposeSuggestion(position, token, suggestion) { startPosition = position - 1; dispatch(useEmoji(suggestion)); + } else if (suggestion[0] === '#') { + completion = suggestion; + startPosition = position - 1; } else { completion = getState().getIn(['accounts', suggestion, 'acct']); startPosition = position; @@ -322,6 +340,48 @@ export function selectComposeSuggestion(position, token, suggestion) { }; }; +export function updateSuggestionTags(token) { + return { + type: COMPOSE_SUGGESTION_TAGS_UPDATE, + token, + }; +} + +export function updateTagHistory(tags) { + return { + type: COMPOSE_TAG_HISTORY_UPDATE, + tags, + }; +} + +export function hydrateCompose() { + return (dispatch, getState) => { + const me = getState().getIn(['meta', 'me']); + const history = tagHistory.get(me); + + if (history !== null) { + dispatch(updateTagHistory(history)); + } + }; +} + +function insertIntoTagHistory(tags) { + return (dispatch, getState) => { + const state = getState(); + const oldHistory = state.getIn(['compose', 'tagHistory']); + const me = state.getIn(['meta', 'me']); + const names = tags.map(({ name }) => name); + const intersectedOldHistory = oldHistory.filter(name => !names.includes(name)); + + names.push(...intersectedOldHistory.toJS()); + + const newHistory = names.slice(0, 1000); + + tagHistory.set(me, newHistory); + dispatch(updateTagHistory(newHistory)); + }; +} + export function mountCompose() { return { type: COMPOSE_MOUNT, diff --git a/app/javascript/mastodon/actions/store.js b/app/javascript/mastodon/actions/store.js index a1db0fdd51c..2dd94a99832 100644 --- a/app/javascript/mastodon/actions/store.js +++ b/app/javascript/mastodon/actions/store.js @@ -1,4 +1,5 @@ import { Iterable, fromJS } from 'immutable'; +import { hydrateCompose } from './compose'; export const STORE_HYDRATE = 'STORE_HYDRATE'; export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY'; @@ -8,10 +9,14 @@ const convertState = rawState => Iterable.isIndexed(v) ? v.toList() : v.toMap()); export function hydrateStore(rawState) { - const state = convertState(rawState); + return dispatch => { + const state = convertState(rawState); - return { - type: STORE_HYDRATE, - state, + dispatch({ + type: STORE_HYDRATE, + state, + }); + + dispatch(hydrateCompose()); }; }; diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js index 6a16e2fc7ae..34904194f73 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.js +++ b/app/javascript/mastodon/components/autosuggest_textarea.js @@ -20,7 +20,7 @@ const textAtCursorMatchesToken = (str, caretPosition) => { word = str.slice(left, right + caretPosition); } - if (!word || word.trim().length < 3 || ['@', ':'].indexOf(word[0]) === -1) { + if (!word || word.trim().length < 3 || ['@', ':', '#'].indexOf(word[0]) === -1) { return [null, null]; } @@ -170,6 +170,9 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { if (typeof suggestion === 'object') { inner = ; key = suggestion.id; + } else if (suggestion[0] === '#') { + inner = suggestion; + key = suggestion; } else { inner = ; key = suggestion; diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 1358fb4aa87..dc88390dfd4 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -16,6 +16,8 @@ import { COMPOSE_SUGGESTIONS_CLEAR, COMPOSE_SUGGESTIONS_READY, COMPOSE_SUGGESTION_SELECT, + COMPOSE_SUGGESTION_TAGS_UPDATE, + COMPOSE_TAG_HISTORY_UPDATE, COMPOSE_SENSITIVITY_CHANGE, COMPOSE_SPOILERNESS_CHANGE, COMPOSE_SPOILER_TEXT_CHANGE, @@ -54,6 +56,7 @@ const initialState = ImmutableMap({ default_sensitive: false, resetFileKey: Math.floor((Math.random() * 0x10000)), idempotencyKey: null, + tagHistory: ImmutableList(), }); function statusToTextMentions(state, status) { @@ -122,6 +125,18 @@ const insertSuggestion = (state, position, token, completion) => { }); }; +const updateSuggestionTags = (state, token) => { + const prefix = token.slice(1); + + return state.merge({ + suggestions: state.get('tagHistory') + .filter(tag => tag.startsWith(prefix)) + .slice(0, 4) + .map(tag => '#' + tag), + suggestion_token: token, + }); +}; + const insertEmoji = (state, position, emojiData) => { const emoji = emojiData.native; @@ -252,6 +267,10 @@ export default function compose(state = initialState, action) { return state.set('suggestions', ImmutableList(action.accounts ? action.accounts.map(item => item.id) : action.emojis)).set('suggestion_token', action.token); case COMPOSE_SUGGESTION_SELECT: return insertSuggestion(state, action.position, action.token, action.completion); + case COMPOSE_SUGGESTION_TAGS_UPDATE: + return updateSuggestionTags(state, action.token); + case COMPOSE_TAG_HISTORY_UPDATE: + return state.set('tagHistory', fromJS(action.tags)); case TIMELINE_DELETE: if (action.id === state.get('in_reply_to')) { return state.set('in_reply_to', null); diff --git a/app/javascript/mastodon/settings.js b/app/javascript/mastodon/settings.js index dbd969cb1bc..7643a508ea0 100644 --- a/app/javascript/mastodon/settings.js +++ b/app/javascript/mastodon/settings.js @@ -44,3 +44,4 @@ export default class Settings { } export const pushNotificationsSetting = new Settings('mastodon_push_notification_data'); +export const tagHistory = new Settings('mastodon_tag_history'); From 7a6eaad445ca009001a31657d163b0316b27e9e4 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 5 Mar 2018 04:27:40 +0900 Subject: [PATCH 10/59] Do not require images in about.js and share.js (#6622) They are already required by common.js. --- app/javascript/packs/about.js | 2 -- app/javascript/packs/share.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/app/javascript/packs/about.js b/app/javascript/packs/about.js index 50c81198e39..63e12da42cc 100644 --- a/app/javascript/packs/about.js +++ b/app/javascript/packs/about.js @@ -1,7 +1,5 @@ import loadPolyfills from '../mastodon/load_polyfills'; -require.context('../images/', true); - function loaded() { const TimelineContainer = require('../mastodon/containers/timeline_container').default; const React = require('react'); diff --git a/app/javascript/packs/share.js b/app/javascript/packs/share.js index 51e4ae38b8a..e9580f648bf 100644 --- a/app/javascript/packs/share.js +++ b/app/javascript/packs/share.js @@ -1,7 +1,5 @@ import loadPolyfills from '../mastodon/load_polyfills'; -require.context('../images/', true); - function loaded() { const ComposeContainer = require('../mastodon/containers/compose_container').default; const React = require('react'); From c110fa62ac0f475efd64572026835a7514c410ae Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 5 Mar 2018 04:28:24 +0900 Subject: [PATCH 11/59] Provide default OTP_SECRET value for development environment (#6617) --- .env.test | 1 - app/models/user.rb | 2 +- config/environments/development.rb | 2 ++ config/environments/production.rb | 2 ++ config/environments/test.rb | 2 ++ 5 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.env.test b/.env.test index e25c040ac04..b57f52e309b 100644 --- a/.env.test +++ b/.env.test @@ -1,4 +1,3 @@ # Federation LOCAL_DOMAIN=cb6e6126.ngrok.io LOCAL_HTTPS=true -OTP_SECRET=100c7faeef00caa29242f6b04156742bf76065771fd4117990c4282b8748ff3d99f8fdae97c982ab5bd2e6756a159121377cce4421f4a8ecd2d67bd7749a3fb4 diff --git a/app/models/user.rb b/app/models/user.rb index 2995d6d54cc..b716c13fd20 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -44,7 +44,7 @@ class User < ApplicationRecord ACTIVE_DURATION = 14.days devise :two_factor_authenticatable, - otp_secret_encryption_key: ENV.fetch('OTP_SECRET') + otp_secret_encryption_key: Rails.configuration.x.otp_secret devise :two_factor_backupable, otp_number_of_backup_codes: 10 diff --git a/config/environments/development.rb b/config/environments/development.rb index 2da407c323d..285fea8b8c5 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -82,6 +82,8 @@ Rails.application.configure do Bullet.add_whitelist type: :n_plus_one_query, class_name: 'User', association: :account end + + config.x.otp_secret = ENV.fetch('OTP_SECRET', '1fc2b87989afa6351912abeebe31ffc5c476ead9bf8b3d74cbc4a302c7b69a45b40b1bbef3506ddad73e942e15ed5ca4b402bf9a66423626051104f4b5f05109') end ActiveRecordQueryTrace.enabled = ENV.fetch('QUERY_TRACE_ENABLED') { false } diff --git a/config/environments/production.rb b/config/environments/production.rb index 51288bc395f..3136a40fc3e 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -96,4 +96,6 @@ Rails.application.configure do 'X-Content-Type-Options' => 'nosniff', 'X-XSS-Protection' => '1; mode=block', } + + config.x.otp_secret = ENV.fetch('OTP_SECRET') end diff --git a/config/environments/test.rb b/config/environments/test.rb index 74e7fa694e4..7d77a170e56 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -44,6 +44,8 @@ Rails.application.configure do # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr + config.x.otp_secret = '100c7faeef00caa29242f6b04156742bf76065771fd4117990c4282b8748ff3d99f8fdae97c982ab5bd2e6756a159121377cce4421f4a8ecd2d67bd7749a3fb4' + # Generate random VAPID keys vapid_key = Webpush.generate_key config.x.vapid_private_key = vapid_key.private_key From 219aac7800a086a75f3ef36f71955bb8b6ccc2c0 Mon Sep 17 00:00:00 2001 From: abcang Date: Mon, 5 Mar 2018 04:29:12 +0900 Subject: [PATCH 12/59] Show media on report UI (#6619) --- .../report/components/status_check_box.js | 44 ++++++++++++++++--- .../styles/mastodon/components.scss | 27 +++++++++--- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.js index cc92322011a..9ff75a082c2 100644 --- a/app/javascript/mastodon/features/report/components/status_check_box.js +++ b/app/javascript/mastodon/features/report/components/status_check_box.js @@ -2,6 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import Toggle from 'react-toggle'; +import noop from 'lodash/noop'; +import StatusContent from '../../../components/status_content'; +import { MediaGallery, Video } from '../../ui/util/async-components'; +import Bundle from '../../ui/components/bundle'; export default class StatusCheckBox extends React.PureComponent { @@ -14,18 +18,48 @@ export default class StatusCheckBox extends React.PureComponent { render () { const { status, checked, onToggle, disabled } = this.props; - const content = { __html: status.get('contentHtml') }; + let media = null; if (status.get('reblog')) { return null; } + if (status.get('media_attachments').size > 0) { + if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { + + } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { + const video = status.getIn(['media_attachments', 0]); + + media = ( + + {Component => ( + + )} + + ); + } else { + media = ( + + {Component => } + + ); + } + } + return (
-
+
+ + {media} +
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 626f515340e..a0ff0953b34 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -862,12 +862,27 @@ border-bottom: 1px solid $ui-secondary-color; display: flex; - .status__content { - flex: 1 1 auto; - padding: 10px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + .status-check-box__status { + margin: 10px 0 10px 10px; + flex: 1; + + .media-gallery { + max-width: 250px; + } + + .status__content { + padding: 0; + white-space: normal; + } + + .video-player { + margin-top: 8px; + max-width: 250px; + } + + .media-gallery__item-thumbnail { + cursor: default; + } } } From ef44c62d17085e71a807705f25c549553676c5f1 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Mon, 5 Mar 2018 04:29:49 +0900 Subject: [PATCH 13/59] Do not default site_title with site_hostname in InstanceHelper (#6624) site_title is "Mastodon" by default configuration, and there is no need to default site_title with site_hostname in InstanceHelper. --- app/helpers/instance_helper.rb | 2 +- spec/helpers/instance_helper_spec.rb | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/app/helpers/instance_helper.rb b/app/helpers/instance_helper.rb index 22a19c52b57..dd0b25f3ef9 100644 --- a/app/helpers/instance_helper.rb +++ b/app/helpers/instance_helper.rb @@ -2,7 +2,7 @@ module InstanceHelper def site_title - Setting.site_title.presence || site_hostname + Setting.site_title end def site_hostname diff --git a/spec/helpers/instance_helper_spec.rb b/spec/helpers/instance_helper_spec.rb index bc5950d91ce..c2e26dbed37 100644 --- a/spec/helpers/instance_helper_spec.rb +++ b/spec/helpers/instance_helper_spec.rb @@ -15,12 +15,6 @@ describe InstanceHelper do expect(helper.site_title).to eq 'New site title' end - - it 'returns empty string when Setting.site_title is nil' do - Setting.site_title = nil - - expect(helper.site_title).to eq 'cb6e6126.ngrok.io' - end end describe 'site_hostname' do From 4e929b2d173fa22b722c58c0e9f8223eb4f44b0e Mon Sep 17 00:00:00 2001 From: Yuto Tokunaga Date: Mon, 5 Mar 2018 04:32:24 +0900 Subject: [PATCH 14/59] [RFC] Improved media modal (#5956) * Improved media modal ImageLoader: Impliment pinch zoom by CSS `transform: scale(X)` ImageLoader: Impliment panning by CSS `overflow: scroll` ImageLoader: Larger image MediaModal: Larger close button MediaModal: Close the modal by swiping vertically MediaModal: Show/hide close button and right/left navigation on tapping image MediaModal: Change the `pointer-event` CSS prpp to get more blank space to close the modal ImageLoader: Zoom/reset zoom on double tap MediaModal: disable vertical swiping while horizontally swiped ImageLoader: prevent propagating touchmove event to MediaModal MediaModal: Adjust size and potision of buttons ImageLoader: Adjust scroll potision on pinch zoom * Remove "swipe to close" and "double tap to zoom" features * remove unused prop and functions removed `onScroll` prop and `handleScroll` func in ImageLoader * separate zoom functionary to ZoomableImage component adjust styling of ImageLoader add styling for ZoomableImage * adjust size and potision of close button of media modal * Fix for gif video add `onClick` prop to ExtendedVideoPlayer specify `onClick` prop to video tag for switching nav of `MediaModal` add `.video-modal` class to scss to separate styling for `VideoModal` * fix styling for centering specify height of `ZoomableImage` by pixel clean styling for `ImageLoader` * fix lint errors * small fix * fixed designated parts --- .../components/extended_video_player.js | 8 + .../features/ui/components/image_loader.js | 32 ++-- .../features/ui/components/media_modal.js | 84 ++++++++-- .../features/ui/components/video_modal.js | 2 +- .../features/ui/components/zoomable_image.js | 151 ++++++++++++++++++ .../styles/mastodon/components.scss | 146 ++++++++++------- 6 files changed, 330 insertions(+), 93 deletions(-) create mode 100644 app/javascript/mastodon/features/ui/components/zoomable_image.js diff --git a/app/javascript/mastodon/components/extended_video_player.js b/app/javascript/mastodon/components/extended_video_player.js index f8bd067e8e5..9e2f6835a8b 100644 --- a/app/javascript/mastodon/components/extended_video_player.js +++ b/app/javascript/mastodon/components/extended_video_player.js @@ -11,6 +11,7 @@ export default class ExtendedVideoPlayer extends React.PureComponent { time: PropTypes.number, controls: PropTypes.bool.isRequired, muted: PropTypes.bool.isRequired, + onClick: PropTypes.func, }; handleLoadedData = () => { @@ -31,6 +32,12 @@ export default class ExtendedVideoPlayer extends React.PureComponent { this.video = c; } + handleClick = e => { + e.stopPropagation(); + const handler = this.props.onClick; + if (handler) handler(); + } + render () { const { src, muted, controls, alt } = this.props; @@ -46,6 +53,7 @@ export default class ExtendedVideoPlayer extends React.PureComponent { muted={muted} controls={controls} loop={!controls} + onClick={this.handleClick} />
); diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js index e3e7197c541..c7360a72647 100644 --- a/app/javascript/mastodon/features/ui/components/image_loader.js +++ b/app/javascript/mastodon/features/ui/components/image_loader.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; +import ZoomableImage from './zoomable_image'; export default class ImageLoader extends React.PureComponent { @@ -10,6 +11,7 @@ export default class ImageLoader extends React.PureComponent { previewSrc: PropTypes.string, width: PropTypes.number, height: PropTypes.number, + onClick: PropTypes.func, } static defaultProps = { @@ -24,6 +26,7 @@ export default class ImageLoader extends React.PureComponent { } removers = []; + canvas = null; get canvasContext() { if (!this.canvas) { @@ -43,6 +46,10 @@ export default class ImageLoader extends React.PureComponent { } } + componentWillUnmount () { + this.removeEventListeners(); + } + loadImage (props) { this.removeEventListeners(); this.setState({ loading: true, error: false }); @@ -118,7 +125,7 @@ export default class ImageLoader extends React.PureComponent { } render () { - const { alt, src, width, height } = this.props; + const { alt, src, width, height, onClick } = this.props; const { loading } = this.state; const className = classNames('image-loader', { @@ -128,22 +135,19 @@ export default class ImageLoader extends React.PureComponent { return (
- - - {!loading && ( - {alt} + ) : ( + )}
); diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js index 02591a51f4c..72ef32256f9 100644 --- a/app/javascript/mastodon/features/ui/components/media_modal.js +++ b/app/javascript/mastodon/features/ui/components/media_modal.js @@ -3,6 +3,7 @@ import ReactSwipeableViews from 'react-swipeable-views'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; +import classNames from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; import IconButton from '../../../components/icon_button'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -26,6 +27,7 @@ export default class MediaModal extends ImmutablePureComponent { state = { index: null, + navigationHidden: false, }; handleSwipe = (index) => { @@ -68,14 +70,21 @@ export default class MediaModal extends ImmutablePureComponent { return this.state.index !== null ? this.state.index : this.props.index; } + toggleNavigation = () => { + this.setState(prevState => ({ + navigationHidden: !prevState.navigationHidden, + })); + }; + render () { const { media, intl, onClose } = this.props; + const { navigationHidden } = this.state; const index = this.getIndex(); let pagination = []; - const leftNav = media.size > 1 && ; - const rightNav = media.size > 1 && ; + const leftNav = media.size > 1 && ; + const rightNav = media.size > 1 && ; if (media.size > 1) { pagination = media.map((item, i) => { @@ -92,9 +101,30 @@ export default class MediaModal extends ImmutablePureComponent { const height = image.getIn(['meta', 'original', 'height']) || null; if (image.get('type') === 'image') { - return ; + return ( + + ); } else if (image.get('type') === 'gifv') { - return ; + return ( + + ); } return null; @@ -104,21 +134,43 @@ export default class MediaModal extends ImmutablePureComponent { alignItems: 'center', // center vertically }; + const navigationClassName = classNames('media-modal__navigation', { + 'media-modal__navigation--hidden': navigationHidden, + }); + return (
- {leftNav} - -
- - - {content} - +
+
+ + {content} + +
+
+
+ + {leftNav} + {rightNav} +
    + {pagination} +
-
    - {pagination} -
- - {rightNav}
); } diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js index 6a883759fec..9ed4a43ad1f 100644 --- a/app/javascript/mastodon/features/ui/components/video_modal.js +++ b/app/javascript/mastodon/features/ui/components/video_modal.js @@ -16,7 +16,7 @@ export default class VideoModal extends ImmutablePureComponent { const { media, time, onClose } = this.props; return ( -
+
); + } else if (account.getIn(['relationship', 'blocking'])) { + actionBtn = ( +
+ +
+ ); } } @@ -124,6 +139,7 @@ export default class Header extends ImmutablePureComponent {
{info} + {mutingInfo} {actionBtn}
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index b143e1d366a..9d594fb0c50 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -82,6 +82,7 @@ export default class Header extends ImmutablePureComponent { Date: Mon, 5 Mar 2018 08:05:52 +0100 Subject: [PATCH 16/59] i18n: Update Polish translation (#6632) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Marcin Mikołajczak --- app/javascript/mastodon/locales/pl.json | 3 +++ config/locales/pl.yml | 1 + 2 files changed, 4 insertions(+) diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 24497d6c4e8..f95cf5b8166 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -1,6 +1,7 @@ { "account.block": "Blokuj @{name}", "account.block_domain": "Blokuj wszystko z {domain}", + "account.blocked": "Zablokowany", "account.disclaimer_full": "Poniższe informacje mogą nie odwzorowywać bezbłędnie profilu użytkownika.", "account.edit_profile": "Edytuj profil", "account.follow": "Śledź", @@ -13,6 +14,7 @@ "account.moved_to": "{name} przeniósł się do:", "account.mute": "Wycisz @{name}", "account.mute_notifications": "Wycisz powiadomienia o @{name}", + "account.muted": "Wyciszony", "account.posts": "Wpisy", "account.posts_with_replies": "Wpisy z odpowiedziami", "account.report": "Zgłoś @{name}", @@ -238,6 +240,7 @@ "status.mute_conversation": "Wycisz konwersację", "status.open": "Rozszerz ten wpis", "status.pin": "Przypnij do profilu", + "status.pinned": "Przypięty wpis", "status.reblog": "Podbij", "status.reblogged_by": "{name} podbił", "status.reply": "Odpowiedz", diff --git a/config/locales/pl.yml b/config/locales/pl.yml index d9f793125c8..539ba7ea4b1 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -371,6 +371,7 @@ pl: logout: Wyloguj się migrate_account: Przenieś konto migrate_account_html: Jeżeli chcesz skonfigurować przekierowanie z obecnego konta na inne, możesz skonfigurować to tutaj. + or: lub or_log_in_with: Lub zaloguj się z użyciem providers: cas: CAS From 1674e2f34cf69a6887c87c2a33deec5748329342 Mon Sep 17 00:00:00 2001 From: "Renato \"Lond\" Cerqueira" Date: Mon, 5 Mar 2018 15:12:17 +0100 Subject: [PATCH 17/59] Normalize translations (#6638) Ran i18n-tasks normalize && yarn manage:translations, so that the translation changes appear on weblate --- app/javascript/mastodon/locales/ar.json | 5 ++++- app/javascript/mastodon/locales/bg.json | 5 ++++- app/javascript/mastodon/locales/ca.json | 5 ++++- app/javascript/mastodon/locales/de.json | 5 ++++- .../mastodon/locales/defaultMessages.json | 16 ++++++++++++++++ app/javascript/mastodon/locales/en.json | 5 ++++- app/javascript/mastodon/locales/eo.json | 5 ++++- app/javascript/mastodon/locales/es.json | 5 ++++- app/javascript/mastodon/locales/fa.json | 5 ++++- app/javascript/mastodon/locales/fi.json | 5 ++++- app/javascript/mastodon/locales/fr.json | 5 ++++- app/javascript/mastodon/locales/gl.json | 5 ++++- app/javascript/mastodon/locales/he.json | 5 ++++- app/javascript/mastodon/locales/hr.json | 5 ++++- app/javascript/mastodon/locales/hu.json | 5 ++++- app/javascript/mastodon/locales/hy.json | 5 ++++- app/javascript/mastodon/locales/id.json | 5 ++++- app/javascript/mastodon/locales/io.json | 5 ++++- app/javascript/mastodon/locales/it.json | 5 ++++- app/javascript/mastodon/locales/ja.json | 5 ++++- app/javascript/mastodon/locales/ko.json | 3 +++ app/javascript/mastodon/locales/nl.json | 5 ++++- app/javascript/mastodon/locales/no.json | 5 ++++- app/javascript/mastodon/locales/oc.json | 5 ++++- app/javascript/mastodon/locales/pl.json | 2 +- app/javascript/mastodon/locales/pt-BR.json | 5 ++++- app/javascript/mastodon/locales/pt.json | 5 ++++- app/javascript/mastodon/locales/ru.json | 5 ++++- app/javascript/mastodon/locales/sk.json | 5 ++++- app/javascript/mastodon/locales/sr-Latn.json | 5 ++++- app/javascript/mastodon/locales/sr.json | 5 ++++- app/javascript/mastodon/locales/sv.json | 5 ++++- app/javascript/mastodon/locales/th.json | 5 ++++- app/javascript/mastodon/locales/tr.json | 5 ++++- app/javascript/mastodon/locales/uk.json | 5 ++++- app/javascript/mastodon/locales/zh-CN.json | 5 ++++- app/javascript/mastodon/locales/zh-HK.json | 5 ++++- app/javascript/mastodon/locales/zh-TW.json | 5 ++++- 38 files changed, 160 insertions(+), 36 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index b326bc3b1ab..41c9c6b0644 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -1,6 +1,7 @@ { "account.block": "حظر @{name}", "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "قد لا تعكس المعلومات أدناه الملف الشخصي الكامل للمستخدم.", "account.edit_profile": "تعديل الملف الشخصي", "account.follow": "تابِع", @@ -13,6 +14,7 @@ "account.moved_to": "{name} إنتقل إلى :", "account.mute": "أكتم @{name}", "account.mute_notifications": "كتم إخطارات @{name}", + "account.muted": "Muted", "account.posts": "التبويقات", "account.posts_with_replies": "Toots with replies", "account.report": "أبلغ عن @{name}", @@ -216,6 +218,7 @@ "report.target": "إبلاغ", "search.placeholder": "ابحث", "search_popout.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": "وسم", "search_popout.tips.status": "حالة", "search_popout.tips.text": "جملة قصيرة تُمكّنُك من عرض أسماء و حسابات و كلمات رمزية", @@ -238,6 +241,7 @@ "status.mute_conversation": "كتم المحادثة", "status.open": "وسع هذه المشاركة", "status.pin": "تدبيس على الملف الشخصي", + "status.pinned": "Pinned toot", "status.reblog": "رَقِّي", "status.reblogged_by": "{name} رقى", "status.reply": "ردّ", @@ -250,7 +254,6 @@ "status.show_more": "أظهر المزيد", "status.unmute_conversation": "فك الكتم عن المحادثة", "status.unpin": "فك التدبيس من الملف الشخصي", - "tabs_bar.compose": "تحرير", "tabs_bar.federated_timeline": "الموحَّد", "tabs_bar.home": "الرئيسية", "tabs_bar.local_timeline": "المحلي", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 90e394a1975..0af5a0fcc5f 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -1,6 +1,7 @@ { "account.block": "Блокирай", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Редактирай профила си", "account.follow": "Последвай", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Публикации", "account.posts_with_replies": "Toots with replies", "account.report": "Report @{name}", @@ -216,6 +218,7 @@ "report.target": "Reporting", "search.placeholder": "Търсене", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Expand this status", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Споделяне", "status.reblogged_by": "{name} сподели", "status.reply": "Отговор", @@ -250,7 +254,6 @@ "status.show_more": "Show more", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Съставяне", "tabs_bar.federated_timeline": "Federated", "tabs_bar.home": "Начало", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index 95b75cfc9a4..eea0d0edb13 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -1,6 +1,7 @@ { "account.block": "Bloca @{name}", "account.block_domain": "Amaga-ho tot de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "La informació següent pot reflectir incompleta el perfil de l'usuari.", "account.edit_profile": "Edita el perfil", "account.follow": "Segueix", @@ -13,6 +14,7 @@ "account.moved_to": "{name} s'ha mogut a:", "account.mute": "Silencia @{name}", "account.mute_notifications": "Notificacions desactivades de @{name}", + "account.muted": "Muted", "account.posts": "Toots", "account.posts_with_replies": "Toots with replies", "account.report": "Informe @{name}", @@ -216,6 +218,7 @@ "report.target": "Informes", "search.placeholder": "Cercar", "search_popout.search_format": "Format de cerca avançada", + "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": "etiqueta", "search_popout.tips.status": "status", "search_popout.tips.text": "El text simple retorna coincidències amb els noms de visualització, els noms d'usuari i els hashtags", @@ -238,6 +241,7 @@ "status.mute_conversation": "Silenciar conversació", "status.open": "Ampliar aquest estat", "status.pin": "Fixat en el perfil", + "status.pinned": "Pinned toot", "status.reblog": "Impuls", "status.reblogged_by": "{name} ha retootejat", "status.reply": "Respondre", @@ -250,7 +254,6 @@ "status.show_more": "Mostra més", "status.unmute_conversation": "Activar conversació", "status.unpin": "Deslliga del perfil", - "tabs_bar.compose": "Compondre", "tabs_bar.federated_timeline": "Federada", "tabs_bar.home": "Inici", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 7f29f83ce69..9fe09487c0c 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -1,6 +1,7 @@ { "account.block": "@{name} blocken", "account.block_domain": "Alles von {domain} verstecken", + "account.blocked": "Blocked", "account.disclaimer_full": "Das Profil wird möglicherweise unvollständig wiedergegeben.", "account.edit_profile": "Profil bearbeiten", "account.follow": "Folgen", @@ -13,6 +14,7 @@ "account.moved_to": "{name} ist umgezogen auf:", "account.mute": "@{name} stummschalten", "account.mute_notifications": "Benachrichtigungen von @{name} verbergen", + "account.muted": "Muted", "account.posts": "Beiträge", "account.posts_with_replies": "Toots with replies", "account.report": "@{name} melden", @@ -216,6 +218,7 @@ "report.target": "{target} melden", "search.placeholder": "Suche", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Thread stummschalten", "status.open": "Diesen Beitrag öffnen", "status.pin": "Im Profil anheften", + "status.pinned": "Pinned toot", "status.reblog": "Teilen", "status.reblogged_by": "{name} teilte", "status.reply": "Antworten", @@ -250,7 +254,6 @@ "status.show_more": "Mehr anzeigen", "status.unmute_conversation": "Stummschaltung von Thread aufheben", "status.unpin": "Vom Profil lösen", - "tabs_bar.compose": "Schreiben", "tabs_bar.federated_timeline": "Föderation", "tabs_bar.home": "Startseite", "tabs_bar.local_timeline": "Lokal", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 52b7ea2cd83..bd21d4cc65f 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -274,6 +274,10 @@ }, { "descriptors": [ + { + "defaultMessage": "Pinned toot", + "id": "status.pinned" + }, { "defaultMessage": "{name} boosted", "id": "status.reblogged_by" @@ -478,9 +482,21 @@ "defaultMessage": "Awaiting approval. Click to cancel follow request", "id": "account.requested" }, + { + "defaultMessage": "Unblock @{name}", + "id": "account.unblock" + }, { "defaultMessage": "Follows you", "id": "account.follows_you" + }, + { + "defaultMessage": "Blocked", + "id": "account.blocked" + }, + { + "defaultMessage": "Muted", + "id": "account.muted" } ], "path": "app/javascript/mastodon/features/account/components/header.json" diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index e571a220b55..3f2367d5bab 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -1,6 +1,7 @@ { "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Edit profile", "account.follow": "Follow", @@ -13,6 +14,7 @@ "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 with replies", "account.report": "Report @{name}", @@ -216,6 +218,7 @@ "report.target": "Reporting {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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Expand this status", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Boost", "status.reblogged_by": "{name} boosted", "status.reply": "Reply", @@ -250,7 +254,6 @@ "status.show_more": "Show more", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Compose", "tabs_bar.federated_timeline": "Federated", "tabs_bar.home": "Home", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index b6153145fcb..8ce035d5eee 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -1,6 +1,7 @@ { "account.block": "Bloki @{name}", "account.block_domain": "Kaŝi ĉion de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Subaj informoj povas reflekti la profilon de la uzanto nekomplete.", "account.edit_profile": "Redakti profilon", "account.follow": "Sekvi", @@ -13,6 +14,7 @@ "account.moved_to": "{name} moviĝis al:", "account.mute": "Silentigi @{name}", "account.mute_notifications": "Silentigi sciigojn el @{name}", + "account.muted": "Muted", "account.posts": "Hupoj", "account.posts_with_replies": "Toots with replies", "account.report": "Signali @{name}", @@ -216,6 +218,7 @@ "report.target": "Signali {target}", "search.placeholder": "Serĉi", "search_popout.search_format": "Detala serĉo", + "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": "kradvorto", "search_popout.tips.status": "mesaĝoj", "search_popout.tips.text": "Simpla teksto montras la kongruajn afiŝitajn nomojn, uzantnomojn kaj kradvortojn", @@ -238,6 +241,7 @@ "status.mute_conversation": "Silentigi konversacion", "status.open": "Grandigi ĉi tiun mesaĝon", "status.pin": "Alpingli en la profilo", + "status.pinned": "Pinned toot", "status.reblog": "Diskonigi", "status.reblogged_by": "{name} diskonigis", "status.reply": "Respondi", @@ -250,7 +254,6 @@ "status.show_more": "Grandigi", "status.unmute_conversation": "Malsilentigi konversacion", "status.unpin": "Depingli de profilo", - "tabs_bar.compose": "Ekskribi", "tabs_bar.federated_timeline": "Fratara tempolinio", "tabs_bar.home": "Hejmo", "tabs_bar.local_timeline": "Loka tempolinio", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index 5f16ec97476..ab1aa7ed798 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -1,6 +1,7 @@ { "account.block": "Bloquear", "account.block_domain": "Ocultar todo de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "La siguiente información del usuario puede estar incompleta.", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", @@ -13,6 +14,7 @@ "account.moved_to": "{name} se ha mudado a:", "account.mute": "Silenciar a @{name}", "account.mute_notifications": "Silenciar notificaciones de @{name}", + "account.muted": "Muted", "account.posts": "Publicaciones", "account.posts_with_replies": "Toots with replies", "account.report": "Reportar a @{name}", @@ -216,6 +218,7 @@ "report.target": "Reportando", "search.placeholder": "Buscar", "search_popout.search_format": "Formato de búsqueda avanzada", + "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": "etiqueta", "search_popout.tips.status": "status", "search_popout.tips.text": "El texto simple devuelve correspondencias de nombre, usuario y hashtag", @@ -238,6 +241,7 @@ "status.mute_conversation": "Silenciar conversación", "status.open": "Expandir estado", "status.pin": "Fijar", + "status.pinned": "Pinned toot", "status.reblog": "Retootear", "status.reblogged_by": "Retooteado por {name}", "status.reply": "Responder", @@ -250,7 +254,6 @@ "status.show_more": "Mostrar más", "status.unmute_conversation": "Dejar de silenciar conversación", "status.unpin": "Dejar de fijar", - "tabs_bar.compose": "Redactar", "tabs_bar.federated_timeline": "Federado", "tabs_bar.home": "Inicio", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index 4fd467a66e9..b589d95adf1 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -1,6 +1,7 @@ { "account.block": "مسدودسازی @{name}", "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "اطلاعات زیر ممکن است نمایهٔ این کاربر را به تمامی نشان ندهد.", "account.edit_profile": "ویرایش نمایه", "account.follow": "پی بگیرید", @@ -13,6 +14,7 @@ "account.moved_to": "{name} منتقل شده است به:", "account.mute": "بی‌صدا کردن @{name}", "account.mute_notifications": "بی‌صداکردن اعلان‌ها از طرف @{name}", + "account.muted": "Muted", "account.posts": "نوشته‌ها", "account.posts_with_replies": "Toots with replies", "account.report": "گزارش @{name}", @@ -216,6 +218,7 @@ "report.target": "گزارش‌دادن", "search.placeholder": "جستجو", "search_popout.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": "هشتگ", "search_popout.tips.status": "نوشته", "search_popout.tips.text": "جستجوی متنی ساده برای نام‌ها، نام‌های کاربری، و هشتگ‌ها", @@ -238,6 +241,7 @@ "status.mute_conversation": "بی‌صداکردن گفتگو", "status.open": "این نوشته را باز کن", "status.pin": "نوشتهٔ ثابت نمایه", + "status.pinned": "Pinned toot", "status.reblog": "بازبوقیدن", "status.reblogged_by": "‫{name}‬ بازبوقید", "status.reply": "پاسخ", @@ -250,7 +254,6 @@ "status.show_more": "نمایش", "status.unmute_conversation": "باصداکردن گفتگو", "status.unpin": "برداشتن نوشتهٔ ثابت نمایه", - "tabs_bar.compose": "بنویسید", "tabs_bar.federated_timeline": "همگانی", "tabs_bar.home": "خانه", "tabs_bar.local_timeline": "محلی", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index d27ba1834d8..9ea3c809407 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -1,6 +1,7 @@ { "account.block": "Estä @{name}", "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.", "account.edit_profile": "Muokkaa", "account.follow": "Seuraa", @@ -13,6 +14,7 @@ "account.moved_to": "{name} on muuttanut instanssiin:", "account.mute": "Mykistä @{name}", "account.mute_notifications": "Mykistä ilmoitukset käyttäjältä @{name}", + "account.muted": "Muted", "account.posts": "Töötit", "account.posts_with_replies": "Toots with replies", "account.report": "Report @{name}", @@ -216,6 +218,7 @@ "report.target": "Reporting", "search.placeholder": "Hae", "search_popout.search_format": "Tarkennettu haku", + "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": "hashtagi", "search_popout.tips.status": "status", "search_popout.tips.text": "Pelkkä tekstihaku palauttaa hakua vastaavat nimimerkit, käyttäjänimet ja hastagit", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mykistä keskustelu", "status.open": "Laajenna statuspäivitys", "status.pin": "Kiinnitä profiiliin", + "status.pinned": "Pinned toot", "status.reblog": "Buustaa", "status.reblogged_by": "{name} buustasi", "status.reply": "Vastaa", @@ -250,7 +254,6 @@ "status.show_more": "Näytä lisää", "status.unmute_conversation": "Poista mykistys keskustelulta", "status.unpin": "Irrota profiilista", - "tabs_bar.compose": "Luo", "tabs_bar.federated_timeline": "Federated", "tabs_bar.home": "Koti", "tabs_bar.local_timeline": "Paikallinen", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index b10187dfd4a..ad1368e9383 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -1,6 +1,7 @@ { "account.block": "Bloquer @{name}", "account.block_domain": "Tout masquer venant de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Les données ci-dessous peuvent ne pas refléter ce profil dans sa totalité.", "account.edit_profile": "Modifier le profil", "account.follow": "Suivre", @@ -13,6 +14,7 @@ "account.moved_to": "{name} a déménagé vers :", "account.mute": "Masquer @{name}", "account.mute_notifications": "Ignorer les notifications de @{name}", + "account.muted": "Muted", "account.posts": "Statuts", "account.posts_with_replies": "Toots with replies", "account.report": "Signaler", @@ -216,6 +218,7 @@ "report.target": "Signalement", "search.placeholder": "Rechercher", "search_popout.search_format": "Recherche avancée", + "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": "statuts", "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les noms d’utilisateur⋅ice et les hashtags correspondants", @@ -238,6 +241,7 @@ "status.mute_conversation": "Masquer la conversation", "status.open": "Déplier ce statut", "status.pin": "Épingler sur le profil", + "status.pinned": "Pinned toot", "status.reblog": "Partager", "status.reblogged_by": "{name} a partagé :", "status.reply": "Répondre", @@ -250,7 +254,6 @@ "status.show_more": "Déplier", "status.unmute_conversation": "Ne plus masquer la conversation", "status.unpin": "Retirer du profil", - "tabs_bar.compose": "Composer", "tabs_bar.federated_timeline": "Fil public global", "tabs_bar.home": "Accueil", "tabs_bar.local_timeline": "Fil public local", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 0b91f57ae5e..1c85b4aa2a2 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -1,6 +1,7 @@ { "account.block": "Bloquear @{name}", "account.block_domain": "Ocultar calquer contido de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "A información inferior podería mostrar un perfil incompleto da usuaria.", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", @@ -13,6 +14,7 @@ "account.moved_to": "{name} marchou a:", "account.mute": "Acalar @{name}", "account.mute_notifications": "Acalar as notificacións de @{name}", + "account.muted": "Muted", "account.posts": "Toots", "account.posts_with_replies": "Toots with replies", "account.report": "Informar sobre @{name}", @@ -216,6 +218,7 @@ "report.target": "Informar {target}", "search.placeholder": "Buscar", "search_popout.search_format": "Formato de busca avanzada", + "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": "etiqueta", "search_popout.tips.status": "estado", "search_popout.tips.text": "Texto simple devolve coincidencias con nomes públicos, nomes de usuaria e etiquetas", @@ -238,6 +241,7 @@ "status.mute_conversation": "Acalar conversa", "status.open": "Expandir este estado", "status.pin": "Fixar no perfil", + "status.pinned": "Pinned toot", "status.reblog": "Promover", "status.reblogged_by": "{name} promoveu", "status.reply": "Resposta", @@ -250,7 +254,6 @@ "status.show_more": "Mostrar máis", "status.unmute_conversation": "Non acalar a conversa", "status.unpin": "Despegar do perfil", - "tabs_bar.compose": "Compoñer", "tabs_bar.federated_timeline": "Federado", "tabs_bar.home": "Inicio", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index e430fabf872..28c6f624996 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -1,6 +1,7 @@ { "account.block": "חסימת @{name}", "account.block_domain": "להסתיר הכל מהקהילה {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "המידע להלן עשוי להיות לא עדכני או לא שלם.", "account.edit_profile": "עריכת פרופיל", "account.follow": "מעקב", @@ -13,6 +14,7 @@ "account.moved_to": "החשבון {name} הועבר אל:", "account.mute": "להשתיק את @{name}", "account.mute_notifications": "להסתיר התראות מאת @{name}", + "account.muted": "Muted", "account.posts": "הודעות", "account.posts_with_replies": "Toots with replies", "account.report": "לדווח על @{name}", @@ -216,6 +218,7 @@ "report.target": "דיווח", "search.placeholder": "חיפוש", "search_popout.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": "האשתג", "search_popout.tips.status": "status", "search_popout.tips.text": "טקסט פשוט מחזיר כינויים, שמות משתמש והאשתגים", @@ -238,6 +241,7 @@ "status.mute_conversation": "השתקת שיחה", "status.open": "הרחבת הודעה", "status.pin": "לקבע באודות", + "status.pinned": "Pinned toot", "status.reblog": "הדהוד", "status.reblogged_by": "הודהד על ידי {name}", "status.reply": "תגובה", @@ -250,7 +254,6 @@ "status.show_more": "הראה יותר", "status.unmute_conversation": "הסרת השתקת שיחה", "status.unpin": "לשחרר מקיבוע באודות", - "tabs_bar.compose": "חיבור", "tabs_bar.federated_timeline": "ציר זמן בין-קהילתי", "tabs_bar.home": "בבית", "tabs_bar.local_timeline": "ציר זמן מקומי", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index 543a739bc9a..ce57c3a9cd6 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -1,6 +1,7 @@ { "account.block": "Blokiraj @{name}", "account.block_domain": "Sakrij sve sa {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Ovaj korisnik je sa druge instance. Ovaj broj bi mogao biti veći.", "account.edit_profile": "Uredi profil", "account.follow": "Slijedi", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Utišaj @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Postovi", "account.posts_with_replies": "Toots with replies", "account.report": "Prijavi @{name}", @@ -216,6 +218,7 @@ "report.target": "Prijavljivanje", "search.placeholder": "Traži", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Utišaj razgovor", "status.open": "Proširi ovaj status", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Podigni", "status.reblogged_by": "{name} je podigao", "status.reply": "Odgovori", @@ -250,7 +254,6 @@ "status.show_more": "Pokaži više", "status.unmute_conversation": "Poništi utišavanje razgovora", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Sastavi", "tabs_bar.federated_timeline": "Federalni", "tabs_bar.home": "Dom", "tabs_bar.local_timeline": "Lokalno", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index 38b3698b687..b45e88e8c0e 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -1,6 +1,7 @@ { "account.block": "@{name} letiltása", "account.block_domain": "Minden elrejtése innen: {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Az alul található információk hiányosan mutathatják be a felhasználót.", "account.edit_profile": "Profil szerkesztése", "account.follow": "Követés", @@ -13,6 +14,7 @@ "account.moved_to": "{name} átköltözött:", "account.mute": "@{name} némítása", "account.mute_notifications": "@{name} értesítések némítása", + "account.muted": "Muted", "account.posts": "Státuszok", "account.posts_with_replies": "Toots with replies", "account.report": "@{name} jelentése", @@ -216,6 +218,7 @@ "report.target": "Reporting", "search.placeholder": "Keresés", "search_popout.search_format": "Fejlett keresés", + "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Beszélgetés némítása", "status.open": "Státusz kinagyítása", "status.pin": "Kitűzés a profilra", + "status.pinned": "Pinned toot", "status.reblog": "Reblog", "status.reblogged_by": "{name} reblogolta", "status.reply": "Válasz", @@ -250,7 +254,6 @@ "status.show_more": "Többet", "status.unmute_conversation": "Beszélgetés némításának elvonása", "status.unpin": "Kitűzés eltávolítása a profilról", - "tabs_bar.compose": "Összeállítás", "tabs_bar.federated_timeline": "Federált", "tabs_bar.home": "Kezdőlap", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 15d8f22e6de..58da05911bb 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -1,6 +1,7 @@ { "account.block": "Արգելափակել @{name}֊ին", "account.block_domain": "Թաքցնել ամենը հետեւյալ տիրույթից՝ {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Ներքոհիշյալը կարող է ոչ ամբողջությամբ արտացոլել օգտատիրոջ էջի տվյալները։", "account.edit_profile": "Խմբագրել անձնական էջը", "account.follow": "Հետեւել", @@ -13,6 +14,7 @@ "account.moved_to": "{name}֊ը տեղափոխվել է՝", "account.mute": "Լռեցնել @{name}֊ին", "account.mute_notifications": "Անջատել ծանուցումները @{name}֊ից", + "account.muted": "Muted", "account.posts": "Գրառումներ", "account.posts_with_replies": "Toots with replies", "account.report": "Բողոքել @{name}֊ից", @@ -216,6 +218,7 @@ "report.target": "Բողոքել {target}֊ի մասին", "search.placeholder": "Փնտրել", "search_popout.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": "պիտակ", "search_popout.tips.status": "թութ", "search_popout.tips.text": "Հասարակ տեքստը կվերադարձնի համընկնող անուններ, օգտանուններ ու պիտակներ", @@ -238,6 +241,7 @@ "status.mute_conversation": "Լռեցնել խոսակցությունը", "status.open": "Ընդարձակել այս թութը", "status.pin": "Ամրացնել անձնական էջում", + "status.pinned": "Pinned toot", "status.reblog": "Տարածել", "status.reblogged_by": "{name} տարածել է", "status.reply": "Պատասխանել", @@ -250,7 +254,6 @@ "status.show_more": "Ավելին", "status.unmute_conversation": "Ապալռեցնել խոսակցությունը", "status.unpin": "Հանել անձնական էջից", - "tabs_bar.compose": "Շարադրել", "tabs_bar.federated_timeline": "Դաշնային", "tabs_bar.home": "Հիմնական", "tabs_bar.local_timeline": "Տեղական", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index ac4aaa1aa7e..683d131bf65 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -1,6 +1,7 @@ { "account.block": "Blokir @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Ubah profil", "account.follow": "Ikuti", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Bisukan @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Postingan", "account.posts_with_replies": "Toots with replies", "account.report": "Laporkan @{name}", @@ -216,6 +218,7 @@ "report.target": "Melaporkan", "search.placeholder": "Pencarian", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Tampilkan status ini", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Boost", "status.reblogged_by": "di-boost {name}", "status.reply": "Balas", @@ -250,7 +254,6 @@ "status.show_more": "Tampilkan semua", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Tulis", "tabs_bar.federated_timeline": "Gabungan", "tabs_bar.home": "Beranda", "tabs_bar.local_timeline": "Lokal", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index d431fac49db..221928caa84 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -1,6 +1,7 @@ { "account.block": "Blokusar @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Modifikar profilo", "account.follow": "Sequar", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Celar @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Mesaji", "account.posts_with_replies": "Toots with replies", "account.report": "Denuncar @{name}", @@ -216,6 +218,7 @@ "report.target": "Denuncante", "search.placeholder": "Serchez", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Detaligar ca mesajo", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Repetar", "status.reblogged_by": "{name} repetita", "status.reply": "Respondar", @@ -250,7 +254,6 @@ "status.show_more": "Montrar plue", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Kompozar", "tabs_bar.federated_timeline": "Federata", "tabs_bar.home": "Hemo", "tabs_bar.local_timeline": "Lokala", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index eec1a7febdf..edaede66300 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -1,6 +1,7 @@ { "account.block": "Blocca @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Modifica profilo", "account.follow": "Segui", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Silenzia @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Posts", "account.posts_with_replies": "Toots with replies", "account.report": "Segnala @{name}", @@ -216,6 +218,7 @@ "report.target": "Invio la segnalazione", "search.placeholder": "Cerca", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Espandi questo post", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Condividi", "status.reblogged_by": "{name} ha condiviso", "status.reply": "Rispondi", @@ -250,7 +254,6 @@ "status.show_more": "Mostra di più", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Scrivi", "tabs_bar.federated_timeline": "Federazione", "tabs_bar.home": "Home", "tabs_bar.local_timeline": "Locale", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 4537a6c5e99..f7005a705e5 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -1,6 +1,7 @@ { "account.block": "@{name}さんをブロック", "account.block_domain": "{domain}全体を非表示", + "account.blocked": "Blocked", "account.disclaimer_full": "以下の情報は不正確な可能性があります。", "account.edit_profile": "プロフィールを編集", "account.follow": "フォロー", @@ -13,6 +14,7 @@ "account.moved_to": "{name}さんは引っ越しました:", "account.mute": "@{name}さんをミュート", "account.mute_notifications": "@{name}さんからの通知を受け取らない", + "account.muted": "Muted", "account.posts": "投稿", "account.posts_with_replies": "トゥートと返信", "account.report": "@{name}さんを通報", @@ -216,6 +218,7 @@ "report.target": "{target}さんを通報する", "search.placeholder": "検索", "search_popout.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": "ハッシュタグ", "search_popout.tips.status": "トゥート", "search_popout.tips.text": "表示名やユーザー名、ハッシュタグに一致する単純なテキスト", @@ -238,6 +241,7 @@ "status.mute_conversation": "会話をミュート", "status.open": "詳細を表示", "status.pin": "プロフィールに固定表示", + "status.pinned": "Pinned toot", "status.reblog": "ブースト", "status.reblogged_by": "{name}さんにブーストされました", "status.reply": "返信", @@ -250,7 +254,6 @@ "status.show_more": "もっと見る", "status.unmute_conversation": "会話のミュートを解除", "status.unpin": "プロフィールの固定表示を解除", - "tabs_bar.compose": "投稿", "tabs_bar.federated_timeline": "連合", "tabs_bar.home": "ホーム", "tabs_bar.local_timeline": "ローカル", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index feb4ee90eb6..3c71beafa49 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -1,6 +1,7 @@ { "account.block": "@{name}을 차단", "account.block_domain": "{domain} 전체를 숨김", + "account.blocked": "Blocked", "account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.", "account.edit_profile": "프로필 편집", "account.follow": "팔로우", @@ -13,6 +14,7 @@ "account.moved_to": "{name}는 계정을 이동했습니다:", "account.mute": "@{name} 뮤트", "account.mute_notifications": "@{name}의 알림을 뮤트", + "account.muted": "Muted", "account.posts": "게시물", "account.posts_with_replies": "Toots with replies", "account.report": "@{name} 신고", @@ -239,6 +241,7 @@ "status.mute_conversation": "이 대화를 뮤트", "status.open": "상세 정보 표시", "status.pin": "고정", + "status.pinned": "Pinned toot", "status.reblog": "부스트", "status.reblogged_by": "{name}님이 부스트 했습니다", "status.reply": "답장", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 315f921202a..d3d9ca5c972 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -1,6 +1,7 @@ { "account.block": "Blokkeer @{name}", "account.block_domain": "Negeer alles van {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "De informatie hieronder kan mogelijk een incompleet beeld geven van dit gebruikersprofiel.", "account.edit_profile": "Profiel bewerken", "account.follow": "Volgen", @@ -13,6 +14,7 @@ "account.moved_to": "{name} is verhuisd naar:", "account.mute": "Negeer @{name}", "account.mute_notifications": "Negeer meldingen van @{name}", + "account.muted": "Muted", "account.posts": "Toots", "account.posts_with_replies": "Toots with replies", "account.report": "Rapporteer @{name}", @@ -216,6 +218,7 @@ "report.target": "Rapporteer {target}", "search.placeholder": "Zoeken", "search_popout.search_format": "Geavanceerd zoeken", + "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": "toot", "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags", @@ -238,6 +241,7 @@ "status.mute_conversation": "Negeer conversatie", "status.open": "Toot volledig tonen", "status.pin": "Aan profielpagina vastmaken", + "status.pinned": "Pinned toot", "status.reblog": "Boost", "status.reblogged_by": "{name} boostte", "status.reply": "Reageren", @@ -250,7 +254,6 @@ "status.show_more": "Meer tonen", "status.unmute_conversation": "Conversatie niet meer negeren", "status.unpin": "Van profielpagina losmaken", - "tabs_bar.compose": "Schrijven", "tabs_bar.federated_timeline": "Globaal", "tabs_bar.home": "Start", "tabs_bar.local_timeline": "Lokaal", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index b319ea1a583..ed408d61cb3 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -1,6 +1,7 @@ { "account.block": "Blokkér @{name}", "account.block_domain": "Skjul alt fra {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Informasjonen nedenfor kan gi et ufullstendig bilde av brukerens profil.", "account.edit_profile": "Rediger profil", "account.follow": "Følg", @@ -13,6 +14,7 @@ "account.moved_to": "{name} har flyttet til:", "account.mute": "Demp @{name}", "account.mute_notifications": "Ignorer varsler fra @{name}", + "account.muted": "Muted", "account.posts": "Innlegg", "account.posts_with_replies": "Toots with replies", "account.report": "Rapportér @{name}", @@ -216,6 +218,7 @@ "report.target": "Rapporterer", "search.placeholder": "Søk", "search_popout.search_format": "Avansert søkeformat", + "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": "emneknagg", "search_popout.tips.status": "status", "search_popout.tips.text": "Enkel tekst returnerer matchende visningsnavn, brukernavn og emneknagger", @@ -238,6 +241,7 @@ "status.mute_conversation": "Demp samtale", "status.open": "Utvid denne statusen", "status.pin": "Fest på profilen", + "status.pinned": "Pinned toot", "status.reblog": "Fremhev", "status.reblogged_by": "Fremhevd av {name}", "status.reply": "Svar", @@ -250,7 +254,6 @@ "status.show_more": "Vis mer", "status.unmute_conversation": "Ikke demp samtale", "status.unpin": "Angre festing på profilen", - "tabs_bar.compose": "Komponer", "tabs_bar.federated_timeline": "Felles", "tabs_bar.home": "Hjem", "tabs_bar.local_timeline": "Lokal", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 2402e175948..01a1d21500e 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -1,6 +1,7 @@ { "account.block": "Blocar @{name}", "account.block_domain": "Tot amagar del domeni {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.", "account.edit_profile": "Modificar lo perfil", "account.follow": "Sègre", @@ -13,6 +14,7 @@ "account.moved_to": "{name} a mudat los catons a :", "account.mute": "Rescondre @{name}", "account.mute_notifications": "Rescondre las notificacions de @{name}", + "account.muted": "Muted", "account.posts": "Estatuts", "account.posts_with_replies": "Toots with replies", "account.report": "Senhalar @{name}", @@ -216,6 +218,7 @@ "report.target": "Senhalar {target}", "search.placeholder": "Recercar", "search_popout.search_format": "Format recèrca avançada", + "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": "etiqueta", "search_popout.tips.status": "estatut", "search_popout.tips.text": "Lo tèxt brut tòrna escais, noms d’utilizaire e etiquetas correspondents", @@ -238,6 +241,7 @@ "status.mute_conversation": "Rescondre la conversacion", "status.open": "Desplegar aqueste estatut", "status.pin": "Penjar al perfil", + "status.pinned": "Pinned toot", "status.reblog": "Partejar", "status.reblogged_by": "{name} a partejat", "status.reply": "Respondre", @@ -250,7 +254,6 @@ "status.show_more": "Desplegar", "status.unmute_conversation": "Tornar mostrar la conversacion", "status.unpin": "Tirar del perfil", - "tabs_bar.compose": "Compausar", "tabs_bar.federated_timeline": "Flux public global", "tabs_bar.home": "Acuèlh", "tabs_bar.local_timeline": "Flux public local", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index f95cf5b8166..d914e22fdb5 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -218,6 +218,7 @@ "report.target": "Zgłaszanie {target}", "search.placeholder": "Szukaj", "search_popout.search_format": "Zaawansowane wyszukiwanie", + "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": "wpis", "search_popout.tips.text": "Proste wyszukiwanie pasujących pseudonimów, nazw użytkowników i hashtagów", @@ -253,7 +254,6 @@ "status.show_more": "Pokaż więcej", "status.unmute_conversation": "Cofnij wyciszenie konwersacji", "status.unpin": "Odepnij z profilu", - "tabs_bar.compose": "Napisz", "tabs_bar.federated_timeline": "Globalne", "tabs_bar.home": "Strona główna", "tabs_bar.local_timeline": "Lokalne", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index c07661e9280..8c8039f251f 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -1,6 +1,7 @@ { "account.block": "Bloquear @{name}", "account.block_domain": "Esconder tudo de {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de maneira incompleta.", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", @@ -13,6 +14,7 @@ "account.moved_to": "{name} se mudou para:", "account.mute": "Silenciar @{name}", "account.mute_notifications": "Silenciar notificações de @{name}", + "account.muted": "Muted", "account.posts": "Posts", "account.posts_with_replies": "Toots with replies", "account.report": "Denunciar @{name}", @@ -216,6 +218,7 @@ "report.target": "Denunciar", "search.placeholder": "Pesquisar", "search_popout.search_format": "Formato de busca avançado", + "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": "Texto simples retorna nomes de exibição, usuários e hashtags correspondentes", @@ -238,6 +241,7 @@ "status.mute_conversation": "Silenciar conversa", "status.open": "Expandir", "status.pin": "Fixar no perfil", + "status.pinned": "Pinned toot", "status.reblog": "Compartilhar", "status.reblogged_by": "{name} compartilhou", "status.reply": "Responder", @@ -250,7 +254,6 @@ "status.show_more": "Mostrar mais", "status.unmute_conversation": "Desativar silêncio desta conversa", "status.unpin": "Desafixar do perfil", - "tabs_bar.compose": "Criar", "tabs_bar.federated_timeline": "Global", "tabs_bar.home": "Página inicial", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json index 61233a1b970..b7061693c87 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt.json @@ -1,6 +1,7 @@ { "account.block": "Bloquear @{name}", "account.block_domain": "Esconder tudo do domínio {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de forma incompleta.", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", @@ -13,6 +14,7 @@ "account.moved_to": "{name} mudou a sua conta para:", "account.mute": "Silenciar @{name}", "account.mute_notifications": "Silenciar notificações de @{name}", + "account.muted": "Muted", "account.posts": "Posts", "account.posts_with_replies": "Toots with replies", "account.report": "Denunciar @{name}", @@ -216,6 +218,7 @@ "report.target": "Denunciar", "search.placeholder": "Pesquisar", "search_popout.search_format": "Formato avançado de pesquisa", + "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": "O texto simples retorna a correspondência de nomes, utilizadores e hashtags", @@ -238,6 +241,7 @@ "status.mute_conversation": "Silenciar conversa", "status.open": "Expandir", "status.pin": "Fixar no perfil", + "status.pinned": "Pinned toot", "status.reblog": "Partilhar", "status.reblogged_by": "{name} partilhou", "status.reply": "Responder", @@ -250,7 +254,6 @@ "status.show_more": "Mostrar mais", "status.unmute_conversation": "Deixar de silenciar esta conversa", "status.unpin": "Não fixar no perfil", - "tabs_bar.compose": "Criar", "tabs_bar.federated_timeline": "Global", "tabs_bar.home": "Home", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 76d3fec139d..18fd90d2582 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -1,6 +1,7 @@ { "account.block": "Блокировать", "account.block_domain": "Блокировать все с {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Нижеуказанная информация может не полностью отражать профиль пользователя.", "account.edit_profile": "Изменить профиль", "account.follow": "Подписаться", @@ -13,6 +14,7 @@ "account.moved_to": "Ищите {name} здесь:", "account.mute": "Заглушить", "account.mute_notifications": "Скрыть уведомления от @{name}", + "account.muted": "Muted", "account.posts": "Посты", "account.posts_with_replies": "Toots with replies", "account.report": "Пожаловаться", @@ -216,6 +218,7 @@ "report.target": "Жалуемся на", "search.placeholder": "Поиск", "search_popout.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": "хэштег", "search_popout.tips.status": "статус", "search_popout.tips.text": "Простой ввод текста покажет совпадающие имена пользователей, отображаемые имена и хэштеги", @@ -238,6 +241,7 @@ "status.mute_conversation": "Заглушить тред", "status.open": "Развернуть статус", "status.pin": "Закрепить в профиле", + "status.pinned": "Pinned toot", "status.reblog": "Продвинуть", "status.reblogged_by": "{name} продвинул(а)", "status.reply": "Ответить", @@ -250,7 +254,6 @@ "status.show_more": "Развернуть", "status.unmute_conversation": "Снять глушение с треда", "status.unpin": "Открепить от профиля", - "tabs_bar.compose": "Написать", "tabs_bar.federated_timeline": "Глобальная", "tabs_bar.home": "Главная", "tabs_bar.local_timeline": "Локальная", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index de273770a54..e345a0e7150 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -1,6 +1,7 @@ { "account.block": "Blokovať @{name}", "account.block_domain": "Ukryť všetko z {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Inofrmácie nižšie nemusia byť úplným odrazom uživateľovho účtu.", "account.edit_profile": "Upraviť profil", "account.follow": "Následovať", @@ -13,6 +14,7 @@ "account.moved_to": "{name} sa presunul/a na:", "account.mute": "Ignorovať @{name}", "account.mute_notifications": "Stĺmiť notifikácie od @{name}", + "account.muted": "Muted", "account.posts": "Hlášky", "account.posts_with_replies": "Toots with replies", "account.report": "Nahlásiť @{name}", @@ -216,6 +218,7 @@ "report.target": "Nahlásenie {target}", "search.placeholder": "Hľadať", "search_popout.search_format": "Pokročilý formát vyhľadávania", + "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": "haštag", "search_popout.tips.status": "status", "search_popout.tips.text": "Jednoduchý text vráti zhodujúce sa mená, prezývky a hashtagy", @@ -238,6 +241,7 @@ "status.mute_conversation": "Ignorovať konverzáciu", "status.open": "Otvoriť tento status", "status.pin": "Pripnúť na profil", + "status.pinned": "Pinned toot", "status.reblog": "Povýšiť", "status.reblogged_by": "{name} povýšil", "status.reply": "Odpovedať", @@ -250,7 +254,6 @@ "status.show_more": "Zobraz viac", "status.unmute_conversation": "Prestať ignorovať konverzáciu", "status.unpin": "Odopnúť z profilu", - "tabs_bar.compose": "Napísať", "tabs_bar.federated_timeline": "Federovaná", "tabs_bar.home": "Domov", "tabs_bar.local_timeline": "Lokálna", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index bf67a52d6dd..ac93aa0136e 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -1,6 +1,7 @@ { "account.block": "Blokiraj korisnika @{name}", "account.block_domain": "Sakrij sve sa domena {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Navedene informacije možda ne odslikavaju korisnički profil u potpunosti.", "account.edit_profile": "Izmeni profil", "account.follow": "Zaprati", @@ -13,6 +14,7 @@ "account.moved_to": "{name} se pomerio na:", "account.mute": "Ućutkaj korisnika @{name}", "account.mute_notifications": "Isključi obaveštenja od korisnika @{name}", + "account.muted": "Muted", "account.posts": "Statusa", "account.posts_with_replies": "Toots with replies", "account.report": "Prijavi @{name}", @@ -216,6 +218,7 @@ "report.target": "Prijavljujem {target}", "search.placeholder": "Pretraga", "search_popout.search_format": "Napredni format pretrage", + "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": "hešteg", "search_popout.tips.status": "status", "search_popout.tips.text": "Traženjem običnog teksta ćete dobiti sva pronađena imena, sva korisnička imena i sve nađene heštegove", @@ -238,6 +241,7 @@ "status.mute_conversation": "Ućutkaj prepisku", "status.open": "Proširi ovaj status", "status.pin": "Prikači na profil", + "status.pinned": "Pinned toot", "status.reblog": "Podrži", "status.reblogged_by": "{name} podržao(la)", "status.reply": "Odgovori", @@ -250,7 +254,6 @@ "status.show_more": "Prikaži više", "status.unmute_conversation": "Uključi prepisku", "status.unpin": "Otkači sa profila", - "tabs_bar.compose": "Napiši", "tabs_bar.federated_timeline": "Federisano", "tabs_bar.home": "Početna", "tabs_bar.local_timeline": "Lokalno", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index d8d1ebae74c..ac1afa682b0 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -1,6 +1,7 @@ { "account.block": "Блокирај корисника @{name}", "account.block_domain": "Сакриј све са домена {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Наведене информације можда не одсликавају кориснички профил у потпуности.", "account.edit_profile": "Измени профил", "account.follow": "Запрати", @@ -13,6 +14,7 @@ "account.moved_to": "{name} се померио на:", "account.mute": "Ућуткај корисника @{name}", "account.mute_notifications": "Искључи обавештења од корисника @{name}", + "account.muted": "Muted", "account.posts": "Статуса", "account.posts_with_replies": "Toots with replies", "account.report": "Пријави @{name}", @@ -216,6 +218,7 @@ "report.target": "Пријављујем {target}", "search.placeholder": "Претрага", "search_popout.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": "хештег", "search_popout.tips.status": "статус", "search_popout.tips.text": "Тражењем обичног текста ћете добити сва пронађена имена, сва корисничка имена и све нађене хештегове", @@ -238,6 +241,7 @@ "status.mute_conversation": "Ућуткај преписку", "status.open": "Прошири овај статус", "status.pin": "Прикачи на профил", + "status.pinned": "Pinned toot", "status.reblog": "Подржи", "status.reblogged_by": "{name} подржао(ла)", "status.reply": "Одговори", @@ -250,7 +254,6 @@ "status.show_more": "Прикажи више", "status.unmute_conversation": "Укључи преписку", "status.unpin": "Откачи са профила", - "tabs_bar.compose": "Напиши", "tabs_bar.federated_timeline": "Федерисано", "tabs_bar.home": "Почетна", "tabs_bar.local_timeline": "Локално", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 0bf66c54746..09d846a1aeb 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -1,6 +1,7 @@ { "account.block": "Blockera @{name}", "account.block_domain": "Dölj allt från {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Informationen nedan kan spegla användarens profil ofullständigt.", "account.edit_profile": "Redigera profil", "account.follow": "Följ", @@ -13,6 +14,7 @@ "account.moved_to": "{name} har flyttat till:", "account.mute": "Tysta @{name}", "account.mute_notifications": "Stäng av notifieringar från @{name}", + "account.muted": "Muted", "account.posts": "Inlägg", "account.posts_with_replies": "Toots with replies", "account.report": "Rapportera @{name}", @@ -216,6 +218,7 @@ "report.target": "Rapporterar {target}", "search.placeholder": "Sök", "search_popout.search_format": "Avancerat sökformat", + "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": "Enkel text returnerar matchande visningsnamn, användarnamn och hashtags", @@ -238,6 +241,7 @@ "status.mute_conversation": "Tysta konversation", "status.open": "Utvidga denna status", "status.pin": "Fäst i profil", + "status.pinned": "Pinned toot", "status.reblog": "Knuff", "status.reblogged_by": "{name} knuffade", "status.reply": "Svara", @@ -250,7 +254,6 @@ "status.show_more": "Visa mer", "status.unmute_conversation": "Öppna konversation", "status.unpin": "Ångra fäst i profil", - "tabs_bar.compose": "Skriv", "tabs_bar.federated_timeline": "Förenad", "tabs_bar.home": "Hem", "tabs_bar.local_timeline": "Lokal", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index d6ccc9412c2..acd4d4ff97a 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -1,6 +1,7 @@ { "account.block": "Block @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Edit profile", "account.follow": "Follow", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Posts", "account.posts_with_replies": "Toots with replies", "account.report": "Report @{name}", @@ -216,6 +218,7 @@ "report.target": "Reporting", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Expand this status", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Boost", "status.reblogged_by": "{name} boosted", "status.reply": "Reply", @@ -250,7 +254,6 @@ "status.show_more": "Show more", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Compose", "tabs_bar.federated_timeline": "Federated", "tabs_bar.home": "Home", "tabs_bar.local_timeline": "Local", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 702c8454db5..5b898d5af4d 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -1,6 +1,7 @@ { "account.block": "Engelle @{name}", "account.block_domain": "Hide everything from {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Profili düzenle", "account.follow": "Takip et", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Sustur @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Gönderiler", "account.posts_with_replies": "Toots with replies", "account.report": "Rapor et @{name}", @@ -216,6 +218,7 @@ "report.target": "Raporlama", "search.placeholder": "Ara", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Mute conversation", "status.open": "Bu gönderiyi genişlet", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Boost'la", "status.reblogged_by": "{name} boost etti", "status.reply": "Cevapla", @@ -250,7 +254,6 @@ "status.show_more": "Daha fazlası", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Oluştur", "tabs_bar.federated_timeline": "Federe", "tabs_bar.home": "Ana sayfa", "tabs_bar.local_timeline": "Yerel", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index b5bd88cbbd5..6d2aa5599ea 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -1,6 +1,7 @@ { "account.block": "Заблокувати", "account.block_domain": "Заглушити {domain}", + "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.edit_profile": "Налаштування профілю", "account.follow": "Підписатися", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "Заглушити", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "Пости", "account.posts_with_replies": "Toots with replies", "account.report": "Поскаржитися", @@ -216,6 +218,7 @@ "report.target": "Скаржимося на", "search.placeholder": "Пошук", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "Заглушити діалог", "status.open": "Розгорнути допис", "status.pin": "Pin on profile", + "status.pinned": "Pinned toot", "status.reblog": "Передмухнути", "status.reblogged_by": "{name} передмухнув(-ла)", "status.reply": "Відповісти", @@ -250,7 +254,6 @@ "status.show_more": "Розгорнути", "status.unmute_conversation": "Зняти глушення з діалогу", "status.unpin": "Unpin from profile", - "tabs_bar.compose": "Написати", "tabs_bar.federated_timeline": "Глобальна", "tabs_bar.home": "Головна", "tabs_bar.local_timeline": "Локальна", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index 7cc5903cdf0..d6875827a69 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -1,6 +1,7 @@ { "account.block": "屏蔽 @{name}", "account.block_domain": "隐藏来自 {domain} 的内容", + "account.blocked": "Blocked", "account.disclaimer_full": "此处显示的信息可能不是全部内容。", "account.edit_profile": "修改个人资料", "account.follow": "关注", @@ -13,6 +14,7 @@ "account.moved_to": "{name} 已经迁移到:", "account.mute": "隐藏 @{name}", "account.mute_notifications": "隐藏来自 @{name} 的通知", + "account.muted": "Muted", "account.posts": "嘟文", "account.posts_with_replies": "Toots with replies", "account.report": "举报 @{name}", @@ -216,6 +218,7 @@ "report.target": "举报 {target}", "search.placeholder": "搜索", "search_popout.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": "话题标签", "search_popout.tips.status": "嘟文", "search_popout.tips.text": "使用普通字符进行搜索将会返回昵称、用户名和话题标签", @@ -238,6 +241,7 @@ "status.mute_conversation": "隐藏此对话", "status.open": "展开嘟文", "status.pin": "在个人资料页面置顶", + "status.pinned": "Pinned toot", "status.reblog": "转嘟", "status.reblogged_by": "{name} 转嘟了", "status.reply": "回复", @@ -250,7 +254,6 @@ "status.show_more": "显示内容", "status.unmute_conversation": "不再隐藏此对话", "status.unpin": "在个人资料页面取消置顶", - "tabs_bar.compose": "撰写", "tabs_bar.federated_timeline": "跨站", "tabs_bar.home": "主页", "tabs_bar.local_timeline": "本站", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index d21ecc463a7..e05e611d071 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -1,6 +1,7 @@ { "account.block": "封鎖 @{name}", "account.block_domain": "隱藏來自 {domain} 的一切文章", + "account.blocked": "Blocked", "account.disclaimer_full": "下列資料不一定完整。", "account.edit_profile": "修改個人資料", "account.follow": "關注", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "將 @{name} 靜音", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "文章", "account.posts_with_replies": "Toots with replies", "account.report": "舉報 @{name}", @@ -216,6 +218,7 @@ "report.target": "舉報", "search.placeholder": "搜尋", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "靜音對話", "status.open": "展開文章", "status.pin": "置頂到資料頁", + "status.pinned": "Pinned toot", "status.reblog": "轉推", "status.reblogged_by": "{name} 轉推", "status.reply": "回應", @@ -250,7 +254,6 @@ "status.show_more": "顯示更多", "status.unmute_conversation": "解禁對話", "status.unpin": "解除置頂", - "tabs_bar.compose": "撰寫", "tabs_bar.federated_timeline": "跨站", "tabs_bar.home": "主頁", "tabs_bar.local_timeline": "本站", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index f1ae29283e9..19ceed99472 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -1,6 +1,7 @@ { "account.block": "封鎖 @{name}", "account.block_domain": "隱藏來自 {domain} 的一切貼文", + "account.blocked": "Blocked", "account.disclaimer_full": "下列資料不一定完整。", "account.edit_profile": "編輯用者資訊", "account.follow": "關注", @@ -13,6 +14,7 @@ "account.moved_to": "{name} has moved to:", "account.mute": "消音 @{name}", "account.mute_notifications": "Mute notifications from @{name}", + "account.muted": "Muted", "account.posts": "貼文", "account.posts_with_replies": "Toots with replies", "account.report": "檢舉 @{name}", @@ -216,6 +218,7 @@ "report.target": "通報中", "search.placeholder": "搜尋", "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", @@ -238,6 +241,7 @@ "status.mute_conversation": "消音對話", "status.open": "展開這個狀態", "status.pin": "置頂到個人資訊頁", + "status.pinned": "Pinned toot", "status.reblog": "轉推", "status.reblogged_by": "{name} 轉推了", "status.reply": "回應", @@ -250,7 +254,6 @@ "status.show_more": "看更多", "status.unmute_conversation": "不消音對話", "status.unpin": "解除置頂", - "tabs_bar.compose": "編輯", "tabs_bar.federated_timeline": "聯盟", "tabs_bar.home": "家", "tabs_bar.local_timeline": "本地", From bd4057447607146c455c14d53af0b66fc0a46571 Mon Sep 17 00:00:00 2001 From: "Renato \"Lond\" Cerqueira" Date: Mon, 5 Mar 2018 16:27:50 +0100 Subject: [PATCH 18/59] Weblate translations (05-03-2018) (#6640) * Translated using Weblate (French) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Japanese) Currently translated at 98.9% (572 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Catalan) Currently translated at 98.4% (569 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Catalan) Currently translated at 100.0% (578 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Catalan) Currently translated at 100.0% (579 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ca/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (577 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (58 of 58 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/pt_BR/ * Translated using Weblate (French) Currently translated at 99.8% (577 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (French) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Esperanto) Currently translated at 99.6% (576 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/eo/ * Translated using Weblate (Esperanto) Currently translated at 100.0% (58 of 58 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/eo/ * Translated using Weblate (Esperanto) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/eo/ * Translated using Weblate (Arabic) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/ar/ * Translated using Weblate (Slovak) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/ * Translated using Weblate (Slovak) Currently translated at 74.5% (431 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Dutch) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/nl/ * Translated using Weblate (Japanese) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * Translated using Weblate (Dutch) Currently translated at 100.0% (578 of 578 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Dutch) Currently translated at 100.0% (579 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/nl/ * Translated using Weblate (Arabic) Currently translated at 99.6% (271 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/ * Translated using Weblate (Japanese) Currently translated at 98.9% (573 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Japanese) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ja/ * Translated using Weblate (Arabic) Currently translated at 66.6% (386 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Galician) Currently translated at 100.0% (579 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/gl/ * Translated using Weblate (Catalan) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ca/ * Translated using Weblate (Slovak) Currently translated at 100.0% (58 of 58 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/sk/ * 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 (Slovak) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/ * Translated using Weblate (Slovak) Currently translated at 100.0% (62 of 62 strings) Translation: Mastodon/Devise Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/devise/sk/ * Translated using Weblate (Slovak) Currently translated at 75.4% (437 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Polish) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pl/ * Translated using Weblate (Slovak) Currently translated at 83.5% (484 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Slovak) Currently translated at 100.0% (272 of 272 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/ * Normalize translations Ran i18n-tasks normalize && yarn manage:translations --- app/javascript/mastodon/locales/ar.json | 14 ++-- app/javascript/mastodon/locales/ca.json | 14 ++-- app/javascript/mastodon/locales/eo.json | 20 +++--- app/javascript/mastodon/locales/fr.json | 16 ++--- app/javascript/mastodon/locales/ja.json | 2 +- app/javascript/mastodon/locales/nl.json | 12 ++-- app/javascript/mastodon/locales/sk.json | 22 +++---- config/locales/ar.yml | 8 ++- config/locales/ca.yml | 18 ++++++ config/locales/devise.ar.yml | 5 ++ config/locales/devise.sk.yml | 8 +-- config/locales/doorkeeper.sk.yml | 4 +- config/locales/eo.yml | 15 +++++ config/locales/fr.yml | 20 ++++++ config/locales/gl.yml | 18 ++++++ config/locales/ja.yml | 9 ++- config/locales/nl.yml | 20 +++++- config/locales/pl.yml | 2 + config/locales/pt-BR.yml | 22 +++++++ config/locales/simple_form.eo.yml | 2 +- config/locales/simple_form.pt-BR.yml | 2 + config/locales/simple_form.sk.yml | 16 ++--- config/locales/sk.yml | 85 +++++++++++++++++++++++-- 23 files changed, 280 insertions(+), 74 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 41c9c6b0644..6c10833fc35 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -16,7 +16,7 @@ "account.mute_notifications": "كتم إخطارات @{name}", "account.muted": "Muted", "account.posts": "التبويقات", - "account.posts_with_replies": "Toots with replies", + "account.posts_with_replies": "تبويقات تحتوي على رُدود", "account.report": "أبلغ عن @{name}", "account.requested": "في انتظار الموافقة", "account.share": "مشاركة @{name}'s profile", @@ -210,8 +210,8 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "reply_indicator.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.forward": "التحويل إلى {target}", + "report.forward_hint": "هذا الحساب ينتمي إلى خادوم آخَر. هل تودّ إرسال نسخة مجهولة مِن التقرير إلى هنالك أيضًا ؟", "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": "تعليقات إضافية", "report.submit": "إرسال", @@ -223,9 +223,9 @@ "search_popout.tips.status": "حالة", "search_popout.tips.text": "جملة قصيرة تُمكّنُك من عرض أسماء و حسابات و كلمات رمزية", "search_popout.tips.user": "مستخدِم", - "search_results.accounts": "People", - "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", + "search_results.accounts": "أشخاص", + "search_results.hashtags": "الوُسوم", + "search_results.statuses": "التبويقات", "search_results.total": "{count, number} {count, plural, one {result} و {results}}", "standalone.public_title": "نظرة على ...", "status.block": "Block @{name}", @@ -262,7 +262,7 @@ "upload_area.title": "إسحب ثم أفلت للرفع", "upload_button.label": "إضافة وسائط", "upload_form.description": "وصف للمعاقين بصريا", - "upload_form.focus": "Crop", + "upload_form.focus": "قص", "upload_form.undo": "إلغاء", "upload_progress.label": "يرفع...", "video.close": "إغلاق الفيديو", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index eea0d0edb13..fa49d352284 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -16,7 +16,7 @@ "account.mute_notifications": "Notificacions desactivades de @{name}", "account.muted": "Muted", "account.posts": "Toots", - "account.posts_with_replies": "Toots with replies", + "account.posts_with_replies": "Toots amb respostes", "account.report": "Informe @{name}", "account.requested": "Esperant aprovació. Clic per a cancel·lar la petició de seguiment", "account.share": "Comparteix el perfil de @{name}", @@ -210,9 +210,9 @@ "relative_time.minutes": "fa {number} minuts", "relative_time.seconds": "fa {number} segons", "reply_indicator.cancel": "Cancel·lar", - "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.forward": "Reenvia a {target}", + "report.forward_hint": "Aquest compte és d'un altre servidor. Enviar-hi també una copia anònima del informe?", + "report.hint": "El informe s'enviarà als moderadors de la teva instància. Pots explicar perquè vols informar d'aquest compte aquí:", "report.placeholder": "Comentaris addicionals", "report.submit": "Enviar", "report.target": "Informes", @@ -223,8 +223,8 @@ "search_popout.tips.status": "status", "search_popout.tips.text": "El text simple retorna coincidències amb els noms de visualització, els noms d'usuari i els hashtags", "search_popout.tips.user": "usuari", - "search_results.accounts": "People", - "search_results.hashtags": "Hashtags", + "search_results.accounts": "Gent", + "search_results.hashtags": "Etiquetes", "search_results.statuses": "Toots", "search_results.total": "{count, number} {count, plural, un {result} altres {results}}", "standalone.public_title": "Una mirada a l'interior ...", @@ -262,7 +262,7 @@ "upload_area.title": "Arrossega i deixa anar per carregar", "upload_button.label": "Afegir multimèdia", "upload_form.description": "Descriure els problemes visuals", - "upload_form.focus": "Crop", + "upload_form.focus": "Retallar", "upload_form.undo": "Desfer", "upload_progress.label": "Pujant...", "video.close": "Tancar el vídeo", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 8ce035d5eee..d1fcb7fe79b 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -15,8 +15,8 @@ "account.mute": "Silentigi @{name}", "account.mute_notifications": "Silentigi sciigojn el @{name}", "account.muted": "Muted", - "account.posts": "Hupoj", - "account.posts_with_replies": "Toots with replies", + "account.posts": "Mesaĝoj", + "account.posts_with_replies": "Mesaĝoj kun respondoj", "account.report": "Signali @{name}", "account.requested": "Atendo de aprobo. Alklaku por nuligi peton de sekvado", "account.share": "Diskonigi la profilon de @{name}", @@ -149,7 +149,7 @@ "navigation_bar.edit_profile": "Redakti profilon", "navigation_bar.favourites": "Stelumoj", "navigation_bar.follow_requests": "Petoj de sekvado", - "navigation_bar.info": "Pri ĉiu tiu nodo", + "navigation_bar.info": "Pri ĉi tiu nodo", "navigation_bar.keyboard_shortcuts": "Klavaraj mallongigoj", "navigation_bar.lists": "Listoj", "navigation_bar.logout": "Elsaluti", @@ -210,9 +210,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "reply_indicator.cancel": "Nuligi", - "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.forward": "Plusendi al {target}", + "report.forward_hint": "La konto estas en alia servilo. Ĉu sendi sennomigitan kopion de la signalo ankaŭ tien?", + "report.hint": "La signalo estos sendita al la kontrolantoj de via nodo. Vi povas doni klarigon pri kial vi signalas ĉi tiun konton sube:", "report.placeholder": "Pliaj komentoj", "report.submit": "Sendi", "report.target": "Signali {target}", @@ -223,9 +223,9 @@ "search_popout.tips.status": "mesaĝoj", "search_popout.tips.text": "Simpla teksto montras la kongruajn afiŝitajn nomojn, uzantnomojn kaj kradvortojn", "search_popout.tips.user": "uzanto", - "search_results.accounts": "People", - "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", + "search_results.accounts": "Homoj", + "search_results.hashtags": "Kradvortoj", + "search_results.statuses": "Mesaĝoj", "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}", "standalone.public_title": "Enrigardo…", "status.block": "Bloki @{name}", @@ -262,7 +262,7 @@ "upload_area.title": "Altreni kaj lasi por alŝuti", "upload_button.label": "Aldoni aŭdovidaĵon", "upload_form.description": "Priskribi por misvidantaj homoj", - "upload_form.focus": "Crop", + "upload_form.focus": "Stuci", "upload_form.undo": "Malfari", "upload_progress.label": "Alŝutado…", "video.close": "Fermi videon", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index ad1368e9383..86a23b264b1 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -15,8 +15,8 @@ "account.mute": "Masquer @{name}", "account.mute_notifications": "Ignorer les notifications de @{name}", "account.muted": "Muted", - "account.posts": "Statuts", - "account.posts_with_replies": "Toots with replies", + "account.posts": "Pouets", + "account.posts_with_replies": "Pouets avec réponses", "account.report": "Signaler", "account.requested": "Invitation envoyée", "account.share": "Partager le profil de @{name}", @@ -210,9 +210,9 @@ "relative_time.minutes": "{number} min", "relative_time.seconds": "{number} s", "reply_indicator.cancel": "Annuler", - "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.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.placeholder": "Commentaires additionnels", "report.submit": "Envoyer", "report.target": "Signalement", @@ -223,9 +223,9 @@ "search_popout.tips.status": "statuts", "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les noms d’utilisateur⋅ice et les hashtags correspondants", "search_popout.tips.user": "utilisateur⋅ice", - "search_results.accounts": "People", + "search_results.accounts": "Personnes", "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", + "search_results.statuses": "Pouets", "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}", "standalone.public_title": "Jeter un coup d’œil…", "status.block": "Block @{name}", @@ -262,7 +262,7 @@ "upload_area.title": "Glissez et déposez pour envoyer", "upload_button.label": "Joindre un média", "upload_form.description": "Décrire pour les malvoyants", - "upload_form.focus": "Crop", + "upload_form.focus": "Recadrer", "upload_form.undo": "Annuler", "upload_progress.label": "Envoi en cours…", "video.close": "Fermer la vidéo", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index f7005a705e5..fd47e7dc940 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -16,7 +16,7 @@ "account.mute_notifications": "@{name}さんからの通知を受け取らない", "account.muted": "Muted", "account.posts": "投稿", - "account.posts_with_replies": "トゥートと返信", + "account.posts_with_replies": "投稿と返信", "account.report": "@{name}さんを通報", "account.requested": "フォロー承認待ちです。クリックしてキャンセル", "account.share": "@{name}さんのプロフィールを共有する", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index d3d9ca5c972..068729cdf14 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -16,7 +16,7 @@ "account.mute_notifications": "Negeer meldingen van @{name}", "account.muted": "Muted", "account.posts": "Toots", - "account.posts_with_replies": "Toots with replies", + "account.posts_with_replies": "Toots met reacties", "account.report": "Rapporteer @{name}", "account.requested": "Wacht op goedkeuring. Klik om het volgverzoek te annuleren", "account.share": "Profiel van @{name} delen", @@ -210,9 +210,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "reply_indicator.cancel": "Annuleren", - "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.forward": "Doorsturen naar {target}", + "report.forward_hint": "Het account bevindt zich op een andere server. Stuur daar eveneens een geanonimiseerde kopie van de gerapporteerde toot(s) naartoe?", + "report.hint": "De gerapporteerde toot(s) worden naar de moderatoren van jouw server gestuurd. Je kunt hieronder een uitleg geven waarom je dit account rapporteert:", "report.placeholder": "Extra opmerkingen", "report.submit": "Verzenden", "report.target": "Rapporteer {target}", @@ -223,7 +223,7 @@ "search_popout.tips.status": "toot", "search_popout.tips.text": "Gebruik gewone tekst om te zoeken op weergavenamen, gebruikersnamen en hashtags", "search_popout.tips.user": "gebruiker", - "search_results.accounts": "People", + "search_results.accounts": "Gebruikers", "search_results.hashtags": "Hashtags", "search_results.statuses": "Toots", "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}", @@ -262,7 +262,7 @@ "upload_area.title": "Hierin slepen om te uploaden", "upload_button.label": "Media toevoegen", "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking", - "upload_form.focus": "Crop", + "upload_form.focus": "Bijsnijden", "upload_form.undo": "Ongedaan maken", "upload_progress.label": "Uploaden...", "video.close": "Video sluiten", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index e345a0e7150..6239abb3a3c 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -7,7 +7,7 @@ "account.follow": "Následovať", "account.followers": "Sledujúci", "account.follows": "Sledujete", - "account.follows_you": "Následuje vás", + "account.follows_you": "Následuje ťa", "account.hide_reblogs": "Skryť povýšenia od @{name}", "account.media": "Médiá", "account.mention": "Spomeňte @{name}", @@ -16,7 +16,7 @@ "account.mute_notifications": "Stĺmiť notifikácie od @{name}", "account.muted": "Muted", "account.posts": "Hlášky", - "account.posts_with_replies": "Toots with replies", + "account.posts_with_replies": "Príspevky s odpoveďami", "account.report": "Nahlásiť @{name}", "account.requested": "Čaká na schválenie. Kliknite pre zrušenie žiadosti", "account.share": "Zdieľať @{name} profil", @@ -158,8 +158,8 @@ "navigation_bar.preferences": "Možnosti", "navigation_bar.public_timeline": "Federovaná časová os", "notification.favourite": "{name} sa páči tvoj status", - "notification.follow": "{name} vás začal(a) sledovať", - "notification.mention": "{name} vás spomenul", + "notification.follow": "{name} ťa začal/a následovať", + "notification.mention": "{name} ťa spomenul/a", "notification.reblog": "{name} re-tootol tvoj status", "notifications.clear": "Vyčistiť zoznam notifikácii", "notifications.clear_confirmation": "Naozaj chcete nenávratne prečistiť všetky vaše notifikácie?", @@ -210,9 +210,9 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "reply_indicator.cancel": "Zrušiť", - "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.forward": "Posuň ku {target}", + "report.forward_hint": "Tento účet je z iného serveru. Chceš poslať anonymnú kópiu reportu aj tam?", + "report.hint": "Toto nahlásenie bude zaslané správcom servera. Môžeš napísať odvôvodnenie prečo si nahlásil/a tento účet:", "report.placeholder": "Ďalšie komentáre", "report.submit": "Poslať", "report.target": "Nahlásenie {target}", @@ -223,9 +223,9 @@ "search_popout.tips.status": "status", "search_popout.tips.text": "Jednoduchý text vráti zhodujúce sa mená, prezývky a hashtagy", "search_popout.tips.user": "používateľ", - "search_results.accounts": "People", - "search_results.hashtags": "Hashtags", - "search_results.statuses": "Toots", + "search_results.accounts": "Ľudia", + "search_results.hashtags": "Haštagy", + "search_results.statuses": "Príspevky", "search_results.total": "{count, number} {count, plural, one {result} ostatné {results}}", "standalone.public_title": "Pohľad dovnútra...", "status.block": "Blokovať @{name}", @@ -262,7 +262,7 @@ "upload_area.title": "Ťahaj a pusti pre nahratie", "upload_button.label": "Pridať médiá", "upload_form.description": "Opis pre slabo vidiacich", - "upload_form.focus": "Crop", + "upload_form.focus": "Vystrihni", "upload_form.undo": "Navrátiť", "upload_progress.label": "Nahráva sa...", "video.close": "Zavrieť video", diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 6ec498efad7..f641d3c2e0c 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -188,6 +188,8 @@ ar: site_title: إسم مثيل الخادم thumbnail: title: الصورة الرمزية المصغرة لمثيل الخادوم + timeline_preview: + desc_html: عرض الخيط العمومي على صفحة الإستقبال title: إعدادات الموقع statuses: back_to_account: العودة إلى صفحة الحساب @@ -221,11 +223,13 @@ ar: change_password: الهوية confirm_email: تأكيد عنوان البريد الإلكتروني delete_account: حذف حساب + delete_account_html: إن كنت ترغب في حذف حسابك يُمكنك المواصلة هنا. سوف يُطلَبُ منك التأكيد قبل الحذف. didnt_get_confirmation: لم تتلق تعليمات التأكيد ؟ forgot_password: نسيت كلمة المرور ؟ login: تسجيل الدخول logout: خروج migrate_account: الإنتقال إلى حساب آخر + migrate_account_html: إن كنت ترغب في تحويل هذا الحساب نحو حساب آخَر، يُمكِنُك إعداده هنا. or_log_in_with: أو قم بتسجيل الدخول بواسطة providers: cas: CAS @@ -414,6 +418,7 @@ ar: weibo: وايبو current_session: الجلسة الحالية description: "%{browser} على %{platform}" + explanation: ها هي قائمة مُتصفِّحات الويب التي تستخدِم حاليًا حساب ماستدون الخاص بك. ip: عنوان الإيبي platforms: adobe_air: أدوبي إيير @@ -455,7 +460,8 @@ ar: private_long: إعرضه لمتتبعيك فقط public: للعامة public_long: يمكن للجميع رؤيته - unlisted: Public, but do not display on the public timeline + unlisted: غير مُدرَج + unlisted_long: يُمكن لأيٍ كان رُؤيتَه و لكن لن يُعرَض على الخيوط العامة stream_entries: click_to_show: إضغط للعرض reblogged: رقى diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 054917fb960..5552202e514 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -273,6 +273,9 @@ ca: contact_information: email: Introdueix una adreça de correu electrònic píblica username: Nom d'usuari del contacte + hero: + desc_html: Es mostra en pàgina frontal. Recomanat 600x100px al menys. Si no es configura es mostrarà el de la instància + title: Imatge d’heroi peers_api_enabled: desc_html: Els noms de domini que ha trobat aquesta instància al fediverse title: Publica la llista d'instàncies descobertes @@ -367,6 +370,7 @@ ca: logout: Tanca sessió migrate_account: Mou a un compte diferent migrate_account_html: Si vols redirigir aquest compte a un altre diferent, el pots configurar aquí. + or: o or_log_in_with: O inicia sessió amb providers: cas: CAS @@ -420,6 +424,13 @@ ca: title: Aquesta pàgina no es correcta noscript_html: Per a utilitzar Mastodon, activa el JavaScript. També pots provar una de les aplicacions natives de Mastodon per a la vostra plataforma. exports: + 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. + in_progress: Compilant el teu arxiu... + request: Sol·licita el teu arxiu + size: Tamany blocks: Persones que has blocat csv: CSV follows: Persones que segueixes @@ -535,7 +546,9 @@ ca: trillion: T unit: " " pagination: + newer: Més recent next: Endavant + older: Més vell prev: Enrere truncate: "…" preferences: @@ -732,6 +745,10 @@ ca: setup: Establir wrong_code: El codi introduït no és vàlid! És correcta l'hora del servidor i del dispositiu? user_mailer: + backup_ready: + explanation: Has sol·licitat una copia completa del teu compte Mastodon. Ara ja està a punt per descàrrega! + subject: El teu arxiu està preparat per a descàrrega + title: Recollida del arxiu welcome: edit_profile_action: Configurar perfil edit_profile_step: Pots personalitzar el teu perfil penjant un avatar, un encapçalament, canviant el teu nom de visualització i molt més. Si prefereixes revisar els seguidors nous abans de que et puguin seguir, pots blocar el teu compte. @@ -753,4 +770,5 @@ ca: users: invalid_email: L'adreça de correu no és correcta invalid_otp_token: El codi de dos factors no és correcte + 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/devise.ar.yml b/config/locales/devise.ar.yml index 564231a1d43..4e302d3eaab 100644 --- a/config/locales/devise.ar.yml +++ b/config/locales/devise.ar.yml @@ -49,6 +49,7 @@ ar: failure: تعذرت المصادقة من %{kind} بسبب "%{reason}". success: تمت المصادقة بنجاح عبر حساب %{kind}. passwords: + no_token: ليس بإمكانك النفاذ إلى هذه الصفحة إن لم تقم بالنقر على الرابط المتواجد في الرسالة الإلكترونية. الرجاء التحقق مِن أنك قمت بإدخال عنوان الرابط كاملا كما هو مذكور في رسالة إعادة تعيين الكلمة السرية. send_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج. send_paranoid_instructions: إن كان عنوان بريدك الإلكتروني ضمن قاعدة بياناتنا، فسوف تتلقّى في غضون دقائق رابطا يُمكّنُك مِن استعادة كلمتك السرية على عنوان علبة البريد الإلكتروني الخاصة بك.إن لم تجد هذه الرسالة، يرجى تفقد مجلّد البريد المزعج. updated: تم تغيير كلمة المرور بنجاح. أنت مسجل الآن. @@ -72,6 +73,10 @@ ar: errors: messages: already_confirmed: قمت بتأكيده من قبل، يرجى إعادة محاولة تسجيل الدخول + confirmation_period_expired: يجب التأكد منه قبل انقضاء مدة %{period}، يرجى إعادة طلب جديد expired: إنتهت مدة صلاحيته، الرجاء طلب واحد جديد not_found: لا يوجد not_locked: ليس مقفلاً + not_saved: + one: 'خطأ واحد منَعَ %{resource} مِن القيام بالإحتفاظ :' + other: "%{count} أخطاء منعت %{resource} مِن القيام بالإحتفاظ :" diff --git a/config/locales/devise.sk.yml b/config/locales/devise.sk.yml index f71f8c62c4f..2ce328d22d1 100644 --- a/config/locales/devise.sk.yml +++ b/config/locales/devise.sk.yml @@ -46,8 +46,8 @@ sk: unlock_instructions: subject: 'Mastodon: Inštrukcie pre odomknutie účtu' omniauth_callbacks: - failure: Nebolo možné vás autentifikovať z %{kind} z dôvodu "%{reason}". - success: Úspešne autentifikovaný z účtu %{kind}. + failure: Nebolo možné ťa overiť z dôvodu,%{kind} že "%{reason}". + success: Úspešné overenie z účtu %{kind}. passwords: no_token: Túto stránku nemôžete navštíviť pokiaľ neprichádzate z emailu s inštrukciami na obnovu hesla. Pokiaľ prichádzate z tohto emailu, prosím uistite sa že ste použili celú URL z emailu. send_instructions: Ak zadaný email existuje v našej databázi, tak o niekoľko minút obdržíte email s inštrukciami ako nastaviť nové heslo. @@ -57,8 +57,8 @@ sk: registrations: destroyed: Dovidenia! Váš účet bol úspešne zrušený. Dúfame ale, že sa tu opäť niekedy zastavíte. signed_up: Vitajte! Vaša registrácia bola úspešná. - signed_up_but_inactive: Registrácia bola úspešná. Avšak, účet ešte nebol aktivovaný, takže vás nemôžeme prihlásiť. - signed_up_but_locked: Prihlasovanie úspešné. Avšak, účet je zablokovaný, takže vás nemôžeme prihlásiť. + signed_up_but_inactive: Registrácia bola úspešná. Avšak, účet ešte nebol aktivovaný, takže ťa nemôžeme prihlásiť. + signed_up_but_locked: Prihlasovanie úspešné. Avšak tvoj účet je zamknutý, takže ťa nieje možné prihlásiť. signed_up_but_unconfirmed: Správa s odkazom potvrdzujúcim registráciu bola poslaná na váš email. Pre aktváciu účtu, kliknite na daný odkaz. update_needs_confirmation: Účet bol úspešne zmenený ale ešte potrebujeme overiť vašu novú emailovú adresu. Pre overenie prosím kliknite na link v správe ktorú sme vám poslali na email. updated: Váš účet bol úspešne aktualizovaný. diff --git a/config/locales/doorkeeper.sk.yml b/config/locales/doorkeeper.sk.yml index a54faebf711..b8fd281f77a 100644 --- a/config/locales/doorkeeper.sk.yml +++ b/config/locales/doorkeeper.sk.yml @@ -91,8 +91,8 @@ sk: unknown: Prístupový token je neplatný resource_owner_authenticator_not_configured: Resource Owner zlyhal pretože Doorkeeper.configure.resource_owner_authenticator nebol nakonfigurovaný. server_error: Nastala neočakávaná chyba na autorizačnom serveri ktorá zabránila vykonať požiadavku. - temporarily_unavailable: Autorizačný server Vás teraz nemôže obslúžiť pretože prebieha údržba alebo je dočasne preťažený. - unauthorized_client: Klient nie je autorizovaný vykonať túto požiadavku touto metódou. + temporarily_unavailable: Autorizačný server ťa teraz nemôže obslúžiť, pretože prebieha údržba alebo je dočasne preťažený. + unauthorized_client: Klient nie je autorizovaný vykonať danú požiadavku takouto metódou. unsupported_grant_type: Tento typ oprávnenia nie je podporovaný autorizačným serverom. unsupported_response_type: Autorizačný server nepodporuje typ tejto odpovede. flash: diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 0a8756b7df6..dee6d4a187d 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -273,6 +273,8 @@ eo: contact_information: email: Publika retadreso username: Kontakta uzantnomo + hero: + desc_html: Montrata en la ĉefpaĝo. Almenaŭ 600x100px rekomendita. Kiam ne agordita, la bildeto de la nodo estos uzata peers_api_enabled: desc_html: Nomoj de domajnoj, kiujn ĉi tiu nodo renkontis en la fediverse title: Publikigi liston de malkovritaj nodoj @@ -422,6 +424,13 @@ eo: Por uzi la retan aplikaĵon de Mastodon, bonvolu ebligi JavaScript. Alimaniere, provu unu el la operaciumaj aplikaĵoj por Mastodon por via platformo. exports: + 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. + in_progress: Kunmetado de via arkivo… + request: Peti vian arkivon + size: Grandeco blocks: Vi blokas csv: CSV follows: Vi sekvas @@ -537,7 +546,9 @@ eo: trillion: Dn unit: " " pagination: + newer: Pli nova next: Sekva + older: Malpli nova prev: Antaŭa truncate: "…" preferences: @@ -734,6 +745,9 @@ eo: setup: Agordi wrong_code: La enmetita kodo estis nevalida! Ĉu la servila tempo kaj la aparata tempo ĝustas? user_mailer: + backup_ready: + explanation: Vi petis kompletan arkivon de via Mastodon-konto. Ĝi nun pretas por elŝutado! + subject: Via arkivo estas preta por elŝutado welcome: edit_profile_action: Agordi profilon edit_profile_step: Vi povas proprigi vian profilon per alŝuto de profilbildo, fonbildo, ŝanĝo de via afiŝita nomo kaj pli. Se vi ŝatus kontroli novajn sekvantojn antaŭ ol ili rajtas sekvi vin, vi povas ŝlosi vian konton. @@ -755,4 +769,5 @@ eo: users: invalid_email: La retadreso estas nevalida invalid_otp_token: Nevalida kodo de dufaktora aŭtentigo + 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/fr.yml b/config/locales/fr.yml index a83854861dd..34910488f21 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -273,6 +273,9 @@ fr: contact_information: email: Entrez une adresse courriel publique username: Entrez un nom d’utilisateur⋅ice + hero: + desc_html: Affichée sur la page d'accueil. Au moins 600x100px recommandé. Lorsqu'elle n'est pas définie, se rabat sur la vignette de l'instance + title: Image d'en-tête peers_api_enabled: desc_html: Noms des domaines que cette instance a découvert dans le fediverse title: Publier la liste des instances découvertes @@ -289,6 +292,9 @@ fr: open: desc_html: Autoriser tout le monde à créer un compte title: Ouvrir les inscriptions + show_known_fediverse_at_about_page: + desc_html: Lorsque l'option est activée, les pouets provenant de toutes les instances connues sont affichés dans la prévisualisation. Si non, seuls les pouets locaux sont affichés. + title: Afficher le fediverse connu dans la prévisualisation du fil show_staff_badge: desc_html: Montrer un badge de responsable sur une page utilisateur title: Montrer un badge de responsable @@ -417,6 +423,13 @@ fr: title: Cette page n’est pas correcte noscript_html: Pour utiliser Mastodon, veuillez activer JavaScript. Sinon, essayez l'une des applications natives pour Mastodon pour votre plate-forme. exports: + 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. + in_progress: Élaboration de votre archive.... + request: Demandez vos archives + size: Taille blocks: Vous bloquez csv: CSV follows: Vous suivez @@ -532,7 +545,9 @@ fr: trillion: T unit: '' pagination: + newer: Jamais next: Suivant + older: Plus ancien prev: Précédent truncate: "…" preferences: @@ -729,6 +744,10 @@ fr: setup: Installer wrong_code: Les codes entrés sont incorrects ! L’heure du serveur et celle de votre appareil sont-elles correctes ? user_mailer: + backup_ready: + explanation: Vous avez demandé une sauvegarde complète de votre compte Mastodon. Elle est maintenant prête à être téléchargée ! + subject: Votre archive est prête à être téléchargée + title: Retrait de l'archive welcome: edit_profile_action: Configuration du profil edit_profile_step: Vous pouvez personnaliser votre profil en téléchargeant un avatar, une image d'en-tête, en changeant votre pseudo et plus encore. Si vous souhaitez examiner les nouveaux abonnés avant qu'ils ne soient autorisés à vous suivre, vous pouvez verrouiller votre compte. @@ -750,4 +769,5 @@ fr: users: invalid_email: L’adresse courriel est invalide invalid_otp_token: Le code d’authentification à deux facteurs est invalide + 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 3333a842f09..def9168cc87 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -273,6 +273,9 @@ gl: contact_information: email: e-mail de traballo username: Nome de usuaria de contacto + hero: + desc_html: Mostrado na portada. Recoméndase 600x100px como mínimo. Si non se establece, mostrará a imaxe por omisión da instancia + title: Imáxe Heróe peers_api_enabled: desc_html: Nome de dominio que esta instancia atopou no fediverso title: Publicar lista de instancias descubertas @@ -367,6 +370,7 @@ gl: logout: Desconectar migrate_account: Mover a unha conta diferente migrate_account_html: Si desexa redirixir esta conta hacia outra diferente, pode configuralo aquí. + or: ou or_log_in_with: ou conectar con providers: cas: CAS @@ -420,6 +424,13 @@ gl: title: Esta páxina non é correcta noscript_html: Para utilizar a aplicación web de Mastodon debe habilitar JavaScript. De xeito alternativo, intente unha das apps nativas para Mastodon da súa plataforma. exports: + 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. + in_progress: Xerando o seu ficheiro... + request: Solicite o ficheiro + size: Tamaño blocks: A bloquear csv: CSV follows: A seguir @@ -535,7 +546,9 @@ gl: trillion: T unit: " " pagination: + newer: Máis novo next: Seguinte + older: Máis antigo prev: Previo truncate: "…" preferences: @@ -732,6 +745,10 @@ gl: setup: Configurar wrong_code: O código introducido non é válido! Son correctas as horas no dispositivo e o servidor? user_mailer: + backup_ready: + explanation: Solicitou un respaldo completo da súa conta de Mastodon. Xa está listo para descargar! + subject: O seu ficheiro xa está listo para descargar + title: Leve o ficheiro welcome: edit_profile_action: Configurar perfil edit_profile_step: Vostede pode personalizar o seu perfil subindo un avatar, cabeceira, cambiar o seu nome público e aínda máis. Si restrinxe a súa conta pode revisar a conta das personas que solicitan seguilas antes de permitirlles o acceso aos seus toots. @@ -753,4 +770,5 @@ gl: users: invalid_email: O enderezo de correo non é válido invalid_otp_token: Código de doble-factor non válido + 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 bfd0393cb68..1ff50855063 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -274,7 +274,7 @@ ja: email: ビジネスメールアドレス username: 連絡先のユーザー名 hero: - desc_html: フロントページに表示されます。サイズは600x100px以上推奨です。未設定の場合、インスタンスのサムネイルが使用されます。 + desc_html: フロントページに表示されます。サイズは600x100px以上推奨です。未設定の場合、インスタンスのサムネイルが使用されます title: ヒーローイメージ peers_api_enabled: desc_html: 連合内でこのインスタンスが遭遇したドメインの名前 @@ -360,6 +360,7 @@ ja: auth: agreement_html: 登録すると インスタンスのルール利用規約 に従うことに同意したことになります。 change_password: セキュリティ + confirm_email: メールアドレスの確認 delete_account: アカウントの削除 delete_account_html: アカウントを削除したい場合、こちら から手続きが行えます。削除する前に、確認画面があります。 didnt_get_confirmation: 確認メールを受信できませんか? @@ -369,7 +370,11 @@ ja: logout: ログアウト migrate_account: 別のアカウントに引っ越す migrate_account_html: 引っ越し先を明記したい場合はこちらで設定できます。 + or: または or_log_in_with: または次のサービスでログイン + providers: + cas: CAS + saml: SAML register: 登録する resend_confirmation: 確認メールを再送する reset_password: パスワードを再発行 @@ -541,7 +546,9 @@ ja: trillion: T unit: '' pagination: + newer: 新しいトゥート next: 次 + older: 以前のトゥート prev: 前 truncate: "…" preferences: diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 2f44bbfe13c..876b91eafcb 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -273,6 +273,9 @@ nl: contact_information: email: Vul een openbaar gebruikt e-mailadres in username: Vul een gebruikersnaam in + hero: + desc_html: Wordt op de voorpagina getoond. Tenminste 600x100px aanbevolen. Wanneer dit niet is ingesteld wordt de thumbnail van de Mastodonserver getoond + title: Hero-afbeelding peers_api_enabled: desc_html: Domeinnamen die deze server in de fediverse is tegengekomen title: Lijst van bekende servers publiceren @@ -309,7 +312,7 @@ nl: desc_html: Gebruikt als voorvertoning voor OpenGraph en de API. 1200x630px aanbevolen title: Thumbnail Mastodonserver timeline_preview: - desc_html: Toon een openbare tijdlijn op de landingspagina + desc_html: Toon een openbare tijdlijn op de voorpagina title: Tijdlijn als voorbeeld tonen title: Server-instellingen statuses: @@ -367,6 +370,7 @@ nl: logout: Afmelden migrate_account: Naar een andere account verhuizen migrate_account_html: Wanneer je dit account naar een ander account wilt doorverwijzen, kun je dit hier instellen. + or: of or_log_in_with: Of aanmelden met providers: cas: CAS @@ -420,6 +424,13 @@ nl: title: Er is iets mis noscript_html: Schakel JavaScript in om de webapp van Mastodon te kunnen gebruiken. Als alternatief kan je een Mastodon-app zoeken voor jouw platform. exports: + 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. + in_progress: Jouw archief wordt samengesteld... + request: Jouw archief opvragen + size: Omvang blocks: Jij blokkeert csv: CSV follows: Jij volgt @@ -535,7 +546,9 @@ nl: trillion: T unit: " " pagination: + newer: Nieuwer next: Volgende + older: Ouder prev: Vorige truncate: "…" preferences: @@ -732,6 +745,10 @@ nl: setup: Instellen wrong_code: De ingevoerde code is ongeldig! Klopt de systeemtijd van de server en die van jouw apparaat? user_mailer: + backup_ready: + explanation: Je hebt een volledige back-up van jouw Mastodon-account opgevraagd. Het staat nu klaar om te worden gedownload! + subject: Jouw archief staat klaar om te worden gedownload + title: Archief ophalen welcome: edit_profile_action: Profiel instellen edit_profile_step: Je kunt jouw profiel aanpassen door een avatar (profielfoto) en omslagfoto te uploaden, jouw weergavenaam in te stellen en iets over jezelf te vertellen. Wanneer je nieuwe volgers eerst wilt goedkeuren, kun je jouw account besloten maken. @@ -753,4 +770,5 @@ nl: users: invalid_email: E-mailadres is ongeldig invalid_otp_token: Ongeldige tweestaps-aanmeldcode + 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/pl.yml b/config/locales/pl.yml index 539ba7ea4b1..5fcc93f9d74 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -553,7 +553,9 @@ pl: trillion: T unit: '' pagination: + newer: Nowsze next: Następna + older: Starsze prev: Poprzednia truncate: "…" preferences: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index bb787d87cb5..f781b704fc6 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -273,6 +273,9 @@ pt-BR: contact_information: email: E-mail username: Contate usuário + hero: + desc_html: Aparece na página inicial. Ao menos 600x100px é recomendado. Se não estiver definido, o thumbnail da instância é usado no lugar + title: Imagem do herói peers_api_enabled: desc_html: Nomes de domínio que essa instância encontrou no fediverso title: Publicar lista de instâncias descobertas @@ -357,6 +360,7 @@ pt-BR: auth: agreement_html: Ao se cadastrar você concorda em seguir as regras da instância e os nossos termos de serviço. change_password: Segurança + confirm_email: Confirmar e-mail delete_account: Excluir conta delete_account_html: Se você deseja excluir a sua conta, você pode prosseguir para cá. Uma confirmação será requisitada. didnt_get_confirmation: Não recebeu instruções de confirmação? @@ -366,6 +370,10 @@ pt-BR: logout: Sair migrate_account: Mudar para uma conta diferente migrate_account_html: Se você quer redirecionar essa conta para uma outra você pode configurar isso aqui. + or_log_in_with: Ou faça login com + providers: + cas: CAS + saml: SAML register: Cadastrar-se resend_confirmation: Reenviar instruções de confirmação reset_password: Redefinir senha @@ -415,6 +423,13 @@ pt-BR: title: Esta página não está certa noscript_html: Para usar o aplicativo web do Mastodon, por favor ative o JavaScript. Ou, se quiser, experimente um dos apps nativos para o Mastodon em sua plataforma. exports: + 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. + in_progress: Preparando seu arquivo... + request: Solicitar o seu arquivo + size: Tamanho blocks: Você bloqueou csv: CSV follows: Você segue @@ -530,7 +545,9 @@ pt-BR: trillion: T unit: '' pagination: + newer: Mais novo next: Próximo + older: Mais antigo prev: Anterior truncate: "…" preferences: @@ -727,6 +744,10 @@ pt-BR: setup: Configurar wrong_code: O código inserido é invalido! O horário do servidor e o horário do seu aparelho estão corretos? user_mailer: + backup_ready: + explanation: Você pediu um backup completo da sua conta no Mastodon. E agora está pronto para ser baixado! + subject: Seu arquivo está pronto para ser baixado + title: Arquivo "pra viagem" welcome: edit_profile_action: Configurar perfil edit_profile_step: Você pode customizar o seu perfil enviando um avatar, uma imagem de topo, mudando seu nome de exibição, dentre outros. Se você gostaria de aprovar novos seguidores antes que eles possam seguir você, você pode trancar a sua conta. @@ -748,4 +769,5 @@ pt-BR: users: invalid_email: O endereço de e-mail é inválido invalid_otp_token: Código de autenticação inválido + 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.eo.yml b/config/locales/simple_form.eo.yml index 2bb0215d507..dfdd05b05ae 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -44,7 +44,7 @@ eo: setting_boost_modal: Montri fenestron por konfirmi antaŭ ol diskonigi setting_default_privacy: Mesaĝa videbleco setting_default_sensitive: Ĉiam marki aŭdovidaĵojn tiklaj - setting_delete_modal: Montri fenestron por konfirmi antaŭ ol forigi hupon + setting_delete_modal: Montri fenestron por konfirmi antaŭ ol forigi mesaĝon setting_display_sensitive_media: Ĉiam montri aŭdovidaĵon markitajn tiklaj setting_noindex: Ellistiĝi de retserĉila indeksado setting_reduce_motion: Malrapidigi animaciojn diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 2ed0e332977..85dc418bd8c 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -45,6 +45,7 @@ pt-BR: setting_default_privacy: Privacidade das postagens setting_default_sensitive: Sempre marcar mídia como sensível setting_delete_modal: Mostrar diálogo de confirmação antes de deletar uma postagem + setting_display_sensitive_media: Sempre mostrar mídia marcada como sensível setting_noindex: Não quero ser indexado por mecanismos de busca setting_reduce_motion: Reduz movimento em animações setting_system_font_ui: Usar a fonte padrão de seu sistema @@ -53,6 +54,7 @@ pt-BR: severity: Gravidade type: Tipo de importação username: Nome de usuário + username_or_email: Nome de usuário ou e-mail interactions: must_be_follower: Bloquear notificações de não-seguidores must_be_following: Bloquear notificações de pessoas que você não segue diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index 1ef8f2c805b..7312f565c27 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -37,8 +37,8 @@ sk: locked: Zamknúť účet max_uses: Maximálne možno použiť new_password: Nové heslo - note: O vás - otp_attempt: Dvoj-faktorový (2FA) kód + note: O tebe + otp_attempt: Dvoj-faktorový overovací (2FA) kód password: Heslo setting_auto_play_gif: Automaticky prehrávať animované GIFy setting_boost_modal: Zobrazovať potvrdzovacie okno pred re-toot @@ -56,16 +56,16 @@ sk: username: Používateľské meno username_or_email: Prezívka, alebo Email interactions: - must_be_follower: Blokovať notifikácie pod používateľov, ktorí vás nesledujú - must_be_following: Blokovať notifikácie od ľudí ktorý vás nesledujú + must_be_follower: Blokovať notifikácie pod používateľov, ktorí ťa nesledujú + must_be_following: Blokovať notifikácie od ľudí ktorí ťa nesledujú must_be_following_dm: Blokovať súkromné správy od ľudí ktorých nesleduješ notification_emails: digest: Posielať súhrnné emaily favourite: Poslať email ak niekto označí váš príspevok ako obľúbený - follow: Poslať email ak vás niekto začne sledovať - follow_request: Poslať email ak vám niekto pošle žiadosť o sledovanie - mention: Poslať email ak vás niekto spomenie v svojom príspevku - reblog: Poslať email ak niekto re-tootne váš príspevok + follow: Poslať email, ak ťa niekto začne následovať + follow_request: Zaslať email ak ti niekto pošle žiadosť o sledovanie + mention: Poslať email ak ťa niekto spomenie v svojom príspevku + reblog: Poslať email ak niekto re-tootne tvoj príspevok 'no': Nie required: mark: "*" diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 5e5dd42e9c0..9938c2bc4c1 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -1,7 +1,7 @@ --- sk: about: - about_hashtag_html: Toto sú verejné tooty otagované #%{tagom}. Ak máš účet niekde vo fediverse, môžeš ich používať. + about_hashtag_html: Toto sú verejné toot príspevky otagované #%{tagom}. 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 instancii closed_registrations: Registrácie sú momentálne uzatvorené. Avšak, existujú ďalšie Mastodon inštancie kde si môžete založiť účet a získať prístup do tej istej siete z tamaď. @@ -43,11 +43,11 @@ sk: people_followed_by: Ľudia, ktorých %{name} sleduje people_who_follow: Ľudia sledujúci %{name} posts: Tooty - posts_with_replies: Tooty s odpoveďami - remote_follow: Vzdialené sledovanie + posts_with_replies: Toot príspevky s odpoveďami + remote_follow: Sleduj vzdialeného reserved_username: Prihlasovacie meno je rezervované roles: - admin: Admin + admin: Administrátor moderator: Moderátor unfollow: Prestať sledovať admin: @@ -273,6 +273,9 @@ sk: contact_information: email: Pracovný e-mail username: Kontaktné užívateľské meno + hero: + desc_html: Zobrazuje sa na hlavnej stránke. Doporučuje sa rozlišenie aspoň 600x100px Pokiaľ tu nieje nič dodané, bude nastavený základný orázok tohoto serveru + title: Obrázok hrdinu peers_api_enabled: desc_html: Domény na ktoré táto instancia už vo fediverse natrafila title: Zverejniť zoznam objavených instancií @@ -290,7 +293,7 @@ sk: desc_html: Povoliť každému aby si mohli vytvoriť účet title: Verejná registrácia show_known_fediverse_at_about_page: - desc_html: Pokiaľ je zapnuté, bude v ukážke osi možné nahliadnúť statusy z celého známeho fediversa. V opačnom prípade tam budú ukázané iba statusy z lokálnej osi. + desc_html: Pokiaľ je zapnuté, bude v ukážke osi možné nahliadnúť toot statusy z celého známeho fediversa. V opačnom prípade tam budú ukázané iba statusy z lokálnej osi. title: Ukázať celé známe fediversum ako ukážku osi show_staff_badge: desc_html: Zobraziť moderátorsku značku na užívateľovej stránke @@ -367,6 +370,7 @@ sk: logout: Odhlásiť sa migrate_account: Presunúť sa na iný účet migrate_account_html: Pokiaľ si želáte presmerovať tento účet na nejaký iný, môžete tak urobiť tu. + or: alebo or_log_in_with: Alebo prihlásiť z providers: cas: CAS @@ -404,7 +408,7 @@ sk: description_html: Týmto natrvalo, nenavrátiteľne vymažeš obsah tvojho účtu, a deaktivuješ ho. Tvoja prezývka ale ostane rezervovaná ako prevencia pred budúcimi impersonáciami. proceed: Vymazať účet success_msg: Váš účet bol úspešne vymazaný - warning_html: Iba vymazanie obsahu z tejto konkrétnej instancie je garantované. Obsah ktorý bol zdieľaný široko=ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré vás ignorujú nezaktualizujú svoje databázy. + warning_html: Iba vymazanie obsahu z tejto konkrétnej instancie je garantované. Obsah ktorý bol zdieľaný široko-ďaleko pravdepodobne zanechá nejaké stopy. Servery ktoré sú offline a tie ktoré ignorujú tvoje zmeny teda nezaktualizujú svoje databázy. warning_title: Dostupnosť distribuovaného obsahu errors: '403': Nemáte dostatočné povolenie na zobrazenie tejto stránky. @@ -419,6 +423,13 @@ sk: title: Táto stránka nieje v poriadku noscript_html: Aby bolo možné používať Mastodon web aplikáciu, prosím povoľte JavaScript. Alebo skúste jednu z aplikácii dostupných pre vašu platformu. exports: + 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. + in_progress: Balím tvoj archív... + request: Vyžiadaj si tvoj archív + size: Veľkosť blocks: Blokujete csv: CSV follows: Následujete @@ -518,9 +529,71 @@ sk: body: "%{name} ťa spomenul/a v:" subject: Boli ste spomenutí užívateľom %{name} title: Nové spomenutie + reblog: + body: 'Tvoj príspevok bol pozdvihnutý užívateľom %{name}:' + subject: "%{name} pozdvihli tvoj príspevok" + title: Novo pozdvyhnuté + number: + human: + decimal_units: + format: "%n%u" + units: + billion: B + million: M + quadrillion: Q + thousand: K + trillion: T + pagination: + newer: Novšie + next: Ďalšie + older: Staršie + prev: Predošlé + truncate: "…" + preferences: + languages: Jazyky + other: Ostatné + publishing: Publikovanie + web: Web + push_notifications: + favourite: + title: "%{name} si obľúbil/a tvoj príspevok" + follow: + title: "%{name} ťa teraz následuje" + group: + title: "%{count} notifikácie" + mention: + action_boost: Pozdvihni + action_expand: Ukáž viac + action_favourite: Obľúbené + title: "%{name} ťa spomenul/a" + reblog: + title: "%{name} vyzdvihli tvoj príspevok" + remote_follow: + acct: Napíš svoju prezývku@doménu z ktorej chceš následovať + missing_resource: Nemôžeme nájsť potrebnú presmerovaciu adresu k tvojmu účtu + proceed: Začni následovať + prompt: 'Budeš sledovať:' + sessions: + activity: Najnovšia aktivita + browser: Prehliadač + browsers: + alipay: Alipay + generic: Neznámy prehliadač + current_session: Aktuálna sezóna + explanation: Tieto sú prehliadače ktoré sú teraz prihlásené na tvoj Mastodon účet. + ip: IP adresa + platforms: + other: neznáma platforma + revoke: Zamietni + revoke_success: Sezóna úspešne zamietnutá + title: Sezóna settings: authorized_apps: Autorizované aplikácie back: Naspäť na stránku + delete: Zmazanie účtu + development: Vývoj + edit_profile: Upraviť profil + export: Exportovať dáta user_mailer: welcome: final_step: 'Začnite písať! Aj bez následovníkov budú vaše verejné správy videné ostatnými, napríklad na lokálnej osi a pod haštagmi. Môžete sa ostatným predstaviť pod haštagom #introductions.' From 3d4e788ea919d97a12d0a7f5c90eeaba63a51ba1 Mon Sep 17 00:00:00 2001 From: haosbvnker Date: Mon, 5 Mar 2018 16:45:09 +0100 Subject: [PATCH 19/59] Fix permissions for volumes (#6637) When volumes are declared, but the corresponding directories don't exist, permissions for those directories will be root:root instead of mastodon:mastodon.. This changes makes sure the permissions of the volume directories are as expected. --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index dab4e87a64c..c22756d0c75 100644 --- a/Dockerfile +++ b/Dockerfile @@ -70,7 +70,9 @@ RUN bundle config build.nokogiri --with-iconv-lib=/usr/local/lib --with-iconv-in && yarn --pure-lockfile \ && yarn cache clean -RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon +RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodon -u ${UID} mastodon \ + && mkdir -p /mastodon/public/system /mastodon/public/assets /mastodon/public/packs \ + && chown -R mastodon:mastodon /mastodon/public COPY --chown=mastodon:mastodon . /mastodon From 4746feaa1c2e5207b03adbec4a84b23d7cfb63d0 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 5 Mar 2018 16:45:36 +0100 Subject: [PATCH 20/59] =?UTF-8?q?Add=20=E2=80=9CDomain=20hidden=E2=80=9D?= =?UTF-8?q?=20badge=20(#6636)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/mastodon/features/account/components/header.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 075bad3f7a8..bb7b3b6329b 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -94,6 +94,8 @@ export default class Header extends ImmutablePureComponent { if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) { mutingInfo = ; + } else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) { + mutingInfo = ; } if (me !== account.get('id')) { From f6a8d835d30f61628ca731462ecfe4f6005e6a9e Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 03:28:56 +0900 Subject: [PATCH 21/59] Place dropdown menu top if it is closer to the bottom of the viewport (#6641) --- .../mastodon/components/dropdown_menu.js | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 43dc0d6e3e6..42c253449bb 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -29,6 +29,10 @@ class DropdownMenu extends React.PureComponent { placement: 'bottom', }; + state = { + mounted: false, + }; + handleDocumentClick = e => { if (this.node && !this.node.contains(e.target)) { this.props.onClose(); @@ -38,6 +42,7 @@ class DropdownMenu extends React.PureComponent { componentDidMount () { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); + this.setState({ mounted: true }); } componentWillUnmount () { @@ -82,11 +87,15 @@ class DropdownMenu extends React.PureComponent { render () { const { items, style, placement, arrowOffsetLeft, arrowOffsetTop } = this.props; + const { mounted } = this.state; return ( {({ opacity, scaleX, scaleY }) => ( -
+ // It should not be transformed when mounting because the resulting + // size will be used to determine the coordinate of the menu by + // react-overlays +
    @@ -124,11 +133,13 @@ export default class Dropdown extends React.PureComponent { }; state = { - expanded: false, + placement: null, }; - handleClick = () => { - if (!this.state.expanded && this.props.isUserTouching() && this.props.onModalOpen) { + handleClick = ({ target }) => { + if (this.state.placement) { + this.setState({ placement: null }); + } else if (this.props.isUserTouching() && this.props.onModalOpen) { const { status, items } = this.props; this.props.onModalOpen({ @@ -136,11 +147,10 @@ export default class Dropdown extends React.PureComponent { actions: items, onClick: this.handleItemClick, }); - - return; + } else { + const { top } = target.getBoundingClientRect(); + this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); } - - this.setState({ expanded: !this.state.expanded }); } handleClose = () => { @@ -148,7 +158,7 @@ export default class Dropdown extends React.PureComponent { this.props.onModalClose(); } - this.setState({ expanded: false }); + this.setState({ placement: null }); } handleKeyDown = e => { @@ -187,21 +197,22 @@ export default class Dropdown extends React.PureComponent { render () { const { icon, items, size, title, disabled } = this.props; - const { expanded } = this.state; + const { placement } = this.state; + const show = placement !== null; return (
    - +
    From a38dbd9c8a5de4626f55d1a0dcd19ccb4a7e2c91 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 03:29:36 +0900 Subject: [PATCH 22/59] Redirect from Web tag timeline to public tag timeline if not signed in (#6633) This is also implemented in Pawoo: https://github.com/pixiv/mastodon/commit/ceafdbd1bbf30fe20a2a814df0f8cae429a4e9db --- app/controllers/home_controller.rb | 3 ++- spec/controllers/home_controller_spec.rb | 15 +++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb index 21dde20ce40..b1f8f1ad902 100644 --- a/app/controllers/home_controller.rb +++ b/app/controllers/home_controller.rb @@ -34,7 +34,8 @@ class HomeController < ApplicationController end end - redirect_to(default_redirect_path) + matches = request.path.match(%r{\A/web/timelines/tag/(?.+)\z}) + redirect_to(matches ? tag_path(CGI.unescape(matches[:tag])) : default_redirect_path) end def set_initial_state_json diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index 1077a7288b6..f43cf0c27ec 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -4,21 +4,24 @@ RSpec.describe HomeController, type: :controller do render_views describe 'GET #index' do + subject { get :index } + context 'when not signed in' do + context 'when requested path is tag timeline' do + before { @request.path = '/web/timelines/tag/name' } + it { is_expected.to redirect_to '/tags/name' } + end + it 'redirects to about page' do @request.path = '/' - get :index - expect(response).to redirect_to(about_path) + is_expected.to redirect_to(about_path) end end context 'when signed in' do let(:user) { Fabricate(:user) } - subject do - sign_in(user) - get :index - end + before { sign_in(user) } it 'assigns @body_classes' do subject From b0664a5e6cee9be602098fb9a2f98a9e61b2ab9b Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 03:31:40 +0900 Subject: [PATCH 23/59] Replace onScrollToBottom with onLoadMore (#6615) onScrollToBottom was a function to run instead of onScrollToTop and onScroll when scrolling to the bottom. The behavior to prevent onScrollToTop was inconvenient because the viewport can be at the bottom and at the top at the same time if the viewport is larger than the container. onScrollToBottom was also called when the button to load more is clicked on contray to the name suggests, which led notifications and status_list_container components to mark the scrolled location is not at the top mistakenly. onLoadMore is a replacement for onScrollToBottom. It will be called independently from onScrollToTop and onScroll. --- .../mastodon/components/scrollable_list.js | 12 +++++++----- app/javascript/mastodon/components/status_list.js | 2 +- .../mastodon/features/account_timeline/index.js | 4 ++-- .../mastodon/features/favourited_statuses/index.js | 4 ++-- .../mastodon/features/notifications/index.js | 7 +++---- .../features/ui/containers/status_list_container.js | 5 +---- 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js index 71228ca6cb8..ac3e404df4f 100644 --- a/app/javascript/mastodon/components/scrollable_list.js +++ b/app/javascript/mastodon/components/scrollable_list.js @@ -17,7 +17,7 @@ export default class ScrollableList extends PureComponent { static propTypes = { scrollKey: PropTypes.string.isRequired, - onScrollToBottom: PropTypes.func, + onLoadMore: PropTypes.func.isRequired, onScrollToTop: PropTypes.func, onScroll: PropTypes.func, trackScroll: PropTypes.bool, @@ -45,9 +45,11 @@ export default class ScrollableList extends PureComponent { const offset = scrollHeight - scrollTop - clientHeight; this._oldScrollPosition = scrollHeight - scrollTop; - if (400 > offset && this.props.onScrollToBottom && !this.props.isLoading) { - this.props.onScrollToBottom(); - } else if (scrollTop < 100 && this.props.onScrollToTop) { + if (400 > offset && this.props.onLoadMore && !this.props.isLoading) { + this.props.onLoadMore(); + } + + if (scrollTop < 100 && this.props.onScrollToTop) { this.props.onScrollToTop(); } else if (this.props.onScroll) { this.props.onScroll(); @@ -138,7 +140,7 @@ export default class ScrollableList extends PureComponent { handleLoadMore = (e) => { e.preventDefault(); - this.props.onScrollToBottom(); + this.props.onLoadMore(); } _recentlyMoved () { diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js index eb65838cea2..3bebf702cf7 100644 --- a/app/javascript/mastodon/components/status_list.js +++ b/app/javascript/mastodon/components/status_list.js @@ -12,7 +12,7 @@ export default class StatusList extends ImmutablePureComponent { scrollKey: PropTypes.string.isRequired, statusIds: ImmutablePropTypes.list.isRequired, featuredStatusIds: ImmutablePropTypes.list, - onScrollToBottom: PropTypes.func, + onLoadMore: PropTypes.func, onScrollToTop: PropTypes.func, onScroll: PropTypes.func, trackScroll: PropTypes.bool, diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js index 95ae5fd0689..f5f2475ea77 100644 --- a/app/javascript/mastodon/features/account_timeline/index.js +++ b/app/javascript/mastodon/features/account_timeline/index.js @@ -52,7 +52,7 @@ export default class AccountTimeline extends ImmutablePureComponent { } } - handleScrollToBottom = () => { + handleLoadMore = () => { if (!this.props.isLoading && this.props.hasMore) { this.props.dispatch(expandAccountTimeline(this.props.params.accountId, this.props.withReplies)); } @@ -80,7 +80,7 @@ export default class AccountTimeline extends ImmutablePureComponent { featuredStatusIds={featuredStatusIds} isLoading={isLoading} hasMore={hasMore} - onScrollToBottom={this.handleScrollToBottom} + onLoadMore={this.handleLoadMore} /> ); diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.js index 67b107bc8f3..6f1c863b43c 100644 --- a/app/javascript/mastodon/features/favourited_statuses/index.js +++ b/app/javascript/mastodon/features/favourited_statuses/index.js @@ -62,7 +62,7 @@ export default class Favourites extends ImmutablePureComponent { this.column = c; } - handleScrollToBottom = debounce(() => { + handleLoadMore = debounce(() => { this.props.dispatch(expandFavouritedStatuses()); }, 300, { leading: true }) @@ -89,7 +89,7 @@ export default class Favourites extends ImmutablePureComponent { scrollKey={`favourited_statuses-${columnId}`} hasMore={hasMore} isLoading={isLoading} - onScrollToBottom={this.handleScrollToBottom} + onLoadMore={this.handleLoadMore} /> ); diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index 77abfae25ae..cb9d025eafa 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -51,14 +51,13 @@ export default class Notifications extends React.PureComponent { }; componentWillUnmount () { - this.handleScrollToBottom.cancel(); + this.handleLoadMore.cancel(); this.handleScrollToTop.cancel(); this.handleScroll.cancel(); this.props.dispatch(scrollTopNotifications(false)); } - handleScrollToBottom = debounce(() => { - this.props.dispatch(scrollTopNotifications(false)); + handleLoadMore = debounce(() => { this.props.dispatch(expandNotifications()); }, 300, { leading: true }); @@ -143,7 +142,7 @@ export default class Notifications extends React.PureComponent { isLoading={isLoading} hasMore={hasMore} emptyMessage={emptyMessage} - onScrollToBottom={this.handleScrollToBottom} + onLoadMore={this.handleLoadMore} onScrollToTop={this.handleScrollToTop} onScroll={this.handleScroll} shouldUpdateScroll={shouldUpdateScroll} 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 59b53d8235d..fc2867cf050 100644 --- a/app/javascript/mastodon/features/ui/containers/status_list_container.js +++ b/app/javascript/mastodon/features/ui/containers/status_list_container.js @@ -56,10 +56,7 @@ const makeMapStateToProps = () => { const mapDispatchToProps = (dispatch, { timelineId, loadMore }) => ({ - onScrollToBottom: debounce(() => { - dispatch(scrollTopTimeline(timelineId, false)); - loadMore(); - }, 300, { leading: true }), + onLoadMore: debounce(loadMore, 300, { leading: true }), onScrollToTop: debounce(() => { dispatch(scrollTopTimeline(timelineId, true)); From 20d1be18af8c10b6f1bc5597643b85ac6dbae9f2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 6 Mar 2018 00:08:35 +0100 Subject: [PATCH 24/59] Fix accounts' display name/bio not being set from initial state (#6644) --- app/javascript/mastodon/reducers/accounts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/reducers/accounts.js b/app/javascript/mastodon/reducers/accounts.js index f77061dfafc..47e6d233077 100644 --- a/app/javascript/mastodon/reducers/accounts.js +++ b/app/javascript/mastodon/reducers/accounts.js @@ -102,7 +102,7 @@ const initialState = ImmutableMap(); export default function accounts(state = initialState, action) { switch(action.type) { case STORE_HYDRATE: - return state.merge(action.state.get('accounts')); + return normalizeAccounts(state, Object.values(action.state.get('accounts').toJS())); case ACCOUNT_FETCH_SUCCESS: case NOTIFICATIONS_UPDATE: return normalizeAccount(state, action.account); From e9e475a29d7b5039c8ce14de4cef7e4f54fb7b0e Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Tue, 6 Mar 2018 14:14:26 +0900 Subject: [PATCH 25/59] Upgrade chewy to version 5.0.0 (#6649) --- Gemfile | 2 +- Gemfile.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/Gemfile b/Gemfile index b1541086d92..7db6e66b773 100644 --- a/Gemfile +++ b/Gemfile @@ -27,7 +27,7 @@ gem 'bootsnap' gem 'browser' gem 'charlock_holmes', '~> 0.7.5' gem 'iso-639' -gem 'chewy', '~> 0.10', git: 'https://github.com/toptal/chewy.git' +gem 'chewy', '~> 5.0' gem 'cld3', '~> 3.2.0' gem 'devise', '~> 4.4' gem 'devise-two-factor', '~> 3.0' diff --git a/Gemfile.lock b/Gemfile.lock index c2a65ca836b..0640b140b17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,12 +1,3 @@ -GIT - remote: https://github.com/toptal/chewy.git - revision: a7d21eb4b0bd7415533ef134bb6d31b2df309701 - specs: - chewy (0.10.1) - activesupport (>= 4.0) - elasticsearch (>= 2.0.0) - elasticsearch-dsl - GEM remote: https://rubygems.org/ specs: @@ -118,6 +109,10 @@ GEM case_transform (0.2) activesupport charlock_holmes (0.7.5) + chewy (5.0.0) + activesupport (>= 4.0) + elasticsearch (>= 2.0.0) + elasticsearch-dsl chunky_png (1.3.8) cld3 (3.2.2) ffi (>= 1.1.0, < 1.10.0) @@ -631,7 +626,7 @@ DEPENDENCIES capistrano-yarn (~> 2.0) capybara (~> 2.15) charlock_holmes (~> 0.7.5) - chewy (~> 0.10)! + chewy (~> 5.0) cld3 (~> 3.2.0) climate_control (~> 0.2) devise (~> 4.4) From 78d772af862c536b2e985977b6ba549efe668fe0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 6 Mar 2018 06:29:01 +0100 Subject: [PATCH 26/59] Fix #3807: Increase avatars to 400x400 max (#6651) But do not upscale when they are smaller --- app/models/concerns/account_avatar.rb | 4 ++-- lib/paperclip/lazy_thumbnail.rb | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb index 7712a29fd08..9e34a946170 100644 --- a/app/models/concerns/account_avatar.rb +++ b/app/models/concerns/account_avatar.rb @@ -7,8 +7,8 @@ module AccountAvatar class_methods do def avatar_styles(file) - styles = { original: { geometry: '120x120#', file_geometry_parser: FastGeometryParser } } - styles[:static] = { geometry: '120x120#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' + styles = { original: { geometry: '400x400#', file_geometry_parser: FastGeometryParser } } + styles[:static] = { geometry: '400x400#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' styles end diff --git a/lib/paperclip/lazy_thumbnail.rb b/lib/paperclip/lazy_thumbnail.rb index 42f9a557ac7..aafa2134398 100644 --- a/lib/paperclip/lazy_thumbnail.rb +++ b/lib/paperclip/lazy_thumbnail.rb @@ -4,6 +4,10 @@ module Paperclip class LazyThumbnail < Paperclip::Thumbnail def make return File.open(@file.path) unless needs_convert? + + min_side = [@current_geometry.width, @current_geometry.height].min + options[:geometry] = "#{min_side.to_i}x#{min_side.to_i}#" if @target_geometry.square? && min_side < @target_geometry.width + Paperclip::Thumbnail.make(file, options, attachment) end From 61e62757816cd8cfe38944d509f8ec13d7d86912 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 15:28:05 +0900 Subject: [PATCH 27/59] Use withRouter for TabsBar (#6652) TabsBar refers to router, which is a private context property of react-router. withRouter is a recommended alternative. It also allows to track location changes even if React.PureComponent is used. --- .../mastodon/features/ui/components/tabs_bar.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js index 77fe5f5e2fe..dba3be98b03 100644 --- a/app/javascript/mastodon/features/ui/components/tabs_bar.js +++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { NavLink } from 'react-router-dom'; +import { NavLink, withRouter } from 'react-router-dom'; import { FormattedMessage, injectIntl } from 'react-intl'; import { debounce } from 'lodash'; import { isUserTouching } from '../../../is_mobile'; @@ -24,14 +24,12 @@ export function getLink (index) { } @injectIntl -export default class TabsBar extends React.Component { - - static contextTypes = { - router: PropTypes.object.isRequired, - } +@withRouter +export default class TabsBar extends React.PureComponent { static propTypes = { intl: PropTypes.object.isRequired, + history: PropTypes.object.isRequired, } setRef = ref => { @@ -59,7 +57,7 @@ export default class TabsBar extends React.Component { const listener = debounce(() => { nextTab.removeEventListener('transitionend', listener); - this.context.router.history.push(to); + this.props.history.push(to); }, 50); nextTab.addEventListener('transitionend', listener); From 13cf92df271e4459ca9122ec7496fa8208864727 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 15:28:26 +0900 Subject: [PATCH 28/59] Use React.PureComponent instead of React.Component (#6653) --- .../features/notifications/components/clear_column_button.js | 2 +- app/javascript/mastodon/features/ui/components/bundle.js | 2 +- .../mastodon/features/ui/components/bundle_column_error.js | 2 +- .../mastodon/features/ui/components/bundle_modal_error.js | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/features/notifications/components/clear_column_button.js b/app/javascript/mastodon/features/notifications/components/clear_column_button.js index 22a10753f55..e0bf4c82d5b 100644 --- a/app/javascript/mastodon/features/notifications/components/clear_column_button.js +++ b/app/javascript/mastodon/features/notifications/components/clear_column_button.js @@ -2,7 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; -export default class ClearColumnButton extends React.Component { +export default class ClearColumnButton extends React.PureComponent { static propTypes = { onClick: PropTypes.func.isRequired, diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.js index 06a6c9cddf0..e7d93525175 100644 --- a/app/javascript/mastodon/features/ui/components/bundle.js +++ b/app/javascript/mastodon/features/ui/components/bundle.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; const emptyComponent = () => null; const noop = () => { }; -class Bundle extends React.Component { +class Bundle extends React.PureComponent { static propTypes = { fetchComponent: PropTypes.func.isRequired, diff --git a/app/javascript/mastodon/features/ui/components/bundle_column_error.js b/app/javascript/mastodon/features/ui/components/bundle_column_error.js index cd124746acb..f39ebd900b1 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_column_error.js +++ b/app/javascript/mastodon/features/ui/components/bundle_column_error.js @@ -13,7 +13,7 @@ const messages = defineMessages({ retry: { id: 'bundle_column_error.retry', defaultMessage: 'Try again' }, }); -class BundleColumnError extends React.Component { +class BundleColumnError extends React.PureComponent { static propTypes = { onRetry: PropTypes.func.isRequired, diff --git a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js b/app/javascript/mastodon/features/ui/components/bundle_modal_error.js index 928bfe1f7d5..f9365b95bcc 100644 --- a/app/javascript/mastodon/features/ui/components/bundle_modal_error.js +++ b/app/javascript/mastodon/features/ui/components/bundle_modal_error.js @@ -10,7 +10,7 @@ const messages = defineMessages({ close: { id: 'bundle_modal_error.close', defaultMessage: 'Close' }, }); -class BundleModalError extends React.Component { +class BundleModalError extends React.PureComponent { static propTypes = { onRetry: PropTypes.func.isRequired, From a07cfee644a6b854c977903775e083c2a3d827b8 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Tue, 6 Mar 2018 15:45:31 +0900 Subject: [PATCH 29/59] Extract columns area from UI component (#6650) UI component used to toggle isComposing state by directly manipulating the DOM element to avoid the expensive rendering. However, it is hacky, and is not effective for other states. Instead, this change makes the rendering cheaper by extracting the huge columns area. --- app/javascript/mastodon/features/ui/index.js | 163 +++++++++++-------- 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index ef909136f8b..9960758afab 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -1,3 +1,4 @@ +import classNames from 'classnames'; import React from 'react'; import NotificationsContainer from './containers/notifications_container'; import PropTypes from 'prop-types'; @@ -84,10 +85,93 @@ const keyMap = { goToMuted: 'g m', }; +class SwitchingColumnsArea extends React.PureComponent { + + static propTypes = { + children: PropTypes.node, + location: PropTypes.object, + onLayoutChange: PropTypes.func.isRequired, + }; + + state = { + mobile: isMobile(window.innerWidth), + }; + + componentWillMount () { + window.addEventListener('resize', this.handleResize, { passive: true }); + } + + componentDidUpdate (prevProps) { + if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) { + this.node.handleChildrenContentChange(); + } + } + + componentWillUnmount () { + window.removeEventListener('resize', this.handleResize); + } + + handleResize = debounce(() => { + // The cached heights are no longer accurate, invalidate + this.props.onLayoutChange(); + + this.setState({ mobile: isMobile(window.innerWidth) }); + }, 500, { + trailing: true, + }); + + setRef = c => { + this.node = c.getWrappedInstance().getWrappedInstance(); + } + + render () { + const { children } = this.props; + const { mobile } = this.state; + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + } + +} + @connect(mapStateToProps) @injectIntl @withRouter -export default class UI extends React.Component { +export default class UI extends React.PureComponent { static contextTypes = { router: PropTypes.object.isRequired, @@ -103,7 +187,6 @@ export default class UI extends React.Component { }; state = { - width: window.innerWidth, draggingOver: false, }; @@ -118,14 +201,10 @@ export default class UI extends React.Component { } } - handleResize = debounce(() => { + handleLayoutChange = () => { // The cached heights are no longer accurate, invalidate this.props.dispatch(clearHeight()); - - this.setState({ width: window.innerWidth }); - }, 500, { - trailing: true, - }); + } handleDragEnter = (e) => { e.preventDefault(); @@ -193,7 +272,6 @@ export default class UI extends React.Component { componentWillMount () { window.addEventListener('beforeunload', this.handleBeforeUnload, false); - window.addEventListener('resize', this.handleResize, { passive: true }); document.addEventListener('dragenter', this.handleDragEnter, false); document.addEventListener('dragover', this.handleDragOver, false); document.addEventListener('drop', this.handleDrop, false); @@ -214,28 +292,8 @@ export default class UI extends React.Component { }; } - shouldComponentUpdate (nextProps) { - if (nextProps.isComposing !== this.props.isComposing) { - // Avoid expensive update just to toggle a class - this.node.classList.toggle('is-composing', nextProps.isComposing); - - return false; - } - - // Why isn't this working?!? - // return super.shouldComponentUpdate(nextProps, nextState); - return true; - } - - componentDidUpdate (prevProps) { - if (![this.props.location.pathname, '/'].includes(prevProps.location.pathname)) { - this.columnsAreaNode.handleChildrenContentChange(); - } - } - componentWillUnmount () { window.removeEventListener('beforeunload', this.handleBeforeUnload); - window.removeEventListener('resize', this.handleResize); document.removeEventListener('dragenter', this.handleDragEnter); document.removeEventListener('dragover', this.handleDragOver); document.removeEventListener('drop', this.handleDrop); @@ -247,10 +305,6 @@ export default class UI extends React.Component { this.node = c; } - setColumnsAreaRef = c => { - this.columnsAreaNode = c.getWrappedInstance().getWrappedInstance(); - } - handleHotkeyNew = e => { e.preventDefault(); @@ -350,8 +404,8 @@ export default class UI extends React.Component { } render () { - const { width, draggingOver } = this.state; - const { children } = this.props; + const { draggingOver } = this.state; + const { children, isComposing, location } = this.props; const handlers = { help: this.handleHotkeyToggleHelp, @@ -374,43 +428,12 @@ export default class UI extends React.Component { return ( -
    +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + {children} + From 81cefc1913e89a3f659d9a2663f4006db94004cd Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Wed, 7 Mar 2018 05:36:46 +0900 Subject: [PATCH 30/59] Do not use npm (#6656) Both of yarn and npm are used in Mastodon, but the combined usage requires a redundant dependency and may lead to data inconsistency. Considering that yarn has autoclean feature which npm does not have, this change replaces all npm usage with yarn. This change requires documentation update. Most notably, the following command must be executed before assets precompilation if any system dependency of node-sass has changed: yarn install --force --pure-lockfile --- Dockerfile | 1 - docker-compose.yml | 2 +- package.json | 5 ++--- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c22756d0c75..377380a84dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,7 +38,6 @@ RUN apk -U upgrade \ libidn \ libpq \ nodejs \ - nodejs-npm \ protobuf \ su-exec \ tini \ diff --git a/docker-compose.yml b/docker-compose.yml index 55b419e9848..4d9a6c40d19 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -55,7 +55,7 @@ services: image: gargron/mastodon restart: always env_file: .env.production - command: npm run start + command: yarn start networks: - external_network - internal_network diff --git a/package.json b/package.json index abc13e1eab5..5b9ea7d37d0 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,9 @@ "build:production": "cross-env RAILS_ENV=production ./bin/webpack", "manage:translations": "node ./config/webpack/translationRunner.js", "start": "node ./streaming/index.js", - "test": "npm run test:lint && npm run test:jest", + "test": "yarn run test:lint && yarn run test:jest", "test:lint": "eslint -c .eslintrc.yml --ext=js app/javascript/ config/webpack/ streaming/", - "test:jest": "cross-env NODE_ENV=test jest --coverage", - "postinstall": "npm rebuild node-sass" + "test:jest": "cross-env NODE_ENV=test jest --coverage" }, "repository": { "type": "git", From b725924f0a2254d6d7799f7558a9f6680ff6134f Mon Sep 17 00:00:00 2001 From: Daniel Hunsaker Date: Tue, 6 Mar 2018 13:59:35 -0700 Subject: [PATCH 31/59] [Nanobox] Tuning Update (#6660) Various preformance and stability enhancements for instances deployed via Nanobox. --- .env.nanobox | 95 ++++++++++++++++++++++++++++++++++++-- boxfile.yml | 23 ++++----- nanobox/nginx-web.conf.erb | 8 +++- 3 files changed, 110 insertions(+), 16 deletions(-) diff --git a/.env.nanobox b/.env.nanobox index 48204a6bf43..0d14f8a0056 100644 --- a/.env.nanobox +++ b/.env.nanobox @@ -13,11 +13,29 @@ DB_PORT=5432 DATABASE_URL=postgresql://$DATA_DB_USER:$DATA_DB_PASS@$DATA_DB_HOST/gonano +# Optional ElasticSearch configuration +# ES_ENABLED=true +# ES_HOST=localhost +# ES_PORT=9200 + +# Optimizations +LD_PRELOAD=/data/lib/libjemalloc.so + +# ImageMagick optimizations +MAGICK_TEMPORARY_PATH=/app/tmp +MAGICK_MEMORY_LIMIT=128MiB +MAGICK_MAP_LIMIT=64MiB +MAGICK_TIME_LIMIT=15 +MAGICK_AREA_LIMIT=16MP +MAGICK_WIDTH_LIMIT=8KP +MAGICK_HEIGHT_LIMIT=8KP + # Federation -# Note: Changing LOCAL_DOMAIN or LOCAL_HTTPS at a later time will cause unwanted side effects. +# Note: Changing LOCAL_DOMAIN at a later time will cause unwanted side effects, including breaking all existing federation. # LOCAL_DOMAIN should *NOT* contain the protocol part of the domain e.g https://example.com. LOCAL_DOMAIN=${APP_NAME}.nanoapp.io -LOCAL_HTTPS=false + +# Changing LOCAL_HTTPS in production is no longer supported. (Mastodon will always serve https:// links) # Use this only if you need to run mastodon on a different domain than the one used for federation. # You can read more about this option on https://github.com/tootsuite/documentation/blob/master/Running-Mastodon/Serving_a_different_domain.md @@ -31,7 +49,6 @@ LOCAL_HTTPS=false # Application secrets # Generate each with the `rake secret` task (`nanobox run bundle exec rake secret`) -PAPERCLIP_SECRET=$PAPERCLIP_SECRET SECRET_KEY_BASE=$SECRET_KEY_BASE OTP_SECRET=$OTP_SECRET @@ -131,9 +148,79 @@ SMTP_FROM_ADDRESS=notifications@${APP_NAME}.nanoapp.io # Cluster number setting for streaming API server. # If you comment out following line, cluster number will be `numOfCpuCores - 1`. -STREAMING_CLUSTER_NUM=1 +# STREAMING_CLUSTER_NUM=1 # Docker mastodon user # If you use Docker, you may want to assign UID/GID manually. # UID=1000 # GID=1000 + +# LDAP authentication (optional) +# LDAP_ENABLED=true +# LDAP_HOST=localhost +# LDAP_PORT=389 +# LDAP_METHOD=simple_tls +# LDAP_BASE= +# LDAP_BIND_DN= +# LDAP_PASSWORD= +# LDAP_UID=cn + +# PAM authentication (optional) +# PAM authentication uses for the email generation the "email" pam variable +# and optional as fallback PAM_DEFAULT_SUFFIX +# The pam environment variable "email" is provided by: +# https://github.com/devkral/pam_email_extractor +# PAM_ENABLED=true +# Fallback Suffix for email address generation (nil by default) +# PAM_DEFAULT_SUFFIX=pam +# Name of the pam service (pam "auth" section is evaluated) +# PAM_DEFAULT_SERVICE=rpam +# Name of the pam service used for checking if an user can register (pam "account" section is evaluated) (nil (disabled) by default) +# PAM_CONTROLLED_SERVICE=rpam + +# Global OAuth settings (optional) : +# If you have only one strategy, you may want to enable this +# OAUTH_REDIRECT_AT_SIGN_IN=true + +# Optional CAS authentication (cf. omniauth-cas) : +# CAS_ENABLED=true +# CAS_URL=https://sso.myserver.com/ +# CAS_HOST=sso.myserver.com/ +# CAS_PORT=443 +# CAS_SSL=true +# CAS_VALIDATE_URL= +# CAS_CALLBACK_URL= +# CAS_LOGOUT_URL= +# CAS_LOGIN_URL= +# CAS_UID_FIELD='user' +# CAS_CA_PATH= +# CAS_DISABLE_SSL_VERIFICATION=false +# CAS_UID_KEY='user' +# CAS_NAME_KEY='name' +# CAS_EMAIL_KEY='email' +# CAS_NICKNAME_KEY='nickname' +# CAS_FIRST_NAME_KEY='firstname' +# CAS_LAST_NAME_KEY='lastname' +# CAS_LOCATION_KEY='location' +# CAS_IMAGE_KEY='image' +# CAS_PHONE_KEY='phone' + +# Optional SAML authentication (cf. omniauth-saml) +# SAML_ENABLED=true +# SAML_ACS_URL= +# SAML_ISSUER=http://localhost:3000/auth/auth/saml/callback +# SAML_IDP_SSO_TARGET_URL=https://idp.testshib.org/idp/profile/SAML2/Redirect/SSO +# SAML_IDP_CERT= +# SAML_IDP_CERT_FINGERPRINT= +# SAML_NAME_IDENTIFIER_FORMAT= +# SAML_CERT= +# SAML_PRIVATE_KEY= +# SAML_SECURITY_WANT_ASSERTION_SIGNED=true +# SAML_SECURITY_WANT_ASSERTION_ENCRYPTED=true +# SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true +# SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1" +# SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" +# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.5.4.42" +# SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1" +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED= +# SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL= diff --git a/boxfile.yml b/boxfile.yml index d36a272e722..bb4149e70a0 100644 --- a/boxfile.yml +++ b/boxfile.yml @@ -1,7 +1,7 @@ run.config: engine: ruby engine.config: - runtime: ruby-2.4 + runtime: ruby-2.5 extra_packages: # basic servers: @@ -10,6 +10,7 @@ run.config: # for images: - ImageMagick + - jemalloc # for videos: - ffmpeg3 @@ -37,7 +38,7 @@ run.config: - yarn.lock extra_steps: - - envsubst < .env.nanobox > .env + - cp .env.nanobox .env - yarn fs_watch: true @@ -47,7 +48,7 @@ deploy.config: extra_steps: - NODE_ENV=production bundle exec rake assets:precompile transform: - - "sed 's/LOCAL_HTTPS=.*/LOCAL_HTTPS=true/i' /app/.env.nanobox | envsubst > /app/.env.production" + - "envsubst < /app/.env.nanobox > /app/.env.production" - |- if [ -z "$LOCAL_DOMAIN" ] then @@ -186,7 +187,7 @@ worker.cron_only: data.db: - image: nanobox/postgresql:9.5 + image: nanobox/postgresql:9.6 cron: - id: backup @@ -196,11 +197,11 @@ data.db: gzip | curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).sql.gz --data-binary @- && curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ | - json_pp | + sed 's/,/\n/g' | grep ${HOSTNAME} | sort | head -n-${BACKUP_COUNT:-1} | - sed 's/.*: "\(.*\)".*/\1/' | + sed 's/.*: \?"\(.*\)".*/\1/' | while read file do curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE @@ -208,7 +209,7 @@ data.db: data.redis: - image: nanobox/redis:3.0 + image: nanobox/redis:4.0 cron: - id: backup @@ -216,11 +217,11 @@ data.redis: command: | curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).rdb --data-binary @/data/var/db/redis/dump.rdb && curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ | - json_pp | + sed 's/,/\n/g' | grep ${HOSTNAME} | sort | head -n-${BACKUP_COUNT:-1} | - sed 's/.*: "\(.*\)".*/\1/' | + sed 's/.*: \?"\(.*\)".*/\1/' | while read file do curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE @@ -237,11 +238,11 @@ data.storage: tar cz -C /data/var/db/unfs/ . | curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/backup-${HOSTNAME}-$(date -u +%Y-%m-%d.%H-%M-%S).tgz --data-binary @- && curl -k -s -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/ | - json_pp | + sed 's/,/\n/g' | grep ${HOSTNAME} | sort | head -n-${BACKUP_COUNT:-1} | - sed 's/.*: "\(.*\)".*/\1/' | + sed 's/.*: \?"\(.*\)".*/\1/' | while read file do curl -k -H "X-AUTH-TOKEN: ${WAREHOUSE_DATA_HOARDER_TOKEN}" https://${WAREHOUSE_DATA_HOARDER_HOST}:7410/blobs/${file} -X DELETE diff --git a/nanobox/nginx-web.conf.erb b/nanobox/nginx-web.conf.erb index a839f3036b8..797201eabf8 100644 --- a/nanobox/nginx-web.conf.erb +++ b/nanobox/nginx-web.conf.erb @@ -58,15 +58,21 @@ http { proxy_pass_header Server; proxy_pass http://rails; - proxy_buffering off; + proxy_buffering on; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; + proxy_cache CACHE; + proxy_cache_valid 200 7d; + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; + tcp_nodelay on; } } + proxy_cache_path /data/var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g; + error_page 500 501 502 503 504 /500.html; } From cb74c0cfe4aa89f9656c054253665ef4965b41df Mon Sep 17 00:00:00 2001 From: Sylvhem Date: Wed, 7 Mar 2018 01:39:40 +0100 Subject: [PATCH 32/59] Add headings to the security settings page (#6661) * Changes the headings' rank of the security settings section This commit changes the existing headings' rank of the security settings section from level 6 to level 4. * Renames the auth.change_password string into auth.security The "Security" preferences' section used to be called "Change password". When it was renamed, the string name wasn't changed. This commits changes auth.change_password to auth.security. * Adds a heading to the password change form There was previously no heading for the part of the "Security" page that contain the password change form. This commit adds a rank 4 heading to this section and reintroduces an "auth.change_password" string to be used inside it. * Removes useless HR elements The various sections of the "Security" settings page were previously separated by HR elements. Now that there is proper headings, they're not required anymore. * Updates CSS This commit updates CSS in such a way that the same style is applied to all the H4 elements of the settings. * Correct a mistake A character went missing on one of the previous commits, broking the CSS. This new commit fixes it. --- app/javascript/styles/mastodon/admin.scss | 10 ++++++++++ app/javascript/styles/mastodon/forms.scss | 10 ---------- app/views/auth/registrations/_sessions.html.haml | 2 +- app/views/auth/registrations/edit.html.haml | 8 +++----- config/locales/ar.yml | 2 +- config/locales/bg.yml | 2 +- config/locales/ca.yml | 2 +- config/locales/de.yml | 2 +- config/locales/en.yml | 3 ++- config/locales/eo.yml | 2 +- config/locales/es.yml | 2 +- config/locales/fa.yml | 2 +- config/locales/fi.yml | 2 +- config/locales/fr.yml | 2 +- config/locales/gl.yml | 2 +- config/locales/he.yml | 2 +- config/locales/hr.yml | 2 +- config/locales/hu.yml | 2 +- config/locales/id.yml | 2 +- config/locales/io.yml | 2 +- config/locales/it.yml | 2 +- config/locales/ja.yml | 2 +- config/locales/ko.yml | 2 +- config/locales/nl.yml | 2 +- config/locales/no.yml | 2 +- config/locales/oc.yml | 2 +- config/locales/pl.yml | 2 +- config/locales/pt-BR.yml | 2 +- config/locales/pt.yml | 2 +- config/locales/ru.yml | 2 +- config/locales/sk.yml | 2 +- config/locales/sr-Latn.yml | 2 +- config/locales/sr.yml | 2 +- config/locales/sv.yml | 2 +- config/locales/th.yml | 2 +- config/locales/tr.yml | 2 +- config/locales/uk.yml | 2 +- config/locales/zh-CN.yml | 2 +- config/locales/zh-HK.yml | 2 +- config/locales/zh-TW.yml | 2 +- config/navigation.rb | 2 +- 41 files changed, 52 insertions(+), 53 deletions(-) diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 0c343e1df15..e6bd0c717e3 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -105,6 +105,16 @@ margin-bottom: 30px; } + h4 { + text-transform: uppercase; + font-size: 13px; + font-weight: 500; + color: $ui-primary-color; + padding-bottom: 8px; + margin-bottom: 8px; + border-bottom: 1px solid lighten($ui-base-color, 8%); + } + h6 { font-size: 16px; color: $ui-secondary-color; diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 2e38cda4ede..d74c5a4fd03 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -22,16 +22,6 @@ code { margin-top: 4px; } - h4 { - text-transform: uppercase; - font-size: 13px; - font-weight: 500; - color: $ui-primary-color; - padding-bottom: 8px; - margin-bottom: 8px; - border-bottom: 1px solid lighten($ui-base-color, 8%); - } - p.hint { margin-bottom: 15px; color: $ui-primary-color; diff --git a/app/views/auth/registrations/_sessions.html.haml b/app/views/auth/registrations/_sessions.html.haml index 8424a890120..8586c054957 100644 --- a/app/views/auth/registrations/_sessions.html.haml +++ b/app/views/auth/registrations/_sessions.html.haml @@ -1,4 +1,4 @@ -%h6= t 'sessions.title' +%h4= t 'sessions.title' %p.muted-hint= t 'sessions.explanation' .table-wrapper diff --git a/app/views/auth/registrations/edit.html.haml b/app/views/auth/registrations/edit.html.haml index fac702b38e8..05fc7df313b 100644 --- a/app/views/auth/registrations/edit.html.haml +++ b/app/views/auth/registrations/edit.html.haml @@ -1,6 +1,7 @@ - content_for :page_title do - = t('auth.change_password') + = t('auth.security') +%h4= t('auth.change_password') = simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put, class: 'auth_edit' }) do |f| = render 'shared/error_messages', object: resource @@ -15,12 +16,9 @@ - else %p.hint= t('users.seamless_external_login') -%hr/ - = render 'sessions' - if open_deletion? - %hr/ - %h6= t('auth.delete_account') + %h4= t('auth.delete_account') %p.muted-hint= t('auth.delete_account_html', path: settings_delete_path) diff --git a/config/locales/ar.yml b/config/locales/ar.yml index f641d3c2e0c..bc71d9c87cb 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -220,7 +220,6 @@ ar: regenerate_token: إعادة توليد رمز النفاذ your_token: رمز نفاذك auth: - change_password: الهوية confirm_email: تأكيد عنوان البريد الإلكتروني delete_account: حذف حساب delete_account_html: إن كنت ترغب في حذف حسابك يُمكنك المواصلة هنا. سوف يُطلَبُ منك التأكيد قبل الحذف. @@ -237,6 +236,7 @@ ar: register: إنشاء حساب resend_confirmation: إعادة إرسال تعليمات التأكيد reset_password: إعادة تعيين كلمة المرور + security: الهوية set_new_password: تعيين كلمة مرور جديدة authorize_follow: error: يا للأسف، وقع هناك خطأ إثر عملية البحث عن الحساب عن بعد diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 56a90489573..cb3ed22449c 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -30,7 +30,6 @@ bg: applications: invalid_url: Предоставеният URL е невалиден auth: - change_password: Идентификационни данни didnt_get_confirmation: Не получих инструкции за потвърждение forgot_password: Забравих си паролата login: Влизане @@ -38,6 +37,7 @@ bg: register: Регистрация resend_confirmation: Изпрати отново инструкции за потвърждение reset_password: Подновяване на паролата + security: Идентификационни данни set_new_password: Задай нова парола authorize_follow: error: Възникна грешка в откриването на потребителя diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 5552202e514..c069adb4b7d 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -359,7 +359,6 @@ ca: your_token: El teu identificador d'accés auth: agreement_html: En inscriure't, acceptes seguir els nostres termes del servei i la nostra política de privadesa. - change_password: Seguretat confirm_email: Confirmar correu electrònic delete_account: Suprimeix el compte delete_account_html: Si vols suprimir el compte pots fer-ho aquí. Se't demanarà confirmació. @@ -378,6 +377,7 @@ ca: register: Registre resend_confirmation: Torna a enviar el correu de confirmació reset_password: Restableix la contrasenya + security: Seguretat set_new_password: Estableix una contrasenya nova authorize_follow: error: Malauradament, ha ocorregut un error cercant el compte remot diff --git a/config/locales/de.yml b/config/locales/de.yml index 8f17413e102..e55ad151ac0 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -353,7 +353,6 @@ de: your_token: Dein Zugangs-Token auth: agreement_html: Indem du dich registrierst, erklärst du dich mit den Regeln, die auf dieser Instanz gelten und der Datenschutzerklärung einverstanden. - change_password: Sicherheit delete_account: Konto löschen delete_account_html: Falls du dein Konto löschen willst, kannst du hier damit fortfahren. Du wirst um Bestätigung gebeten werden. didnt_get_confirmation: Keine Bestätigungs-Mail erhalten? @@ -366,6 +365,7 @@ de: register: Registrieren resend_confirmation: Bestätigungs-Mail erneut versenden reset_password: Passwort zurücksetzen + security: Sicherheit set_new_password: Neues Passwort setzen authorize_follow: error: Das Profil konnte nicht geladen werden diff --git a/config/locales/en.yml b/config/locales/en.yml index 971a9976f7f..176135657d8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -359,7 +359,7 @@ en: your_token: Your access token auth: agreement_html: By signing up you agree to follow the rules of the instance and our terms of service. - change_password: Security + change_password: Password confirm_email: Confirm email delete_account: Delete account delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. @@ -378,6 +378,7 @@ en: register: Sign up resend_confirmation: Resend confirmation instructions reset_password: Reset password + security: Security set_new_password: Set new password authorize_follow: error: Unfortunately, there was an error looking up the remote account diff --git a/config/locales/eo.yml b/config/locales/eo.yml index dee6d4a187d..6daa1caed55 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -358,7 +358,6 @@ eo: your_token: Via alira ĵetono auth: agreement_html: Per registriĝo, vi konsentas kun la reguloj de la nodo kaj niaj uzkondiĉoj. - change_password: Sekureco confirm_email: Konfirmi retadreson delete_account: Forigi konton delete_account_html: Se vi deziras forigi vian konton, vi povas fari tion ĉi tie. Vi bezonos konfirmi vian peton. @@ -376,6 +375,7 @@ eo: register: Registriĝi resend_confirmation: Resendi la instrukciojn por konfirmi reset_password: Ŝanĝi pasvorton + security: Sekureco set_new_password: Elekti novan pasvorton authorize_follow: error: Bedaŭrinde, estis eraro en la serĉado de la fora konto diff --git a/config/locales/es.yml b/config/locales/es.yml index 9eb61aaac53..f55b8bb51aa 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -353,7 +353,6 @@ es: your_token: Tu token de acceso auth: agreement_html: Al registrarte, acepta seguir las reglas de la instancia y nuestros términos de servicio. - change_password: Cambiar contraseña delete_account: Borrar cuenta delete_account_html: Si desea eliminar su cuenta, puede proceder aquí. Será pedido de una confirmación. didnt_get_confirmation: "¿No recibió el correo de confirmación?" @@ -366,6 +365,7 @@ es: register: Registrarse resend_confirmation: Volver a enviar el correo de confirmación reset_password: Restablecer contraseña + security: Cambiar contraseña set_new_password: Establecer nueva contraseña authorize_follow: error: Desafortunadamente, ha ocurrido un error buscando la cuenta remota diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 395d226bd26..86756c01b8b 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -344,7 +344,6 @@ fa: your_token: کد دسترسی شما auth: agreement_html: پیش از عضو شدن باید قوانین این سرور و شرایط استفادهٔ ما را بپذیرید. - change_password: امنیت delete_account: پاک‌کردن حساب delete_account_html: اگر می‌خواهید حساب خود را پاک کنید، از این‌جا پیش بروید. از شما درخواست تأیید خواهد شد. didnt_get_confirmation: راهنمایی برای تأیید را دریافت نکردید؟ @@ -357,6 +356,7 @@ fa: register: عضو شوید resend_confirmation: راهنمایی برای تأیید را دوباره بفرست reset_password: بازنشانی رمز + security: امنیت set_new_password: تعیین رمز تازه authorize_follow: error: متأسفانه حین یافتن آن حساب خطایی رخ داد diff --git a/config/locales/fi.yml b/config/locales/fi.yml index e9c7273ce69..71e019e5498 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -67,7 +67,6 @@ fi: applications: invalid_url: Annettu URL on väärä auth: - change_password: Tunnukset didnt_get_confirmation: Etkö saanut varmennusohjeita? forgot_password: Unohditko salasanasi? login: Kirjaudu sisään @@ -75,6 +74,7 @@ fi: register: Rekisteröidy resend_confirmation: Lähetä varmennusohjeet uudestaan reset_password: Palauta salasana + security: Tunnukset set_new_password: Aseta uusi salasana authorize_follow: error: Valitettavasti tapahtui virhe etätilin haussa. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 34910488f21..65effe7004d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -359,7 +359,6 @@ fr: your_token: Votre jeton d’accès auth: agreement_html: En vous inscrivant, vous souscrivez aux règles de l’instance et à nos conditions d’utilisation. - change_password: Sécurité confirm_email: Confirmer mon adresse mail delete_account: Supprimer le compte delete_account_html: Si vous désirez supprimer votre compte, vous pouvez cliquer ici. Il vous sera demandé de confirmer cette action. @@ -377,6 +376,7 @@ fr: register: S’inscrire resend_confirmation: Envoyer à nouveau les consignes de confirmation reset_password: Réinitialiser le mot de passe + security: Sécurité set_new_password: Définir le nouveau mot de passe authorize_follow: error: Malheureusement, il y a eu une erreur en cherchant les détails du compte distant diff --git a/config/locales/gl.yml b/config/locales/gl.yml index def9168cc87..ca02ea69394 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -359,7 +359,6 @@ gl: your_token: O seu testemuño de acceso auth: agreement_html: Rexistrándose acorda seguir as normas da instancia e os termos do servizo. - change_password: Seguridade confirm_email: Confirmar correo-e delete_account: Eliminar conta delete_account_html: Se desexa eliminar a súa conta, pode facelo aquí. Pediráselle confirmación. @@ -378,6 +377,7 @@ gl: register: Rexistro resend_confirmation: Voltar a enviar intruccións de confirmación reset_password: Restablecer contrasinal + security: Seguridade set_new_password: Establecer novo contrasinal authorize_follow: error: Desgraciadamente, algo fallou ao buscar a conta remota diff --git a/config/locales/he.yml b/config/locales/he.yml index c83f4ba10ea..1a7c84d7cb4 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -232,7 +232,6 @@ he: applications: invalid_url: כתובת הקישורית אינה חוקית auth: - change_password: החלפת סיסמא didnt_get_confirmation: לא התקבלו הוראות אימות? forgot_password: הנשתכחה סיסמתך? login: כניסה @@ -240,6 +239,7 @@ he: register: הרשמה resend_confirmation: שלח הוראות אימות בשנית reset_password: איפוס סיסמא + security: החלפת סיסמא set_new_password: שינוי סיסמא authorize_follow: error: למרבה הצער, היתה שגיאה בחיפוש החשבון המרוחק diff --git a/config/locales/hr.yml b/config/locales/hr.yml index a3c9aa4368f..2d2eddc08c6 100644 --- a/config/locales/hr.yml +++ b/config/locales/hr.yml @@ -30,7 +30,6 @@ hr: applications: invalid_url: Uneseni link nije valjan auth: - change_password: Vjerodajnica didnt_get_confirmation: Niste primili instrukcije za potvrđivanje? forgot_password: Zaboravljena lozinka? login: Prijavi se @@ -38,6 +37,7 @@ hr: register: Registriraj se resend_confirmation: Ponovo pošalji instrukcije za potvrđivanje reset_password: Resetiraj lozinku + security: Vjerodajnica set_new_password: Postavi novu lozinku authorize_follow: error: Nažalost, došlo je do greške looking up the remote račun diff --git a/config/locales/hu.yml b/config/locales/hu.yml index de35044d48f..6be82c1de32 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -353,7 +353,6 @@ hu: your_token: Hozzáférési kulcsod auth: agreement_html: A feliratkozással elfogatod az instancia szabályzatát és a felhasználási feltételeket. - change_password: Biztonság delete_account: Felhasználói fiók törlése delete_account_html: Felhasználói fiókod törléséhez kattints ide. A rendszer újbóli megerősítést fog kérni. didnt_get_confirmation: Nem kaptad meg a megerősítési lépéseket? @@ -366,6 +365,7 @@ hu: register: Regisztráció resend_confirmation: Megerősítési lépések újraküldése reset_password: Jelszó visszaállítása + security: Biztonság set_new_password: Új jelszó beállítása authorize_follow: error: Hiba történt a távoli felhasználó keresésekor diff --git a/config/locales/id.yml b/config/locales/id.yml index 6e4d60fd888..0ef1d504041 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -155,7 +155,6 @@ id: applications: invalid_url: URL tidak sesuai auth: - change_password: Identitas didnt_get_confirmation: Tidak menerima petunjuk konfirmasi? forgot_password: Lupa kata sandi? login: Masuk @@ -163,6 +162,7 @@ id: register: Daftar resend_confirmation: Kirim ulang email konfirmasi reset_password: Reset kata sandi + security: Identitas set_new_password: Tentukan kata sandi baru authorize_follow: error: Sayangnya, ada error saat melihat akun remote diff --git a/config/locales/io.yml b/config/locales/io.yml index db821476836..29ab4516b54 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -153,7 +153,6 @@ io: applications: invalid_url: La URL donita ne esas valida auth: - change_password: Chanjar pasvorto didnt_get_confirmation: Ka tu ne recevis la instrucioni por konfirmar? forgot_password: Pasvorto obliviita? login: Enirar @@ -161,6 +160,7 @@ io: register: Membreskar resend_confirmation: Risendar la instrucioni por konfirmar reset_password: Chanjar la pasvorto + security: Chanjar pasvorto set_new_password: Selektar nova pasvorto authorize_follow: error: Regretinde, eventis eraro probante konsultar la fora konto diff --git a/config/locales/it.yml b/config/locales/it.yml index 6ab57d2fcc9..7e5bfd20e23 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -30,7 +30,6 @@ it: applications: invalid_url: L'URL fornito non è valido auth: - change_password: Credenziali didnt_get_confirmation: Non hai ricevuto le istruzioni di conferma? forgot_password: Hai dimenticato la tua password? login: Entra @@ -38,6 +37,7 @@ it: register: Iscriviti resend_confirmation: Invia di nuovo le istruzioni di conferma reset_password: Resetta la password + security: Credenziali set_new_password: Imposta una nuova password authorize_follow: error: Sfortunatamente c'è stato un errore nel consultare l'account remoto diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 1ff50855063..e44a093b51f 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -359,7 +359,6 @@ ja: your_token: アクセストークン auth: agreement_html: 登録すると インスタンスのルール利用規約 に従うことに同意したことになります。 - change_password: セキュリティ confirm_email: メールアドレスの確認 delete_account: アカウントの削除 delete_account_html: アカウントを削除したい場合、こちら から手続きが行えます。削除する前に、確認画面があります。 @@ -378,6 +377,7 @@ ja: register: 登録する resend_confirmation: 確認メールを再送する reset_password: パスワードを再発行 + security: セキュリティ set_new_password: 新しいパスワード authorize_follow: error: 残念ながら、リモートアカウント情報の取得中にエラーが発生しました diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 4f26d87515a..8a11b096ac5 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -361,7 +361,6 @@ ko: your_token: 액세스 토큰 auth: agreement_html: 이 등록으로 이용규약약관에 동의하는 것으로 간주됩니다. - change_password: 보안 confirm_email: 확인 메일 승인 delete_account: 계정 삭제 delete_account_html: 계정을 삭제하고 싶은 경우, 여기서 삭제할 수 있습니다. 삭제 전 확인 화면이 표시됩니다. @@ -377,6 +376,7 @@ ko: register: 등록하기 resend_confirmation: 확인 메일을 다시 보내기 reset_password: 비밀번호 재설정 + security: 보안 set_new_password: 새 비밀번호 authorize_follow: error: 리모트 계정을 확인하는 도중 오류가 발생했습니다 diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 876b91eafcb..90139ca0e6d 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -359,7 +359,6 @@ nl: your_token: Jouw toegangscode auth: agreement_html: Wanneer je op registreren klikt ga je akkoord met het opvolgen van de regels van deze server en onze gebruikersvoorwaarden. - change_password: Beveiliging confirm_email: E-mail bevestigen delete_account: Account verwijderen delete_account_html: Wanneer je jouw account graag wilt verwijderen, kan je dat hier doen. We vragen jou daar om een bevestiging. @@ -378,6 +377,7 @@ nl: register: Registreren resend_confirmation: Verstuur de bevestigingsinstructies nogmaals reset_password: Wachtwoord opnieuw instellen + security: Beveiliging set_new_password: Nieuw wachtwoord instellen authorize_follow: error: Helaas, er is een fout opgetreden bij het opzoeken van de externe account diff --git a/config/locales/no.yml b/config/locales/no.yml index d198177cd11..3adf71bee3a 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -353,7 +353,6 @@ your_token: Din tilgangsnøkkel auth: agreement_html: Ved å registrere deg godtar du å følge instansens regler og våre brukervilkår. - change_password: Sikkerhet delete_account: Slett konto delete_account_html: Hvis du ønsker å slette din konto kan du fortsette her. Du vil bli spurt om bekreftelse. didnt_get_confirmation: Mottok du ikke instruksjoner om bekreftelse? @@ -366,6 +365,7 @@ register: Bli med resend_confirmation: Send bekreftelsesinstruksjoner på nytt reset_password: Nullstill passord + security: Sikkerhet set_new_password: Sett nytt passord authorize_follow: error: Uheldigvis skjedde det en feil da vi prøvde å få tak i en bruker fra en annen instans diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 869118c0869..160bbc3ed9d 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -353,7 +353,6 @@ oc: your_token: Vòstre geton d’accès auth: agreement_html: En vos marcar acceptatz las règlas de l’instància e politica de confidencialitat. - change_password: Seguretat delete_account: Suprimir lo compte delete_account_html: Se volètz suprimir vòstre compte, podètz o far aquí. Vos demandarem que confirmetz. didnt_get_confirmation: Avètz pas recebut las instruccions de confirmacion ? @@ -369,6 +368,7 @@ oc: register: Se marcar resend_confirmation: Tornar mandar las instruccions de confirmacion reset_password: Reïnicializar lo senhal + security: Seguretat set_new_password: Picar un nòu senhal authorize_follow: error: O planhèm, i a agut una error al moment de cercar lo compte diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 5fcc93f9d74..9a0c6ae1554 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -360,7 +360,6 @@ pl: your_token: Twój token dostępu auth: agreement_html: Rejestrując się, oświadczasz, że zapoznałeś się z informacjami o instancji i zasadami korzystania z usługi. - change_password: Bezpieczeństwo confirm_email: Potwierdź adres e-mail delete_account: Usunięcie konta delete_account_html: Jeżeli chcesz usunąć konto, przejdź tutaj. Otrzymasz prośbę o potwierdzenie. @@ -379,6 +378,7 @@ pl: register: Rejestracja resend_confirmation: Ponownie prześlij instrukcje weryfikacji reset_password: Zresetuj hasło + security: Bezpieczeństwo set_new_password: Ustaw nowe hasło authorize_follow: error: Niestety, podczas sprawdzania zdalnego konta wystąpił błąd diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index f781b704fc6..04836c121bb 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -359,7 +359,6 @@ pt-BR: your_token: Seu token de acesso auth: agreement_html: Ao se cadastrar você concorda em seguir as regras da instância e os nossos termos de serviço. - change_password: Segurança confirm_email: Confirmar e-mail delete_account: Excluir conta delete_account_html: Se você deseja excluir a sua conta, você pode prosseguir para cá. Uma confirmação será requisitada. @@ -377,6 +376,7 @@ pt-BR: register: Cadastrar-se resend_confirmation: Reenviar instruções de confirmação reset_password: Redefinir senha + security: Segurança set_new_password: Definir uma nova senha authorize_follow: error: Infelizmente, ocorreu um erro ao buscar a conta remota diff --git a/config/locales/pt.yml b/config/locales/pt.yml index 455f2789812..5012e176f21 100644 --- a/config/locales/pt.yml +++ b/config/locales/pt.yml @@ -353,7 +353,6 @@ pt: your_token: O teu token de acesso auth: agreement_html: Registando-te concordas em seguir as regras da instância e os nossos termos de serviço. - change_password: Alterar palavra-passe confirm_email: Confirmar e-mail delete_account: Eliminar conta delete_account_html: Se desejas eliminar a conta, podes continua aqui. Uma confirmação será pedida. @@ -367,6 +366,7 @@ pt: register: Registar resend_confirmation: Reenviar instruções de confirmação reset_password: Criar nova palavra-passe + security: Alterar palavra-passe set_new_password: Editar palavra-passe authorize_follow: error: Infelizmente, ocorreu um erro ao buscar a conta remota diff --git a/config/locales/ru.yml b/config/locales/ru.yml index 467f24ca8db..a2cb1e793b5 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -353,7 +353,6 @@ ru: your_token: Ваш токен доступа auth: agreement_html: Создавая аккаунт, вы соглашаетесь с правилами узла и нашими условиями обслуживания. - change_password: Изменить пароль delete_account: Удалить аккаунт delete_account_html: Если Вы хотите удалить свой аккаунт, вы можете перейти сюда. У Вас будет запрошено подтверждение. didnt_get_confirmation: Не получили инструкцию для подтверждения? @@ -366,6 +365,7 @@ ru: register: Зарегистрироваться resend_confirmation: Повторить отправку инструкции для подтверждения reset_password: Сбросить пароль + security: Изменить пароль set_new_password: Задать новый пароль authorize_follow: error: К сожалению, при поиске удаленного аккаунта возникла ошибка diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 9938c2bc4c1..551fab3224a 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -359,7 +359,6 @@ sk: your_token: Váš prístupový token auth: agreement_html: V rámci registrácie súhlasíte, že sa budete riadiť 1 pravidlami tejto instancie 2 a taktiež 3 našími servisnými podmienkami 4. - change_password: Zabezpečenie confirm_email: Potvrdiť email delete_account: Vymazať účet delete_account_html: Pokiaľ si želáte vymazať svoj účet, môžete tak 1 urobiť tu 2. Budete požiadaný/á o potvrdenie tohto kroku. @@ -378,6 +377,7 @@ sk: register: Zaregistrovať sa resend_confirmation: Poslať potvrdzujúce pokyny znovu reset_password: Resetovať heslo + security: Zabezpečenie set_new_password: Nastaviť nové heslo authorize_follow: error: Naneštastie nastala chyba pri hľadaní vzdialeného účtu diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 4eed44345b2..2d984049aa9 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -346,7 +346,6 @@ sr-Latn: your_token: Vaš pristupni token auth: agreement_html: Pristupanjem instanci se slažete sa pravilima instance i uslovima korišćenja. - change_password: Bezbednost delete_account: Obriši nalog delete_account_html: Ako želite da obrišete Vaš nalog, možete nastaviti ovde. Bićete upitani da potvrdite. didnt_get_confirmation: Niste dobili poruku sa uputstvima za potvrdu naloga? @@ -359,6 +358,7 @@ sr-Latn: register: Registruj se resend_confirmation: Pošalji poruku sa uputstvima o potvrdi naloga ponovo reset_password: Resetuj lozinku + security: Bezbednost set_new_password: Postavi novu lozinku authorize_follow: error: Nažalost, desila se greška pri traženju udaljenog naloga diff --git a/config/locales/sr.yml b/config/locales/sr.yml index c5649876569..2daf3291557 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -346,7 +346,6 @@ sr: your_token: Ваш приступни токен auth: agreement_html: Приступањем инстанци се слажете са правилима инстанце и условима коришћења. - change_password: Безбедност delete_account: Обриши налог delete_account_html: Ако желите да обришете Ваш налог, можете наставити овде. Бићете упитани да потврдите. didnt_get_confirmation: Нисте добили поруку са упутствима за потврду налога? @@ -359,6 +358,7 @@ sr: register: Региструј се resend_confirmation: Пошаљи поруку са упутствима о потврди налога поново reset_password: Ресетуј лозинку + security: Безбедност set_new_password: Постави нову лозинку authorize_follow: error: Нажалост, десила се грешка при тражењу удаљеног налога diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 1e79b63e561..8d9c6d5dfa9 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -356,7 +356,6 @@ sv: your_token: Din access token auth: agreement_html: Genom att registrera dig godkänner du att följa instansens regler och våra användarvillkor. - change_password: Säkerhet confirm_email: Bekräfta e-postadress delete_account: Ta bort konto delete_account_html: Om du vill radera ditt konto kan du fortsätta här. Du kommer att bli ombedd att bekräfta. @@ -374,6 +373,7 @@ sv: register: Registrera resend_confirmation: Skicka instruktionerna om bekräftelse igen reset_password: Återställ lösenord + security: Säkerhet set_new_password: Skriv in nytt lösenord authorize_follow: error: Tyvärr inträffade ett fel när vi kontrollerade fjärrkontot diff --git a/config/locales/th.yml b/config/locales/th.yml index 737b3aa9592..45fe1e4752f 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -157,7 +157,6 @@ th: applications: invalid_url: URL ที่ระบุไม่ถูกตั้ง auth: - change_password: Credentials didnt_get_confirmation: Didn't receive confirmation instructions? forgot_password: คุณลืมพาสเวริ์ดใช่ัม้ย? login: ล๊อคอิน @@ -165,6 +164,7 @@ th: register: สมัคร resend_confirmation: ส่งขั้นตอนวิธีการยืนยันใหม่อีกครั้ง reset_password: เปลี่ยนรหัสผ่าน + security: Credentials set_new_password: ตั้งรหัสผ่านใหม่ authorize_follow: error: Unfortunately, there was an error looking up the remote account diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 23b4d7a2447..ee0e330748a 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -156,7 +156,6 @@ tr: applications: invalid_url: Verilen URL geçerli değil auth: - change_password: Kimlik bilgileri didnt_get_confirmation: Hesap doğrulama mailini almadınız mı? forgot_password: Parolanızı unuttunuz mu? login: Giriş yap @@ -164,6 +163,7 @@ tr: register: Üye ol resend_confirmation: Doğrulama mailini tekrar gönder reset_password: Parolayı değiştir + security: Kimlik bilgileri set_new_password: Yeni parola oluştur authorize_follow: error: Uzak hesap aranırken bir hata oluştu. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index 0ddfa919060..4c1c66b318e 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -147,7 +147,6 @@ uk: applications: invalid_url: Введена URL неправильна auth: - change_password: Зміна паролю didnt_get_confirmation: Ви не отримали інструкції з підтвердження? forgot_password: Забули свій пароль? login: Увійти @@ -155,6 +154,7 @@ uk: register: Зареєструватися resend_confirmation: Повторно відправити інструкції з підтвердження reset_password: Скинути пароль + security: Зміна паролю set_new_password: Встановити новий пароль authorize_follow: error: На жаль, при пошуку віддаленого аккаунту виникла помилка diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 1bd2e5039a5..1254651cd32 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -351,7 +351,6 @@ zh-CN: your_token: 你的访问令牌 auth: agreement_html: 注册即表示你同意遵守本实例的相关规定我们的使用条款。 - change_password: 帐户安全 delete_account: 删除帐户 delete_account_html: 如果你想删除你的帐户,请点击这里继续。你需要确认你的操作。 didnt_get_confirmation: 没有收到确认邮件? @@ -364,6 +363,7 @@ zh-CN: register: 注册 resend_confirmation: 重新发送确认邮件 reset_password: 重置密码 + security: 帐户安全 set_new_password: 设置新密码 authorize_follow: error: 对不起,寻找这个跨站用户时出错 diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index ed73b724421..e7ab347a1ae 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -156,7 +156,6 @@ zh-HK: applications: invalid_url: 所提供的網址不正確 auth: - change_password: 登入資訊 didnt_get_confirmation: 沒有收到確認指示電郵? forgot_password: 忘記了密碼? login: 登入 @@ -164,6 +163,7 @@ zh-HK: register: 登記 resend_confirmation: 重發確認指示電郵 reset_password: 重設密碼 + security: 登入資訊 set_new_password: 設定新密碼 authorize_follow: error: 對不起,尋找這個跨站用戶的過程發生錯誤 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index bd9f8584023..2fec09ed8e3 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -127,7 +127,6 @@ zh-TW: applications: invalid_url: 網址不正確 auth: - change_password: 登入資訊 didnt_get_confirmation: 沒有收到驗證信? forgot_password: 忘記密碼? login: 登入 @@ -137,6 +136,7 @@ zh-TW: register: 註冊 resend_confirmation: 重寄驗證信 reset_password: 重設密碼 + security: 登入資訊 set_new_password: 設定新密碼 authorize_follow: error: 對不起,搜尋遠端使用者出現錯誤 diff --git a/config/navigation.rb b/config/navigation.rb index 9c7a7d2ec61..2bee5a4f964 100644 --- a/config/navigation.rb +++ b/config/navigation.rb @@ -8,7 +8,7 @@ SimpleNavigation::Configuration.run do |navigation| settings.item :profile, safe_join([fa_icon('user fw'), t('settings.edit_profile')]), settings_profile_url, highlights_on: %r{/settings/profile|/settings/migration} settings.item :preferences, safe_join([fa_icon('sliders fw'), t('settings.preferences')]), settings_preferences_url settings.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_notifications_url - settings.item :password, safe_join([fa_icon('lock fw'), t('auth.change_password')]), edit_user_registration_url, highlights_on: %r{/auth/edit|/settings/delete} + settings.item :password, safe_join([fa_icon('lock fw'), t('auth.security')]), edit_user_registration_url, highlights_on: %r{/auth/edit|/settings/delete} settings.item :two_factor_authentication, safe_join([fa_icon('mobile fw'), t('settings.two_factor_authentication')]), settings_two_factor_authentication_url, highlights_on: %r{/settings/two_factor_authentication} settings.item :import, safe_join([fa_icon('cloud-upload fw'), t('settings.import')]), settings_import_url settings.item :export, safe_join([fa_icon('cloud-download fw'), t('settings.export')]), settings_export_url From d7573fe584ea622e22f5a68f2bf120b7682c49f7 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 01:57:31 +0100 Subject: [PATCH 33/59] Separate chown command in Dockerfile. Use tootsuite/mastodon image (#6662) Fix #6605 --- Dockerfile | 6 ++++-- docker-compose.yml | 6 +++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 377380a84dd..443cb289a4c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ FROM ruby:2.5.0-alpine3.7 LABEL maintainer="https://github.com/tootsuite/mastodon" \ - description="A GNU Social-compatible microblogging server" + description="Your self-hosted, globally interconnected microblogging community" ARG UID=991 ARG GID=991 @@ -73,7 +73,9 @@ RUN addgroup -g ${GID} mastodon && adduser -h /mastodon -s /bin/sh -D -G mastodo && mkdir -p /mastodon/public/system /mastodon/public/assets /mastodon/public/packs \ && chown -R mastodon:mastodon /mastodon/public -COPY --chown=mastodon:mastodon . /mastodon +COPY . /mastodon + +RUN chown -R mastodon:mastodon /mastodon VOLUME /mastodon/public/system /mastodon/public/assets /mastodon/public/packs diff --git a/docker-compose.yml b/docker-compose.yml index 4d9a6c40d19..836cb00b8c2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -32,7 +32,7 @@ services: web: build: . - image: gargron/mastodon + image: tootsuite/mastodon restart: always env_file: .env.production command: bundle exec rails s -p 3000 -b '0.0.0.0' @@ -52,7 +52,7 @@ services: streaming: build: . - image: gargron/mastodon + image: tootsuite/mastodon restart: always env_file: .env.production command: yarn start @@ -67,7 +67,7 @@ services: sidekiq: build: . - image: gargron/mastodon + image: tootsuite/mastodon restart: always env_file: .env.production command: bundle exec sidekiq -q default -q mailers -q pull -q push From 4847149b6eb6fb1023c49f6e0d428290a906c6de Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 02:25:17 +0100 Subject: [PATCH 34/59] Always install LDAP, CAS and SAML gems, because they don't require deps (#6663) Fix #6534 PAM requires a system dependency so... --- Gemfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 7db6e66b773..3fce2ddc758 100644 --- a/Gemfile +++ b/Gemfile @@ -33,9 +33,9 @@ gem 'devise', '~> 4.4' gem 'devise-two-factor', '~> 3.0' gem 'devise_pam_authenticatable2', '~> 8.0', install_if: -> { ENV['PAM_ENABLED'] == 'true' } -gem 'net-ldap', '~> 0.10', install_if: -> { ENV['LDAP_ENABLED'] == 'true' } -gem 'omniauth-cas', '~> 1.1', install_if: -> { ENV['CAS_ENABLED'] == 'true' } -gem 'omniauth-saml', '~> 1.10', install_if: -> { ENV['SAML_ENABLED'] == 'true' } +gem 'net-ldap', '~> 0.10' +gem 'omniauth-cas', '~> 1.1' +gem 'omniauth-saml', '~> 1.10' gem 'omniauth', '~> 1.2' gem 'doorkeeper', '~> 4.2' From 913a38111ff5b0cb7f412bec93e8314859c88855 Mon Sep 17 00:00:00 2001 From: Akihiko Odaki Date: Wed, 7 Mar 2018 10:26:43 +0900 Subject: [PATCH 35/59] Remove pointer events on the entire UI when a dropdown menu is open (#6648) * Remove pointer events on the entire UI when a dropdown menu is open This prevents operations to change the location of the menu such as scrolling. * Fix mistake from merge --- .../mastodon/actions/dropdown_menu.js | 10 +++++ .../mastodon/components/dropdown_menu.js | 42 ++++++++----------- .../containers/dropdown_menu_container.js | 19 +++++++-- app/javascript/mastodon/features/ui/index.js | 6 ++- .../mastodon/reducers/dropdown_menu.js | 18 ++++++++ app/javascript/mastodon/reducers/index.js | 2 + 6 files changed, 66 insertions(+), 31 deletions(-) create mode 100644 app/javascript/mastodon/actions/dropdown_menu.js create mode 100644 app/javascript/mastodon/reducers/dropdown_menu.js diff --git a/app/javascript/mastodon/actions/dropdown_menu.js b/app/javascript/mastodon/actions/dropdown_menu.js new file mode 100644 index 00000000000..217ba4e74a5 --- /dev/null +++ b/app/javascript/mastodon/actions/dropdown_menu.js @@ -0,0 +1,10 @@ +export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN'; +export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE'; + +export function openDropdownMenu(id, placement) { + return { type: DROPDOWN_MENU_OPEN, id, placement }; +} + +export function closeDropdownMenu(id) { + return { type: DROPDOWN_MENU_CLOSE, id }; +} diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js index 42c253449bb..c5c6f73b337 100644 --- a/app/javascript/mastodon/components/dropdown_menu.js +++ b/app/javascript/mastodon/components/dropdown_menu.js @@ -8,6 +8,7 @@ import spring from 'react-motion/lib/spring'; import detectPassiveEvents from 'detect-passive-events'; const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false; +let id = 0; class DropdownMenu extends React.PureComponent { @@ -124,8 +125,10 @@ export default class Dropdown extends React.PureComponent { status: ImmutablePropTypes.map, isUserTouching: PropTypes.func, isModalOpen: PropTypes.bool.isRequired, - onModalOpen: PropTypes.func, - onModalClose: PropTypes.func, + onOpen: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + dropdownPlacement: PropTypes.string, + openDropdownId: PropTypes.number, }; static defaultProps = { @@ -133,38 +136,28 @@ export default class Dropdown extends React.PureComponent { }; state = { - placement: null, + id: id++, }; handleClick = ({ target }) => { - if (this.state.placement) { - this.setState({ placement: null }); - } else if (this.props.isUserTouching() && this.props.onModalOpen) { - const { status, items } = this.props; - - this.props.onModalOpen({ - status, - actions: items, - onClick: this.handleItemClick, - }); + if (this.state.id === this.props.openDropdownId) { + this.handleClose(); } else { const { top } = target.getBoundingClientRect(); - this.setState({ placement: top * 2 < innerHeight ? 'bottom' : 'top' }); + const placement = top * 2 < innerHeight ? 'bottom' : 'top'; + + this.props.onOpen(this.state.id, this.handleItemClick, placement); } } handleClose = () => { - if (this.props.onModalClose) { - this.props.onModalClose(); - } - - this.setState({ placement: null }); + this.props.onClose(this.state.id); } handleKeyDown = e => { switch(e.key) { case 'Enter': - this.handleClick(); + this.handleClick(e); break; case 'Escape': this.handleClose(); @@ -196,23 +189,22 @@ export default class Dropdown extends React.PureComponent { } render () { - const { icon, items, size, title, disabled } = this.props; - const { placement } = this.state; - const show = placement !== null; + const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId } = this.props; + const open = this.state.id === openDropdownId; return (
    - +
    diff --git a/app/javascript/mastodon/containers/dropdown_menu_container.js b/app/javascript/mastodon/containers/dropdown_menu_container.js index 151f253908c..7cbcdcd3572 100644 --- a/app/javascript/mastodon/containers/dropdown_menu_container.js +++ b/app/javascript/mastodon/containers/dropdown_menu_container.js @@ -1,3 +1,4 @@ +import { openDropdownMenu, closeDropdownMenu } from '../actions/dropdown_menu'; import { openModal, closeModal } from '../actions/modal'; import { connect } from 'react-redux'; import DropdownMenu from '../components/dropdown_menu'; @@ -5,12 +6,22 @@ import { isUserTouching } from '../is_mobile'; const mapStateToProps = state => ({ isModalOpen: state.get('modal').modalType === 'ACTIONS', + dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), + openDropdownId: state.getIn(['dropdown_menu', 'openId']), }); -const mapDispatchToProps = dispatch => ({ - isUserTouching, - onModalOpen: props => dispatch(openModal('ACTIONS', props)), - onModalClose: () => dispatch(closeModal()), +const mapDispatchToProps = (dispatch, { status, items }) => ({ + onOpen(id, onItemClick, dropdownPlacement) { + dispatch(isUserTouching() ? openModal('ACTIONS', { + status, + actions: items, + onClick: onItemClick, + }) : openDropdownMenu(id, dropdownPlacement)); + }, + onClose(id) { + dispatch(closeModal()); + dispatch(closeDropdownMenu(id)); + }, }); export default connect(mapStateToProps, mapDispatchToProps)(DropdownMenu); diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index 9960758afab..6cf00222a5b 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -56,6 +56,7 @@ const messages = defineMessages({ const mapStateToProps = state => ({ isComposing: state.getIn(['compose', 'is_composing']), hasComposingText: state.getIn(['compose', 'text']) !== '', + dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null, }); const keyMap = { @@ -184,6 +185,7 @@ export default class UI extends React.PureComponent { hasComposingText: PropTypes.bool, location: PropTypes.object, intl: PropTypes.object.isRequired, + dropdownMenuIsOpen: PropTypes.bool, }; state = { @@ -405,7 +407,7 @@ export default class UI extends React.PureComponent { render () { const { draggingOver } = this.state; - const { children, isComposing, location } = this.props; + const { children, isComposing, location, dropdownMenuIsOpen } = this.props; const handlers = { help: this.handleHotkeyToggleHelp, @@ -428,7 +430,7 @@ export default class UI extends React.PureComponent { return ( -
    +
    diff --git a/app/javascript/mastodon/reducers/dropdown_menu.js b/app/javascript/mastodon/reducers/dropdown_menu.js new file mode 100644 index 00000000000..5449884cc58 --- /dev/null +++ b/app/javascript/mastodon/reducers/dropdown_menu.js @@ -0,0 +1,18 @@ +import Immutable from 'immutable'; +import { + DROPDOWN_MENU_OPEN, + DROPDOWN_MENU_CLOSE, +} from '../actions/dropdown_menu'; + +const initialState = Immutable.Map({ openId: null, placement: null }); + +export default function dropdownMenu(state = initialState, action) { + switch (action.type) { + case DROPDOWN_MENU_OPEN: + return state.merge({ openId: action.id, placement: action.placement }); + case DROPDOWN_MENU_CLOSE: + return state.get('openId') === action.id ? state.set('openId', null) : state; + default: + return state; + } +} diff --git a/app/javascript/mastodon/reducers/index.js b/app/javascript/mastodon/reducers/index.js index a028e989cae..b84b2d18a6c 100644 --- a/app/javascript/mastodon/reducers/index.js +++ b/app/javascript/mastodon/reducers/index.js @@ -1,4 +1,5 @@ import { combineReducers } from 'redux-immutable'; +import dropdown_menu from './dropdown_menu'; import timelines from './timelines'; import meta from './meta'; import alerts from './alerts'; @@ -26,6 +27,7 @@ import lists from './lists'; import listEditor from './list_editor'; const reducers = { + dropdown_menu, timelines, meta, alerts, From e6520c027014aae9444dc58f8b3e7b618214a574 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 03:54:46 +0100 Subject: [PATCH 36/59] Fix #6657 - Use target instead of origin in Remove activity (#6664) --- app/lib/activitypub/activity/remove.rb | 2 +- app/serializers/activitypub/remove_serializer.rb | 4 ++-- spec/lib/activitypub/activity/remove_spec.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/lib/activitypub/activity/remove.rb b/app/lib/activitypub/activity/remove.rb index 97cee511687..62a1e3196ef 100644 --- a/app/lib/activitypub/activity/remove.rb +++ b/app/lib/activitypub/activity/remove.rb @@ -2,7 +2,7 @@ class ActivityPub::Activity::Remove < ActivityPub::Activity def perform - return unless @json['origin'].present? && value_or_id(@json['origin']) == @account.featured_collection_url + return unless @json['target'].present? && value_or_id(@json['target']) == @account.featured_collection_url status = status_from_uri(object_uri) diff --git a/app/serializers/activitypub/remove_serializer.rb b/app/serializers/activitypub/remove_serializer.rb index 6da7e35d3d2..c35ee916e64 100644 --- a/app/serializers/activitypub/remove_serializer.rb +++ b/app/serializers/activitypub/remove_serializer.rb @@ -3,7 +3,7 @@ class ActivityPub::RemoveSerializer < ActiveModel::Serializer include RoutingHelper - attributes :type, :actor, :origin + attributes :type, :actor, :target attribute :proper_object, key: :object def type @@ -18,7 +18,7 @@ class ActivityPub::RemoveSerializer < ActiveModel::Serializer ActivityPub::TagManager.instance.uri_for(object) end - def origin + def target account_collection_url(object, :featured) end end diff --git a/spec/lib/activitypub/activity/remove_spec.rb b/spec/lib/activitypub/activity/remove_spec.rb index c3f015053d1..4209dfde202 100644 --- a/spec/lib/activitypub/activity/remove_spec.rb +++ b/spec/lib/activitypub/activity/remove_spec.rb @@ -11,7 +11,7 @@ RSpec.describe ActivityPub::Activity::Remove do type: 'Add', actor: ActivityPub::TagManager.instance.uri_for(sender), object: ActivityPub::TagManager.instance.uri_for(status), - origin: sender.featured_collection_url, + target: sender.featured_collection_url, }.with_indifferent_access end From 89a52d6280e0643605613e507cd045ce17d7b625 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 05:58:24 +0100 Subject: [PATCH 37/59] Fix wrong target URIs in ActivityPub Add/Remove (#6668) --- app/serializers/activitypub/add_serializer.rb | 2 +- app/serializers/activitypub/remove_serializer.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/serializers/activitypub/add_serializer.rb b/app/serializers/activitypub/add_serializer.rb index a5f091e3792..c0906e8d036 100644 --- a/app/serializers/activitypub/add_serializer.rb +++ b/app/serializers/activitypub/add_serializer.rb @@ -19,6 +19,6 @@ class ActivityPub::AddSerializer < ActiveModel::Serializer end def target - account_collection_url(object, :featured) + account_collection_url(object.account, :featured) end end diff --git a/app/serializers/activitypub/remove_serializer.rb b/app/serializers/activitypub/remove_serializer.rb index c35ee916e64..c2a5ae1b3a8 100644 --- a/app/serializers/activitypub/remove_serializer.rb +++ b/app/serializers/activitypub/remove_serializer.rb @@ -19,6 +19,6 @@ class ActivityPub::RemoveSerializer < ActiveModel::Serializer end def target - account_collection_url(object, :featured) + account_collection_url(object.account, :featured) end end From dd9d00d293c127fd84183e4fc30690aea4913e02 Mon Sep 17 00:00:00 2001 From: Effy Elden Date: Wed, 7 Mar 2018 16:19:10 +1100 Subject: [PATCH 38/59] Add additional first_name and last_name SAML attribute statement options, and modify Omniauthable concern to use full_name or first_name + last_name if not available (#6669) --- .env.production.sample | 4 +++- app/models/concerns/omniauthable.rb | 3 ++- config/initializers/omniauth.rb | 2 ++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.env.production.sample b/.env.production.sample index b96754e7850..587b567579c 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -204,7 +204,9 @@ STREAMING_CLUSTER_NUM=1 # SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED=true # SAML_ATTRIBUTES_STATEMENTS_UID="urn:oid:0.9.2342.19200300.100.1.1" # SAML_ATTRIBUTES_STATEMENTS_EMAIL="urn:oid:1.3.6.1.4.1.5923.1.1.1.6" -# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.5.4.42" +# SAML_ATTRIBUTES_STATEMENTS_FULL_NAME="urn:oid:2.16.840.1.113730.3.1.241" +# SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME="urn:oid:2.5.4.42" +# SAML_ATTRIBUTES_STATEMENTS_LAST_NAME="urn:oid:2.5.4.4" # SAML_UID_ATTRIBUTE="urn:oid:0.9.2342.19200300.100.1.1" # SAML_ATTRIBUTES_STATEMENTS_VERIFIED= # SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL= diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb index 87d93c1fd1e..50288e70055 100644 --- a/app/models/concerns/omniauthable.rb +++ b/app/models/concerns/omniauthable.rb @@ -58,13 +58,14 @@ module Omniauthable email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified email = auth.info.verified_email || auth.info.email email = email_is_verified && !User.exists?(email: auth.info.email) && email + display_name = auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' ') { email: email ? email : "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com", password: Devise.friendly_token[0, 20], account_attributes: { username: ensure_unique_username(auth.uid), - display_name: [auth.info.first_name, auth.info.last_name].join(' '), + display_name: display_name, }, } end diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb index 92a73d82a23..85fb8125060 100644 --- a/config/initializers/omniauth.rb +++ b/config/initializers/omniauth.rb @@ -55,6 +55,8 @@ Devise.setup do |config| saml_options[:attribute_statements][:uid] = [ENV['SAML_ATTRIBUTES_STATEMENTS_UID']] if ENV['SAML_ATTRIBUTES_STATEMENTS_UID'] saml_options[:attribute_statements][:email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL'] saml_options[:attribute_statements][:full_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME'] + saml_options[:attribute_statements][:first_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME'] + saml_options[:attribute_statements][:last_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME'] saml_options[:attribute_statements][:verified] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED'] saml_options[:attribute_statements][:verified_email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL'] saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE'] From e26d5ca923353c9cd61073c444c0841bae4b9664 Mon Sep 17 00:00:00 2001 From: vpzomtrrfrt Date: Tue, 6 Mar 2018 23:12:01 -0700 Subject: [PATCH 39/59] Don't escape statuses while truncating (#6671) --- app/views/stream_entries/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stream_entries/show.html.haml b/app/views/stream_entries/show.html.haml index cf6671e67fe..a87c51952c7 100644 --- a/app/views/stream_entries/show.html.haml +++ b/app/views/stream_entries/show.html.haml @@ -1,5 +1,5 @@ - content_for :page_title do - = t('statuses.title', name: display_name(@account), quote: truncate(@stream_entry.activity.spoiler_text.presence || @stream_entry.activity.text, length: 50, omission: '…')) + = t('statuses.title', name: display_name(@account), quote: truncate(@stream_entry.activity.spoiler_text.presence || @stream_entry.activity.text, length: 50, omission: '…', escape: false)) - content_for :header_tags do - if @account.user&.setting_noindex From cfa9b6e13ab3c434f3901df6f614d0aa94a3d1ed Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 08:28:52 +0100 Subject: [PATCH 40/59] Remove text requirement when media attached from statuses (#6672) --- app/javascript/mastodon/actions/compose.js | 5 +++-- app/javascript/mastodon/components/status_content.js | 11 ++++++++++- .../features/compose/components/compose_form.js | 7 ++++--- .../compose/containers/compose_form_container.js | 1 + app/javascript/mastodon/reducers/compose.js | 3 --- app/lib/formatter.rb | 2 ++ app/models/status.rb | 8 ++++++-- app/services/post_status_service.rb | 9 ++------- 8 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index 0fe4800227c..130b4af2395 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -96,8 +96,9 @@ export function mentionCompose(account, router) { export function submitCompose() { return function (dispatch, getState) { const status = getState().getIn(['compose', 'text'], ''); + const media = getState().getIn(['compose', 'media_attachments']); - if (!status || !status.length) { + if ((!status || !status.length) && media.size === 0) { return; } @@ -106,7 +107,7 @@ export function submitCompose() { api(getState).post('/api/v1/statuses', { status, in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null), - media_ids: getState().getIn(['compose', 'media_attachments']).map(item => item.get('id')), + media_ids: media.map(item => item.get('id')), sensitive: getState().getIn(['compose', 'sensitive']), spoiler_text: getState().getIn(['compose', 'spoiler_text'], ''), visibility: getState().getIn(['compose', 'privacy']), diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 3b815563295..701b5702cc5 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -24,7 +24,12 @@ export default class StatusContent extends React.PureComponent { }; _updateStatusLinks () { - const node = this.node; + const node = this.node; + + if (!node) { + return; + } + const links = node.querySelectorAll('a'); for (var i = 0; i < links.length; ++i) { @@ -115,6 +120,10 @@ export default class StatusContent extends React.PureComponent { render () { const { status } = this.props; + if (status.get('content').length === 0) { + return null; + } + const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden; const content = { __html: status.get('contentHtml') }; diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js index a876c5197e7..663ccfb8eac 100644 --- a/app/javascript/mastodon/features/compose/components/compose_form.js +++ b/app/javascript/mastodon/features/compose/components/compose_form.js @@ -50,6 +50,7 @@ export default class ComposeForm extends ImmutablePureComponent { onPaste: PropTypes.func.isRequired, onPickEmoji: PropTypes.func.isRequired, showSearch: PropTypes.bool, + anyMedia: PropTypes.bool, }; static defaultProps = { @@ -142,10 +143,10 @@ export default class ComposeForm extends ImmutablePureComponent { } render () { - const { intl, onPaste, showSearch } = this.props; + const { intl, onPaste, showSearch, anyMedia } = this.props; const disabled = this.props.is_submitting; const text = [this.props.spoiler_text, countableText(this.props.text)].join(''); - + const disabledButton = disabled || this.props.is_uploading || length(text) > 500 || (text.length !== 0 && text.trim().length === 0 && !anyMedia); let publishText = ''; if (this.props.privacy === 'private' || this.props.privacy === 'direct') { @@ -203,7 +204,7 @@ export default class ComposeForm extends ImmutablePureComponent {
    -
    +
    ); diff --git a/app/javascript/mastodon/features/compose/containers/compose_form_container.js b/app/javascript/mastodon/features/compose/containers/compose_form_container.js index 5f5509dbea5..ede23d36105 100644 --- a/app/javascript/mastodon/features/compose/containers/compose_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/compose_form_container.js @@ -23,6 +23,7 @@ const mapStateToProps = state => ({ is_submitting: state.getIn(['compose', 'is_submitting']), is_uploading: state.getIn(['compose', 'is_uploading']), showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']), + anyMedia: state.getIn(['compose', 'media_attachments']).size > 0, }); const mapDispatchToProps = (dispatch) => ({ diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index dc88390dfd4..532f4b2a70f 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -90,7 +90,6 @@ function appendMedia(state, media) { map.update('media_attachments', list => list.push(media)); map.set('is_uploading', false); map.set('resetFileKey', Math.floor((Math.random() * 0x10000))); - map.update('text', oldText => `${oldText.trim()} ${media.get('text_url')}`); map.set('focusDate', new Date()); map.set('idempotencyKey', uuid()); @@ -101,12 +100,10 @@ function appendMedia(state, media) { }; function removeMedia(state, mediaId) { - const media = state.get('media_attachments').find(item => item.get('id') === mediaId); const prevSize = state.get('media_attachments').size; return state.withMutations(map => { map.update('media_attachments', list => list.filterNot(item => item.get('id') === mediaId)); - map.update('text', text => text.replace(media.get('text_url'), '').trim()); map.set('idempotencyKey', uuid()); if (prevSize === 1) { diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 8c0f8cebce5..1df4ff8d47a 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -19,6 +19,8 @@ class Formatter raw_content = status.text + return '' if raw_content.blank? + unless status.local? html = reformat(raw_content) html = encode_custom_emojis(html, status.emojis) if options[:custom_emojify] diff --git a/app/models/status.rb b/app/models/status.rb index f806a59fcb3..60fa7a22eb8 100644 --- a/app/models/status.rb +++ b/app/models/status.rb @@ -57,7 +57,7 @@ class Status < ApplicationRecord has_one :stream_entry, as: :activity, inverse_of: :status validates :uri, uniqueness: true, presence: true, unless: :local? - validates :text, presence: true, unless: :reblog? + validates :text, presence: true, unless: -> { with_media? || reblog? } validates_with StatusLengthValidator validates :reblog, uniqueness: { scope: :account }, if: :reblog? @@ -150,8 +150,12 @@ class Status < ApplicationRecord private_visibility? || direct_visibility? end + def with_media? + media_attachments.any? + end + def non_sensitive_with_media? - !sensitive? && media_attachments.any? + !sensitive? && with_media? end def emojis diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 92d868afe45..df38d16a6c0 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -21,17 +21,17 @@ class PostStatusService < BaseService media = validate_media!(options[:media_ids]) status = nil + text = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present? ApplicationRecord.transaction do status = account.statuses.create!(text: text, + media_attachments: media || [], thread: in_reply_to, sensitive: options[:sensitive], spoiler_text: options[:spoiler_text] || '', visibility: options[:visibility] || account.user&.setting_default_privacy, language: LanguageDetector.instance.detect(text, account), application: options[:application]) - - attach_media(status, media) end process_mentions_service.call(status) @@ -64,11 +64,6 @@ class PostStatusService < BaseService media end - def attach_media(status, media) - return if media.nil? - media.update(status_id: status.id) - end - def process_mentions_service ProcessMentionsService.new end From 8de048fcdb328167922f3056e460afc6f055cb8d Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 08:59:27 +0100 Subject: [PATCH 41/59] In wide layout, columnize Mastodon features on landing page (#6674) --- app/javascript/styles/mastodon/about.scss | 21 ++++++++++++++------- app/views/about/show.html.haml | 6 ++++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss index 9ce83aa9be5..f2991813549 100644 --- a/app/javascript/styles/mastodon/about.scss +++ b/app/javascript/styles/mastodon/about.scss @@ -832,8 +832,13 @@ $small-breakpoint: 960px; } &__features { + & > p { + padding-right: 60px; + } + .features-list { - margin: 40px 0 !important; + margin: 40px 0; + margin-top: 30px; } &__action { @@ -842,17 +847,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; @@ -878,6 +877,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 { diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml index 4f3cedacd65..d067d487416 100644 --- a/app/views/about/show.html.haml +++ b/app/views/about/show.html.haml @@ -103,8 +103,10 @@ - if Setting.timeline_preview .column-4.landing-page__information .landing-page__features - %h3= t 'about.what_is_mastodon' - %p= t 'about.about_mastodon_html' + .features-list + %div + %h3= t 'about.what_is_mastodon' + %p= t 'about.about_mastodon_html' = render 'features' From a1b065700a9aafd0989bd5686c849f961f727c83 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 12:01:53 +0100 Subject: [PATCH 42/59] Fix focal point modals broken by #5956 (#6676) --- .../mastodon/features/ui/components/focal_point_modal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js index ee5c791d4ab..1038e186470 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js @@ -103,8 +103,8 @@ export default class FocalPointModal extends ImmutablePureComponent { const height = media.getIn(['meta', 'original', 'height']) || null; return ( -
    -
    +
    +
    Date: Wed, 7 Mar 2018 12:02:05 +0100 Subject: [PATCH 43/59] Fix cover behaviour of thumbnails that are wider than taller (#6678) --- app/javascript/mastodon/components/media_gallery.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 3568a844077..71436500af0 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -167,6 +167,14 @@ class Item extends React.PureComponent { vShift = shiftToPoint(widthRatio, (containerHeight * (height / 100)), originalHeight, focusY, true); } + if (originalWidth > originalHeight) { + imageStyle.height = '100%'; + imageStyle.width = 'auto'; + } else { + imageStyle.height = 'auto'; + imageStyle.width = '100%'; + } + imageStyle.top = vShift; imageStyle.left = hShift; } else { From 4ca60c665e02103b8730748c9b82b52bcd0d8d1c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 7 Mar 2018 12:06:23 +0100 Subject: [PATCH 44/59] Bump version to 2.3.0rc2 --- lib/mastodon/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 4150b39b6a7..418ce4828e6 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -21,7 +21,7 @@ module Mastodon end def flags - 'rc1' + 'rc2' end def to_a From 6dcf96271ee5b81ecb910f80f8218bb2a9b1b404 Mon Sep 17 00:00:00 2001 From: MitarashiDango Date: Thu, 8 Mar 2018 09:22:47 +0900 Subject: [PATCH 45/59] fix validation error (media only status) (#6684) * fix validation error (media only status) * Incorporating review suggestions * Reflect similar fix to OStatus side * Fix not to include media in transaction * Restore the limit of the number of media * Fix not to return nil --- app/lib/activitypub/activity/create.rb | 15 ++++----------- app/lib/ostatus/activity/creation.rb | 13 +++---------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index a7afbb859ce..5a1c13d6781 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -20,13 +20,12 @@ class ActivityPub::Activity::Create < ActivityPub::Activity private def process_status - media_attachments = process_attachments + status_params = process_status_params ApplicationRecord.transaction do @status = Status.create!(status_params) process_tags(@status) - attach_media(@status, media_attachments) end resolve_thread(@status) @@ -40,7 +39,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity status end - def status_params + def process_status_params { uri: @object['id'], url: object_url || @object['id'], @@ -54,6 +53,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity visibility: visibility_from_audience, thread: replied_to_status, conversation: conversation_from_uri(@object['conversation']), + media_attachments: process_attachments.take(4), } end @@ -108,7 +108,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity end def process_attachments - return if @object['attachment'].nil? + return [] if @object['attachment'].nil? media_attachments = [] @@ -132,13 +132,6 @@ class ActivityPub::Activity::Create < ActivityPub::Activity media_attachments end - def attach_media(status, media_attachments) - return if media_attachments.blank? - - media = MediaAttachment.where(status_id: nil, id: media_attachments.take(4).map(&:id)) - media.update(status_id: status.id) - end - def resolve_thread(status) return unless status.reply? && status.thread.nil? ThreadResolveWorker.perform_async(status.id, in_reply_to_uri) diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb index 7cf2d90dcaa..aa46267dc71 100644 --- a/app/lib/ostatus/activity/creation.rb +++ b/app/lib/ostatus/activity/creation.rb @@ -29,7 +29,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base # Skip if the reblogged status is not public return if cached_reblog && !(cached_reblog.public_visibility? || cached_reblog.unlisted_visibility?) - media_attachments = save_media + media_attachments = save_media.take(4) ApplicationRecord.transaction do status = Status.create!( @@ -44,12 +44,12 @@ class OStatus::Activity::Creation < OStatus::Activity::Base language: content_language, visibility: visibility_scope, conversation: find_or_create_conversation, - thread: thread? ? find_status(thread.first) || find_activitypub_status(thread.first, thread.second) : nil + thread: thread? ? find_status(thread.first) || find_activitypub_status(thread.first, thread.second) : nil, + media_attachments: media_attachments ) save_mentions(status) save_hashtags(status) - attach_media(status, media_attachments) save_emojis(status) end @@ -159,13 +159,6 @@ class OStatus::Activity::Creation < OStatus::Activity::Base media_attachments end - def attach_media(parent, media_attachments) - return if media_attachments.blank? - - media = MediaAttachment.where(status_id: nil, id: media_attachments.take(4).map(&:id)) - media.update(status_id: parent.id) - end - def save_emojis(parent) do_not_download = DomainBlock.find_by(domain: parent.account.domain)&.reject_media? From 9aba44ea79c4c1bd21e9232b65f3cf1a9736c6cc Mon Sep 17 00:00:00 2001 From: "Renato \"Lond\" Cerqueira" Date: Thu, 8 Mar 2018 02:25:10 +0100 Subject: [PATCH 46/59] Rescue when there's no extension in the remotable (#6358) * Rescue when there's no extension in the remotable Sometimes the remotable is pointing to a directory with no file extension. Maybe it should not be expecting to identify based on extensions to begin with, but since it's the case, it should be ready for it. * Fix codeclimate issue * Check if filename is nil instead of rescueing exception Suggestion made in the PR * Avoid concatenation issue if filename is nil If filename is nil, extname was undefined * Invert condition Address PR comments --- app/models/concerns/remotable.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 990035b34b8..020303a2f97 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -28,7 +28,11 @@ module Remotable matches = response.headers['content-disposition']&.match(/filename="([^"]*)"/) filename = matches.nil? ? parsed_url.path.split('/').last : matches[1] basename = SecureRandom.hex(8) - extname = File.extname(filename) + extname = if filename.nil? + '' + else + File.extname(filename) + end send("#{attachment_name}=", StringIO.new(response.to_s)) send("#{attachment_name}_file_name=", basename + extname) From 83c982b4584b8fcbe75c670f15e562a3510a3804 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 8 Mar 2018 12:43:57 +0900 Subject: [PATCH 47/59] Run tests with npm-run-all (#6688) --- package.json | 3 +- yarn.lock | 131 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 130 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5b9ea7d37d0..fc8e2425ec8 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "build:production": "cross-env RAILS_ENV=production ./bin/webpack", "manage:translations": "node ./config/webpack/translationRunner.js", "start": "node ./streaming/index.js", - "test": "yarn run test:lint && yarn run test:jest", + "test": "npm-run-all test:lint test:jest", "test:lint": "eslint -c .eslintrc.yml --ext=js app/javascript/ config/webpack/ streaming/", "test:jest": "cross-env NODE_ENV=test jest --coverage" }, @@ -67,6 +67,7 @@ "marky": "^1.2.0", "mkdirp": "^0.5.1", "node-sass": "^4.7.2", + "npm-run-all": "^4.1.2", "npmlog": "^4.1.2", "object-assign": "^4.1.1", "object-fit-images": "^3.2.3", diff --git a/yarn.lock b/yarn.lock index c5e132022d2..fbce624be9e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -244,6 +244,10 @@ array-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + array-find-index@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" @@ -263,6 +267,14 @@ array-includes@^3.0.3: define-properties "^1.1.2" es-abstract "^1.7.0" +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -2166,7 +2178,7 @@ double-ended-queue@^2.1.0-0: version "2.1.0-0" resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -2282,7 +2294,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.6.1, es-abstract@^1.7.0: +es-abstract@^1.4.3, es-abstract@^1.6.1, es-abstract@^1.7.0: version "1.10.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.10.0.tgz#1ecb36c197842a00d8ee4c2dfd8646bb97d60864" dependencies: @@ -2534,6 +2546,18 @@ event-emitter@~0.3.5: d "1" es5-ext "~0.10.14" +event-stream@~3.3.0: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + eventemitter3@1.x.x: version "1.2.0" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" @@ -2868,6 +2892,10 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -4048,6 +4076,10 @@ json-loader@^0.5.4: version "0.5.7" resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" +json-parse-better-errors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.1.tgz#50183cd1b2d25275de069e9e71b467ac9eab973a" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -4187,6 +4219,15 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" @@ -4377,6 +4418,10 @@ map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + mark-loader@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/mark-loader/-/mark-loader-0.1.6.tgz#0abb477dca7421d70e20128ff6489f5cae8676d5" @@ -4425,6 +4470,10 @@ memory-fs@^0.4.0, memory-fs@~0.4.1: errno "^0.1.3" readable-stream "^2.0.1" +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + meow@^3.3.0, meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -4756,6 +4805,20 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" +npm-run-all@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.2.tgz#90d62d078792d20669139e718621186656cea056" + dependencies: + ansi-styles "^3.2.0" + chalk "^2.1.0" + cross-spawn "^5.1.0" + memorystream "^0.3.1" + minimatch "^3.0.4" + ps-tree "^1.1.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -5028,6 +5091,13 @@ parse-json@^3.0.0: dependencies: error-ex "^1.3.1" +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" @@ -5100,6 +5170,18 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + dependencies: + through "~2.3" + pbkdf2@^3.0.3: version "3.0.14" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.14.tgz#a35e13c64799b06ce15320f459c230e68e73bade" @@ -5763,6 +5845,12 @@ prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +ps-tree@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.1.0.tgz#b421b24140d6203f1ed3c76996b4427b08e8c014" + dependencies: + event-stream "~3.3.0" + pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -6126,6 +6214,14 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9, readable-stream@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" @@ -6675,6 +6771,15 @@ shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + shellwords@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" @@ -6809,6 +6914,12 @@ spdy@^3.4.1: select-hose "^2.0.0" spdy-transport "^2.0.18" +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + dependencies: + through "2" + split@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" @@ -6854,6 +6965,12 @@ stream-browserify@^2.0.1: inherits "~2.0.1" readable-stream "^2.0.2" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + dependencies: + duplexer "~0.1.1" + stream-http@^2.7.2: version "2.7.2" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.7.2.tgz#40a050ec8dc3b53b33d9909415c02c0bf1abfbad" @@ -6890,6 +7007,14 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + string_decoder@^1.0.0, string_decoder@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" @@ -7057,7 +7182,7 @@ throng@^4.0.0: dependencies: lodash.defaults "^4.0.1" -through@2, through@^2.3.6: +through@2, through@^2.3.6, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" From 86a9de6753fc425b247699c7822bc8a5d49af043 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 04:54:26 +0100 Subject: [PATCH 48/59] Display AttachmentList in timelines in compact style when media missing (#6680) --- .../mastodon/components/attachment_list.js | 18 +++- app/javascript/mastodon/components/status.js | 8 +- .../styles/mastodon/components.scss | 86 +++++++++++-------- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.js index 9f2d46ddd76..d8f90b5b6d8 100644 --- a/app/javascript/mastodon/components/attachment_list.js +++ b/app/javascript/mastodon/components/attachment_list.js @@ -1,5 +1,6 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; import ImmutablePureComponent from 'react-immutable-pure-component'; const filename = url => url.split('/').pop().split('#')[0].split('?')[0]; @@ -8,10 +9,25 @@ export default class AttachmentList extends ImmutablePureComponent { static propTypes = { media: ImmutablePropTypes.list.isRequired, + compact: PropTypes.bool, }; render () { - const { media } = this.props; + const { media, compact } = this.props; + + if (compact) { + return ( +
    + +
    + ); + } return (
    diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 85baeffca7d..c6f11c37901 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -7,6 +7,7 @@ import RelativeTimestamp from './relative_timestamp'; import DisplayName from './display_name'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; +import AttachmentList from './attachment_list'; import { FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { MediaGallery, Video } from '../features/ui/util/async-components'; @@ -179,7 +180,12 @@ export default class Status extends ImmutablePureComponent { if (status.get('media_attachments').size > 0 && !this.props.muted) { if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { - + media = ( + + ); } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { const video = status.getIn(['media_attachments', 0]); diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index c8850dede3c..c35cc9d75eb 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4222,45 +4222,59 @@ a.status-card { border-radius: 4px; margin-top: 14px; overflow: hidden; -} -.attachment-list__icon { - flex: 0 0 auto; - color: $ui-base-lighter-color; - padding: 8px 18px; - cursor: default; - border-right: 1px solid lighten($ui-base-color, 8%); - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 26px; - - .fa { - display: block; - } -} - -.attachment-list__list { - list-style: none; - padding: 4px 0; - padding-left: 8px; - display: flex; - flex-direction: column; - justify-content: center; - - li { - display: block; - padding: 4px 0; - } - - a { - text-decoration: none; + &__icon { + flex: 0 0 auto; color: $ui-base-lighter-color; - font-weight: 500; + padding: 8px 18px; + cursor: default; + border-right: 1px solid lighten($ui-base-color, 8%); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: 26px; - &:hover { - text-decoration: underline; + .fa { + display: block; + } + } + + &__list { + list-style: none; + padding: 4px 0; + padding-left: 8px; + display: flex; + flex-direction: column; + justify-content: center; + + li { + display: block; + padding: 4px 0; + } + + a { + text-decoration: none; + color: $ui-base-lighter-color; + font-weight: 500; + + &:hover { + text-decoration: underline; + } + } + } + + &.compact { + border: 0; + margin-top: 4px; + + .attachment-list__list { + padding: 0; + display: block; + } + + .fa { + color: $ui-base-lighter-color; } } } From 1085ef38365facd52ca0f49046ee1d55b3763dcc Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 8 Mar 2018 14:59:34 +0900 Subject: [PATCH 49/59] Weblate translations (2018-03-08) (#6690) * Translated using Weblate (French) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (French) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (French) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (French) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/fr/ * Translated using Weblate (Slovak) Currently translated at 85.3% (494 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Slovak) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/sk/ * Translated using Weblate (Japanese) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/pt_BR/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/pt_BR/ * Translated using Weblate (Japanese) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * Translated using Weblate (Arabic) Currently translated at 99.2% (273 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ar/ * Translated using Weblate (Japanese) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * Translated using Weblate (Arabic) Currently translated at 66.8% (387 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/ar/ * Translated using Weblate (Arabic) Currently translated at 93.1% (54 of 58 strings) Translation: Mastodon/Preferences Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/simple_form/ar/ * Translated using Weblate (French) Currently translated at 99.8% (578 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/fr/ * Translated using Weblate (Slovak) Currently translated at 87.7% (508 of 579 strings) Translation: Mastodon/Backend Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/backend/sk/ * Translated using Weblate (Japanese) Currently translated at 100.0% (275 of 275 strings) Translation: Mastodon/React Translate-URL: https://weblate.joinmastodon.org/projects/mastodon/frontend/ja/ * bundle exec i18n-tasks normalize && yarn manage:translations * Remove ar.simple_form.hints.defaults.{display_name,note} --- app/javascript/mastodon/locales/ar.json | 7 +++-- app/javascript/mastodon/locales/bg.json | 1 + app/javascript/mastodon/locales/ca.json | 1 + app/javascript/mastodon/locales/de.json | 1 + .../mastodon/locales/defaultMessages.json | 13 +++------ 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/fa.json | 1 + app/javascript/mastodon/locales/fi.json | 1 + app/javascript/mastodon/locales/fr.json | 9 +++--- 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 | 13 +++++---- app/javascript/mastodon/locales/ko.json | 1 + app/javascript/mastodon/locales/nl.json | 1 + 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 | 23 +++++++-------- app/javascript/mastodon/locales/pt.json | 1 + app/javascript/mastodon/locales/ru.json | 1 + app/javascript/mastodon/locales/sk.json | 7 +++-- 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/th.json | 1 + app/javascript/mastodon/locales/tr.json | 1 + app/javascript/mastodon/locales/uk.json | 1 + 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/ar.yml | 1 + config/locales/fr.yml | 9 +++--- config/locales/pt-BR.yml | 1 + config/locales/simple_form.ar.yml | 6 ---- config/locales/sk.yml | 28 +++++++++++++++++++ 43 files changed, 103 insertions(+), 46 deletions(-) diff --git a/app/javascript/mastodon/locales/ar.json b/app/javascript/mastodon/locales/ar.json index 6c10833fc35..33e223b2adf 100644 --- a/app/javascript/mastodon/locales/ar.json +++ b/app/javascript/mastodon/locales/ar.json @@ -1,8 +1,9 @@ { "account.block": "حظر @{name}", "account.block_domain": "إخفاء كل شيئ قادم من إسم النطاق {domain}", - "account.blocked": "Blocked", + "account.blocked": "محظور", "account.disclaimer_full": "قد لا تعكس المعلومات أدناه الملف الشخصي الكامل للمستخدم.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "تعديل الملف الشخصي", "account.follow": "تابِع", "account.followers": "المتابعون", @@ -14,7 +15,7 @@ "account.moved_to": "{name} إنتقل إلى :", "account.mute": "أكتم @{name}", "account.mute_notifications": "كتم إخطارات @{name}", - "account.muted": "Muted", + "account.muted": "مكتوم", "account.posts": "التبويقات", "account.posts_with_replies": "تبويقات تحتوي على رُدود", "account.report": "أبلغ عن @{name}", @@ -241,7 +242,7 @@ "status.mute_conversation": "كتم المحادثة", "status.open": "وسع هذه المشاركة", "status.pin": "تدبيس على الملف الشخصي", - "status.pinned": "Pinned toot", + "status.pinned": "تبويق مثبَّت", "status.reblog": "رَقِّي", "status.reblogged_by": "{name} رقى", "status.reply": "ردّ", diff --git a/app/javascript/mastodon/locales/bg.json b/app/javascript/mastodon/locales/bg.json index 0af5a0fcc5f..a84e6e9d1dc 100644 --- a/app/javascript/mastodon/locales/bg.json +++ b/app/javascript/mastodon/locales/bg.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Редактирай профила си", "account.follow": "Последвай", "account.followers": "Последователи", diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index fa49d352284..bac807dbb14 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -3,6 +3,7 @@ "account.block_domain": "Amaga-ho tot de {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "La informació següent pot reflectir incompleta el perfil de l'usuari.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Edita el perfil", "account.follow": "Segueix", "account.followers": "Seguidors", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 9fe09487c0c..6e0b4456cf1 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -3,6 +3,7 @@ "account.block_domain": "Alles von {domain} verstecken", "account.blocked": "Blocked", "account.disclaimer_full": "Das Profil wird möglicherweise unvollständig wiedergegeben.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Profil bearbeiten", "account.follow": "Folgen", "account.followers": "Folgende", diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index bd21d4cc65f..c10afce5c9a 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -319,15 +319,6 @@ ], "path": "app/javascript/mastodon/containers/status_container.json" }, - { - "descriptors": [ - { - "defaultMessage": "Media", - "id": "account.media" - } - ], - "path": "app/javascript/mastodon/features/account_gallery/index.json" - }, { "descriptors": [ { @@ -497,6 +488,10 @@ { "defaultMessage": "Muted", "id": "account.muted" + }, + { + "defaultMessage": "Domain hidden", + "id": "account.domain_blocked" } ], "path": "app/javascript/mastodon/features/account/components/header.json" diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 3f2367d5bab..b23332df4da 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "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", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index d1fcb7fe79b..0e5e22749bc 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -3,6 +3,7 @@ "account.block_domain": "Kaŝi ĉion de {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Subaj informoj povas reflekti la profilon de la uzanto nekomplete.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Redakti profilon", "account.follow": "Sekvi", "account.followers": "Sekvantoj", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index ab1aa7ed798..d172dff1c5a 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -3,6 +3,7 @@ "account.block_domain": "Ocultar todo de {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "La siguiente información del usuario puede estar incompleta.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", "account.followers": "Seguidores", diff --git a/app/javascript/mastodon/locales/fa.json b/app/javascript/mastodon/locales/fa.json index b589d95adf1..b5b81bff998 100644 --- a/app/javascript/mastodon/locales/fa.json +++ b/app/javascript/mastodon/locales/fa.json @@ -3,6 +3,7 @@ "account.block_domain": "پنهان‌سازی همه چیز از سرور {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "اطلاعات زیر ممکن است نمایهٔ این کاربر را به تمامی نشان ندهد.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "ویرایش نمایه", "account.follow": "پی بگیرید", "account.followers": "پیگیران", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index 9ea3c809407..aa97aae8485 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -3,6 +3,7 @@ "account.block_domain": "Piilota kaikki sisältö verkkotunnuksesta {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Alla olevat käyttäjän profiilitiedot saattavat olla epätäydellisiä.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Muokkaa", "account.follow": "Seuraa", "account.followers": "Seuraajia", diff --git a/app/javascript/mastodon/locales/fr.json b/app/javascript/mastodon/locales/fr.json index 86a23b264b1..77f4a0cca8a 100644 --- a/app/javascript/mastodon/locales/fr.json +++ b/app/javascript/mastodon/locales/fr.json @@ -1,8 +1,9 @@ { "account.block": "Bloquer @{name}", "account.block_domain": "Tout masquer venant de {domain}", - "account.blocked": "Blocked", + "account.blocked": "Bloqué", "account.disclaimer_full": "Les données ci-dessous peuvent ne pas refléter ce profil dans sa totalité.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Modifier le profil", "account.follow": "Suivre", "account.followers": "Abonné⋅e⋅s", @@ -14,7 +15,7 @@ "account.moved_to": "{name} a déménagé vers :", "account.mute": "Masquer @{name}", "account.mute_notifications": "Ignorer les notifications de @{name}", - "account.muted": "Muted", + "account.muted": "Silencé", "account.posts": "Pouets", "account.posts_with_replies": "Pouets avec réponses", "account.report": "Signaler", @@ -218,7 +219,7 @@ "report.target": "Signalement", "search.placeholder": "Rechercher", "search_popout.search_format": "Recherche avancée", - "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": "Les textes simples retournent les pouets que vous avez écris, mis en favori, épinglés, ou ayant été mentionnés, ainsi que les noms d'utilisateurs, les noms affichés, et les hashtags correspondant.", "search_popout.tips.hashtag": "hashtag", "search_popout.tips.status": "statuts", "search_popout.tips.text": "Un texte simple renvoie les noms affichés, les noms d’utilisateur⋅ice et les hashtags correspondants", @@ -241,7 +242,7 @@ "status.mute_conversation": "Masquer la conversation", "status.open": "Déplier ce statut", "status.pin": "Épingler sur le profil", - "status.pinned": "Pinned toot", + "status.pinned": "Pouet épinglé", "status.reblog": "Partager", "status.reblogged_by": "{name} a partagé :", "status.reply": "Répondre", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 1c85b4aa2a2..e222ddaea45 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -3,6 +3,7 @@ "account.block_domain": "Ocultar calquer contido de {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "A información inferior podería mostrar un perfil incompleto da usuaria.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", "account.followers": "Seguidoras", diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 28c6f624996..b31976c4253 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -3,6 +3,7 @@ "account.block_domain": "להסתיר הכל מהקהילה {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "המידע להלן עשוי להיות לא עדכני או לא שלם.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "עריכת פרופיל", "account.follow": "מעקב", "account.followers": "עוקבים", diff --git a/app/javascript/mastodon/locales/hr.json b/app/javascript/mastodon/locales/hr.json index ce57c3a9cd6..d176a5df665 100644 --- a/app/javascript/mastodon/locales/hr.json +++ b/app/javascript/mastodon/locales/hr.json @@ -3,6 +3,7 @@ "account.block_domain": "Sakrij sve sa {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Ovaj korisnik je sa druge instance. Ovaj broj bi mogao biti veći.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Uredi profil", "account.follow": "Slijedi", "account.followers": "Sljedbenici", diff --git a/app/javascript/mastodon/locales/hu.json b/app/javascript/mastodon/locales/hu.json index b45e88e8c0e..a4d2091efaf 100644 --- a/app/javascript/mastodon/locales/hu.json +++ b/app/javascript/mastodon/locales/hu.json @@ -3,6 +3,7 @@ "account.block_domain": "Minden elrejtése innen: {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Az alul található információk hiányosan mutathatják be a felhasználót.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Profil szerkesztése", "account.follow": "Követés", "account.followers": "Követők", diff --git a/app/javascript/mastodon/locales/hy.json b/app/javascript/mastodon/locales/hy.json index 58da05911bb..b5e9a2b5aaf 100644 --- a/app/javascript/mastodon/locales/hy.json +++ b/app/javascript/mastodon/locales/hy.json @@ -3,6 +3,7 @@ "account.block_domain": "Թաքցնել ամենը հետեւյալ տիրույթից՝ {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Ներքոհիշյալը կարող է ոչ ամբողջությամբ արտացոլել օգտատիրոջ էջի տվյալները։", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Խմբագրել անձնական էջը", "account.follow": "Հետեւել", "account.followers": "Հետեւվողներ", diff --git a/app/javascript/mastodon/locales/id.json b/app/javascript/mastodon/locales/id.json index 683d131bf65..596415cde27 100644 --- a/app/javascript/mastodon/locales/id.json +++ b/app/javascript/mastodon/locales/id.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Ubah profil", "account.follow": "Ikuti", "account.followers": "Pengikut", diff --git a/app/javascript/mastodon/locales/io.json b/app/javascript/mastodon/locales/io.json index 221928caa84..4f554b08f41 100644 --- a/app/javascript/mastodon/locales/io.json +++ b/app/javascript/mastodon/locales/io.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Modifikar profilo", "account.follow": "Sequar", "account.followers": "Sequanti", diff --git a/app/javascript/mastodon/locales/it.json b/app/javascript/mastodon/locales/it.json index edaede66300..6b253251285 100644 --- a/app/javascript/mastodon/locales/it.json +++ b/app/javascript/mastodon/locales/it.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Modifica profilo", "account.follow": "Segui", "account.followers": "Seguaci", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index fd47e7dc940..8db3f7cabed 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -1,8 +1,9 @@ { "account.block": "@{name}さんをブロック", "account.block_domain": "{domain}全体を非表示", - "account.blocked": "Blocked", + "account.blocked": "ブロック済み", "account.disclaimer_full": "以下の情報は不正確な可能性があります。", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "プロフィールを編集", "account.follow": "フォロー", "account.followers": "フォロワー", @@ -14,7 +15,7 @@ "account.moved_to": "{name}さんは引っ越しました:", "account.mute": "@{name}さんをミュート", "account.mute_notifications": "@{name}さんからの通知を受け取らない", - "account.muted": "Muted", + "account.muted": "ミュート済み", "account.posts": "投稿", "account.posts_with_replies": "投稿と返信", "account.report": "@{name}さんを通報", @@ -218,7 +219,7 @@ "report.target": "{target}さんを通報する", "search.placeholder": "検索", "search_popout.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.full_text": "表示名やユーザー名、ハッシュタグのほか、あなたのトゥートやお気に入り、ブーストしたトゥート、返信に一致する単純なテキスト。", "search_popout.tips.hashtag": "ハッシュタグ", "search_popout.tips.status": "トゥート", "search_popout.tips.text": "表示名やユーザー名、ハッシュタグに一致する単純なテキスト", @@ -241,9 +242,9 @@ "status.mute_conversation": "会話をミュート", "status.open": "詳細を表示", "status.pin": "プロフィールに固定表示", - "status.pinned": "Pinned toot", + "status.pinned": "固定されたトゥート", "status.reblog": "ブースト", - "status.reblogged_by": "{name}さんにブーストされました", + "status.reblogged_by": "{name}さんがブースト", "status.reply": "返信", "status.replyAll": "全員に返信", "status.report": "@{name}さんを通報", @@ -258,7 +259,7 @@ "tabs_bar.home": "ホーム", "tabs_bar.local_timeline": "ローカル", "tabs_bar.notifications": "通知", - "ui.beforeunload": "Mastodonから離れるとあなたのドラフトは失われます。", + "ui.beforeunload": "Mastodonから離れると送信前の投稿は失われます。", "upload_area.title": "ドラッグ&ドロップでアップロード", "upload_button.label": "メディアを追加", "upload_form.description": "視覚障害者のための説明", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 3c71beafa49..9f7cebf6be0 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -3,6 +3,7 @@ "account.block_domain": "{domain} 전체를 숨김", "account.blocked": "Blocked", "account.disclaimer_full": "여기 있는 정보는 유저의 프로파일을 정확히 반영하지 못 할 수도 있습니다.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "프로필 편집", "account.follow": "팔로우", "account.followers": "팔로워", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index 068729cdf14..ccf3cefc280 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -3,6 +3,7 @@ "account.block_domain": "Negeer alles van {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "De informatie hieronder kan mogelijk een incompleet beeld geven van dit gebruikersprofiel.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Profiel bewerken", "account.follow": "Volgen", "account.followers": "Volgers", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index ed408d61cb3..b7ceb9f7348 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -3,6 +3,7 @@ "account.block_domain": "Skjul alt fra {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Informasjonen nedenfor kan gi et ufullstendig bilde av brukerens profil.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Rediger profil", "account.follow": "Følg", "account.followers": "Følgere", diff --git a/app/javascript/mastodon/locales/oc.json b/app/javascript/mastodon/locales/oc.json index 01a1d21500e..c9a15c7518c 100644 --- a/app/javascript/mastodon/locales/oc.json +++ b/app/javascript/mastodon/locales/oc.json @@ -3,6 +3,7 @@ "account.block_domain": "Tot amagar del domeni {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Aquelas informacions de perfil pòdon èsser incomplètas.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Modificar lo perfil", "account.follow": "Sègre", "account.followers": "Seguidors", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index d914e22fdb5..d85d8ae640f 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -3,6 +3,7 @@ "account.block_domain": "Blokuj wszystko z {domain}", "account.blocked": "Zablokowany", "account.disclaimer_full": "Poniższe informacje mogą nie odwzorowywać bezbłędnie profilu użytkownika.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Edytuj profil", "account.follow": "Śledź", "account.followers": "Śledzący", diff --git a/app/javascript/mastodon/locales/pt-BR.json b/app/javascript/mastodon/locales/pt-BR.json index 8c8039f251f..fa36bb89062 100644 --- a/app/javascript/mastodon/locales/pt-BR.json +++ b/app/javascript/mastodon/locales/pt-BR.json @@ -1,8 +1,9 @@ { "account.block": "Bloquear @{name}", "account.block_domain": "Esconder tudo de {domain}", - "account.blocked": "Blocked", + "account.blocked": "Bloqueado", "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de maneira incompleta.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", "account.followers": "Seguidores", @@ -14,9 +15,9 @@ "account.moved_to": "{name} se mudou para:", "account.mute": "Silenciar @{name}", "account.mute_notifications": "Silenciar notificações de @{name}", - "account.muted": "Muted", - "account.posts": "Posts", - "account.posts_with_replies": "Toots with replies", + "account.muted": "Silenciado", + "account.posts": "Toots", + "account.posts_with_replies": "Toots e respostas", "account.report": "Denunciar @{name}", "account.requested": "Aguardando aprovação. Clique para cancelar a solicitação", "account.share": "Compartilhar perfil de @{name}", @@ -210,20 +211,20 @@ "relative_time.minutes": "{number}m", "relative_time.seconds": "{number}s", "reply_indicator.cancel": "Cancelar", - "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.forward": "Encaminhar para {target}", + "report.forward_hint": "Essa conta pertence à um outro servidor. Encaminhar uma cópia da denúncia com seus dados tornados anônimos para esse servidor?", + "report.hint": "A sua denúncia será enviada aos moderadores da instância. Você pode adicionar uma explicação de porque você está denunciando essa conta abaixo:", "report.placeholder": "Comentários adicionais", "report.submit": "Enviar", "report.target": "Denunciar", "search.placeholder": "Pesquisar", "search_popout.search_format": "Formato de busca avançado", - "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": "Texto simples retorna status que você escreveu, favoritou, compartilhou ou em que tenha sido mencionado; também retorna nomes de exibição, usuários e hashtags correspondentes.", "search_popout.tips.hashtag": "hashtag", "search_popout.tips.status": "status", "search_popout.tips.text": "Texto simples retorna nomes de exibição, usuários e hashtags correspondentes", "search_popout.tips.user": "usuário", - "search_results.accounts": "People", + "search_results.accounts": "Pessoas", "search_results.hashtags": "Hashtags", "search_results.statuses": "Toots", "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}", @@ -241,7 +242,7 @@ "status.mute_conversation": "Silenciar conversa", "status.open": "Expandir", "status.pin": "Fixar no perfil", - "status.pinned": "Pinned toot", + "status.pinned": "Toot fixado", "status.reblog": "Compartilhar", "status.reblogged_by": "{name} compartilhou", "status.reply": "Responder", @@ -262,7 +263,7 @@ "upload_area.title": "Arraste e solte para enviar", "upload_button.label": "Adicionar mídia", "upload_form.description": "Descreva a imagem para deficientes visuais", - "upload_form.focus": "Crop", + "upload_form.focus": "Recortar", "upload_form.undo": "Desfazer", "upload_progress.label": "Salvando...", "video.close": "Fechar vídeo", diff --git a/app/javascript/mastodon/locales/pt.json b/app/javascript/mastodon/locales/pt.json index b7061693c87..f059e7c2033 100644 --- a/app/javascript/mastodon/locales/pt.json +++ b/app/javascript/mastodon/locales/pt.json @@ -3,6 +3,7 @@ "account.block_domain": "Esconder tudo do domínio {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "As informações abaixo podem refletir o perfil do usuário de forma incompleta.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Editar perfil", "account.follow": "Seguir", "account.followers": "Seguidores", diff --git a/app/javascript/mastodon/locales/ru.json b/app/javascript/mastodon/locales/ru.json index 18fd90d2582..06a7d732b40 100644 --- a/app/javascript/mastodon/locales/ru.json +++ b/app/javascript/mastodon/locales/ru.json @@ -3,6 +3,7 @@ "account.block_domain": "Блокировать все с {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Нижеуказанная информация может не полностью отражать профиль пользователя.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Изменить профиль", "account.follow": "Подписаться", "account.followers": "Подписаны", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index 6239abb3a3c..b767538998a 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -1,8 +1,9 @@ { "account.block": "Blokovať @{name}", "account.block_domain": "Ukryť všetko z {domain}", - "account.blocked": "Blocked", + "account.blocked": "Blokovaný/á", "account.disclaimer_full": "Inofrmácie nižšie nemusia byť úplným odrazom uživateľovho účtu.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Upraviť profil", "account.follow": "Následovať", "account.followers": "Sledujúci", @@ -14,7 +15,7 @@ "account.moved_to": "{name} sa presunul/a na:", "account.mute": "Ignorovať @{name}", "account.mute_notifications": "Stĺmiť notifikácie od @{name}", - "account.muted": "Muted", + "account.muted": "Utíšený/á", "account.posts": "Hlášky", "account.posts_with_replies": "Príspevky s odpoveďami", "account.report": "Nahlásiť @{name}", @@ -241,7 +242,7 @@ "status.mute_conversation": "Ignorovať konverzáciu", "status.open": "Otvoriť tento status", "status.pin": "Pripnúť na profil", - "status.pinned": "Pinned toot", + "status.pinned": "Pripnutý príspevok", "status.reblog": "Povýšiť", "status.reblogged_by": "{name} povýšil", "status.reply": "Odpovedať", diff --git a/app/javascript/mastodon/locales/sr-Latn.json b/app/javascript/mastodon/locales/sr-Latn.json index ac93aa0136e..a672ae6ca0d 100644 --- a/app/javascript/mastodon/locales/sr-Latn.json +++ b/app/javascript/mastodon/locales/sr-Latn.json @@ -3,6 +3,7 @@ "account.block_domain": "Sakrij sve sa domena {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Navedene informacije možda ne odslikavaju korisnički profil u potpunosti.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Izmeni profil", "account.follow": "Zaprati", "account.followers": "Pratioca", diff --git a/app/javascript/mastodon/locales/sr.json b/app/javascript/mastodon/locales/sr.json index ac1afa682b0..1e3a3ce2bac 100644 --- a/app/javascript/mastodon/locales/sr.json +++ b/app/javascript/mastodon/locales/sr.json @@ -3,6 +3,7 @@ "account.block_domain": "Сакриј све са домена {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Наведене информације можда не одсликавају кориснички профил у потпуности.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Измени профил", "account.follow": "Запрати", "account.followers": "Пратиоца", diff --git a/app/javascript/mastodon/locales/sv.json b/app/javascript/mastodon/locales/sv.json index 09d846a1aeb..9c51d5b365e 100644 --- a/app/javascript/mastodon/locales/sv.json +++ b/app/javascript/mastodon/locales/sv.json @@ -3,6 +3,7 @@ "account.block_domain": "Dölj allt från {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Informationen nedan kan spegla användarens profil ofullständigt.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Redigera profil", "account.follow": "Följ", "account.followers": "Följare", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index acd4d4ff97a..cab2ce08927 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "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", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 5b898d5af4d..83c10de3421 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -3,6 +3,7 @@ "account.block_domain": "Hide everything from {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Profili düzenle", "account.follow": "Takip et", "account.followers": "Takipçiler", diff --git a/app/javascript/mastodon/locales/uk.json b/app/javascript/mastodon/locales/uk.json index 6d2aa5599ea..b49f707e180 100644 --- a/app/javascript/mastodon/locales/uk.json +++ b/app/javascript/mastodon/locales/uk.json @@ -3,6 +3,7 @@ "account.block_domain": "Заглушити {domain}", "account.blocked": "Blocked", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "Налаштування профілю", "account.follow": "Підписатися", "account.followers": "Підписники", diff --git a/app/javascript/mastodon/locales/zh-CN.json b/app/javascript/mastodon/locales/zh-CN.json index d6875827a69..5ccfbc4f417 100644 --- a/app/javascript/mastodon/locales/zh-CN.json +++ b/app/javascript/mastodon/locales/zh-CN.json @@ -3,6 +3,7 @@ "account.block_domain": "隐藏来自 {domain} 的内容", "account.blocked": "Blocked", "account.disclaimer_full": "此处显示的信息可能不是全部内容。", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "修改个人资料", "account.follow": "关注", "account.followers": "关注者", diff --git a/app/javascript/mastodon/locales/zh-HK.json b/app/javascript/mastodon/locales/zh-HK.json index e05e611d071..b105fe426b9 100644 --- a/app/javascript/mastodon/locales/zh-HK.json +++ b/app/javascript/mastodon/locales/zh-HK.json @@ -3,6 +3,7 @@ "account.block_domain": "隱藏來自 {domain} 的一切文章", "account.blocked": "Blocked", "account.disclaimer_full": "下列資料不一定完整。", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "修改個人資料", "account.follow": "關注", "account.followers": "關注的人", diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index 19ceed99472..b0a94f67b21 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -3,6 +3,7 @@ "account.block_domain": "隱藏來自 {domain} 的一切貼文", "account.blocked": "Blocked", "account.disclaimer_full": "下列資料不一定完整。", + "account.domain_blocked": "Domain hidden", "account.edit_profile": "編輯用者資訊", "account.follow": "關注", "account.followers": "專注者", diff --git a/config/locales/ar.yml b/config/locales/ar.yml index bc71d9c87cb..41d83e4ad82 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -123,6 +123,7 @@ ar: emoji: إيموجي enable: تفعيل image_hint: ملف PNG إلى غاية حجم 50 ك.ب + shortcode_hint: على الأقل حرفين، و فقط رموز أبجدية عددية و أسطر سفلية title: الإيموجي الخاصة upload: رفع domain_blocks: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 65effe7004d..b97a9ead14a 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -38,7 +38,7 @@ fr: followers: Abonné⋅e⋅s following: Abonnements media: Médias - moved_html: "%{name} a déménagé vers %{new_profile_link} :" + moved_html: "%{name} a changé de compte pour %{new_profile_link} :" nothing_here: Rien à voir ici ! people_followed_by: Personnes suivies par %{name} people_who_follow: Personnes qui suivent %{name} @@ -369,6 +369,7 @@ fr: logout: Se déconnecter migrate_account: Déplacer vers un compte différent migrate_account_html: Si vous voulez rediriger ce compte vers un autre, vous pouvez le configurer ici. + or: ou or_log_in_with: Ou authentifiez-vous avec providers: cas: CAS @@ -462,7 +463,7 @@ fr: following: Liste d’utilisateur⋅ice⋅s suivi⋅e⋅s muting: Liste d’utilisateur⋅ice⋅s que vous masquez upload: Importer - in_memoriam_html: In Memoriam. + in_memoriam_html: En mémoire de. invites: delete: Désactiver expired: Expiré @@ -545,7 +546,7 @@ fr: trillion: T unit: '' pagination: - newer: Jamais + newer: Plus récent next: Suivant older: Plus ancien prev: Précédent @@ -649,7 +650,7 @@ fr: unlisted_long: Tout le monde peut voir vos statuts mais ils ne seront pas sur listés sur les fils publics stream_entries: click_to_show: Cliquer pour afficher - pinned: Statut épinglé + pinned: Pouet épinglé reblogged: partagé sensitive_content: Contenu sensible terms: diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 04836c121bb..a231e4fb6aa 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -369,6 +369,7 @@ pt-BR: logout: Sair migrate_account: Mudar para uma conta diferente migrate_account_html: Se você quer redirecionar essa conta para uma outra você pode configurar isso aqui. + or: ou or_log_in_with: Ou faça login com providers: cas: CAS diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index abed908fb24..2459f6da616 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -5,14 +5,8 @@ ar: defaults: avatar: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 120x120px digest: تُرسَل إليك بعد مُضيّ مدة مِن خمول نشاطك و فقط إذا ما تلقيت رسائل شخصية مباشِرة أثناء فترة غيابك مِن الشبكة - display_name: - one: 1 حرف متبقي - other: %{count} حروف متبقية header: ملف PNG أو GIF أو JPG. حجمه على أقصى تصدير 2MB. سيتم تصغيره إلى 700x335px locked: يتطلب منك الموافقة يدويا على طلبات المتابعة - note: - one: 1 حرف متبقي - other: %{count} حروف متبقية setting_noindex: ذلك يؤثر على حالة ملفك الشخصي و صفحاتك setting_theme: ذلك يؤثر على الشكل الذي سيبدو عليه ماستدون عندما تقوم بالدخول مِن أي جهاز. imports: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 551fab3224a..4fa745d5ad7 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -580,9 +580,11 @@ sk: alipay: Alipay generic: Neznámy prehliadač current_session: Aktuálna sezóna + description: "%{browser} na %{platform}" explanation: Tieto sú prehliadače ktoré sú teraz prihlásené na tvoj Mastodon účet. ip: IP adresa platforms: + mac: MacOSX other: neznáma platforma revoke: Zamietni revoke_success: Sezóna úspešne zamietnutá @@ -594,6 +596,32 @@ sk: development: Vývoj edit_profile: Upraviť profil export: Exportovať dáta + followers: Povolení sledovatelia + import: Importovať + migrate: Presunúť účet + notifications: Oznámenia + preferences: Možnosti + settings: Nastavenia + two_factor_authentication: Dvoj-faktorové overenie + your_apps: Tvoje aplikácie + statuses: + open_in_web: Otvor v okne prehliadača + over_character_limit: limit počtu %{max} znakov bol presiahnutý + pin_errors: + ownership: Nemožno pripnúť príspevok od niekoho iného + private: Neverejné príspevky nemôžu byť pripnuté + show_more: Ukáž viac + visibilities: + private: Iba pre sledovateľov + private_long: Ukáž iba následovateľom + public: Verejné + public_long: Všetci môžu vidieť + unlisted: Nezaradené + unlisted_long: Všetci môžu vidieť, ale nieje zaradené do verejnej osi + stream_entries: + click_to_show: Klikni pre zobrazenie + pinned: Pripnutý toot + reblogged: vyzdvihnutý user_mailer: welcome: final_step: 'Začnite písať! Aj bez následovníkov budú vaše verejné správy videné ostatnými, napríklad na lokálnej osi a pod haštagmi. Môžete sa ostatným predstaviť pod haštagom #introductions.' From 64db9ed5f6c8ff826104b3294956416d08d7a135 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 06:59:42 +0100 Subject: [PATCH 50/59] After blocking domain with reject_media, invalidate cache (#6679) Media attachments are part of the association cache of statuses, since they are presumed to be immutable. Unless this cache is cleared manually, the statuses will continue to look like they have media embedded. --- app/services/block_domain_service.rb | 37 +++++++++++++++++++--------- lib/tasks/mastodon.rake | 8 +++--- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/app/services/block_domain_service.rb b/app/services/block_domain_service.rb index eefdc0dbf9a..d082de40b9b 100644 --- a/app/services/block_domain_service.rb +++ b/app/services/block_domain_service.rb @@ -5,13 +5,14 @@ class BlockDomainService < BaseService def call(domain_block) @domain_block = domain_block - process_domain_block + process_domain_block! end private - def process_domain_block + def process_domain_block! clear_media! if domain_block.reject_media? + if domain_block.silence? silence_accounts! elsif domain_block.suspend? @@ -19,14 +20,26 @@ class BlockDomainService < BaseService end end + def invalidate_association_caches! + # Normally, associated models of a status are immutable (except for accounts) + # so they are aggressively cached. After updating the media attachments to no + # longer point to a local file, we need to clear the cache to make those + # changes appear in the API and UI + @affected_status_ids.each { |id| Rails.cache.delete_matched("statuses/#{id}-*") } + end + def silence_accounts! blocked_domain_accounts.in_batches.update_all(silenced: true) end def clear_media! - clear_account_images - clear_account_attachments - clear_emojos + @affected_status_ids = [] + + clear_account_images! + clear_account_attachments! + clear_emojos! + + invalidate_association_caches! end def suspend_accounts! @@ -36,23 +49,25 @@ class BlockDomainService < BaseService end end - def clear_account_images + def clear_account_images! blocked_domain_accounts.find_each do |account| - account.avatar.destroy - account.header.destroy + account.avatar.destroy if account.avatar.exists? + account.header.destroy if account.header.exists? account.save end end - def clear_account_attachments + def clear_account_attachments! media_from_blocked_domain.find_each do |attachment| - attachment.file.destroy + @affected_status_ids << attachment.status_id if attachment.status_id.present? + + attachment.file.destroy if attachment.file.exists? attachment.type = :unknown attachment.save end end - def clear_emojos + def clear_emojos! emojis_from_blocked_domains.destroy_all end diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 9202b4839ce..0b011bf57fd 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -476,10 +476,10 @@ namespace :mastodon do time_ago = ENV.fetch('NUM_DAYS') { 7 }.to_i.days.ago MediaAttachment.where.not(remote_url: '').where.not(file_file_name: nil).where('created_at < ?', time_ago).find_each do |media| - if media.file.exists? - media.file.destroy - media.save - end + next unless media.file.exists? + + media.file.destroy + media.save end end From ed902581d3d468c2e99a9ed262535b711d39e240 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 8 Mar 2018 15:09:10 +0900 Subject: [PATCH 51/59] Update Yarn to version 1.5.1 (#6689) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 443cb289a4c..7a195b31e6a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,8 @@ ARG GID=991 ENV RAILS_SERVE_STATIC_FILES=true \ RAILS_ENV=production NODE_ENV=production -ARG YARN_VERSION=1.3.2 -ARG YARN_DOWNLOAD_SHA256=6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d +ARG YARN_VERSION=1.5.1 +ARG YARN_DOWNLOAD_SHA256=cd31657232cf48d57fdbff55f38bfa058d2fb4950450bd34af72dac796af4de1 ARG LIBICONV_VERSION=1.15 ARG LIBICONV_DOWNLOAD_SHA256=ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178 From 510c9049c79f4eb1e082932ff067fdb4216d1039 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 08:20:49 +0100 Subject: [PATCH 52/59] For now, put a "." into no-text statuses with media for backcompat (#6691) --- app/services/post_status_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index df38d16a6c0..c9119218174 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -22,6 +22,7 @@ class PostStatusService < BaseService media = validate_media!(options[:media_ids]) status = nil text = options.delete(:spoiler_text) if text.blank? && options[:spoiler_text].present? + text = '.' if text.blank? && !media.empty? ApplicationRecord.transaction do status = account.statuses.create!(text: text, From 77406d3a092db48250a85984dde2f2cc81386146 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 08:22:04 +0100 Subject: [PATCH 53/59] Display AttachmentList in notifications (#6693) --- .../mastodon/components/attachment_list.js | 28 ++++++++++++------- app/javascript/mastodon/components/status.js | 4 +-- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.js index d8f90b5b6d8..8e5bb0e0be8 100644 --- a/app/javascript/mastodon/components/attachment_list.js +++ b/app/javascript/mastodon/components/attachment_list.js @@ -19,11 +19,15 @@ export default class AttachmentList extends ImmutablePureComponent { return (
    ); @@ -36,11 +40,15 @@ export default class AttachmentList extends ImmutablePureComponent {
    ); diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index c6f11c37901..8102d1e06a4 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -178,8 +178,8 @@ export default class Status extends ImmutablePureComponent { status = status.get('reblog'); } - if (status.get('media_attachments').size > 0 && !this.props.muted) { - if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { + if (status.get('media_attachments').size > 0) { + if (this.props.muted || status.get('media_attachments').some(item => item.get('type') === 'unknown')) { media = ( Date: Thu, 8 Mar 2018 08:57:21 +0100 Subject: [PATCH 54/59] When enabled, always display media in gallery. Also: click to reveal (#6692) Fix #6677 --- .../mastodon/components/permalink.js | 10 ++++-- .../account_gallery/components/media_item.js | 32 ++++++++++++++++--- .../styles/mastodon/components.scss | 11 ++++++- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/app/javascript/mastodon/components/permalink.js b/app/javascript/mastodon/components/permalink.js index d726d37a20a..b369e98126d 100644 --- a/app/javascript/mastodon/components/permalink.js +++ b/app/javascript/mastodon/components/permalink.js @@ -12,9 +12,15 @@ export default class Permalink extends React.PureComponent { href: PropTypes.string.isRequired, to: PropTypes.string.isRequired, children: PropTypes.node, + onInterceptClick: PropTypes.func, }; - handleClick = (e) => { + handleClick = e => { + if (this.props.onInterceptClick && this.props.onInterceptClick()) { + e.preventDefault(); + return; + } + if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) { e.preventDefault(); this.context.router.history.push(this.props.to); @@ -22,7 +28,7 @@ export default class Permalink extends React.PureComponent { } render () { - const { href, children, className, ...other } = this.props; + const { href, children, className, onInterceptClick, ...other } = this.props; return ( diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index 59c805c38d3..f7a802dc794 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -2,6 +2,7 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import Permalink from '../../../components/permalink'; +import { displaySensitiveMedia } from '../../../initial_state'; export default class MediaItem extends ImmutablePureComponent { @@ -9,8 +10,22 @@ export default class MediaItem extends ImmutablePureComponent { media: ImmutablePropTypes.map.isRequired, }; + state = { + visible: !this.props.media.getIn(['status', 'sensitive']) || displaySensitiveMedia, + }; + + handleClick = () => { + if (!this.state.visible) { + this.setState({ visible: true }); + return true; + } + + return false; + } + render () { const { media } = this.props; + const { visible } = this.state; const status = media.get('status'); const focusX = media.getIn(['meta', 'focus', 'x']); const focusY = media.getIn(['meta', 'focus', 'y']); @@ -18,21 +33,28 @@ export default class MediaItem extends ImmutablePureComponent { const y = ((focusY / -2) + .5) * 100; const style = {}; - let content; + let label, icon; if (media.get('type') === 'gifv') { - content = GIF; + label = GIF; } - if (!status.get('sensitive')) { + if (visible) { style.backgroundImage = `url(${media.get('preview_url')})`; style.backgroundPosition = `${x}% ${y}%`; + } else { + icon = ( + + + + ); } return (
    - - {content} + + {icon} + {label}
    ); diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index c35cc9d75eb..5c2e5713de0 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4680,7 +4680,7 @@ a.status-card { background-size: cover; background-position: center; position: absolute; - color: inherit; + color: $ui-primary-color; text-decoration: none; border-radius: 4px; @@ -4688,6 +4688,7 @@ a.status-card { &:active, &:focus { outline: 0; + color: $ui-secondary-color; &::before { content: ""; @@ -4699,6 +4700,14 @@ a.status-card { } } } + + &__icons { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + font-size: 24px; + } } .account__section-headline { From 5acd5315f23b4472f31c4a0bb612b7356032defc Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 11:10:37 +0100 Subject: [PATCH 55/59] Improve styling of closed registrations message, rename button (#6695) * Improve styling of closed registrations message, rename button "Sign up on another server" Fix #6683 * Adjust styling of closed registrations message --- app/javascript/styles/mastodon/about.scss | 22 ++++++++++++++++++++++ app/views/about/_forms.html.haml | 11 ++++++----- config/locales/en.yml | 1 + 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/javascript/styles/mastodon/about.scss b/app/javascript/styles/mastodon/about.scss index f2991813549..c484f074b6c 100644 --- a/app/javascript/styles/mastodon/about.scss +++ b/app/javascript/styles/mastodon/about.scss @@ -194,6 +194,28 @@ $small-breakpoint: 960px; } } + .closed-registrations-message { + margin-top: 20px; + + &, + p { + text-align: center; + font-size: 12px; + line-height: 18px; + color: $ui-primary-color; + margin-bottom: 0; + + a { + color: $ui-highlight-color; + text-decoration: underline; + } + } + + p:last-child { + margin-bottom: 0; + } + } + em { display: inline; margin: 0; diff --git a/app/views/about/_forms.html.haml b/app/views/about/_forms.html.haml index 9916b6bf4cd..81f7173f7b1 100644 --- a/app/views/about/_forms.html.haml +++ b/app/views/about/_forms.html.haml @@ -1,12 +1,13 @@ - if @instance_presenter.open_registrations = render 'registration' - else - - if @instance_presenter.closed_registrations_message.blank? - %p= t('about.closed_registrations') - - else - = @instance_presenter.closed_registrations_message.html_safe + = link_to t('auth.register_elsewhere'), 'https://joinmastodon.org', class: 'button button-primary' - = link_to t('auth.register'), 'https://joinmastodon.org', class: 'button button-primary' + .closed-registrations-message + - if @instance_presenter.closed_registrations_message.blank? + %p= t('about.closed_registrations') + - else + = @instance_presenter.closed_registrations_message.html_safe .separator-or %span= t('auth.or') diff --git a/config/locales/en.yml b/config/locales/en.yml index 176135657d8..2dd09626d14 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -376,6 +376,7 @@ en: cas: CAS saml: SAML register: Sign up + register_elsewhere: Sign up on another server resend_confirmation: Resend confirmation instructions reset_password: Reset password security: Security From a29d409e20e74c9a4f168c5c45fec9092e03ac61 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 11:18:26 +0100 Subject: [PATCH 56/59] If login redirects to omniauth, redirect logout to root_path (#6694) Fix #6670 --- app/controllers/auth/sessions_controller.rb | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index 02447dde069..c1ebe760c5d 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -12,10 +12,9 @@ class Auth::SessionsController < Devise::SessionsController def new Devise.omniauth_configs.each do |provider, config| - if config.strategy.redirect_at_sign_in - return redirect_to(omniauth_authorize_path(resource_name, provider)) - end + return redirect_to(omniauth_authorize_path(resource_name, provider)) if config.strategy.redirect_at_sign_in end + super end @@ -59,6 +58,14 @@ class Auth::SessionsController < Devise::SessionsController end end + def after_sign_out_path_for(_resource_or_scope) + Devise.omniauth_configs.each_value do |config| + return root_path if config.strategy.redirect_at_sign_in + end + + super + end + def two_factor_enabled? find_user.try(:otp_required_for_login?) end From bd077ad7d9633a4ef1415aa123c7ecf54e829ae8 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 8 Mar 2018 11:19:02 +0100 Subject: [PATCH 57/59] Bump version to 2.3.0rc3 --- lib/mastodon/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 418ce4828e6..9155702ac5f 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -21,7 +21,7 @@ module Mastodon end def flags - 'rc2' + 'rc3' end def to_a From 188aa3ea50799f4a81f28416fe47b3330091ef6f Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 8 Mar 2018 21:07:25 +0900 Subject: [PATCH 58/59] Add polyfill for Object.values (#6697) --- app/javascript/mastodon/base_polyfills.js | 5 +++++ app/javascript/mastodon/load_polyfills.js | 1 + package.json | 1 + 3 files changed, 7 insertions(+) diff --git a/app/javascript/mastodon/base_polyfills.js b/app/javascript/mastodon/base_polyfills.js index 7856b26f9d8..8fbb1778581 100644 --- a/app/javascript/mastodon/base_polyfills.js +++ b/app/javascript/mastodon/base_polyfills.js @@ -3,6 +3,7 @@ import 'intl/locale-data/jsonp/en'; import 'es6-symbol/implement'; import includes from 'array-includes'; import assign from 'object-assign'; +import values from 'object.values'; import isNaN from 'is-nan'; if (!Array.prototype.includes) { @@ -13,6 +14,10 @@ if (!Object.assign) { Object.assign = assign; } +if (!Object.values) { + values.shim(); +} + if (!Number.isNaN) { Number.isNaN = isNaN; } diff --git a/app/javascript/mastodon/load_polyfills.js b/app/javascript/mastodon/load_polyfills.js index 8927b735855..815e1905b8f 100644 --- a/app/javascript/mastodon/load_polyfills.js +++ b/app/javascript/mastodon/load_polyfills.js @@ -14,6 +14,7 @@ function loadPolyfills() { const needsBasePolyfills = !( window.Intl && Object.assign && + Object.values && Number.isNaN && window.Symbol && Array.prototype.includes diff --git a/package.json b/package.json index fc8e2425ec8..33853516b11 100644 --- a/package.json +++ b/package.json @@ -71,6 +71,7 @@ "npmlog": "^4.1.2", "object-assign": "^4.1.1", "object-fit-images": "^3.2.3", + "object.values": "^1.0.4", "offline-plugin": "^4.8.3", "path-complete-extname": "^0.1.0", "pg": "^6.4.0", From ff44b2e92d496c6027b20157fea6ebd885906bea Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 9 Mar 2018 00:35:07 +0100 Subject: [PATCH 59/59] Add missing meta description to profiles, some other SEO stuff (#6706) - Add missing meta description to profiles - Add canonical rel link to landing page - Remove linebreaks from title tags - Add username to profile title - Add toots/following/followers to profile description tags - Add next/prev rel links to profiles - Do not index follower/following variants of profiles --- app/helpers/stream_entries_helper.rb | 21 ++++++++++++++++++++ app/views/about/show.html.haml | 1 + app/views/accounts/_og.html.haml | 2 +- app/views/accounts/show.html.haml | 13 +++++++++--- app/views/follower_accounts/index.html.haml | 4 +--- app/views/following_accounts/index.html.haml | 4 +--- app/views/layouts/application.html.haml | 8 ++------ 7 files changed, 37 insertions(+), 16 deletions(-) diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index 44511498577..54b92bdf471 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -8,6 +8,27 @@ module StreamEntriesHelper account.display_name.presence || account.username end + def account_description(account) + prepend_str = [ + [ + number_to_human(account.statuses_count, strip_insignificant_zeros: true), + t('accounts.posts'), + ].join(' '), + + [ + number_to_human(account.following_count, strip_insignificant_zeros: true), + t('accounts.following'), + ].join(' '), + + [ + number_to_human(account.followers_count, strip_insignificant_zeros: true), + t('accounts.followers'), + ].join(' '), + ].join(', ') + + [prepend_str, account.note].join(' · ') + end + def stream_link_target embedded_view? ? '_blank' : nil end diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml index d067d487416..dbb914f1187 100644 --- a/app/views/about/show.html.haml +++ b/app/views/about/show.html.haml @@ -2,6 +2,7 @@ = site_hostname - content_for :header_tags do + %link{ rel: 'canonical', href: about_url }/ %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json) = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous' = render partial: 'shared/og' diff --git a/app/views/accounts/_og.html.haml b/app/views/accounts/_og.html.haml index 1d16be590ab..26424a49c9a 100644 --- a/app/views/accounts/_og.html.haml +++ b/app/views/accounts/_og.html.haml @@ -1,7 +1,7 @@ = opengraph 'og:url', url = opengraph 'og:site_name', site_title = opengraph 'og:title', [yield(:page_title).strip.presence, site_title].compact.join(' - ') -= opengraph 'og:description', account.note += opengraph 'og:description', account_description(account) = opengraph 'og:image', full_asset_url(account.avatar.url(:original)) = opengraph 'og:image:width', '120' = opengraph 'og:image:height', '120' diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml index 21c585daba6..c62a573b0ba 100644 --- a/app/views/accounts/show.html.haml +++ b/app/views/accounts/show.html.haml @@ -1,7 +1,9 @@ - content_for :page_title do - = display_name(@account) + = "#{display_name(@account)} (@#{@account.username})" - content_for :header_tags do + %meta{ name: 'description', content: account_description(@account) }/ + - if @account.user&.setting_noindex %meta{ name: 'robots', content: 'noindex' }/ @@ -9,6 +11,11 @@ %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) }/ + - if @older_url + %link{ rel: 'next', href: @older_url }/ + - if @newer_url + %link{ rel: 'prev', href: @newer_url }/ + = opengraph 'og:type', 'profile' = render 'og', account: @account, url: short_account_url(@account, only_path: false) @@ -42,6 +49,6 @@ - if @newer_url || @older_url .pagination - if @older_url - = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'older' + = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'next' - if @newer_url - = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'newer' + = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'prev' diff --git a/app/views/follower_accounts/index.html.haml b/app/views/follower_accounts/index.html.haml index 738b3163817..a24e4ea20fb 100644 --- a/app/views/follower_accounts/index.html.haml +++ b/app/views/follower_accounts/index.html.haml @@ -2,9 +2,7 @@ = t('accounts.people_who_follow', name: display_name(@account)) - content_for :header_tags do - - if @account.user&.setting_noindex - %meta{ name: 'robots', content: 'noindex' }/ - + %meta{ name: 'robots', content: 'noindex' }/ = render 'accounts/og', account: @account, url: account_followers_url(@account, only_path: false) = render 'accounts/header', account: @account diff --git a/app/views/following_accounts/index.html.haml b/app/views/following_accounts/index.html.haml index 9637c689f99..67f6cfede4d 100644 --- a/app/views/following_accounts/index.html.haml +++ b/app/views/following_accounts/index.html.haml @@ -2,9 +2,7 @@ = t('accounts.people_followed_by', name: display_name(@account)) - content_for :header_tags do - - if @account.user&.setting_noindex - %meta{ name: 'robots', content: 'noindex' }/ - + %meta{ name: 'robots', content: 'noindex' }/ = render 'accounts/og', account: @account, url: account_followers_url(@account, only_path: false) = render 'accounts/header', account: @account diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index f38c59165ce..b26d2c5091e 100755 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -2,7 +2,7 @@ %html{ lang: I18n.locale } %head %meta{ charset: 'utf-8' }/ - %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }/ + %meta{ name: 'viewport', content: 'width=device-width, initial-scale=1' }/ %link{ rel: 'icon', href: favicon_path, type: 'image/x-icon' }/ %link{ rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }/ %link{ rel: 'mask-icon', href: '/mask-icon.svg', color: '#2B90D9' }/ @@ -11,11 +11,7 @@ %meta{ name: 'theme-color', content: '#282c37' }/ %meta{ name: 'apple-mobile-web-app-capable', content: 'yes' }/ - %title< - - if content_for?(:page_title) - = yield(:page_title) - = ' - ' - = title + %title= content_for?(:page_title) ? safe_join([yield(:page_title).chomp, ' - ', title]) : title = stylesheet_pack_tag 'common', media: 'all' = stylesheet_pack_tag current_theme, media: 'all'