| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-07 13:09:25 -05:00
										 |  |  | class Api::V1::Accounts::StatusesController < Api::BaseController | 
					
						
							| 
									
										
										
										
											2018-12-19 18:30:43 -06:00
										 |  |  |   before_action -> { authorize_if_got_token! :read, :'read:statuses' } | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   before_action :set_account | 
					
						
							|  |  |  |   after_action :insert_pagination_headers | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   respond_to :json | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def index | 
					
						
							|  |  |  |     @statuses = load_statuses | 
					
						
							| 
									
										
										
										
											2017-07-06 21:02:06 -05:00
										 |  |  |     render json: @statuses, each_serializer: REST::StatusSerializer, relationships: StatusRelationshipsPresenter.new(@statuses, current_user&.account_id) | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   private | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def set_account | 
					
						
							|  |  |  |     @account = Account.find(params[:account_id]) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def load_statuses | 
					
						
							| 
									
										
										
										
											2017-07-06 21:02:06 -05:00
										 |  |  |     cached_account_statuses | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def cached_account_statuses | 
					
						
							|  |  |  |     cache_collection account_statuses, Status | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def account_statuses | 
					
						
							| 
									
										
										
										
											2018-05-16 05:30:14 -05:00
										 |  |  |     statuses = truthy_param?(:pinned) ? pinned_scope : permitted_account_statuses | 
					
						
							| 
									
										
										
										
											2018-12-26 20:42:35 -06:00
										 |  |  |     statuses = statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id)) | 
					
						
							| 
									
										
										
										
											2018-05-16 05:30:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     statuses.merge!(only_media_scope) if truthy_param?(:only_media) | 
					
						
							|  |  |  |     statuses.merge!(no_replies_scope) if truthy_param?(:exclude_replies) | 
					
						
							| 
									
										
										
										
											2018-12-26 20:42:35 -06:00
										 |  |  |     statuses.merge!(no_reblogs_scope) if truthy_param?(:exclude_reblogs) | 
					
						
							| 
									
										
										
										
											2019-02-03 21:25:59 -06:00
										 |  |  |     statuses.merge!(hashtag_scope)    if params[:tagged].present? | 
					
						
							| 
									
										
										
										
											2018-05-16 05:30:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     statuses | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def permitted_account_statuses | 
					
						
							|  |  |  |     @account.statuses.permitted_for(@account, current_account) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def only_media_scope | 
					
						
							|  |  |  |     Status.where(id: account_media_status_ids) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def account_media_status_ids | 
					
						
							| 
									
										
										
										
											2018-03-10 10:44:26 -06:00
										 |  |  |     # `SELECT DISTINCT id, updated_at` is too slow, so pluck ids at first, and then select id, updated_at with ids. | 
					
						
							|  |  |  |     # Also, Avoid getting slow by not narrowing down by `statuses.account_id`. | 
					
						
							|  |  |  |     # When narrowing down by `statuses.account_id`, `index_statuses_20180106` will be used | 
					
						
							|  |  |  |     # and the table will be joined by `Merge Semi Join`, so the query will be slow. | 
					
						
							| 
									
										
										
										
											2019-02-26 08:23:24 -06:00
										 |  |  |     @account.statuses.joins(:media_attachments).merge(@account.media_attachments).permitted_for(@account, current_account) | 
					
						
							|  |  |  |             .paginate_by_max_id(limit_param(DEFAULT_STATUSES_LIMIT), params[:max_id], params[:since_id]) | 
					
						
							|  |  |  |             .reorder(id: :desc).distinct(:id).pluck(:id) | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-24 18:41:18 -05:00
										 |  |  |   def pinned_scope | 
					
						
							|  |  |  |     @account.pinned_statuses | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   def no_replies_scope | 
					
						
							|  |  |  |     Status.without_replies | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-26 20:42:35 -06:00
										 |  |  |   def no_reblogs_scope | 
					
						
							|  |  |  |     Status.without_reblogs | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-03 21:25:59 -06:00
										 |  |  |   def hashtag_scope | 
					
						
							| 
									
										
										
										
											2019-03-13 07:02:13 -05:00
										 |  |  |     tag = Tag.find_normalized(params[:tagged]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if tag | 
					
						
							|  |  |  |       Status.tagged_with(tag.id) | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       Status.none | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2019-02-03 21:25:59 -06:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   def pagination_params(core_params) | 
					
						
							| 
									
										
										
										
											2018-04-01 19:09:50 -05:00
										 |  |  |     params.slice(:limit, :only_media, :exclude_replies).permit(:limit, :only_media, :exclude_replies).merge(core_params) | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def insert_pagination_headers | 
					
						
							|  |  |  |     set_pagination_headers(next_path, prev_path) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def next_path | 
					
						
							|  |  |  |     if records_continue? | 
					
						
							|  |  |  |       api_v1_account_statuses_url pagination_params(max_id: pagination_max_id) | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def prev_path | 
					
						
							|  |  |  |     unless @statuses.empty? | 
					
						
							| 
									
										
										
										
											2018-09-27 19:23:45 -05:00
										 |  |  |       api_v1_account_statuses_url pagination_params(min_id: pagination_since_id) | 
					
						
							| 
									
										
										
										
											2017-05-31 14:36:24 -05:00
										 |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def records_continue? | 
					
						
							|  |  |  |     @statuses.size == limit_param(DEFAULT_STATUSES_LIMIT) | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def pagination_max_id | 
					
						
							|  |  |  |     @statuses.last.id | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def pagination_since_id | 
					
						
							|  |  |  |     @statuses.first.id | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |