You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
3.1 KiB
98 lines
3.1 KiB
# 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 |
|
# published_at :datetime |
|
# status_ids :bigint(8) is an Array |
|
# |
|
|
|
class Announcement < ApplicationRecord |
|
scope :unpublished, -> { where(published: false) } |
|
scope :published, -> { where(published: true) } |
|
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 IS NULL') } |
|
scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC')) } |
|
scope :reverse_chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) DESC')) } |
|
|
|
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? } |
|
|
|
before_validation :set_all_day |
|
before_validation :set_published, on: :create |
|
|
|
def publish! |
|
update!(published: true, published_at: Time.now.utc, scheduled_at: nil) |
|
end |
|
|
|
def unpublish! |
|
update!(published: false, scheduled_at: nil) |
|
end |
|
|
|
def time_range? |
|
starts_at.present? && ends_at.present? |
|
end |
|
|
|
def mentions |
|
@mentions ||= Account.from_text(text) |
|
end |
|
|
|
def statuses |
|
@statuses ||= begin |
|
if status_ids.nil? |
|
[] |
|
else |
|
Status.where(id: status_ids, visibility: [:public, :unlisted]) |
|
end |
|
end |
|
end |
|
|
|
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 |
|
end |
|
|
|
ActiveRecord::Associations::Preloader.new.preload(records, :custom_emoji) |
|
records |
|
end |
|
|
|
private |
|
|
|
def set_all_day |
|
self.all_day = false if starts_at.blank? || ends_at.blank? |
|
end |
|
|
|
def set_published |
|
return unless scheduled_at.blank? || scheduled_at.past? |
|
|
|
self.published = true |
|
self.published_at = Time.now.utc |
|
end |
|
end
|
|
|