2020-01-23 23:00:13 +02: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 23:43:18 +02:00
# published_at :datetime
2020-04-15 21:33:24 +03:00
# status_ids :bigint(8) is an Array
2020-01-23 23:00:13 +02:00
#
class Announcement < ApplicationRecord
scope :unpublished , - > { where ( published : false ) }
scope :published , - > { where ( published : true ) }
2024-01-08 13:22:16 +02:00
scope :chronological , - > { order ( coalesced_chronology_timestamps . asc ) }
scope :reverse_chronological , - > { order ( coalesced_chronology_timestamps . desc ) }
2020-01-23 23:00:13 +02:00
has_many :announcement_mutes , dependent : :destroy
has_many :announcement_reactions , dependent : :destroy
validates :text , presence : true
2023-12-29 12:55:50 +02:00
validates :starts_at , presence : true , if : :ends_at?
validates :ends_at , presence : true , if : :starts_at?
2020-01-23 23:00:13 +02:00
2020-01-26 21:07:26 +02:00
before_validation :set_published , on : :create
2024-01-08 13:22:16 +02:00
class << self
def coalesced_chronology_timestamps
Arel . sql (
<< ~ SQL . squish
COALESCE ( announcements . starts_at , announcements . scheduled_at , announcements . published_at , announcements . created_at )
SQL
)
end
end
2022-08-25 21:39:40 +03:00
def to_log_human_identifier
text
end
2020-01-27 12:05:33 +02: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 23:00:13 +02:00
def mentions
@mentions || = Account . from_text ( text )
end
2020-03-08 17:10:48 +02:00
def statuses
2023-02-19 00:09:40 +02:00
@statuses || = if status_ids . nil?
[ ]
else
Status . where ( id : status_ids , visibility : [ :public , :unlisted ] )
end
2020-03-08 17:10:48 +02:00
end
2020-01-23 23:00:13 +02: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-13 09:47:32 +02:00
end . to_a
2020-01-23 23:00:13 +02:00
2023-12-13 09:47:32 +02:00
ActiveRecord :: Associations :: Preloader . new ( records : records , associations : :custom_emoji ) . call
2020-01-23 23:00:13 +02:00
records
end
private
2020-01-26 21:07:26 +02:00
def set_published
2020-01-26 23:43:18 +02:00
return unless scheduled_at . blank? || scheduled_at . past?
self . published = true
self . published_at = Time . now . utc
2020-01-23 23:00:13 +02:00
end
end