From 620f50752f3f476832d1b78f2f3c26e22a6a141d Mon Sep 17 00:00:00 2001 From: mgabdev <> Date: Thu, 24 Dec 2020 13:34:14 -0500 Subject: [PATCH] Updated SortingQueryBuilder for ExploreTimeline, GroupCollectionTimeline, GroupTimeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Updated: - SortingQueryBuilder for ExploreTimeline, GroupCollectionTimeline, GroupTimeline • TODO - Test on a lot of data to ensure no repeats - Test reducers/timeline updates to appending and concating non status.id sorted results --- .../api/v1/timelines/explore_controller.rb | 10 ++-- .../timelines/group_collection_controller.rb | 10 ++-- .../api/v1/timelines/group_controller.rb | 10 ++-- app/javascript/gabsocial/actions/timelines.js | 9 ++-- .../gabsocial/features/explore_timeline.js | 23 ++++----- .../features/group_collection_timeline.js | 25 ++++------ .../gabsocial/features/group_timeline.js | 30 +++++------ app/lib/sorting_query_builder.rb | 50 ++++++++++++++----- 8 files changed, 95 insertions(+), 72 deletions(-) diff --git a/app/controllers/api/v1/timelines/explore_controller.rb b/app/controllers/api/v1/timelines/explore_controller.rb index 04e936ab..eb5665f4 100644 --- a/app/controllers/api/v1/timelines/explore_controller.rb +++ b/app/controllers/api/v1/timelines/explore_controller.rb @@ -4,9 +4,7 @@ class Api::V1::Timelines::ExploreController < EmptyController before_action :set_sort_type before_action :set_statuses - after_action :insert_pagination_headers, unless: -> { - @statuses.empty? - } + after_action :insert_pagination_headers, unless: -> { @statuses.empty? } def show if current_user @@ -46,9 +44,11 @@ class Api::V1::Timelines::ExploreController < EmptyController def explore_statuses if current_account - SortingQueryBuilder.new.call(@sort_type, params[:max_id]).reject { |status| FeedManager.instance.filter?(:home, status, current_account.id) } + SortingQueryBuilder.new.call(@sort_type, nil, params[:page]).reject {|status| + FeedManager.instance.filter?(:home, status, current_account.id) + } else - SortingQueryBuilder.new.call(@sort_type, params[:max_id]) + SortingQueryBuilder.new.call(@sort_type, nil, params[:page]) end end diff --git a/app/controllers/api/v1/timelines/group_collection_controller.rb b/app/controllers/api/v1/timelines/group_collection_controller.rb index 27ac50c6..86597e55 100644 --- a/app/controllers/api/v1/timelines/group_collection_controller.rb +++ b/app/controllers/api/v1/timelines/group_collection_controller.rb @@ -5,9 +5,7 @@ class Api::V1::Timelines::GroupCollectionController < Api::BaseController before_action :set_sort_type before_action :set_statuses - after_action :insert_pagination_headers, unless: -> { - @statuses.empty? - } + after_action :insert_pagination_headers, unless: -> { @statuses.empty? } def show if current_account @@ -69,9 +67,11 @@ class Api::V1::Timelines::GroupCollectionController < Api::BaseController end if current_account - SortingQueryBuilder.new.call(@sort_type, params[:max_id], @groupIds).reject { |status| FeedManager.instance.filter?(:home, status, current_account.id) } + SortingQueryBuilder.new.call(@sort_type, @groupIds, params[:page]).reject {|status| + FeedManager.instance.filter?(:home, status, current_account.id) + } else - SortingQueryBuilder.new.call(@sort_type, params[:max_id], @groupIds) + SortingQueryBuilder.new.call(@sort_type, @groupIds, params[:page]) end end diff --git a/app/controllers/api/v1/timelines/group_controller.rb b/app/controllers/api/v1/timelines/group_controller.rb index 7bcd7926..7b2f49df 100644 --- a/app/controllers/api/v1/timelines/group_controller.rb +++ b/app/controllers/api/v1/timelines/group_controller.rb @@ -5,9 +5,7 @@ class Api::V1::Timelines::GroupController < Api::BaseController before_action :set_sort_type before_action :set_statuses - after_action :insert_pagination_headers, unless: -> { - @statuses.empty? - } + after_action :insert_pagination_headers, unless: -> { @statuses.empty? } def show if current_user @@ -52,9 +50,11 @@ class Api::V1::Timelines::GroupController < Api::BaseController def group_statuses if current_account - SortingQueryBuilder.new.call(@sort_type, params[:max_id], @group).reject { |status| FeedManager.instance.filter?(:home, status, current_account.id) } + SortingQueryBuilder.new.call(@sort_type, @group, params[:page]).reject {|status| + FeedManager.instance.filter?(:home, status, current_account.id) + } else - SortingQueryBuilder.new.call(@sort_type, params[:max_id], @group) + SortingQueryBuilder.new.call(@sort_type, @group, params[:page]) end end diff --git a/app/javascript/gabsocial/actions/timelines.js b/app/javascript/gabsocial/actions/timelines.js index 58e4e738..de10276c 100644 --- a/app/javascript/gabsocial/actions/timelines.js +++ b/app/javascript/gabsocial/actions/timelines.js @@ -230,8 +230,9 @@ export const expandHomeTimeline = ({ maxId } = {}, done = noop) => { /** * */ -export const expandExploreTimeline = ({ maxId, sortBy } = {}, done = noop) => { +export const expandExploreTimeline = ({ maxId, sortBy, page } = {}, done = noop) => { return expandTimeline('explore', '/api/v1/timelines/explore', { + page, max_id: maxId, sort_by: sortBy, }, done) @@ -303,10 +304,11 @@ export const expandListTimeline = (id, { maxId } = {}, done = noop) => { /** * */ -export const expandGroupTimeline = (id, { sortBy, maxId, onlyMedia } = {}, done = noop) => { +export const expandGroupTimeline = (id, { sortBy, maxId, onlyMedia, page } = {}, done = noop) => { if (!id) return return expandTimeline(`group:${id}`, `/api/v1/timelines/group/${id}`, { + page, sort_by: sortBy, max_id: maxId, only_media: onlyMedia @@ -323,8 +325,9 @@ export const expandGroupFeaturedTimeline = (groupId, done = noop) => { /** * */ -export const expandGroupCollectionTimeline = (collectionType, { sortBy, maxId } = {}, done = noop) => { +export const expandGroupCollectionTimeline = (collectionType, { sortBy, maxId, page } = {}, done = noop) => { return expandTimeline(`group_collection:${collectionType}`, `/api/v1/timelines/group_collection/${collectionType}`, { + page, sort_by: sortBy, max_id: maxId, }, done) diff --git a/app/javascript/gabsocial/features/explore_timeline.js b/app/javascript/gabsocial/features/explore_timeline.js index a95ead53..1d5de9ba 100644 --- a/app/javascript/gabsocial/features/explore_timeline.js +++ b/app/javascript/gabsocial/features/explore_timeline.js @@ -23,9 +23,9 @@ import GroupSortBlock from '../components/group_sort_block' class ExploreTimeline extends React.PureComponent { state = { - //keep track of loads for if no user, - //only allow 2 loads before showing sign up msg - loadCount: 0, + //keep track of page loads for if no user, + //only allow 2 page loads before showing sign up msg + page: 1, } componentDidMount() { @@ -55,26 +55,23 @@ class ExploreTimeline extends React.PureComponent { sortByValue, sortByTopValue, } = this.props - const { loadCount } = this.state + const { page } = this.state - if (!!maxId && !me) { - this.setState({ loadCount: this.state.loadCount + 1 }) - if (loadCount >= 2) return false - } else if (!maxId && loadCount !== 0) { - this.setState({ loadCount: 0 }) - } + const newPage = !!maxId ? this.state.page + 1 : 1 + if (!!maxId && !me && page >= 2) return false + this.setState({ page: newPage }) const sortBy = getSortBy(sortByValue, sortByTopValue) - const options = { sortBy, maxId } + const options = { sortBy, maxId, page: newPage } this.props.onExpandExploreTimeline(options) } render() { const { intl } = this.props - const { loadCount } = this.state + const { page } = this.state - const canLoadMore = loadCount < 2 && !me || !!me + const canLoadMore = page < 2 && !me || !!me return ( diff --git a/app/javascript/gabsocial/features/group_collection_timeline.js b/app/javascript/gabsocial/features/group_collection_timeline.js index 1b7a98f5..28c0cca2 100644 --- a/app/javascript/gabsocial/features/group_collection_timeline.js +++ b/app/javascript/gabsocial/features/group_collection_timeline.js @@ -24,9 +24,9 @@ import GroupsCollection from './groups_collection' class GroupCollectionTimeline extends React.PureComponent { state = { - //keep track of loads for if no user, - //only allow 2 loads before showing sign up msg - loadCount: 0, + //keep track of page loads for if no user, + //only allow 2 page loads before showing sign up msg + page: 1, } componentDidMount() { @@ -61,17 +61,14 @@ class GroupCollectionTimeline extends React.PureComponent { sortByValue, sortByTopValue, } = this.props - const { loadCount } = this.state - - if (!!maxId && !me) { - this.setState({ loadCount: this.state.loadCount + 1 }) - if (loadCount >= 2) return false - } else if (!maxId && loadCount !== 0) { - this.setState({ loadCount: 0 }) - } + const { page } = this.state + + const newPage = !!maxId ? this.state.page + 1 : 1 + if (!!maxId && !me && page >= 2) return false + this.setState({ page: newPage }) const sortBy = getSortBy(sortByValue, sortByTopValue) - const options = { sortBy, maxId } + const options = { sortBy, maxId, page: newPage } this.props.onExpandGroupCollectionTimeline(collectionType, options) } @@ -82,7 +79,7 @@ class GroupCollectionTimeline extends React.PureComponent { intl, hasNoGroupMembers, } = this.props - const { loadCount } = this.state + const { page } = this.state const emptyMessage = !!me && collectionType === 'member' && hasNoGroupMembers ? (
@@ -93,7 +90,7 @@ class GroupCollectionTimeline extends React.PureComponent {
) : intl.formatMessage(messages.empty) - const canLoadMore = loadCount < 2 && !me || !!me + const canLoadMore = page < 2 && !me || !!me return ( diff --git a/app/javascript/gabsocial/features/group_timeline.js b/app/javascript/gabsocial/features/group_timeline.js index d4ecc9c8..31b3299b 100644 --- a/app/javascript/gabsocial/features/group_timeline.js +++ b/app/javascript/gabsocial/features/group_timeline.js @@ -25,9 +25,9 @@ import GroupSortBlock from '../components/group_sort_block' class GroupTimeline extends ImmutablePureComponent { state = { - //keep track of loads for if no user, - //only allow 2 loads before showing sign up msg - loadCount: 0, + //keep track of page loads for if no user, + //only allow 2 page loads before showing sign up msg + page: 1, } componentDidMount() { @@ -72,17 +72,19 @@ class GroupTimeline extends ImmutablePureComponent { sortByTopValue, onlyMedia, } = this.props - const { loadCount } = this.state - - if (!!maxId && !me) { - this.setState({ loadCount: this.state.loadCount + 1 }) - if (loadCount >= 2) return false - } else if (!maxId && loadCount !== 0) { - this.setState({ loadCount: 0 }) - } + const { page } = this.state + + const newPage = !!maxId ? this.state.page + 1 : 1 + if (!!maxId && !me && page >= 2) return false + this.setState({ page: newPage }) const sortBy = getSortBy(sortByValue, sortByTopValue) - this.props.onExpandGroupTimeline(groupId, { sortBy, maxId, onlyMedia }) + this.props.onExpandGroupTimeline(groupId, { + sortBy, + maxId, + onlyMedia, + page: newPage, + }) } render() { @@ -92,7 +94,7 @@ class GroupTimeline extends ImmutablePureComponent { intl, groupPinnedStatusIds, } = this.props - const { loadCount } = this.state + const { page } = this.state if (typeof group === 'undefined') { return @@ -100,7 +102,7 @@ class GroupTimeline extends ImmutablePureComponent { return } - const canLoadMore = loadCount < 2 && !me || !!me + const canLoadMore = page < 2 && !me || !!me return ( diff --git a/app/lib/sorting_query_builder.rb b/app/lib/sorting_query_builder.rb index 3607d019..46e8505f 100644 --- a/app/lib/sorting_query_builder.rb +++ b/app/lib/sorting_query_builder.rb @@ -1,11 +1,14 @@ # frozen_string_literal: true class SortingQueryBuilder < BaseService - def call(sort_type, max_id = nil, group = nil) - min_likes = 20 - min_reblogs = 10 - min_replies = 2 + def call(sort_type, group = nil, page = 1) + limit = 20 + + min_likes = 5 + min_reblogs = 2 + min_replies = 1 date_limit = 30.days.ago + max_page = 8 case sort_type when 'hot' @@ -32,14 +35,35 @@ class SortingQueryBuilder < BaseService 'top_all_time', ] - query = Status.unscoped.without_replies - query = query.joins(:status_stat).order(top_order) unless ['newest'].include? sort_type - query = query.where('statuses.created_at > ?', date_limit) - query = query.where(group: group) unless group.nil? - query = query.where('statuses.id > ? AND statuses.id <> ?', max_id, max_id) unless max_id.nil? || max_id.empty? - query = query.limit(20) - - query + if page.to_i > max_page + return [] + 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.where(group: group) unless group.nil? + 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.where('statuses.group_id': group) unless group.nil? + 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 +end \ No newline at end of file