about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2020-03-08 16:10:48 +0100
committerGitHub <noreply@github.com>2020-03-08 16:10:48 +0100
commitaa67036b41d37935210c8b5094ac20c153a62011 (patch)
tree27afe119c6d80b7100e2e92d73df40fc3db2dc7c /app
parent5e4b6496557b5ef167518dbc6015307158e30ccf (diff)
Add support for links to statuses in announcements to be opened in web UI (#13212)
* Add support for links to public statuses in announcements to be opened in WebUI

* Please CodeClimate
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/features/getting_started/components/announcements.js11
-rw-r--r--app/models/announcement.rb4
-rw-r--r--app/models/status.rb15
-rw-r--r--app/serializers/rest/announcement_serializer.rb13
4 files changed, 43 insertions, 0 deletions
diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.js
index 91cf6215e..fb4a6bf0d 100644
--- a/app/javascript/mastodon/features/getting_started/components/announcements.js
+++ b/app/javascript/mastodon/features/getting_started/components/announcements.js
@@ -95,6 +95,10 @@ class Content extends ImmutablePureComponent {
       } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
         link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false);
       } else {
+        let status = this.props.announcement.get('statuses').find(item => link.href === item.get('url'));
+        if (status) {
+          link.addEventListener('click', this.onStatusClick.bind(this, status), false);
+        }
         link.setAttribute('title', link.href);
         link.classList.add('unhandled-link');
       }
@@ -120,6 +124,13 @@ class Content extends ImmutablePureComponent {
     }
   }
 
+  onStatusClick = (status, e) => {
+    if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${status.get('id')}`);
+    }
+  }
+
   handleEmojiMouseEnter = ({ target }) => {
     target.src = target.getAttribute('data-original');
   }
diff --git a/app/models/announcement.rb b/app/models/announcement.rb
index d99502f44..f8ac4e09d 100644
--- a/app/models/announcement.rb
+++ b/app/models/announcement.rb
@@ -48,6 +48,10 @@ class Announcement < ApplicationRecord
     @mentions ||= Account.from_text(text)
   end
 
+  def statuses
+    @statuses ||= Status.from_text(text)
+  end
+
   def tags
     @tags ||= Tag.find_or_create_by_names(Extractor.extract_hashtags(text))
   end
diff --git a/app/models/status.rb b/app/models/status.rb
index 1610da245..8e040f0e6 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -369,6 +369,21 @@ class Status < ApplicationRecord
       end
     end
 
+    def from_text(text)
+      return [] if text.blank?
+
+      text.scan(FetchLinkCardService::URL_PATTERN).map(&:first).uniq.map do |url|
+        status = begin
+          if TagManager.instance.local_url?(url)
+            ActivityPub::TagManager.instance.uri_to_resource(url, Status)
+          else
+            Status.find_by(uri: url) || Status.find_by(url: url)
+          end
+        end
+        status&.distributable? ? status : nil
+      end.compact
+    end
+
     private
 
     def timeline_scope(local_only = false)
diff --git a/app/serializers/rest/announcement_serializer.rb b/app/serializers/rest/announcement_serializer.rb
index f27feb669..9343b97d2 100644
--- a/app/serializers/rest/announcement_serializer.rb
+++ b/app/serializers/rest/announcement_serializer.rb
@@ -7,6 +7,7 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer
   attribute :read, if: :current_user?
 
   has_many :mentions
+  has_many :statuses
   has_many :tags, serializer: REST::StatusSerializer::TagSerializer
   has_many :emojis, serializer: REST::CustomEmojiSerializer
   has_many :reactions, serializer: REST::ReactionSerializer
@@ -46,4 +47,16 @@ class REST::AnnouncementSerializer < ActiveModel::Serializer
       object.pretty_acct
     end
   end
+
+  class StatusSerializer < ActiveModel::Serializer
+    attributes :id, :url
+
+    def id
+      object.id.to_s
+    end
+
+    def url
+      ActivityPub::TagManager.instance.url_for(object)
+    end
+  end
 end