Add soft delete for statuses for instant deletes through API (#11623)

* Add soft delete for statuses to allow them to appear instant

* Allow reporting soft-deleted statuses and show them in the admin UI

* Change index for getting an account's statuses
This commit is contained in:
Eugen Rochko
2019-08-22 21:55:56 +02:00
committed by GitHub
parent 5ab1e0e738
commit 282ea17078
14 changed files with 42 additions and 8 deletions

View File

@ -21,7 +21,7 @@ class Api::V1::ReportsController < Api::BaseController
private
def reported_status_ids
reported_account.statuses.find(status_ids).pluck(:id)
reported_account.statuses.with_discarded.find(status_ids).pluck(:id)
end
def status_ids

View File

@ -18,6 +18,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
@reblogs_map = { @status.id => false }
authorize status_for_destroy, :unreblog?
status_for_destroy.discard
RemovalWorker.perform_async(status_for_destroy.id)
render json: @status, serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new([@status], current_user&.account_id, reblogs_map: @reblogs_map)
@ -30,7 +31,7 @@ class Api::V1::Statuses::ReblogsController < Api::BaseController
end
def status_for_destroy
current_user.account.statuses.where(reblog_of_id: params[:status_id]).first!
@status_for_destroy ||= current_user.account.statuses.where(reblog_of_id: params[:status_id]).first!
end
def reblog_params

View File

@ -53,6 +53,7 @@ class Api::V1::StatusesController < Api::BaseController
@status = Status.where(account_id: current_user.account).find(params[:id])
authorize @status, :destroy?
@status.discard
RemovalWorker.perform_async(@status.id, redraft: true)
render json: @status, serializer: REST::StatusSerializer, source_requested: true

View File

@ -34,6 +34,7 @@ class Form::StatusBatch
def delete_statuses
Status.where(id: status_ids).reorder(nil).find_each do |status|
status.discard
RemovalWorker.perform_async(status.id, redraft: false)
Tombstone.find_or_create_by(uri: status.uri, account: status.account, by_moderator: true)
log_action :destroy, status

View File

@ -43,7 +43,7 @@ class Report < ApplicationRecord
end
def statuses
Status.where(id: status_ids).includes(:account, :media_attachments, :mentions)
Status.with_discarded.where(id: status_ids).includes(:account, :media_attachments, :mentions)
end
def media_attachments

View File

@ -22,15 +22,19 @@
# application_id :bigint(8)
# in_reply_to_account_id :bigint(8)
# poll_id :bigint(8)
# deleted_at :datetime
#
class Status < ApplicationRecord
before_destroy :unlink_from_conversations
include Discard::Model
include Paginable
include Cacheable
include StatusThreadingConcern
self.discard_column = :deleted_at
# If `override_timestamps` is set at creation time, Snowflake ID creation
# will be based on current time instead of `created_at`
attr_accessor :override_timestamps
@ -72,7 +76,7 @@ class Status < ApplicationRecord
accepts_nested_attributes_for :poll
default_scope { recent }
default_scope { recent.kept }
scope :recent, -> { reorder(id: :desc) }
scope :remote, -> { where(local: false).where.not(uri: nil) }

View File

@ -16,11 +16,14 @@
- video = status.proper.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description
- else
= react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
= react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
.detailed-status__meta
= link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
- if status.discarded?
·
%span.negative-hint= t('admin.statuses.deleted')
·
- if status.reblog?
= fa_icon('retweet fw')

View File

@ -4,7 +4,7 @@ class RemovalWorker
include Sidekiq::Worker
def perform(status_id, options = {})
RemoveStatusService.new.call(Status.find(status_id), **options.symbolize_keys)
RemoveStatusService.new.call(Status.with_discarded.find(status_id), **options.symbolize_keys)
rescue ActiveRecord::RecordNotFound
true
end