optional delayed publishing of roars for proofreading
parent
02729ab3ae
commit
74290d4eb3
|
@ -54,6 +54,7 @@ class Settings::PreferencesController < Settings::BaseController
|
|||
:setting_hide_public_outbox,
|
||||
:setting_max_public_history,
|
||||
:setting_roar_lifespan,
|
||||
:setting_delayed_roars,
|
||||
|
||||
:setting_default_privacy,
|
||||
:setting_default_sensitive,
|
||||
|
|
|
@ -38,6 +38,7 @@ class UserSettingsDecorator
|
|||
user.settings['larger_emoji'] = larger_emoji_preference if change?('setting_larger_emoji')
|
||||
user.settings['max_public_history'] = max_public_history_preference if change?('setting_max_public_history')
|
||||
user.settings['roar_lifespan'] = roar_lifespan_preference if change?('setting_roar_lifespan')
|
||||
user.settings['delayed_roars'] = delayed_roars_preference if change?('setting_delayed_roars')
|
||||
|
||||
user.settings['notification_emails'] = merged_notification_emails if change?('notification_emails')
|
||||
user.settings['interactions'] = merged_interactions if change?('interactions')
|
||||
|
@ -135,6 +136,10 @@ class UserSettingsDecorator
|
|||
settings['setting_roar_lifespan']
|
||||
end
|
||||
|
||||
def delayed_roars_preference
|
||||
settings['setting_delayed_roars']
|
||||
end
|
||||
|
||||
def merged_notification_emails
|
||||
user.settings['notification_emails'].merge coerced_settings('notification_emails').to_h
|
||||
end
|
||||
|
|
|
@ -130,6 +130,7 @@ class Account < ApplicationRecord
|
|||
:always_local_only?,
|
||||
:max_public_history,
|
||||
:roar_lifespan,
|
||||
:delayed_roars?,
|
||||
|
||||
:hides_public_profile?,
|
||||
:hides_public_outbox?,
|
||||
|
|
|
@ -126,6 +126,7 @@ class User < ApplicationRecord
|
|||
:hide_public_outbox,
|
||||
:max_public_history,
|
||||
:roar_lifespan,
|
||||
:delayed_roars,
|
||||
|
||||
:auto_play_gif,
|
||||
:default_sensitive,
|
||||
|
@ -304,6 +305,10 @@ class User < ApplicationRecord
|
|||
@_roar_lifespan ||= (settings.roar_lifespan || 0)
|
||||
end
|
||||
|
||||
def delayed_roars?
|
||||
@delayed_roars ||= (settings.delayed_roars || false)
|
||||
end
|
||||
|
||||
def defaults_to_local_only?
|
||||
@defaults_to_local_only ||= (settings.default_local || false)
|
||||
end
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
class FanOutOnWriteService < BaseService
|
||||
# Push a status into home and mentions feeds
|
||||
# @param [Status] status
|
||||
def call(status)
|
||||
def call(status, delayed = false)
|
||||
raise Mastodon::RaceConditionError if status.visibility.nil?
|
||||
|
||||
deliver_to_self(status) if status.account.local?
|
||||
return if delayed
|
||||
|
||||
render_anonymous_payload(status)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ class PostStatusService < BaseService
|
|||
# @option [String] :delete_after
|
||||
# @option [Boolean] :nocrawl Optional skip link card generation
|
||||
# @option [Boolean] :nomentions Optional skip mention processing
|
||||
# @option [Boolean] :delayed Optional publishing delay of 30 secs
|
||||
# @option [Hash] :poll Optional poll to attach
|
||||
# @option [Enumerable] :media_ids Optional array of media IDs to attach
|
||||
# @option [Doorkeeper::Application] :application
|
||||
|
@ -57,9 +58,24 @@ class PostStatusService < BaseService
|
|||
schedule_status!
|
||||
else
|
||||
return unless process_status!
|
||||
if @options[:delayed] || @account&.user&.delayed_roars?
|
||||
delay_until = Time.now.utc + 30.seconds
|
||||
opts = {
|
||||
visibility: @visibility,
|
||||
federate: @options[:federate],
|
||||
distribute: @options[:distribute],
|
||||
nocrawl: @options[:nocrawl],
|
||||
nomentions: @options[:nomentions],
|
||||
delete_after: @delete_after.nil? ? nil : @delete_after + 30.seconds,
|
||||
}.compact
|
||||
|
||||
PostStatusWorker.perform_at(delay_until, @status.id, opts)
|
||||
DistributionWorker.perform_async(@status.id, delayed = true) unless @options[:distribute] == false
|
||||
else
|
||||
postprocess_status!
|
||||
bump_potential_friendship!
|
||||
end
|
||||
end
|
||||
|
||||
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
|
||||
|
||||
|
@ -149,7 +165,7 @@ class PostStatusService < BaseService
|
|||
return false if @status.destroyed?
|
||||
|
||||
process_hashtags_service.call(@status, @tags, @preloaded_tags)
|
||||
process_mentions_service.call(@status) unless @options[:nomentions]
|
||||
process_mentions_service.call(@status) unless @delayed || @options[:nomentions]
|
||||
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
= f.input :setting_always_local, as: :boolean, wrapper: :with_label
|
||||
= f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
|
||||
|
||||
.fields-group
|
||||
= f.input :setting_delayed_roars, as: :boolean, wrapper: :with_label
|
||||
|
||||
%hr#settings_other/
|
||||
|
||||
.fields-group
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
class DistributionWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
def perform(status_id)
|
||||
def perform(status_id, delayed = false)
|
||||
RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
|
||||
if lock.acquired?
|
||||
FanOutOnWriteService.new.call(Status.find(status_id))
|
||||
FanOutOnWriteService.new.call(Status.find(status_id), delayed)
|
||||
else
|
||||
raise Mastodon::RaceConditionError
|
||||
end
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PostStatusWorker
|
||||
include Sidekiq::Worker
|
||||
|
||||
sidekiq_options unique: :until_executed
|
||||
|
||||
def perform(status_id, options = {})
|
||||
status = Status.find(status_id)
|
||||
return false if status.destroyed?
|
||||
|
||||
if options[:visibility]
|
||||
status.visibility = options[:visibility]
|
||||
status.save!
|
||||
end
|
||||
|
||||
process_mentions_service.call(status) unless options[:nomentions]
|
||||
|
||||
LinkCrawlWorker.perform_async(status.id) unless options[:nocrawl] || status.spoiler_text?
|
||||
DistributionWorker.perform_async(status.id) unless options[:distribute] == false
|
||||
|
||||
unless status.local_only? || options[:distribute] == false || options[:federate] == false
|
||||
ActivityPub::DistributionWorker.perform_async(status.id)
|
||||
end
|
||||
|
||||
PollExpirationNotifyWorker.perform_at(status.poll.expires_at, status.poll.id) if status.poll
|
||||
|
||||
status.delete_after = options[:delete_after] if options[:delete_after]
|
||||
|
||||
return true if !status.reply? || status.account.id == status.in_reply_to_account_id
|
||||
ActivityTracker.increment('activity:interactions')
|
||||
return if status.account.following?(status.in_reply_to_account_id)
|
||||
PotentialFriendshipTracker.record(status.account.id, status.in_reply_to_account_id, :reply)
|
||||
|
||||
true
|
||||
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
|
||||
true
|
||||
end
|
||||
|
||||
def process_mentions_service
|
||||
ProcessMentionsService.new
|
||||
end
|
||||
end
|
|
@ -118,6 +118,7 @@ en:
|
|||
setting_default_language: Posting language
|
||||
setting_default_privacy: Post privacy
|
||||
setting_roar_lifespan: Auto-delete new roars after
|
||||
setting_delayed_roars: Delayed publishing of roars for proofreading (30 secs)
|
||||
setting_default_local: Default to Monsterpit-only roars (in Glitch flavour)
|
||||
setting_always_local: Don't send your roars outside Monsterpit
|
||||
setting_rawr_federated: Show raw world timeline (may contain offensive content!)
|
||||
|
|
Loading…
Reference in New Issue