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/account.rb52
-rw-r--r--app/models/notification.rb27
-rw-r--r--app/models/status.rb2
-rw-r--r--app/models/tag.rb4
4 files changed, 67 insertions, 18 deletions
diff --git a/app/models/account.rb b/app/models/account.rb
index cbba8b5b6..8ceda7f97 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -12,12 +12,12 @@ class Account < ApplicationRecord
   validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
 
   # Avatar upload
-  has_attached_file :avatar, styles: { original: '120x120#' }, convert_options: { all: '-quality 80 -strip' }
+  has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' }
   validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES
   validates_attachment_size :avatar, less_than: 2.megabytes
 
   # Header upload
-  has_attached_file :header, styles: { original: '700x335#' }, convert_options: { all: '-quality 80 -strip' }
+  has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-quality 80 -strip' }
   validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES
   validates_attachment_size :header, less_than: 2.megabytes
 
@@ -120,6 +120,14 @@ class Account < ApplicationRecord
     local? ? username : "#{username}@#{domain}"
   end
 
+  def local_username_and_domain
+    "#{username}@#{Rails.configuration.x.local_domain}"
+  end
+
+  def to_webfinger_s
+    "acct:#{local_username_and_domain}"
+  end
+
   def subscribed?
     !subscription_expires_at.blank?
   end
@@ -150,6 +158,22 @@ class Account < ApplicationRecord
     save!
   end
 
+  def avatar_original_url
+    avatar.url(:original)
+  end
+
+  def avatar_static_url
+    avatar_content_type == 'image/gif' ? avatar.url(:static) : avatar_original_url
+  end
+
+  def header_original_url
+    header.url(:original)
+  end
+
+  def header_static_url
+    header_content_type == 'image/gif' ? header.url(:static) : header_original_url
+  end
+
   def avatar_remote_url=(url)
     parsed_url = URI.parse(url)
 
@@ -203,7 +227,7 @@ class Account < ApplicationRecord
     end
 
     def triadic_closures(account, limit = 5)
-      sql = <<SQL
+      sql = <<-SQL.squish
         WITH first_degree AS (
             SELECT target_account_id
             FROM follows
@@ -216,7 +240,7 @@ class Account < ApplicationRecord
         GROUP BY target_account_id, accounts.id
         ORDER BY count(account_id) DESC
         LIMIT ?
-SQL
+      SQL
 
       Account.find_by_sql([sql, account.id, account.id, limit])
     end
@@ -226,7 +250,7 @@ SQL
       textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
       query      = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
 
-      sql = <<SQL
+      sql = <<-SQL.squish
         SELECT
           accounts.*,
           ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
@@ -234,7 +258,7 @@ SQL
         WHERE #{query} @@ #{textsearch}
         ORDER BY rank DESC
         LIMIT ?
-SQL
+      SQL
 
       Account.find_by_sql([sql, limit])
     end
@@ -244,7 +268,7 @@ SQL
       textsearch = '(setweight(to_tsvector(\'simple\', accounts.display_name), \'A\') || setweight(to_tsvector(\'simple\', accounts.username), \'B\') || setweight(to_tsvector(\'simple\', coalesce(accounts.domain, \'\')), \'C\'))'
       query      = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
 
-      sql = <<SQL
+      sql = <<-SQL.squish
         SELECT
           accounts.*,
           (count(f.id) + 1) * ts_rank_cd(#{textsearch}, #{query}, 32) AS rank
@@ -254,7 +278,7 @@ SQL
         GROUP BY accounts.id
         ORDER BY rank DESC
         LIMIT ?
-SQL
+      SQL
 
       Account.find_by_sql([sql, account.id, account.id, limit])
     end
@@ -284,6 +308,18 @@ SQL
     def follow_mapping(query, field)
       query.pluck(field).inject({}) { |mapping, id| mapping[id] = true; mapping }
     end
+
+    def avatar_styles(file)
+      styles = { original: '120x120#' }
+      styles[:static] = { format: 'png' } if file.content_type == 'image/gif'
+      styles
+    end
+
+    def header_styles(file)
+      styles = { original: '700x335#' }
+      styles[:static] = { format: 'png' } if file.content_type == 'image/gif'
+      styles
+    end
   end
 
   before_create do
diff --git a/app/models/notification.rb b/app/models/notification.rb
index b7b474869..302d4382d 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -16,10 +16,17 @@ class Notification < ApplicationRecord
 
   validates :account_id, uniqueness: { scope: [:activity_type, :activity_id] }
 
+  TYPE_CLASS_MAP = {
+    mention:        'Mention',
+    reblog:         'Status',
+    follow:         'Follow',
+    follow_request: 'FollowRequest',
+    favourite:      'Favourite',
+  }.freeze
+
   STATUS_INCLUDES = [:account, :stream_entry, :media_attachments, :tags, mentions: :account, reblog: [:stream_entry, :account, :media_attachments, :tags, mentions: :account]].freeze
 
   scope :cache_ids, -> { select(:id, :updated_at, :activity_type, :activity_id) }
-  scope :browserable, -> { where.not(activity_type: ['FollowRequest']) }
 
   cache_associated :from_account, status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account
 
@@ -28,12 +35,7 @@ class Notification < ApplicationRecord
   end
 
   def type
-    case activity_type
-    when 'Status'
-      :reblog
-    else
-      activity_type.underscore.to_sym
-    end
+    @type ||= TYPE_CLASS_MAP.invert[activity_type].to_sym
   end
 
   def target_status
@@ -50,6 +52,11 @@ class Notification < ApplicationRecord
   end
 
   class << self
+    def browserable(types = [])
+      types.concat([:follow_request])
+      where.not(activity_type: activity_types_from_types(types))
+    end
+
     def reload_stale_associations!(cached_items)
       account_ids = cached_items.map(&:from_account_id).uniq
       accounts    = Account.where(id: account_ids).map { |a| [a.id, a] }.to_h
@@ -58,6 +65,12 @@ class Notification < ApplicationRecord
         item.from_account = accounts[item.from_account_id]
       end
     end
+
+    private
+
+    def activity_types_from_types(types)
+      types.map { |type| TYPE_CLASS_MAP[type.to_sym] }.compact
+    end
   end
 
   after_initialize :set_from_account
diff --git a/app/models/status.rb b/app/models/status.rb
index 7e3dd3e28..16cd4383f 100644
--- a/app/models/status.rb
+++ b/app/models/status.rb
@@ -75,7 +75,7 @@ class Status < ApplicationRecord
   end
 
   def title
-    content
+    reblog? ? "#{account.acct} shared a status by #{reblog.account.acct}" : "New status by #{account.acct}"
   end
 
   def hidden?
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 15625ca43..6209d7dab 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -17,7 +17,7 @@ class Tag < ApplicationRecord
       textsearch = 'to_tsvector(\'simple\', tags.name)'
       query      = 'to_tsquery(\'simple\', \'\'\' \' || ' + terms + ' || \' \'\'\' || \':*\')'
 
-      sql = <<SQL
+      sql = <<-SQL.squish
         SELECT
           tags.*,
           ts_rank_cd(#{textsearch}, #{query}) AS rank
@@ -25,7 +25,7 @@ class Tag < ApplicationRecord
         WHERE #{query} @@ #{textsearch}
         ORDER BY rank DESC
         LIMIT ?
-SQL
+      SQL
 
       Tag.find_by_sql([sql, limit])
     end