diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/javascript/core/settings.js | 10 | ||||
-rw-r--r-- | app/javascript/mastodon/locales/defaultMessages.json | 70 | ||||
-rw-r--r-- | app/javascript/mastodon/locales/en.json | 6 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/accounts.scss | 4 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/components.scss | 2 | ||||
-rw-r--r-- | app/lib/activitypub/activity.rb | 2 | ||||
-rw-r--r-- | app/lib/activitypub/activity/move.rb | 2 | ||||
-rw-r--r-- | app/lib/feed_manager.rb | 2 | ||||
-rw-r--r-- | app/lib/response_with_limit.rb | 10 | ||||
-rw-r--r-- | app/models/account_conversation.rb | 2 | ||||
-rw-r--r-- | app/models/concerns/attachmentable.rb | 17 | ||||
-rw-r--r-- | app/models/concerns/remotable.rb | 40 | ||||
-rw-r--r-- | app/models/encrypted_message.rb | 5 | ||||
-rw-r--r-- | app/models/home_feed.rb | 2 | ||||
-rw-r--r-- | app/views/application/_card.html.haml | 2 | ||||
-rw-r--r-- | app/workers/activitypub/move_distribution_worker.rb | 2 | ||||
-rw-r--r-- | app/workers/move_worker.rb | 27 | ||||
-rw-r--r-- | app/workers/publish_announcement_reaction_worker.rb | 2 | ||||
-rw-r--r-- | app/workers/publish_scheduled_announcement_worker.rb | 2 | ||||
-rw-r--r-- | app/workers/unpublish_announcement_worker.rb | 2 |
20 files changed, 147 insertions, 64 deletions
diff --git a/app/javascript/core/settings.js b/app/javascript/core/settings.js index 9fe03f90c..9403e339b 100644 --- a/app/javascript/core/settings.js +++ b/app/javascript/core/settings.js @@ -34,10 +34,12 @@ delegate(document, '#account_header', 'change', ({ target }) => { delegate(document, '#account_locked', 'change', ({ target }) => { const lock = document.querySelector('.card .display-name i'); - if (target.checked) { - lock.style.display = 'inline'; - } else { - lock.style.display = 'none'; + if (lock) { + if (target.checked) { + delete lock.dataset.hidden; + } else { + lock.dataset.hidden = 'true'; + } } }); diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index c7ca77376..867595986 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -493,6 +493,22 @@ { "descriptors": [ { + "defaultMessage": "Public", + "id": "privacy.public.short" + }, + { + "defaultMessage": "Unlisted", + "id": "privacy.unlisted.short" + }, + { + "defaultMessage": "Followers-only", + "id": "privacy.private.short" + }, + { + "defaultMessage": "Direct", + "id": "privacy.direct.short" + }, + { "defaultMessage": "Filtered", "id": "status.filtered" }, @@ -650,6 +666,31 @@ { "descriptors": [ { + "defaultMessage": "No comment provided", + "id": "account_note.placeholder" + }, + { + "defaultMessage": "Cancel", + "id": "account_note.cancel" + }, + { + "defaultMessage": "Save", + "id": "account_note.save" + }, + { + "defaultMessage": "Your note for @{name}", + "id": "account.account_note_header" + }, + { + "defaultMessage": "Edit", + "id": "account_note.edit" + } + ], + "path": "app/javascript/mastodon/features/account/components/account_note.json" + }, + { + "descriptors": [ + { "defaultMessage": "Unfollow", "id": "account.unfollow" }, @@ -778,6 +819,10 @@ "id": "status.admin_account" }, { + "defaultMessage": "Add note for @{name}", + "id": "account.add_account_note" + }, + { "defaultMessage": "Follows you", "id": "account.follows_you" }, @@ -2468,6 +2513,27 @@ { "descriptors": [ { + "defaultMessage": "Public", + "id": "privacy.public.short" + }, + { + "defaultMessage": "Unlisted", + "id": "privacy.unlisted.short" + }, + { + "defaultMessage": "Followers-only", + "id": "privacy.private.short" + }, + { + "defaultMessage": "Direct", + "id": "privacy.direct.short" + } + ], + "path": "app/javascript/mastodon/features/status/components/detailed_status.json" + }, + { + "descriptors": [ + { "defaultMessage": "Delete", "id": "confirmations.delete.confirm" }, @@ -3006,10 +3072,6 @@ "id": "video.exit_fullscreen" }, { - "defaultMessage": "Download file", - "id": "video.download" - }, - { "defaultMessage": "Sensitive content", "id": "status.sensitive_warning" }, diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index b12409a8c..95df50be1 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -1,4 +1,6 @@ { + "account.account_note_header": "Your note for @{name}", + "account.add_account_note": "Add note for @{name}", "account.add_or_remove_from_list": "Add or Remove from lists", "account.badges.bot": "Bot", "account.badges.group": "Group", @@ -40,6 +42,10 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "account_note.cancel": "Cancel", + "account_note.edit": "Edit", + "account_note.placeholder": "No comment provided", + "account_note.save": "Save", "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", diff --git a/app/javascript/styles/mastodon/accounts.scss b/app/javascript/styles/mastodon/accounts.scss index 5dc067f0e..2c78e81be 100644 --- a/app/javascript/styles/mastodon/accounts.scss +++ b/app/javascript/styles/mastodon/accounts.scss @@ -76,6 +76,10 @@ margin-left: 15px; text-align: left; + i[data-hidden] { + display: none; + } + strong { font-size: 15px; color: $primary-text-color; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 0c594ef56..d483af220 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -992,7 +992,7 @@ position: relative; min-height: 54px; border-bottom: 1px solid lighten($ui-base-color, 8%); - cursor: default; + cursor: auto; @supports (-ms-overflow-style: -ms-autohiding-scrollbar) { // Add margin to avoid Edge auto-hiding scrollbar appearing over content. diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index ee35e1e8d..58cec7ac4 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -132,7 +132,7 @@ class ActivityPub::Activity end def delete_arrived_first?(uri) - redis.exists("delete_upon_arrival:#{@account.id}:#{uri}") + redis.exists?("delete_upon_arrival:#{@account.id}:#{uri}") end def delete_later!(uri) diff --git a/app/lib/activitypub/activity/move.rb b/app/lib/activitypub/activity/move.rb index 12bb82d25..2103f503f 100644 --- a/app/lib/activitypub/activity/move.rb +++ b/app/lib/activitypub/activity/move.rb @@ -33,7 +33,7 @@ class ActivityPub::Activity::Move < ActivityPub::Activity end def processed? - redis.exists("move_in_progress:#{@account.id}") + redis.exists?("move_in_progress:#{@account.id}") end def mark_as_processing! diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index af0fa2b98..6afdd3b08 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -205,7 +205,7 @@ class FeedManager private def push_update_required?(timeline_id) - redis.exists("subscribed:#{timeline_id}") + redis.exists?("subscribed:#{timeline_id}") end def blocks_or_mutes?(receiver_id, account_ids, context) diff --git a/app/lib/response_with_limit.rb b/app/lib/response_with_limit.rb new file mode 100644 index 000000000..2cc17bc5f --- /dev/null +++ b/app/lib/response_with_limit.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class ResponseWithLimit + def initialize(response, limit) + @response = response + @limit = limit + end + + attr_reader :response, :limit +end diff --git a/app/models/account_conversation.rb b/app/models/account_conversation.rb index 0c03747e2..b43816588 100644 --- a/app/models/account_conversation.rb +++ b/app/models/account_conversation.rb @@ -108,7 +108,7 @@ class AccountConversation < ApplicationRecord end def subscribed_to_timeline? - Redis.current.exists("subscribed:#{streaming_channel}") + Redis.current.exists?("subscribed:#{streaming_channel}") end def streaming_channel diff --git a/app/models/concerns/attachmentable.rb b/app/models/concerns/attachmentable.rb index 18b872c1e..c5febb828 100644 --- a/app/models/concerns/attachmentable.rb +++ b/app/models/concerns/attachmentable.rb @@ -8,6 +8,17 @@ module Attachmentable MAX_MATRIX_LIMIT = 16_777_216 # 4096x4096px or approx. 16MB GIF_MATRIX_LIMIT = 921_600 # 1280x720px + # For some file extensions, there exist different content + # type variants, and browsers often send the wrong one, + # for example, sending an audio .ogg file as video/ogg, + # likewise, MimeMagic also misreports them as such. For + # those files, it is necessary to use the output of the + # `file` utility instead + INCORRECT_CONTENT_TYPES = %w( + video/ogg + video/webm + ).freeze + included do before_post_process :obfuscate_file_name before_post_process :set_file_extensions @@ -21,7 +32,7 @@ module Attachmentable self.class.attachment_definitions.each_key do |attachment_name| attachment = send(attachment_name) - next if attachment.blank? || attachment.queued_for_write[:original].blank? + next if attachment.blank? || attachment.queued_for_write[:original].blank? || !INCORRECT_CONTENT_TYPES.include?(attachment.instance_read(:content_type)) attachment.instance_write :content_type, calculated_content_type(attachment) end @@ -63,9 +74,7 @@ module Attachmentable end def calculated_content_type(attachment) - content_type = Paperclip.run('file', '-b --mime :file', file: attachment.queued_for_write[:original].path).split(/[:;\s]+/).first.chomp - content_type = 'video/mp4' if content_type == 'video/x-m4v' - content_type + Paperclip.run('file', '-b --mime :file', file: attachment.queued_for_write[:original].path).split(/[:;\s]+/).first.chomp rescue Terrapin::CommandLineError '' end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 53ebc0835..c6d0c7f1f 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -24,28 +24,16 @@ module Remotable Request.new(:get, url).perform do |response| raise Mastodon::UnexpectedResponseError, response unless (200...300).cover?(response.code) - content_type = parse_content_type(response.headers.get('content-type').last) - extname = detect_extname_from_content_type(content_type) - - if extname.nil? - disposition = response.headers.get('content-disposition').last - matches = disposition&.match(/filename="([^"]*)"/) - filename = matches.nil? ? parsed_url.path.split('/').last : matches[1] - extname = filename.nil? ? '' : File.extname(filename) - end - - basename = SecureRandom.hex(8) - - public_send("#{attachment_name}_file_name=", basename + extname) - public_send("#{attachment_name}=", StringIO.new(response.body_with_limit(limit))) + public_send("#{attachment_name}=", ResponseWithLimit.new(response, limit)) end rescue Mastodon::UnexpectedResponseError, HTTP::TimeoutError, HTTP::ConnectionError, OpenSSL::SSL::SSLError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" raise e unless suppress_errors rescue Paperclip::Errors::NotIdentifiedByImageMagickError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, Paperclip::Error, Mastodon::DimensionsValidationError => e Rails.logger.debug "Error fetching remote #{attachment_name}: #{e}" - nil end + + nil end define_method("#{attribute_name}=") do |url| @@ -59,26 +47,4 @@ module Remotable alias_method("reset_#{attachment_name}!", "download_#{attachment_name}!") end end - - private - - def detect_extname_from_content_type(content_type) - return if content_type.nil? - - type = MIME::Types[content_type].first - - return if type.nil? - - extname = type.extensions.first - - return if extname.nil? - - ".#{extname}" - end - - def parse_content_type(content_type) - return if content_type.nil? - - content_type.split(/\s*;\s*/).first - end end diff --git a/app/models/encrypted_message.rb b/app/models/encrypted_message.rb index 5e0aba434..aa4182b4e 100644 --- a/app/models/encrypted_message.rb +++ b/app/models/encrypted_message.rb @@ -32,16 +32,13 @@ class EncryptedMessage < ApplicationRecord private def push_to_streaming_api - Rails.logger.info(streaming_channel) - Rails.logger.info(subscribed_to_timeline?) - return if destroyed? || !subscribed_to_timeline? PushEncryptedMessageWorker.perform_async(id) end def subscribed_to_timeline? - Redis.current.exists("subscribed:#{streaming_channel}") + Redis.current.exists?("subscribed:#{streaming_channel}") end def streaming_channel diff --git a/app/models/home_feed.rb b/app/models/home_feed.rb index 1fd506138..0fe9dae46 100644 --- a/app/models/home_feed.rb +++ b/app/models/home_feed.rb @@ -8,6 +8,6 @@ class HomeFeed < Feed end def regenerating? - redis.exists("account:#{@id}:regeneration") + redis.exists?("account:#{@id}:regeneration") end end diff --git a/app/views/application/_card.html.haml b/app/views/application/_card.html.haml index e7ecfecd9..909d9ff81 100644 --- a/app/views/application/_card.html.haml +++ b/app/views/application/_card.html.haml @@ -13,4 +13,4 @@ %strong.emojify.p-name= display_name(account, custom_emojify: true) %span = acct(account) - = fa_icon('lock') if account.locked? + = fa_icon('lock', { :data => ({hidden: true} unless account.locked?)}) diff --git a/app/workers/activitypub/move_distribution_worker.rb b/app/workers/activitypub/move_distribution_worker.rb index bf1c0e7ae..65c5c0d1c 100644 --- a/app/workers/activitypub/move_distribution_worker.rb +++ b/app/workers/activitypub/move_distribution_worker.rb @@ -24,7 +24,7 @@ class ActivityPub::MoveDistributionWorker private def inboxes - @inboxes ||= @migration.account.followers.inboxes + @inboxes ||= (@migration.account.followers.inboxes + @migration.account.blocked_by.inboxes).uniq end def signed_payload diff --git a/app/workers/move_worker.rb b/app/workers/move_worker.rb index 4d76461b0..39e321316 100644 --- a/app/workers/move_worker.rb +++ b/app/workers/move_worker.rb @@ -14,6 +14,8 @@ class MoveWorker end copy_account_notes! + carry_blocks_over! + carry_mutes_over! rescue ActiveRecord::RecordNotFound true end @@ -51,4 +53,29 @@ class MoveWorker end end end + + def carry_blocks_over! + @source_account.blocked_by_relationships.where(account: Account.local).find_each do |block| + unless block.account.blocking?(@target_account) || block.account.following?(@target_account) + BlockService.new.call(block.account, @target_account) + add_account_note_if_needed!(block.account, 'move_handler.carry_blocks_over_text') + end + end + end + + def carry_mutes_over! + @source_account.muted_by_relationships.where(account: Account.local).find_each do |mute| + MuteService.new.call(mute.account, @target_account, notifications: mute.hide_notifications) unless mute.account.muting?(@target_account) || mute.account.following?(@target_account) + add_account_note_if_needed!(mute.account, 'move_handler.carry_mutes_over_text') + end + end + + def add_account_note_if_needed!(account, id) + unless AccountNote.where(account: account, target_account: @target_account).exists? + text = I18n.with_locale(account.user.locale || I18n.default_locale) do + I18n.t(id, acct: @source_account.acct) + end + AccountNote.create!(account: account, target_account: @target_account, comment: text) + end + end end diff --git a/app/workers/publish_announcement_reaction_worker.rb b/app/workers/publish_announcement_reaction_worker.rb index 418dc7127..03da56550 100644 --- a/app/workers/publish_announcement_reaction_worker.rb +++ b/app/workers/publish_announcement_reaction_worker.rb @@ -14,7 +14,7 @@ class PublishAnnouncementReactionWorker payload = Oj.dump(event: :'announcement.reaction', payload: payload) FeedManager.instance.with_active_accounts do |account| - redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}") + redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}") end rescue ActiveRecord::RecordNotFound true diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb index 1392efed0..c23eae6af 100644 --- a/app/workers/publish_scheduled_announcement_worker.rb +++ b/app/workers/publish_scheduled_announcement_worker.rb @@ -15,7 +15,7 @@ class PublishScheduledAnnouncementWorker payload = Oj.dump(event: :announcement, payload: payload) FeedManager.instance.with_active_accounts do |account| - redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}") + redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}") end end diff --git a/app/workers/unpublish_announcement_worker.rb b/app/workers/unpublish_announcement_worker.rb index e99d70cf8..e58c07554 100644 --- a/app/workers/unpublish_announcement_worker.rb +++ b/app/workers/unpublish_announcement_worker.rb @@ -8,7 +8,7 @@ class UnpublishAnnouncementWorker payload = Oj.dump(event: :'announcement.delete', payload: announcement_id.to_s) FeedManager.instance.with_active_accounts do |account| - redis.publish("timeline:#{account.id}", payload) if redis.exists("subscribed:timeline:#{account.id}") + redis.publish("timeline:#{account.id}", payload) if redis.exists?("subscribed:timeline:#{account.id}") end end end |