# frozen_string_literal: true class SortingQueryBuilder < BaseService def call(sort_type, group = nil, page = 1, account_id = nil, source = nil) limit = 20 min_likes = 5 min_reblogs = 2 min_replies = 1 date_limit = 5.years.ago pure_limit = "NOW() - INTERVAL '14 days'" max_page = 8 case sort_type when 'hot' date_limit = 8.hours.ago pure_limit = "NOW() - INTERVAL '8 hours'" when 'top_today' date_limit = 24.hours.ago pure_limit = "NOW() - INTERVAL '24 hours'" when 'top_weekly' date_limit = 7.days.ago pure_limit = "NOW() - INTERVAL '7 days'" when 'top_monthly' date_limit = 30.days.ago pure_limit = "NOW() - INTERVAL '30 days'" when 'top_yearly' date_limit = 1.year.ago end top_order = 'status_stats.replies_count DESC, status_stats.reblogs_count DESC, status_stats.favourites_count DESC' valid_sort_types = [ 'hot', 'newest', 'recent', 'top_today', 'top_weekly', 'top_monthly', 'top_yearly', 'top_all_time', ] if page.to_i > max_page return [] end if source == 'group_collection' return [] if account_id.nil? query = " select q.* from ( select s.* from statuses s join accounts a on s.account_id = a.id and a.is_flagged_as_spam is false join group_accounts ga on s.group_id = ga.group_id and ga.account_id = #{account_id} " query += " join status_stats ss on s.id = ss.status_id " if sort_type != 'newest' query += " where " query += " ss.updated_at > #{pure_limit} " if sort_type == 'recent' query += " s.created_at > #{pure_limit} " if sort_type != 'recent' query += " and s.reply is false and s.reblog_of_id is null " if sort_type != 'newest' query += " order by ss.replies_count desc, ss.reblogs_count desc, ss.favourites_count desc " else query += " order by s.created_at desc " end query += "limit #{limit} " if page.to_i > 1 query += "offset #{page.to_i * limit}" end query += " ) q " return Status.find_by_sql query end if sort_type == 'newest' query = Status.without_replies.without_reblogs query = query.with_public_visibility if group.nil? query = query.where('statuses.created_at > ?', date_limit) query = query.joins(:account) query = query.where('accounts.is_flagged_as_spam is false') if source == "explore" query = query.where(group: nil) else query = query.where(group: group) unless group.nil? end query = query.page(page.to_i) query = query.per(limit) return query else query = StatusStat.where('status_stats.created_at > ?', date_limit) query = query.order(top_order) unless sort_type == 'recent' query = query.order(updated_at: :desc) if sort_type == 'recent' query = query.where('status_stats.replies_count > ?', min_replies) unless sort_type == 'recent' query = query.where('status_stats.reblogs_count > ?', min_reblogs) unless sort_type == 'recent' query = query.where('status_stats.favourites_count > ?', min_likes) unless sort_type == 'recent' query = query.joins(:status) query = query.where('statuses.reblog_of_id IS NULL') query = query.where('statuses.in_reply_to_id IS NULL') query = query.joins(<<-SQL). join accounts on statuses.account_id = accounts.id SQL where('accounts.is_flagged_as_spam is false') if source == "explore" query = query.where('statuses.group_id': nil) else query = query.where('statuses.group_id': group) unless group.nil? end query = query.where('statuses.visibility': 0) if group.nil? query = query.page(page) query = query.per(limit) query = query.map(&:status) return query end end end