# frozen_string_literal: true
class AccountsController < ApplicationController
+ PAGE_SIZE = 20
+
include AccountControllerConcern
before_action :set_cache_headers
end
@pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
- @statuses = filtered_statuses.paginate_by_max_id(20, params[:max_id], params[:since_id])
+ @statuses = filtered_status_page(params)
@statuses = cache_collection(@statuses, Status)
- @next_url = next_url unless @statuses.empty?
+ unless @statuses.empty?
+ @older_url = older_url if @statuses.last.id > filtered_statuses.last.id
+ @newer_url = newer_url if @statuses.first.id < filtered_statuses.first.id
+ end
end
format.atom do
- @entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id])
+ @entries = @account.stream_entries.where(hidden: false).with_includes.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id])
render xml: OStatus::AtomSerializer.render(OStatus::AtomSerializer.new.feed(@account, @entries.reject { |entry| entry.status.nil? }))
end
@account = Account.find_local!(params[:username])
end
- def next_url
+ def older_url
+ ::Rails.logger.info("older: max_id #{@statuses.last.id}, url #{pagination_url(max_id: @statuses.last.id)}")
+ pagination_url(max_id: @statuses.last.id)
+ end
+
+ def newer_url
+ pagination_url(min_id: @statuses.first.id)
+ end
+
+ def pagination_url(max_id: nil, min_id: nil)
if media_requested?
- short_account_media_url(@account, max_id: @statuses.last.id)
+ short_account_media_url(@account, max_id: max_id, min_id: min_id)
elsif replies_requested?
- short_account_with_replies_url(@account, max_id: @statuses.last.id)
+ short_account_with_replies_url(@account, max_id: max_id, min_id: min_id)
else
- short_account_url(@account, max_id: @statuses.last.id)
+ short_account_url(@account, max_id: max_id, min_id: min_id)
end
end
def replies_requested?
request.path.ends_with?('/with_replies')
end
+
+ def filtered_status_page(params)
+ if params[:min_id].present?
+ filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
+ else
+ filtered_statuses.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id]).to_a
+ end
+ end
end
query = query.where(arel_table[:id].gt(since_id)) if since_id.present?
query
}
+
+ # Differs from :paginate_by_max_id in that it gives the results immediately following min_id,
+ # whereas since_id gives the items with largest id, but with since_id as a cutoff.
+ # Results will be in ascending order by id.
+ scope :paginate_by_min_id, ->(limit, min_id = nil) {
+ query = reorder(arel_table[:id]).limit(limit)
+ query = query.where(arel_table[:id].gt(min_id)) if min_id.present?
+ query
+ }
end
end
= render partial: 'stream_entries/status', collection: @statuses, as: :status
- - if @statuses.size == 20
+ - if @newer_url || @older_url
.pagination
- = link_to safe_join([t('pagination.next'), fa_icon('chevron-right')], ' '), @next_url, class: 'next', rel: 'next'
+ - if @older_url
+ = link_to safe_join([fa_icon('chevron-left'), t('pagination.older')], ' '), @older_url, class: 'older', rel: 'older'
+ - if @newer_url
+ = link_to safe_join([t('pagination.newer'), fa_icon('chevron-right')], ' '), @newer_url, class: 'newer', rel: 'newer'