diff options
Diffstat (limited to 'app/lib')
-rw-r--r-- | app/lib/activitypub/activity.rb | 7 | ||||
-rw-r--r-- | app/lib/feed_manager.rb | 77 | ||||
-rw-r--r-- | app/lib/ostatus/activity/creation.rb | 2 | ||||
-rw-r--r-- | app/lib/user_settings_decorator.rb | 5 |
4 files changed, 71 insertions, 20 deletions
diff --git a/app/lib/activitypub/activity.rb b/app/lib/activitypub/activity.rb index 9688f57a6..01144f595 100644 --- a/app/lib/activitypub/activity.rb +++ b/app/lib/activitypub/activity.rb @@ -67,9 +67,14 @@ class ActivityPub::Activity end def distribute(status) + crawl_links(status) + + # Only continue if the status is supposed to have + # arrived in real-time + return unless @options[:override_timestamps] + notify_about_reblog(status) if reblog_of_local_account?(status) notify_about_mentions(status) - crawl_links(status) distribute_to_followers(status) end diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index 5a3af7206..39d3333da 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -56,7 +56,17 @@ class FeedManager falloff_rank = FeedManager::REBLOG_FALLOFF - 1 falloff_range = redis.zrevrange(timeline_key, falloff_rank, falloff_rank, with_scores: true) falloff_score = falloff_range&.first&.last&.to_i || 0 - redis.zremrangebyscore(reblog_key, 0, falloff_score) + + # Get any reblogs we might have to clean up after. + redis.zrangebyscore(reblog_key, 0, falloff_score).each do |reblogged_id| + # Remove it from the set of reblogs we're tracking *first* to avoid races. + redis.zrem(reblog_key, reblogged_id) + # Just drop any set we might have created to track additional reblogs. + # This means that if this reblog is deleted, we won't automatically insert + # another reblog, but also that any new reblog can be inserted into the + # feed. + redis.del(key(type, account_id, "reblogs:#{reblogged_id}")) + end end def push_update_required?(timeline_type, account_id) @@ -100,11 +110,24 @@ class FeedManager end def populate_feed(account) - prepopulate_limit = FeedManager::MAX_ITEMS / 4 - statuses = Status.as_home_timeline(account).order(account_id: :desc).limit(prepopulate_limit) - statuses.reverse_each do |status| - next if filter_from_home?(status, account) - add_to_feed(:home, account, status) + added = 0 + limit = FeedManager::MAX_ITEMS / 2 + max_id = nil + + loop do + statuses = Status.as_home_timeline(account) + .paginate_by_max_id(limit, max_id) + + break if statuses.empty? + + statuses.each do |status| + next if filter_from_home?(status, account) + added += 1 if add_to_feed(:home, account, status) + end + + break unless added.zero? + + max_id = statuses.last.id end end @@ -167,20 +190,31 @@ class FeedManager # either action is appropriate. def add_to_feed(timeline_type, account, status) timeline_key = key(timeline_type, account.id) - reblog_key = key(timeline_type, account.id, 'reblogs') + reblog_key = key(timeline_type, account.id, 'reblogs') if status.reblog? # If the original status or a reblog of it is within # REBLOG_FALLOFF statuses from the top, do not re-insert it into # the feed rank = redis.zrevrank(timeline_key, status.reblog_of_id) + return false if !rank.nil? && rank < FeedManager::REBLOG_FALLOFF reblog_rank = redis.zrevrank(reblog_key, status.reblog_of_id) - return false unless reblog_rank.nil? - - redis.zadd(timeline_key, status.id, status.id) - redis.zadd(reblog_key, status.id, status.reblog_of_id) + if reblog_rank.nil? + # This is not something we've already seen reblogged, so we + # can just add it to the feed (and note that we're + # reblogging it). + redis.zadd(timeline_key, status.id, status.id) + redis.zadd(reblog_key, status.id, status.reblog_of_id) + else + # Another reblog of the same status was already in the + # REBLOG_FALLOFF most recent statuses, so we note that this + # is an "extra" reblog, by storing it in reblog_set_key. + reblog_set_key = key(timeline_type, account.id, "reblogs:#{status.reblog_of_id}") + redis.sadd(reblog_set_key, status.id) + return false + end else redis.zadd(timeline_key, status.id, status.id) end @@ -194,22 +228,29 @@ class FeedManager # do so if appropriate. def remove_from_feed(timeline_type, account, status) timeline_key = key(timeline_type, account.id) - reblog_key = key(timeline_type, account.id, 'reblogs') if status.reblog? # 1. If the reblogging status is not in the feed, stop. status_rank = redis.zrevrank(timeline_key, status.id) return false if status_rank.nil? - # 2. Remove the reblogged status from the `:reblogs` zset. - redis.zrem(reblog_key, status.reblog_of_id) + # 2. Remove reblog from set of this status's reblogs. + reblog_set_key = key(timeline_type, account.id, "reblogs:#{status.reblog_of_id}") + + redis.srem(reblog_set_key, status.id) + # 3. Re-insert another reblog or original into the feed if one + # remains in the set. We could pick a random element, but this + # set should generally be small, and it seems ideal to show the + # oldest potential such reblog. + other_reblog = redis.smembers(reblog_set_key).map(&:to_i).sort.first - # 3. Add the reblogged status to the feed using the reblogging - # status' ID as its score, and the reblogged status' ID as its - # value. - redis.zadd(timeline_key, status.id, status.reblog_of_id) + redis.zadd(timeline_key, other_reblog, other_reblog) if other_reblog # 4. Remove the reblogging status from the feed (as normal) + # (outside conditional) + else + # If the original is getting deleted, no use for reblog references + redis.del(key(timeline_type, account.id, "reblogs:#{status.id}")) end redis.zrem(timeline_key, status.id) diff --git a/app/lib/ostatus/activity/creation.rb b/app/lib/ostatus/activity/creation.rb index a1ab522e2..3418e2420 100644 --- a/app/lib/ostatus/activity/creation.rb +++ b/app/lib/ostatus/activity/creation.rb @@ -56,7 +56,7 @@ class OStatus::Activity::Creation < OStatus::Activity::Base Rails.logger.debug "Queuing remote status #{status.id} (#{id}) for distribution" LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text? - DistributionWorker.perform_async(status.id) + DistributionWorker.perform_async(status.id) if @options[:override_timestamps] status end diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index 3b7a856ee..d86959c0b 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -23,6 +23,7 @@ class UserSettingsDecorator user.settings['boost_modal'] = boost_modal_preference if change?('setting_boost_modal') user.settings['delete_modal'] = delete_modal_preference if change?('setting_delete_modal') user.settings['auto_play_gif'] = auto_play_gif_preference if change?('setting_auto_play_gif') + user.settings['reduce_motion'] = reduce_motion_preference if change?('setting_reduce_motion') user.settings['system_font_ui'] = system_font_ui_preference if change?('setting_system_font_ui') user.settings['noindex'] = noindex_preference if change?('setting_noindex') user.settings['theme'] = theme_preference if change?('setting_theme') @@ -64,6 +65,10 @@ class UserSettingsDecorator boolean_cast_setting 'setting_auto_play_gif' end + def reduce_motion_preference + boolean_cast_setting 'setting_reduce_motion' + end + def noindex_preference boolean_cast_setting 'setting_noindex' end |