diff options
Diffstat (limited to 'app')
20 files changed, 106 insertions, 22 deletions
diff --git a/app/javascript/flavours/glitch/features/follow_recommendations/index.js b/app/javascript/flavours/glitch/features/follow_recommendations/index.js index 8165c39a9..fee4d8757 100644 --- a/app/javascript/flavours/glitch/features/follow_recommendations/index.js +++ b/app/javascript/flavours/glitch/features/follow_recommendations/index.js @@ -76,7 +76,7 @@ class FollowRecommendations extends ImmutablePureComponent { return ( <Column> - <div className='scrollable'> + <div className='scrollable follow-recommendations-container'> <div className='column-title'> <Logo /> <h3><FormattedMessage id='follow_recommendations.heading' defaultMessage="Follow people you'd like to see posts from! Here are some suggestions." /></h3> diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js index 915e26718..893e76585 100644 --- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js @@ -309,7 +309,7 @@ class FocalPointModal extends ImmutablePureComponent { return ( <div className='modal-root__modal report-modal' style={{ maxWidth: 960 }}> <div className='report-modal__target'> - <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} /> + <IconButton className='report-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={20} /> <FormattedMessage id='upload_modal.edit_media' defaultMessage='Edit media' /> </div> diff --git a/app/javascript/flavours/glitch/features/ui/components/report_modal.js b/app/javascript/flavours/glitch/features/ui/components/report_modal.js index 9016b08d7..5cb7c5d07 100644 --- a/app/javascript/flavours/glitch/features/ui/components/report_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/report_modal.js @@ -91,7 +91,7 @@ class ReportModal extends ImmutablePureComponent { return ( <div className='modal-root__modal report-modal'> <div className='report-modal__target'> - <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} /> + <IconButton className='report-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={20} /> <FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get('acct')}</strong> }} /> </div> diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss index 7f3d27dba..ad17ed4b0 100644 --- a/app/javascript/flavours/glitch/styles/components/columns.scss +++ b/app/javascript/flavours/glitch/styles/components/columns.scss @@ -823,13 +823,20 @@ } } +.follow-recommendations-container { + display: flex; + flex-direction: column; +} + .column-actions { display: flex; - align-items: center; + align-items: start; justify-content: center; padding: 40px; padding-top: 40px; padding-bottom: 200px; + flex-grow: 1; + position: relative; &__background { position: absolute; diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 671323bc5..cb776e88f 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -847,9 +847,10 @@ .report-modal__target { padding: 15px; - .media-modal__close { - top: 14px; - right: 15px; + .report-modal__close { + position: absolute; + top: 10px; + right: 10px; } } diff --git a/app/javascript/mastodon/actions/boosts.js b/app/javascript/mastodon/actions/boosts.js index 6e14065d6..c0f0f3acc 100644 --- a/app/javascript/mastodon/actions/boosts.js +++ b/app/javascript/mastodon/actions/boosts.js @@ -11,7 +11,7 @@ export function initBoostModal(props) { dispatch({ type: BOOSTS_INIT_MODAL, - privacy + privacy, }); dispatch(openModal('BOOST', props)); diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index abd5681d4..5002292b9 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -60,6 +60,7 @@ export function normalizeStatus(status, normalOldStatus) { normalStatus.search_index = normalOldStatus.get('search_index'); normalStatus.contentHtml = normalOldStatus.get('contentHtml'); normalStatus.spoilerHtml = normalOldStatus.get('spoilerHtml'); + normalStatus.spoiler_text = normalOldStatus.get('spoiler_text'); normalStatus.hidden = normalOldStatus.get('hidden'); } else { // If the status has a CW but no contents, treat the CW as if it were the diff --git a/app/javascript/mastodon/features/follow_recommendations/index.js b/app/javascript/mastodon/features/follow_recommendations/index.js index a35ff3e82..26c8b2471 100644 --- a/app/javascript/mastodon/features/follow_recommendations/index.js +++ b/app/javascript/mastodon/features/follow_recommendations/index.js @@ -76,7 +76,7 @@ class FollowRecommendations extends ImmutablePureComponent { return ( <Column> - <div className='scrollable'> + <div className='scrollable follow-recommendations-container'> <div className='column-title'> <Logo /> <h3><FormattedMessage id='follow_recommendations.heading' defaultMessage="Follow people you'd like to see posts from! Here are some suggestions." /></h3> diff --git a/app/javascript/mastodon/features/notifications/containers/notification_container.js b/app/javascript/mastodon/features/notifications/containers/notification_container.js index 555d5e1b5..5c984197f 100644 --- a/app/javascript/mastodon/features/notifications/containers/notification_container.js +++ b/app/javascript/mastodon/features/notifications/containers/notification_container.js @@ -2,7 +2,6 @@ import { connect } from 'react-redux'; import { makeGetNotification, makeGetStatus } from '../../../selectors'; import Notification from '../components/notification'; import { initBoostModal } from '../../../actions/boosts'; -import { openModal } from '../../../actions/modal'; import { mentionCompose } from '../../../actions/compose'; import { reblog, 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 ffa783e3b..3457b7633 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js @@ -309,7 +309,7 @@ class FocalPointModal extends ImmutablePureComponent { return ( <div className='modal-root__modal report-modal' style={{ maxWidth: 960 }}> <div className='report-modal__target'> - <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} /> + <IconButton className='report-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={20} /> <FormattedMessage id='upload_modal.edit_media' defaultMessage='Edit media' /> </div> diff --git a/app/javascript/mastodon/features/ui/components/report_modal.js b/app/javascript/mastodon/features/ui/components/report_modal.js index 2e41f784d..f4f0a3884 100644 --- a/app/javascript/mastodon/features/ui/components/report_modal.js +++ b/app/javascript/mastodon/features/ui/components/report_modal.js @@ -91,7 +91,7 @@ class ReportModal extends ImmutablePureComponent { return ( <div className='modal-root__modal report-modal'> <div className='report-modal__target'> - <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} /> + <IconButton className='report-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={20} /> <FormattedMessage id='report.target' defaultMessage='Report {target}' values={{ target: <strong>{account.get('acct')}</strong> }} /> </div> diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 9d936e684..c1dd63bc3 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -2508,13 +2508,20 @@ a.account__display-name { } } +.follow-recommendations-container { + display: flex; + flex-direction: column; +} + .column-actions { display: flex; - align-items: center; + align-items: start; justify-content: center; padding: 40px; padding-top: 40px; padding-bottom: 200px; + flex-grow: 1; + position: relative; &__background { position: absolute; @@ -5297,9 +5304,10 @@ a.status-card.compact:hover { .report-modal__target { padding: 15px; - .media-modal__close { - top: 14px; - right: 15px; + .report-modal__close { + position: absolute; + top: 10px; + right: 10px; } } diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 763c417f9..cc2d391fb 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -46,7 +46,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity return reject_payload! if unsupported_object_type? || invalid_origin?(object_uri) || tombstone_exists? || !related_to_local_activity? lock_or_fail("create:#{object_uri}") do - return if delete_arrived_first?(object_uri) || poll_vote? # rubocop:disable Lint/NonLocalExitFromIterator + return if delete_arrived_first?(object_uri) || poll_vote? @status = find_existing_status diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb index 2d5ebfca3..1af53ed23 100644 --- a/app/models/concerns/account_avatar.rb +++ b/app/models/concerns/account_avatar.rb @@ -21,7 +21,7 @@ module AccountAvatar has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail] validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES validates_attachment_size :avatar, less_than: LIMIT - remotable_attachment :avatar, LIMIT + remotable_attachment :avatar, LIMIT, suppress_errors: false end def avatar_original_url diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb index 067e166eb..72a3d0566 100644 --- a/app/models/concerns/account_header.rb +++ b/app/models/concerns/account_header.rb @@ -22,7 +22,7 @@ module AccountHeader has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail] validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES validates_attachment_size :header, less_than: LIMIT - remotable_attachment :header, LIMIT + remotable_attachment :header, LIMIT, suppress_errors: false end def header_original_url diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 56b9c0164..ffe8a7565 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -28,9 +28,11 @@ module Remotable end rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present? raise e unless suppress_errors rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError, Mastodon::StreamValidationError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" + public_send("#{attachment_name}=", nil) if public_send("#{attachment_name}_file_name").present? end nil diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index d92aae7b3..a7d948976 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -177,7 +177,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer end def href - explore_hashtag_url(object) + tag_url(object) end def name diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index bb2e8f665..7e268f4d4 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -106,8 +106,16 @@ class ActivityPub::ProcessAccountService < BaseService end def set_fetchable_attributes! - @account.avatar_remote_url = image_url('icon') || '' unless skip_download? - @account.header_remote_url = image_url('image') || '' unless skip_download? + begin + @account.avatar_remote_url = image_url('icon') || '' unless skip_download? + rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + RedownloadAvatarWorker.perform_in(rand(30..600).seconds, @account.id) + end + begin + @account.header_remote_url = image_url('image') || '' unless skip_download? + rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError + RedownloadHeaderWorker.perform_in(rand(30..600).seconds, @account.id) + end @account.statuses_count = outbox_total_items if outbox_total_items.present? @account.following_count = following_total_items if following_total_items.present? @account.followers_count = followers_total_items if followers_total_items.present? diff --git a/app/workers/redownload_avatar_worker.rb b/app/workers/redownload_avatar_worker.rb new file mode 100644 index 000000000..df17b7718 --- /dev/null +++ b/app/workers/redownload_avatar_worker.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class RedownloadAvatarWorker + include Sidekiq::Worker + include ExponentialBackoff + include JsonLdHelper + + sidekiq_options queue: 'pull', retry: 7 + + def perform(id) + account = Account.find(id) + + return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media? + return if account.avatar_remote_url.blank? || account.avatar_file_name.present? + + account.reset_avatar! + account.save! + rescue ActiveRecord::RecordNotFound + # Do nothing + rescue Mastodon::UnexpectedResponseError => e + response = e.response + + if response_error_unsalvageable?(response) + # Give up + else + raise e + end + end +end diff --git a/app/workers/redownload_header_worker.rb b/app/workers/redownload_header_worker.rb new file mode 100644 index 000000000..3b142ec5f --- /dev/null +++ b/app/workers/redownload_header_worker.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class RedownloadHeaderWorker + include Sidekiq::Worker + include ExponentialBackoff + include JsonLdHelper + + sidekiq_options queue: 'pull', retry: 7 + + def perform(id) + account = Account.find(id) + + return if account.suspended? || DomainBlock.rule_for(account.domain)&.reject_media? + return if account.header_remote_url.blank? || account.header_file_name.present? + + account.reset_header! + account.save! + rescue ActiveRecord::RecordNotFound + # Do nothing + rescue Mastodon::UnexpectedResponseError => e + response = e.response + + if response_error_unsalvageable?(response) + # Give up + else + raise e + end + end +end |