From b9d74d407673a6dbdc87c3310618b22c85358c85 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 26 Jan 2020 20:07:26 +0100 Subject: Add streaming API updates for announcements being modified or deleted (#12963) Change `all_day` to be a visual client-side cue only Publish immediately if `scheduled_at` is in the past Add `published_at` and `updated_at` to announcements JSON --- app/models/announcement.rb | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'app/models/announcement.rb') diff --git a/app/models/announcement.rb b/app/models/announcement.rb index 4da9f94d6..c5cf08f7c 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -16,8 +16,6 @@ # class Announcement < ApplicationRecord - after_commit :queue_publish, on: :create - 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') } @@ -31,8 +29,11 @@ class Announcement < ApplicationRecord validates :ends_at, presence: true, if: -> { starts_at.present? } before_validation :set_all_day - before_validation :set_starts_at, on: :create - before_validation :set_ends_at, on: :create + before_validation :set_published, on: :create + + def published_at + scheduled_at || created_at + end def time_range? starts_at.present? && ends_at.present? @@ -71,15 +72,7 @@ class Announcement < ApplicationRecord self.all_day = false if starts_at.blank? || ends_at.blank? end - def set_starts_at - self.starts_at = starts_at.change(hour: 0, min: 0, sec: 0) if all_day? && starts_at.present? - end - - def set_ends_at - self.ends_at = ends_at.change(hour: 23, min: 59, sec: 59) if all_day? && ends_at.present? - end - - def queue_publish - PublishScheduledAnnouncementWorker.perform_async(id) if scheduled_at.blank? + def set_published + self.published = true if scheduled_at.blank? || scheduled_at.past? end end -- cgit From 401f32f9eedf9f41c097ee01c1f6203eae568663 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 26 Jan 2020 22:43:18 +0100 Subject: Fix expired announcements being re-published (#12964) --- app/models/announcement.rb | 12 ++++++------ app/workers/publish_scheduled_announcement_worker.rb | 3 ++- app/workers/scheduler/scheduled_statuses_scheduler.rb | 2 +- .../20200126203551_add_published_at_to_announcements.rb | 5 +++++ db/schema.rb | 3 ++- 5 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20200126203551_add_published_at_to_announcements.rb (limited to 'app/models/announcement.rb') diff --git a/app/models/announcement.rb b/app/models/announcement.rb index c5cf08f7c..670b24f01 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -13,13 +13,14 @@ # ends_at :datetime # created_at :datetime not null # updated_at :datetime not null +# published_at :datetime # 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.created_at) ASC')) } + scope :chronological, -> { order(Arel.sql('COALESCE(announcements.starts_at, announcements.scheduled_at, announcements.published_at, announcements.created_at) ASC')) } has_many :announcement_mutes, dependent: :destroy has_many :announcement_reactions, dependent: :destroy @@ -31,10 +32,6 @@ class Announcement < ApplicationRecord before_validation :set_all_day before_validation :set_published, on: :create - def published_at - scheduled_at || created_at - end - def time_range? starts_at.present? && ends_at.present? end @@ -73,6 +70,9 @@ class Announcement < ApplicationRecord end def set_published - self.published = true if scheduled_at.blank? || scheduled_at.past? + return unless scheduled_at.blank? || scheduled_at.past? + + self.published = true + self.published_at = Time.now.utc end end diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb index 6b5898bf5..4fc6bef2f 100644 --- a/app/workers/publish_scheduled_announcement_worker.rb +++ b/app/workers/publish_scheduled_announcement_worker.rb @@ -6,7 +6,8 @@ class PublishScheduledAnnouncementWorker def perform(announcement_id) announcement = Announcement.find(announcement_id) - announcement.update(published: true) + + announcement.update(published: true, published_at: Time.now.utc, scheduled_at: nil) unless announcement.published? payload = InlineRenderer.render(announcement, nil, :announcement) payload = Oj.dump(event: :announcement, payload: payload) diff --git a/app/workers/scheduler/scheduled_statuses_scheduler.rb b/app/workers/scheduler/scheduled_statuses_scheduler.rb index 4262f1d01..9cfe949de 100644 --- a/app/workers/scheduler/scheduled_statuses_scheduler.rb +++ b/app/workers/scheduler/scheduled_statuses_scheduler.rb @@ -34,7 +34,7 @@ class Scheduler::ScheduledStatusesScheduler end def unpublish_expired_announcements! - expired_announcements.in_batches.update_all(published: false) + expired_announcements.in_batches.update_all(published: false, scheduled_at: nil) end def expired_announcements diff --git a/db/migrate/20200126203551_add_published_at_to_announcements.rb b/db/migrate/20200126203551_add_published_at_to_announcements.rb new file mode 100644 index 000000000..d99f95694 --- /dev/null +++ b/db/migrate/20200126203551_add_published_at_to_announcements.rb @@ -0,0 +1,5 @@ +class AddPublishedAtToAnnouncements < ActiveRecord::Migration[5.2] + def change + add_column :announcements, :published_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index d3a2c05b3..b09ee0e76 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_01_19_112504) do +ActiveRecord::Schema.define(version: 2020_01_26_203551) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -228,6 +228,7 @@ ActiveRecord::Schema.define(version: 2020_01_19_112504) do t.datetime "ends_at" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.datetime "published_at" end create_table "backups", force: :cascade do |t| -- cgit From 663ea84b08162578cd06b54bfb998072b2bef8b9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 27 Jan 2020 11:05:33 +0100 Subject: Add publish/unpublish controls to announcements in admin UI (#12967) --- app/controllers/admin/announcements_controller.rb | 22 +++++++++++++++++++--- app/models/announcement.rb | 8 ++++++++ .../admin/announcements/_announcement.html.haml | 9 ++++++++- app/views/admin/announcements/edit.html.haml | 2 +- .../publish_scheduled_announcement_worker.rb | 2 +- config/locales/en.yml | 5 +++++ config/routes.rb | 8 +++++++- 7 files changed, 49 insertions(+), 7 deletions(-) (limited to 'app/models/announcement.rb') diff --git a/app/controllers/admin/announcements_controller.rb b/app/controllers/admin/announcements_controller.rb index 212a9f693..494fd13d0 100644 --- a/app/controllers/admin/announcements_controller.rb +++ b/app/controllers/admin/announcements_controller.rb @@ -22,7 +22,7 @@ class Admin::AnnouncementsController < Admin::BaseController if @announcement.save PublishScheduledAnnouncementWorker.perform_async(@announcement.id) if @announcement.published? log_action :create, @announcement - redirect_to admin_announcements_path + redirect_to admin_announcements_path, notice: @announcement.published? ? I18n.t('admin.announcements.published_msg') : I18n.t('admin.announcements.scheduled_msg') else render :new end @@ -38,18 +38,34 @@ class Admin::AnnouncementsController < Admin::BaseController if @announcement.update(resource_params) PublishScheduledAnnouncementWorker.perform_async(@announcement.id) if @announcement.published? log_action :update, @announcement - redirect_to admin_announcements_path + redirect_to admin_announcements_path, notice: I18n.t('admin.announcements.updated_msg') else render :edit end end + def publish + authorize :announcement, :update? + @announcement.publish! + PublishScheduledAnnouncementWorker.perform_async(@announcement.id) + log_action :update, @announcement + redirect_to admin_announcements_path, notice: I18n.t('admin.announcements.published_msg') + end + + def unpublish + authorize :announcement, :update? + @announcement.unpublish! + UnpublishAnnouncementWorker.perform_async(@announcement.id) + log_action :update, @announcement + redirect_to admin_announcements_path, notice: I18n.t('admin.announcements.unpublished_msg') + end + def destroy authorize :announcement, :destroy? @announcement.destroy! UnpublishAnnouncementWorker.perform_async(@announcement.id) if @announcement.published? log_action :destroy, @announcement - redirect_to admin_announcements_path + redirect_to admin_announcements_path, notice: I18n.t('admin.announcements.destroyed_msg') end private diff --git a/app/models/announcement.rb b/app/models/announcement.rb index 670b24f01..d99502f44 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -32,6 +32,14 @@ class Announcement < ApplicationRecord 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 diff --git a/app/views/admin/announcements/_announcement.html.haml b/app/views/admin/announcements/_announcement.html.haml index 75768c7ba..f8a6c66de 100644 --- a/app/views/admin/announcements/_announcement.html.haml +++ b/app/views/admin/announcements/_announcement.html.haml @@ -10,5 +10,12 @@ - else = l(announcement.created_at) %td - = table_link_to 'pencil', t('generic.edit'), edit_admin_announcement_path(announcement) if can?(:update, announcement) + - if can?(:update, announcement) + - if announcement.published? + = table_link_to 'pause', t('admin.announcements.unpublish'), unpublish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } + - else + = table_link_to 'play', t('admin.announcements.publish'), publish_admin_announcement_path(announcement), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } + + = table_link_to 'pencil', t('generic.edit'), edit_admin_announcement_path(announcement) + = table_link_to 'trash', t('generic.delete'), admin_announcement_path(announcement), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:destroy, announcement) diff --git a/app/views/admin/announcements/edit.html.haml b/app/views/admin/announcements/edit.html.haml index c5c605e93..5f56db5e7 100644 --- a/app/views/admin/announcements/edit.html.haml +++ b/app/views/admin/announcements/edit.html.haml @@ -14,7 +14,7 @@ .fields-group = f.input :text, wrapper: :with_block_label - - if @announcement.scheduled_at.present? && !@announcement.published? + - unless @announcement.published? .fields-group = f.input :scheduled_at, include_blank: true, wrapper: :with_block_label diff --git a/app/workers/publish_scheduled_announcement_worker.rb b/app/workers/publish_scheduled_announcement_worker.rb index 4fc6bef2f..efca39d3d 100644 --- a/app/workers/publish_scheduled_announcement_worker.rb +++ b/app/workers/publish_scheduled_announcement_worker.rb @@ -7,7 +7,7 @@ class PublishScheduledAnnouncementWorker def perform(announcement_id) announcement = Announcement.find(announcement_id) - announcement.update(published: true, published_at: Time.now.utc, scheduled_at: nil) unless announcement.published? + announcement.publish! unless announcement.published? payload = InlineRenderer.render(announcement, nil, :announcement) payload = Oj.dump(event: :announcement, payload: payload) diff --git a/config/locales/en.yml b/config/locales/en.yml index 0ba573020..4687b471a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -232,6 +232,7 @@ en: deleted_status: "(deleted status)" title: Audit log announcements: + destroyed_msg: Announcement successfully deleted! edit: title: Edit announcement empty: No announcements found. @@ -240,8 +241,12 @@ en: create: Create announcement title: New announcement published: Published + published_msg: Announcement successfully published! + scheduled_msg: Announcement scheduled for publication! time_range: Time range title: Announcements + unpublished_msg: Announcement successfully unpublished! + updated_msg: Announcement successfully updated! custom_emojis: assign_category: Assign category by_domain: Domain diff --git a/config/routes.rb b/config/routes.rb index da7bf6f88..c22efc1e1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,7 +177,13 @@ Rails.application.routes.draw do resources :email_domain_blocks, only: [:index, :new, :create, :destroy] resources :action_logs, only: [:index] resources :warning_presets, except: [:new] - resources :announcements, except: [:show] + + resources :announcements, except: [:show] do + member do + post :publish + post :unpublish + end + end resource :settings, only: [:edit, :update] -- cgit