The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

86 lines
2.8 KiB

  1. # frozen_string_literal: true
  2. # == Schema Information
  3. #
  4. # Table name: announcements
  5. #
  6. # id :bigint(8) not null, primary key
  7. # text :text default(""), not null
  8. # published :boolean default(FALSE), not null
  9. # all_day :boolean default(FALSE), not null
  10. # scheduled_at :datetime
  11. # starts_at :datetime
  12. # ends_at :datetime
  13. # created_at :datetime not null
  14. # updated_at :datetime not null
  15. #
  16. class Announcement < ApplicationRecord
  17. after_commit :queue_publish, on: :create
  18. scope :unpublished, -> { where(published: false) }
  19. scope :published, -> { where(published: true) }
  20. 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') }
  21. scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.created_at) ASC')) }
  22. has_many :announcement_mutes, dependent: :destroy
  23. has_many :announcement_reactions, dependent: :destroy
  24. validates :text, presence: true
  25. validates :starts_at, presence: true, if: -> { ends_at.present? }
  26. validates :ends_at, presence: true, if: -> { starts_at.present? }
  27. before_validation :set_all_day
  28. before_validation :set_starts_at, on: :create
  29. before_validation :set_ends_at, on: :create
  30. def time_range?
  31. starts_at.present? && ends_at.present?
  32. end
  33. def mentions
  34. @mentions ||= Account.from_text(text)
  35. end
  36. def tags
  37. @tags ||= Tag.find_or_create_by_names(Extractor.extract_hashtags(text))
  38. end
  39. def emojis
  40. @emojis ||= CustomEmoji.from_text(text)
  41. end
  42. def reactions(account = nil)
  43. records = begin
  44. scope = announcement_reactions.group(:announcement_id, :name, :custom_emoji_id).order(Arel.sql('MIN(created_at) ASC'))
  45. if account.nil?
  46. scope.select('name, custom_emoji_id, count(*) as count, false as me')
  47. else
  48. 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")
  49. end
  50. end
  51. ActiveRecord::Associations::Preloader.new.preload(records, :custom_emoji)
  52. records
  53. end
  54. private
  55. def set_all_day
  56. self.all_day = false if starts_at.blank? || ends_at.blank?
  57. end
  58. def set_starts_at
  59. self.starts_at = starts_at.change(hour: 0, min: 0, sec: 0) if all_day? && starts_at.present?
  60. end
  61. def set_ends_at
  62. self.ends_at = ends_at.change(hour: 23, min: 59, sec: 59) if all_day? && ends_at.present?
  63. end
  64. def queue_publish
  65. PublishScheduledAnnouncementWorker.perform_async(id) if scheduled_at.blank?
  66. end
  67. end