about summary refs log tree commit diff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/block.rb22
-rw-r--r--app/models/concerns/streamable.rb6
-rw-r--r--app/models/status.rb29
-rw-r--r--app/models/stream_entry.rb5
4 files changed, 52 insertions, 10 deletions
diff --git a/app/models/block.rb b/app/models/block.rb
index dc05bce87..ad225d180 100644
--- a/app/models/block.rb
+++ b/app/models/block.rb
@@ -1,9 +1,31 @@
 # frozen_string_literal: true
 
 class Block < ApplicationRecord
+  include Streamable
+
   belongs_to :account
   belongs_to :target_account, class_name: 'Account'
 
   validates :account, :target_account, presence: true
   validates :account_id, uniqueness: { scope: :target_account_id }
+
+  def verb
+    destroyed? ? :unblock : :block
+  end
+
+  def target
+    target_account
+  end
+
+  def object_type
+    :person
+  end
+
+  def hidden?
+    true
+  end
+
+  def title
+    destroyed? ? "#{account.acct} is no longer blocking #{target_account.acct}" : "#{account.acct} blocked #{target_account.acct}"
+  end
 end
diff --git a/app/models/concerns/streamable.rb b/app/models/concerns/streamable.rb
index d9f5dc4d8..58c15cfbc 100644
--- a/app/models/concerns/streamable.rb
+++ b/app/models/concerns/streamable.rb
@@ -26,8 +26,12 @@ module Streamable
       super
     end
 
+    def hidden?
+      false
+    end
+
     after_create do
-      account.stream_entries.create!(activity: self) if account.local?
+      account.stream_entries.create!(activity: self, hidden: hidden?) if account.local?
     end
   end
 end
diff --git a/app/models/status.rb b/app/models/status.rb
index e87828e32..603f3b7a2 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -5,7 +5,7 @@ class Status < ApplicationRecord
   include Streamable
   include Cacheable
 
-  enum visibility: [:public, :unlisted], _suffix: :visibility
+  enum visibility: [:public, :unlisted, :private], _suffix: :visibility
 
   belongs_to :account, inverse_of: :statuses
 
@@ -66,19 +66,19 @@ class Status < ApplicationRecord
     content
   end
 
-  def reblogs_count
-    attributes['reblogs_count'] || reblogs.count
+  def hidden?
+    private_visibility?
   end
 
-  def favourites_count
-    attributes['favourites_count'] || favourites.count
+  def permitted?(other_account = nil)
+    private_visibility? ? (account.id == other_account&.id || other_account&.following?(account)) : true
   end
 
   def ancestors(account = nil)
     ids      = (Status.find_by_sql(['WITH RECURSIVE search_tree(id, in_reply_to_id, path) AS (SELECT id, in_reply_to_id, ARRAY[id] FROM statuses WHERE id = ? UNION ALL SELECT statuses.id, statuses.in_reply_to_id, path || statuses.id FROM search_tree JOIN statuses ON statuses.id = search_tree.in_reply_to_id WHERE NOT statuses.id = ANY(path)) SELECT id FROM search_tree ORDER BY path DESC', id]) - [self]).pluck(:id)
     statuses = Status.where(id: ids).with_includes.group_by(&:id)
     results  = ids.map { |id| statuses[id].first }
-    results  = results.reject { |status| account.blocking?(status.account) } unless account.nil?
+    results  = results.reject { |status| filter_from_context?(status, account) }
 
     results
   end
@@ -87,7 +87,7 @@ class Status < ApplicationRecord
     ids      = (Status.find_by_sql(['WITH RECURSIVE search_tree(id, path) AS (SELECT id, ARRAY[id] FROM statuses WHERE id = ? UNION ALL SELECT statuses.id, path || statuses.id FROM search_tree JOIN statuses ON statuses.in_reply_to_id = search_tree.id WHERE NOT statuses.id = ANY(path)) SELECT id FROM search_tree ORDER BY path', id]) - [self]).pluck(:id)
     statuses = Status.where(id: ids).with_includes.group_by(&:id)
     results  = ids.map { |id| statuses[id].first }
-    results  = results.reject { |status| account.blocking?(status.account) } unless account.nil?
+    results  = results.reject { |status| filter_from_context?(status, account) }
 
     results
   end
@@ -128,6 +128,14 @@ class Status < ApplicationRecord
       select('reblog_of_id').where(reblog_of_id: status_ids).where(account_id: account_id).map { |s| [s.reblog_of_id, true] }.to_h
     end
 
+    def permitted_for(target_account, account)
+      if account&.id == target_account.id || account&.following?(target_account)
+        self
+      else
+        where.not(visibility: :private)
+      end
+    end
+
     def reload_stale_associations!(cached_items)
       account_ids = []
 
@@ -161,5 +169,12 @@ class Status < ApplicationRecord
   before_validation do
     text.strip!
     self.in_reply_to_account_id = thread.account_id if reply?
+    self.visibility             = :public if visibility.nil?
+  end
+
+  private
+
+  def filter_from_context?(status, account)
+    account&.blocking?(status.account) || !status.permitted?(account)
   end
 end
diff --git a/app/models/stream_entry.rb b/app/models/stream_entry.rb
index f6c8f461b..fcc691bef 100644
--- a/app/models/stream_entry.rb
+++ b/app/models/stream_entry.rb
@@ -9,6 +9,7 @@ class StreamEntry < ApplicationRecord
   belongs_to :status,    foreign_type: 'Status',    foreign_key: 'activity_id'
   belongs_to :follow,    foreign_type: 'Follow',    foreign_key: 'activity_id'
   belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id'
+  belongs_to :block,     foreign_type: 'Block',     foreign_key: 'activity_id'
 
   validates :account, :activity, presence: true
 
@@ -29,7 +30,7 @@ class StreamEntry < ApplicationRecord
   end
 
   def targeted?
-    [:follow, :share, :favorite].include? verb
+    [:follow, :unfollow, :block, :unblock, :share, :favorite].include? verb
   end
 
   def target
@@ -57,7 +58,7 @@ class StreamEntry < ApplicationRecord
   end
 
   def activity
-    send(activity_type.downcase.to_sym)
+    !new_record? ? send(activity_type.downcase) : super
   end
 
   private