2020-01-23 13:00:13 -08:00
# frozen_string_literal: true
# == Schema Information
#
# Table name: announcements
#
# id :bigint(8) not null, primary key
# text :text default(""), not null
# published :boolean default(FALSE), not null
# all_day :boolean default(FALSE), not null
# scheduled_at :datetime
# starts_at :datetime
# ends_at :datetime
# created_at :datetime not null
# updated_at :datetime not null
2020-01-26 13:43:18 -08:00
# published_at :datetime
2020-04-15 11:33:24 -07:00
# status_ids :bigint(8) is an Array
2020-01-23 13:00:13 -08:00
#
class Announcement < ApplicationRecord
scope :unpublished , - > { where ( published : false ) }
scope :published , - > { where ( published : true ) }
2023-02-20 10:20:56 -08:00
scope :without_muted , - > ( account ) { joins ( " LEFT OUTER JOIN announcement_mutes ON announcement_mutes.announcement_id = announcements.id AND announcement_mutes.account_id = #{ account . id } " ) . where ( announcement_mutes : { id : nil } ) }
2020-01-26 13:43:18 -08:00
scope :chronological , - > { order ( Arel . sql ( 'COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC' ) ) }
2020-11-04 12:15:22 -08:00
scope :reverse_chronological , - > { order ( Arel . sql ( 'COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) DESC' ) ) }
2020-01-23 13:00:13 -08:00
has_many :announcement_mutes , dependent : :destroy
has_many :announcement_reactions , dependent : :destroy
validates :text , presence : true
validates :starts_at , presence : true , if : - > { ends_at . present? }
validates :ends_at , presence : true , if : - > { starts_at . present? }
2020-01-26 11:07:26 -08:00
before_validation :set_published , on : :create
2022-08-25 11:39:40 -07:00
def to_log_human_identifier
text
end
2020-01-27 02:05:33 -08:00
def publish!
update! ( published : true , published_at : Time . now . utc , scheduled_at : nil )
end
def unpublish!
update! ( published : false , scheduled_at : nil )
end
2020-01-23 13:00:13 -08:00
def time_range?
starts_at . present? && ends_at . present?
end
def mentions
@mentions || = Account . from_text ( text )
end
2020-03-08 08:10:48 -07:00
def statuses
2023-02-18 14:09:40 -08:00
@statuses || = if status_ids . nil?
[ ]
else
Status . where ( id : status_ids , visibility : [ :public , :unlisted ] )
end
2020-03-08 08:10:48 -07:00
end
2020-01-23 13:00:13 -08:00
def tags
@tags || = Tag . find_or_create_by_names ( Extractor . extract_hashtags ( text ) )
end
def emojis
@emojis || = CustomEmoji . from_text ( text )
end
def reactions ( account = nil )
records = begin
scope = announcement_reactions . group ( :announcement_id , :name , :custom_emoji_id ) . order ( Arel . sql ( 'MIN(created_at) ASC' ) )
if account . nil?
scope . select ( 'name, custom_emoji_id, count(*) as count, false as me' )
else
scope . select ( " name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{ account . id } and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me " )
end
2023-12-12 23:47:32 -08:00
end . to_a
2020-01-23 13:00:13 -08:00
2023-12-12 23:47:32 -08:00
ActiveRecord :: Associations :: Preloader . new ( records : records , associations : :custom_emoji ) . call
2020-01-23 13:00:13 -08:00
records
end
private
2020-01-26 11:07:26 -08:00
def set_published
2020-01-26 13:43:18 -08:00
return unless scheduled_at . blank? || scheduled_at . past?
self . published = true
self . published_at = Time . now . utc
2020-01-23 13:00:13 -08:00
end
end