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_hide_public_outbox,
|
||||||
:setting_max_public_history,
|
:setting_max_public_history,
|
||||||
:setting_roar_lifespan,
|
:setting_roar_lifespan,
|
||||||
|
:setting_delayed_roars,
|
||||||
|
|
||||||
:setting_default_privacy,
|
:setting_default_privacy,
|
||||||
:setting_default_sensitive,
|
:setting_default_sensitive,
|
||||||
|
|
|
@ -38,6 +38,7 @@ class UserSettingsDecorator
|
||||||
user.settings['larger_emoji'] = larger_emoji_preference if change?('setting_larger_emoji')
|
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['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['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['notification_emails'] = merged_notification_emails if change?('notification_emails')
|
||||||
user.settings['interactions'] = merged_interactions if change?('interactions')
|
user.settings['interactions'] = merged_interactions if change?('interactions')
|
||||||
|
@ -135,6 +136,10 @@ class UserSettingsDecorator
|
||||||
settings['setting_roar_lifespan']
|
settings['setting_roar_lifespan']
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delayed_roars_preference
|
||||||
|
settings['setting_delayed_roars']
|
||||||
|
end
|
||||||
|
|
||||||
def merged_notification_emails
|
def merged_notification_emails
|
||||||
user.settings['notification_emails'].merge coerced_settings('notification_emails').to_h
|
user.settings['notification_emails'].merge coerced_settings('notification_emails').to_h
|
||||||
end
|
end
|
||||||
|
|
|
@ -130,6 +130,7 @@ class Account < ApplicationRecord
|
||||||
:always_local_only?,
|
:always_local_only?,
|
||||||
:max_public_history,
|
:max_public_history,
|
||||||
:roar_lifespan,
|
:roar_lifespan,
|
||||||
|
:delayed_roars?,
|
||||||
|
|
||||||
:hides_public_profile?,
|
:hides_public_profile?,
|
||||||
:hides_public_outbox?,
|
:hides_public_outbox?,
|
||||||
|
|
|
@ -126,6 +126,7 @@ class User < ApplicationRecord
|
||||||
:hide_public_outbox,
|
:hide_public_outbox,
|
||||||
:max_public_history,
|
:max_public_history,
|
||||||
:roar_lifespan,
|
:roar_lifespan,
|
||||||
|
:delayed_roars,
|
||||||
|
|
||||||
:auto_play_gif,
|
:auto_play_gif,
|
||||||
:default_sensitive,
|
:default_sensitive,
|
||||||
|
@ -304,6 +305,10 @@ class User < ApplicationRecord
|
||||||
@_roar_lifespan ||= (settings.roar_lifespan || 0)
|
@_roar_lifespan ||= (settings.roar_lifespan || 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delayed_roars?
|
||||||
|
@delayed_roars ||= (settings.delayed_roars || false)
|
||||||
|
end
|
||||||
|
|
||||||
def defaults_to_local_only?
|
def defaults_to_local_only?
|
||||||
@defaults_to_local_only ||= (settings.default_local || false)
|
@defaults_to_local_only ||= (settings.default_local || false)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
class FanOutOnWriteService < BaseService
|
class FanOutOnWriteService < BaseService
|
||||||
# Push a status into home and mentions feeds
|
# Push a status into home and mentions feeds
|
||||||
# @param [Status] status
|
# @param [Status] status
|
||||||
def call(status)
|
def call(status, delayed = false)
|
||||||
raise Mastodon::RaceConditionError if status.visibility.nil?
|
raise Mastodon::RaceConditionError if status.visibility.nil?
|
||||||
|
|
||||||
deliver_to_self(status) if status.account.local?
|
deliver_to_self(status) if status.account.local?
|
||||||
|
return if delayed
|
||||||
|
|
||||||
render_anonymous_payload(status)
|
render_anonymous_payload(status)
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ class PostStatusService < BaseService
|
||||||
# @option [String] :delete_after
|
# @option [String] :delete_after
|
||||||
# @option [Boolean] :nocrawl Optional skip link card generation
|
# @option [Boolean] :nocrawl Optional skip link card generation
|
||||||
# @option [Boolean] :nomentions Optional skip mention processing
|
# @option [Boolean] :nomentions Optional skip mention processing
|
||||||
|
# @option [Boolean] :delayed Optional publishing delay of 30 secs
|
||||||
# @option [Hash] :poll Optional poll to attach
|
# @option [Hash] :poll Optional poll to attach
|
||||||
# @option [Enumerable] :media_ids Optional array of media IDs to attach
|
# @option [Enumerable] :media_ids Optional array of media IDs to attach
|
||||||
# @option [Doorkeeper::Application] :application
|
# @option [Doorkeeper::Application] :application
|
||||||
|
@ -57,8 +58,23 @@ class PostStatusService < BaseService
|
||||||
schedule_status!
|
schedule_status!
|
||||||
else
|
else
|
||||||
return unless process_status!
|
return unless process_status!
|
||||||
postprocess_status!
|
if @options[:delayed] || @account&.user&.delayed_roars?
|
||||||
bump_potential_friendship!
|
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
|
end
|
||||||
|
|
||||||
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
|
redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
|
||||||
|
@ -149,7 +165,7 @@ class PostStatusService < BaseService
|
||||||
return false if @status.destroyed?
|
return false if @status.destroyed?
|
||||||
|
|
||||||
process_hashtags_service.call(@status, @tags, @preloaded_tags)
|
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
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,6 +31,9 @@
|
||||||
= f.input :setting_always_local, as: :boolean, wrapper: :with_label
|
= f.input :setting_always_local, as: :boolean, wrapper: :with_label
|
||||||
= f.input :setting_default_sensitive, 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/
|
%hr#settings_other/
|
||||||
|
|
||||||
.fields-group
|
.fields-group
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
class DistributionWorker
|
class DistributionWorker
|
||||||
include Sidekiq::Worker
|
include Sidekiq::Worker
|
||||||
|
|
||||||
def perform(status_id)
|
def perform(status_id, delayed = false)
|
||||||
RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
|
RedisLock.acquire(redis: Redis.current, key: "distribute:#{status_id}") do |lock|
|
||||||
if lock.acquired?
|
if lock.acquired?
|
||||||
FanOutOnWriteService.new.call(Status.find(status_id))
|
FanOutOnWriteService.new.call(Status.find(status_id), delayed)
|
||||||
else
|
else
|
||||||
raise Mastodon::RaceConditionError
|
raise Mastodon::RaceConditionError
|
||||||
end
|
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_language: Posting language
|
||||||
setting_default_privacy: Post privacy
|
setting_default_privacy: Post privacy
|
||||||
setting_roar_lifespan: Auto-delete new roars after
|
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_default_local: Default to Monsterpit-only roars (in Glitch flavour)
|
||||||
setting_always_local: Don't send your roars outside Monsterpit
|
setting_always_local: Don't send your roars outside Monsterpit
|
||||||
setting_rawr_federated: Show raw world timeline (may contain offensive content!)
|
setting_rawr_federated: Show raw world timeline (may contain offensive content!)
|
||||||
|
|
Loading…
Reference in New Issue