From 3ff14e0b024614bd1ffc6b614acfbe904936d8a3 Mon Sep 17 00:00:00 2001 From: KMY Date: Sun, 1 Oct 2023 17:44:17 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BB=96=E3=81=AE=E3=82=B5=E3=83=BC=E3=83=90?= =?UTF-8?q?=E3=83=BC=E3=81=8B=E3=82=89=E6=9D=A5=E3=81=9F=E5=BC=95=E7=94=A8?= =?UTF-8?q?=E4=BB=98=E3=81=8D=E6=8A=95=E7=A8=BF=E3=82=92=E5=87=A6=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mastodon/components/compacted_status.jsx | 25 ----- app/javascript/mastodon/components/status.jsx | 4 +- app/lib/activitypub/activity/create.rb | 3 +- .../process_status_update_service.rb | 3 +- app/services/process_references_service.rb | 15 ++- spec/lib/activitypub/activity/create_spec.rb | 91 +++++++++++++++++++ .../process_references_service_spec.rb | 17 +++- 7 files changed, 119 insertions(+), 39 deletions(-) diff --git a/app/javascript/mastodon/components/compacted_status.jsx b/app/javascript/mastodon/components/compacted_status.jsx index 142b2ea83ca9cc..1be477c82eff5d 100644 --- a/app/javascript/mastodon/components/compacted_status.jsx +++ b/app/javascript/mastodon/components/compacted_status.jsx @@ -281,11 +281,6 @@ class CompactedStatus extends ImmutablePureComponent { this.handleToggleMediaVisibility(); }; - handleUnfilterClick = e => { - this.setState({ forceFilter: false }); - e.preventDefault(); - }; - _properStatus () { const { status } = this.props; @@ -335,26 +330,6 @@ class CompactedStatus extends ImmutablePureComponent { const connectUp = previousId && previousId === status.get('in_reply_to_id'); const connectToRoot = rootId && rootId === status.get('in_reply_to_id'); const connectReply = nextInReplyToId && nextInReplyToId === status.get('id'); - const matchedFilters = status.get('matched_filters'); - - if (this.state.forceFilter === undefined ? matchedFilters : this.state.forceFilter) { - const minHandlers = this.props.muted ? {} : { - moveUp: this.handleHotkeyMoveUp, - moveDown: this.handleHotkeyMoveDown, - }; - - return ( - -
- : {matchedFilters.join(', ')}. - {' '} - -
-
- ); - } if (showThread && status.get('in_reply_to_id') && status.get('in_reply_to_account_id') === status.getIn(['account', 'id'])) { const display_name_html = { __html: status.getIn(['account', 'display_name_html']) }; diff --git a/app/javascript/mastodon/components/status.jsx b/app/javascript/mastodon/components/status.jsx index f1ff5581cd0be2..c60e70eb5c1c05 100644 --- a/app/javascript/mastodon/components/status.jsx +++ b/app/javascript/mastodon/components/status.jsx @@ -624,7 +624,8 @@ class Status extends ImmutablePureComponent { const expanded = !status.get('hidden') || status.get('spoiler_text').length === 0; const withLimited = status.get('visibility_ex') === 'limited' && status.get('limited_scope') ? : null; - const withReference = status.get('status_references_count') > 0 ? : null; + const withQuote = status.get('quote_id') ? : null; + const withReference = (!withQuote && status.get('status_references_count') > 0) ? : null; const withExpiration = status.get('expires_at') ? : null; const quote = !muted && status.get('quote_id') && @@ -640,6 +641,7 @@ class Status extends ImmutablePureComponent { {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions */}
+ {withQuote} {withReference} {withExpiration} {withLimited} diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb index 1f81fcda6c53b1..f2841300dfe599 100644 --- a/app/lib/activitypub/activity/create.rb +++ b/app/lib/activitypub/activity/create.rb @@ -486,9 +486,8 @@ def increment_voters_count! def process_references! references = @object['references'].nil? ? [] : ActivityPub::FetchReferencesService.new.call(@status, @object['references']) quote = @object['quote'] || @object['quoteUrl'] || @object['quoteURL'] || @object['_misskey_quote'] - references << quote if quote - ProcessReferencesService.perform_worker_async(@status, [], references) + ProcessReferencesService.perform_worker_async(@status, [], references, [quote].compact) end def join_group! diff --git a/app/services/activitypub/process_status_update_service.rb b/app/services/activitypub/process_status_update_service.rb index da82af8dff69ac..2ae2824a1e5e67 100644 --- a/app/services/activitypub/process_status_update_service.rb +++ b/app/services/activitypub/process_status_update_service.rb @@ -254,9 +254,8 @@ def update_emojis! def update_references! references = @json['references'].nil? ? [] : ActivityPub::FetchReferencesService.new.call(@status, @json['references']) quote = @json['quote'] || @json['quoteUrl'] || @json['quoteURL'] || @json['_misskey_quote'] - references << quote if quote - ProcessReferencesService.perform_worker_async(@status, [], references) + ProcessReferencesService.perform_worker_async(@status, [], references, [quote].compact) end def expected_type? diff --git a/app/services/process_references_service.rb b/app/services/process_references_service.rb index 9d2db9860b67d1..782fbb015d7203 100644 --- a/app/services/process_references_service.rb +++ b/app/services/process_references_service.rb @@ -41,19 +41,19 @@ def call(status, reference_parameters, urls: nil, fetch_remote: true, no_fetch_u launch_worker if @again end - def self.need_process?(status, reference_parameters, urls) - reference_parameters.any? || (urls || []).any? || FormattingHelper.extract_status_plain_text(status).scan(REFURL_EXP).pluck(3).uniq.any? + def self.need_process?(status, reference_parameters, urls, quote_urls) + reference_parameters.any? || (urls || []).any? || (quote_urls || []).any? || FormattingHelper.extract_status_plain_text(status).scan(REFURL_EXP).pluck(3).uniq.any? end - def self.perform_worker_async(status, reference_parameters, urls, quote_urls = []) - return unless need_process?(status, reference_parameters, urls) + def self.perform_worker_async(status, reference_parameters, urls, quote_urls) + return unless need_process?(status, reference_parameters, urls, quote_urls) Rails.cache.write("status_reference:#{status.id}", true, expires_in: 10.minutes) ProcessReferencesWorker.perform_async(status.id, reference_parameters, urls, [], quote_urls || []) end def self.call_service(status, reference_parameters, urls, quote_urls = []) - return unless need_process?(status, reference_parameters, urls) + return unless need_process?(status, reference_parameters, urls, quote_urls) ProcessReferencesService.new.call(status, reference_parameters || [], urls: urls || [], fetch_remote: false, quote_urls: quote_urls) end @@ -92,7 +92,7 @@ def fetch_statuses!(urls) target_urls.map do |url| status = url_to_status(url) - @no_fetch_urls << url if !@fetch_remote && status.present? && status.local? + @no_fetch_urls << url if !@fetch_remote && status.present? status end end @@ -118,8 +118,7 @@ def add_references statuses.each do |status| attribute_type = quote_status_ids.include?(status.id) ? 'QT' : @attributes[status.id] attribute_type = 'BT' unless quotable?(status) - quote_type = attribute_type.casecmp('QT').zero? - @status.quote_of_id = status.id if quote_type && @status.quote_of_id.nil? + quote_type = attribute_type.present? ? attribute_type.casecmp('QT').zero? : false @added_objects << @status.reference_objects.new(target_status: status, attribute_type: attribute_type, quote: quote_type) status.increment_count!(:status_referred_by_count) diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb index c199fcd0382113..41bde8b0c4e080 100644 --- a/spec/lib/activitypub/activity/create_spec.rb +++ b/spec/lib/activitypub/activity/create_spec.rb @@ -1089,6 +1089,97 @@ end end + context 'with references' do + let(:recipient) { Fabricate(:account) } + let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + references: { + id: 'target_status', + type: 'Collection', + first: { + type: 'CollectionPage', + next: nil, + partOf: 'target_status', + items: [ + ActivityPub::TagManager.instance.uri_for(target_status), + ], + }, + }, + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.quote).to be_nil + expect(status.references.pluck(:id)).to eq [target_status.id] + end + end + + context 'with quote' do + let(:recipient) { Fabricate(:account) } + let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + quote: ActivityPub::TagManager.instance.uri_for(target_status), + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.references.pluck(:id)).to eq [target_status.id] + expect(status.quote).to_not be_nil + expect(status.quote.id).to eq target_status.id + end + end + + context 'with references and quote' do + let(:recipient) { Fabricate(:account) } + let!(:target_status) { Fabricate(:status, account: Fabricate(:account, domain: nil)) } + + let(:object_json) do + { + id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join, + type: 'Note', + content: 'Lorem ipsum', + quote: ActivityPub::TagManager.instance.uri_for(target_status), + references: { + id: 'target_status', + type: 'Collection', + first: { + type: 'CollectionPage', + next: nil, + partOf: 'target_status', + items: [ + ActivityPub::TagManager.instance.uri_for(target_status), + ], + }, + }, + } + end + + it 'creates status' do + status = sender.statuses.first + + expect(status).to_not be_nil + expect(status.references.pluck(:id)).to eq [target_status.id] + expect(status.quote).to_not be_nil + expect(status.quote.id).to eq target_status.id + end + end + context 'with language' do let(:to) { 'https://www.w3.org/ns/activitystreams#Public' } let(:object_json) do diff --git a/spec/services/process_references_service_spec.rb b/spec/services/process_references_service_spec.rb index 131dc4c6a8cf5d..6371f210d3eeae 100644 --- a/spec/services/process_references_service_spec.rb +++ b/spec/services/process_references_service_spec.rb @@ -10,6 +10,7 @@ let(:status) { Fabricate(:status, account: account, text: text, visibility: visibility) } let(:target_status) { Fabricate(:status, account: Fabricate(:user).account, visibility: target_status_visibility) } let(:target_status_uri) { ActivityPub::TagManager.instance.uri_for(target_status) } + let(:quote_urls) { nil } def notify?(target_status_id = nil) target_status_id ||= target_status.id @@ -18,7 +19,7 @@ def notify?(target_status_id = nil) describe 'posting new status' do subject do - described_class.new.call(status, reference_parameters, urls: urls, fetch_remote: fetch_remote) + described_class.new.call(status, reference_parameters, urls: urls, fetch_remote: fetch_remote, quote_urls: quote_urls) status.reference_objects.pluck(:target_status_id, :attribute_type) end @@ -90,6 +91,20 @@ def notify?(target_status_id = nil) end end + context 'with quote as parameter only' do + let(:text) { 'Hello' } + let(:quote_urls) { [ActivityPub::TagManager.instance.uri_for(target_status)] } + + it 'post status' do + expect(subject.size).to eq 1 + expect(subject.pluck(0)).to include target_status.id + expect(subject.pluck(1)).to include 'QT' + expect(status.quote).to_not be_nil + expect(status.quote.id).to eq target_status.id + expect(notify?).to be true + end + end + context 'with quote and reference' do let(:target_status2) { Fabricate(:status) } let(:target_status2_uri) { ActivityPub::TagManager.instance.uri_for(target_status2) }