Add a moderation action to close a post to the public
This commit is contained in:
parent
0e257f6264
commit
b5b756df95
14 changed files with 75 additions and 7 deletions
|
@ -32,6 +32,8 @@ module Admin
|
||||||
'nsfw_on'
|
'nsfw_on'
|
||||||
elsif params[:nsfw_off]
|
elsif params[:nsfw_off]
|
||||||
'nsfw_off'
|
'nsfw_off'
|
||||||
|
elsif params[:expire]
|
||||||
|
'expire'
|
||||||
elsif params[:delete]
|
elsif params[:delete]
|
||||||
'delete'
|
'delete'
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,10 +11,11 @@ module Admin
|
||||||
def index
|
def index
|
||||||
authorize :status, :index?
|
authorize :status, :index?
|
||||||
|
|
||||||
@statuses = @account.statuses.where(visibility: [:public, :unlisted])
|
@statuses = Status.include_expired.where(account: @account).where(visibility: [:public, :unlisted])
|
||||||
|
|
||||||
if params[:media]
|
if params[:media]
|
||||||
@statuses.merge!(Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id))
|
@statuses.merge!(Status.include_expired.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id))
|
||||||
|
@statuses = @statuses.order(id: :desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
@statuses = @statuses.preload(:media_attachments, :mentions).page(params[:page]).per(PER_PAGE)
|
||||||
|
@ -67,6 +68,8 @@ module Admin
|
||||||
'nsfw_on'
|
'nsfw_on'
|
||||||
elsif params[:nsfw_off]
|
elsif params[:nsfw_off]
|
||||||
'nsfw_off'
|
'nsfw_off'
|
||||||
|
elsif params[:expire]
|
||||||
|
'expire'
|
||||||
elsif params[:delete]
|
elsif params[:delete]
|
||||||
'delete'
|
'delete'
|
||||||
end
|
end
|
||||||
|
|
|
@ -611,6 +611,22 @@ html {
|
||||||
.nothing-here {
|
.nothing-here {
|
||||||
border-color: lighten($ui-base-color, 8%);
|
border-color: lighten($ui-base-color, 8%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__row--expired {
|
||||||
|
background: darken($warning-red, 29%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($warning-red, 27%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background: darken($warning-red, 25%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($warning-red, 23%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-stream {
|
.activity-stream {
|
||||||
|
|
|
@ -217,6 +217,22 @@ a.table-action-link {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--expired {
|
||||||
|
background: darken($warning-red, 54%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($warning-red, 52%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(even) {
|
||||||
|
background: darken($warning-red, 50%);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($warning-red, 48%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&__content {
|
&__content {
|
||||||
padding-top: 12px;
|
padding-top: 12px;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
|
|
|
@ -31,7 +31,7 @@ class Admin::ActionLog < ApplicationRecord
|
||||||
|
|
||||||
def set_changes
|
def set_changes
|
||||||
case action
|
case action
|
||||||
when :destroy, :create
|
when :destroy, :create, :expire
|
||||||
self.recorded_changes = target.attributes
|
self.recorded_changes = target.attributes
|
||||||
when :update, :promote, :demote
|
when :update, :promote, :demote
|
||||||
self.recorded_changes = target.previous_changes
|
self.recorded_changes = target.previous_changes
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Admin::ActionLogFilter
|
||||||
disable_user: { target_type: 'User', action: 'disable' }.freeze,
|
disable_user: { target_type: 'User', action: 'disable' }.freeze,
|
||||||
enable_custom_emoji: { target_type: 'CustomEmoji', action: 'enable' }.freeze,
|
enable_custom_emoji: { target_type: 'CustomEmoji', action: 'enable' }.freeze,
|
||||||
enable_user: { target_type: 'User', action: 'enable' }.freeze,
|
enable_user: { target_type: 'User', action: 'enable' }.freeze,
|
||||||
|
expire_status: { target_type: 'Status', action: 'expire' }.freeze,
|
||||||
memorialize_account: { target_type: 'Account', action: 'memorialize' }.freeze,
|
memorialize_account: { target_type: 'Account', action: 'memorialize' }.freeze,
|
||||||
promote_user: { target_type: 'User', action: 'promote' }.freeze,
|
promote_user: { target_type: 'User', action: 'promote' }.freeze,
|
||||||
remove_avatar_user: { target_type: 'User', action: 'remove_avatar' }.freeze,
|
remove_avatar_user: { target_type: 'User', action: 'remove_avatar' }.freeze,
|
||||||
|
|
|
@ -10,6 +10,8 @@ class Form::StatusBatch
|
||||||
case action
|
case action
|
||||||
when 'nsfw_on', 'nsfw_off'
|
when 'nsfw_on', 'nsfw_off'
|
||||||
change_sensitive(action == 'nsfw_on')
|
change_sensitive(action == 'nsfw_on')
|
||||||
|
when 'expire'
|
||||||
|
expire_statuses
|
||||||
when 'delete'
|
when 'delete'
|
||||||
delete_statuses
|
delete_statuses
|
||||||
end
|
end
|
||||||
|
@ -32,8 +34,17 @@ class Form::StatusBatch
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete_statuses
|
def expire_statuses
|
||||||
Status.where(id: status_ids).reorder(nil).find_each do |status|
|
Status.where(id: status_ids).reorder(nil).find_each do |status|
|
||||||
|
RemoveStatusService.new.call(status, mark_expired: true)
|
||||||
|
log_action :expire, status
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_statuses
|
||||||
|
Status.include_expired.where(id: status_ids).reorder(nil).find_each do |status|
|
||||||
status.discard
|
status.discard
|
||||||
RemovalWorker.perform_async(status.id, immediate: true)
|
RemovalWorker.perform_async(status.id, immediate: true)
|
||||||
Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true)
|
Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true)
|
||||||
|
|
|
@ -15,10 +15,10 @@ class RemoveStatusService < BaseService
|
||||||
@status = status
|
@status = status
|
||||||
@account = status.account
|
@account = status.account
|
||||||
@options = options
|
@options = options
|
||||||
@status_expire = status.status_expire
|
@status_expire = status.status_expire || mark_expired? && StatusExpire.new(status_id: status.id, expires_at: Time.now) || nil
|
||||||
@payload = Oj.dump(event: mark_expired? ? :expire : :delete, payload: status.id.to_s)
|
@payload = Oj.dump(event: mark_expired? ? :expire : :delete, payload: status.id.to_s)
|
||||||
|
|
||||||
return if mark_expired? && @status_expire.nil?
|
return if mark_expired? && already_expired?
|
||||||
|
|
||||||
@status.discard unless mark_expired?
|
@status.discard unless mark_expired?
|
||||||
|
|
||||||
|
@ -70,6 +70,10 @@ class RemoveStatusService < BaseService
|
||||||
@options[:mark_expired]
|
@options[:mark_expired]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def already_expired?
|
||||||
|
@status.expired?
|
||||||
|
end
|
||||||
|
|
||||||
def remove_from_self
|
def remove_from_self
|
||||||
FeedManager.instance.unpush_from_home(@account, @status, @options)
|
FeedManager.instance.unpush_from_home(@account, @status, @options)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.batch-table__row
|
.batch-table__row{ class: ('batch-table__row--expired' if status.proper.expired?)}
|
||||||
%label.batch-table__row__select.batch-checkbox
|
%label.batch-table__row__select.batch-checkbox
|
||||||
= f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
|
= f.check_box :status_ids, { multiple: true, include_hidden: false }, status.id
|
||||||
.batch-table__row__content
|
.batch-table__row__content
|
||||||
|
@ -38,3 +38,7 @@
|
||||||
·
|
·
|
||||||
= fa_icon('eye-slash fw')
|
= fa_icon('eye-slash fw')
|
||||||
= t('stream_entries.sensitive_content')
|
= t('stream_entries.sensitive_content')
|
||||||
|
- if status.proper.expired?
|
||||||
|
·
|
||||||
|
= fa_icon('clock-o fw')
|
||||||
|
= t('stream_entries.expired')
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
.batch-table__toolbar__actions
|
.batch-table__toolbar__actions
|
||||||
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
= f.button safe_join([fa_icon('clock-o'), t('admin.statuses.batch.expire')]), name: :expire, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
.batch-table__body
|
.batch-table__body
|
||||||
= render partial: 'admin/reports/status', collection: @report.statuses, locals: { f: f }
|
= render partial: 'admin/reports/status', collection: @report.statuses, locals: { f: f }
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
.batch-table__toolbar__actions
|
.batch-table__toolbar__actions
|
||||||
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
= f.button safe_join([fa_icon('clock-o'), t('admin.statuses.batch.expire')]), name: :expire, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
.batch-table__body
|
.batch-table__body
|
||||||
= render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
|
= render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
.batch-table__toolbar__actions
|
.batch-table__toolbar__actions
|
||||||
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye-slash'), t('admin.statuses.batch.nsfw_on')]), name: :nsfw_on, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('eye'), t('admin.statuses.batch.nsfw_off')]), name: :nsfw_off, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
|
= f.button safe_join([fa_icon('clock-o'), t('admin.statuses.batch.expire')]), name: :expire, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
= f.button safe_join([fa_icon('trash'), t('admin.statuses.batch.delete')]), name: :delete, class: 'table-action-link', type: :submit, data: { confirm: t('admin.reports.are_you_sure') }
|
||||||
.batch-table__body
|
.batch-table__body
|
||||||
= render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
|
= render partial: 'admin/reports/status', collection: @statuses, locals: { f: f }
|
||||||
|
|
|
@ -260,6 +260,7 @@ en:
|
||||||
enable_custom_emoji: Enable Custom Emoji
|
enable_custom_emoji: Enable Custom Emoji
|
||||||
enable_sign_in_token_auth_user: Enable E-mail Token Authentication for User
|
enable_sign_in_token_auth_user: Enable E-mail Token Authentication for User
|
||||||
enable_user: Enable User
|
enable_user: Enable User
|
||||||
|
expire_status: Close Post
|
||||||
memorialize_account: Memorialize Account
|
memorialize_account: Memorialize Account
|
||||||
promote_user: Promote User
|
promote_user: Promote User
|
||||||
remove_avatar_user: Remove Avatar
|
remove_avatar_user: Remove Avatar
|
||||||
|
@ -305,6 +306,7 @@ en:
|
||||||
enable_custom_emoji_html: "%{name} enabled emoji %{target}"
|
enable_custom_emoji_html: "%{name} enabled emoji %{target}"
|
||||||
enable_sign_in_token_auth_user_html: "%{name} enabled e-mail token authentication for %{target}"
|
enable_sign_in_token_auth_user_html: "%{name} enabled e-mail token authentication for %{target}"
|
||||||
enable_user_html: "%{name} enabled login for user %{target}"
|
enable_user_html: "%{name} enabled login for user %{target}"
|
||||||
|
expire_status_html: "%{name} closed post by %{target}"
|
||||||
memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page"
|
memorialize_account_html: "%{name} turned %{target}'s account into a memoriam page"
|
||||||
promote_user_html: "%{name} promoted user %{target}"
|
promote_user_html: "%{name} promoted user %{target}"
|
||||||
remove_avatar_user_html: "%{name} removed %{target}'s avatar"
|
remove_avatar_user_html: "%{name} removed %{target}'s avatar"
|
||||||
|
@ -694,6 +696,7 @@ en:
|
||||||
back_to_account: Back to account page
|
back_to_account: Back to account page
|
||||||
batch:
|
batch:
|
||||||
delete: Delete
|
delete: Delete
|
||||||
|
expire: Close
|
||||||
nsfw_off: Mark as not sensitive
|
nsfw_off: Mark as not sensitive
|
||||||
nsfw_on: Mark as sensitive
|
nsfw_on: Mark as sensitive
|
||||||
deleted: Deleted
|
deleted: Deleted
|
||||||
|
@ -1442,6 +1445,7 @@ en:
|
||||||
invalid_expire_at: Invalid expires are specified.
|
invalid_expire_at: Invalid expires are specified.
|
||||||
invalid_expire_action: Invalid expires_action are specified.
|
invalid_expire_action: Invalid expires_action are specified.
|
||||||
stream_entries:
|
stream_entries:
|
||||||
|
expired: Expired
|
||||||
pinned: Pinned post
|
pinned: Pinned post
|
||||||
reblogged: boosted
|
reblogged: boosted
|
||||||
sensitive_content: Sensitive content
|
sensitive_content: Sensitive content
|
||||||
|
|
|
@ -246,6 +246,7 @@ ja:
|
||||||
disable_user: ユーザーを無効化
|
disable_user: ユーザーを無効化
|
||||||
enable_custom_emoji: カスタム絵文字を有効化
|
enable_custom_emoji: カスタム絵文字を有効化
|
||||||
enable_user: ユーザーを有効化
|
enable_user: ユーザーを有効化
|
||||||
|
expire_status: 投稿を公開終了
|
||||||
memorialize_account: 追悼アカウント化
|
memorialize_account: 追悼アカウント化
|
||||||
promote_user: ユーザーを昇格
|
promote_user: ユーザーを昇格
|
||||||
remove_avatar_user: アイコンを削除
|
remove_avatar_user: アイコンを削除
|
||||||
|
@ -289,6 +290,7 @@ ja:
|
||||||
disable_user_html: "%{name} さんが %{target} さんのログインを無効化しました"
|
disable_user_html: "%{name} さんが %{target} さんのログインを無効化しました"
|
||||||
enable_custom_emoji_html: "%{name} さんがカスタム絵文字 %{target} を有効化しました"
|
enable_custom_emoji_html: "%{name} さんがカスタム絵文字 %{target} を有効化しました"
|
||||||
enable_user_html: "%{name} さんが %{target} さんのログインを有効化しました"
|
enable_user_html: "%{name} さんが %{target} さんのログインを有効化しました"
|
||||||
|
expire_status_html: "%{name} さんが %{target} さんの投稿を公開終了しました"
|
||||||
memorialize_account_html: "%{name} さんが %{target} さんを追悼アカウントページに登録しました"
|
memorialize_account_html: "%{name} さんが %{target} さんを追悼アカウントページに登録しました"
|
||||||
promote_user_html: "%{name} さんが %{target} さんを昇格しました"
|
promote_user_html: "%{name} さんが %{target} さんを昇格しました"
|
||||||
remove_avatar_user_html: "%{name} さんが %{target} さんのアイコンを削除しました"
|
remove_avatar_user_html: "%{name} さんが %{target} さんのアイコンを削除しました"
|
||||||
|
@ -672,6 +674,7 @@ ja:
|
||||||
back_to_account: アカウントページに戻る
|
back_to_account: アカウントページに戻る
|
||||||
batch:
|
batch:
|
||||||
delete: 削除
|
delete: 削除
|
||||||
|
expire: 公開終了
|
||||||
nsfw_off: 閲覧注意をはずす
|
nsfw_off: 閲覧注意をはずす
|
||||||
nsfw_on: 閲覧注意にする
|
nsfw_on: 閲覧注意にする
|
||||||
deleted: 削除済み
|
deleted: 削除済み
|
||||||
|
@ -1345,6 +1348,7 @@ ja:
|
||||||
invalid_expire_at: 不正な公開期限が指定されています
|
invalid_expire_at: 不正な公開期限が指定されています
|
||||||
invalid_expire_action: 不正な公開期限時のアクションが指定されています
|
invalid_expire_action: 不正な公開期限時のアクションが指定されています
|
||||||
stream_entries:
|
stream_entries:
|
||||||
|
expired: 公開終了
|
||||||
pinned: 固定された投稿
|
pinned: 固定された投稿
|
||||||
reblogged: さんがブースト
|
reblogged: さんがブースト
|
||||||
sensitive_content: 閲覧注意
|
sensitive_content: 閲覧注意
|
||||||
|
|
Loading…
Reference in a new issue