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