kopia lustrzana https://github.com/pixelfed/pixelfed
				
				
				
			Update ApiV1Controller, fix link header pagination in /api/v1/statuses/{id}/reblogged_by
							rodzic
							
								
									adc82ecab3
								
							
						
					
					
						commit
						e346b675d4
					
				|  | @ -527,7 +527,7 @@ class ApiV1Controller extends Controller | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if($paginator->hasMorePages()) { | 			if($paginator->hasMorePages()) { | ||||||
| 				$link .= ($link ? ',' : '') . '<'.$paginator->nextPageUrl().'>; rel="prev"'; | 				$link .= ($link ? ', ' : '') . '<'.$paginator->nextPageUrl().'>; rel="prev"'; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -617,7 +617,7 @@ class ApiV1Controller extends Controller | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			if($paginator->hasMorePages()) { | 			if($paginator->hasMorePages()) { | ||||||
| 				$link .= ($link ? ',' : '') . '<'.$paginator->nextPageUrl().'>; rel="prev"'; | 				$link .= ($link ? ', ' : '') . '<'.$paginator->nextPageUrl().'>; rel="prev"'; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -2582,13 +2582,17 @@ class ApiV1Controller extends Controller | ||||||
| 		abort_if(!$request->user(), 403); | 		abort_if(!$request->user(), 403); | ||||||
| 
 | 
 | ||||||
| 		$this->validate($request, [ | 		$this->validate($request, [ | ||||||
| 			'limit' => 'nullable|integer|min:1|max:100' | 			'limit' => 'sometimes|integer|min:1|max:80' | ||||||
| 		]); | 		]); | ||||||
| 
 | 
 | ||||||
| 		$limit = $request->input('limit') ?? 10; | 		$limit = $request->input('limit', 10); | ||||||
| 		$user = $request->user(); | 		$user = $request->user(); | ||||||
|  | 		$pid = $user->profile_id; | ||||||
| 		$status = Status::findOrFail($id); | 		$status = Status::findOrFail($id); | ||||||
| 		$author = intval($status->profile_id) === intval($user->profile_id) || $user->is_admin; | 		$account = AccountService::get($status->profile_id, true); | ||||||
|  | 		abort_if(!$account, 404); | ||||||
|  | 		$author = intval($status->profile_id) === intval($pid) || $user->is_admin; | ||||||
|  | 		$napi = $request->has(self::PF_API_ENTITY_KEY); | ||||||
| 
 | 
 | ||||||
| 		abort_if( | 		abort_if( | ||||||
| 			!$status->type || | 			!$status->type || | ||||||
|  | @ -2598,10 +2602,14 @@ class ApiV1Controller extends Controller | ||||||
| 
 | 
 | ||||||
| 		if(!$author) { | 		if(!$author) { | ||||||
| 			if($status->scope == 'private') { | 			if($status->scope == 'private') { | ||||||
| 				abort_if(!FollowerService::follows($user->profile_id, $status->profile_id), 403); | 				abort_if(!FollowerService::follows($pid, $status->profile_id), 403); | ||||||
| 			} else { | 			} else { | ||||||
| 				abort_if(!in_array($status->scope, ['public','unlisted']), 403); | 				abort_if(!in_array($status->scope, ['public','unlisted']), 403); | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			if($request->has('cursor')) { | ||||||
|  | 				return $this->json([]); | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		$res = Status::where('reblog_of_id', $status->id) | 		$res = Status::where('reblog_of_id', $status->id) | ||||||
|  | @ -2616,26 +2624,34 @@ class ApiV1Controller extends Controller | ||||||
| 		$headers = []; | 		$headers = []; | ||||||
| 		if($author && $res->hasPages()) { | 		if($author && $res->hasPages()) { | ||||||
| 			$links = ''; | 			$links = ''; | ||||||
| 			if($res->previousPageUrl()) { | 			if($res->onFirstPage()) { | ||||||
| 				$links = '<' . $res->previousPageUrl() .'>; rel="prev"'; | 				if($res->nextPageUrl()) { | ||||||
| 			} | 					$links = '<' . $res->nextPageUrl() .'>; rel="prev"'; | ||||||
| 
 | 				} | ||||||
| 			if($res->nextPageUrl()) { | 			} else { | ||||||
| 				if(!empty($links)) { | 				if($res->previousPageUrl()) { | ||||||
| 					$links .= ', '; | 					$links = '<' . $res->previousPageUrl() .'>; rel="next"'; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if($res->nextPageUrl()) { | ||||||
|  | 					if(!empty($links)) { | ||||||
|  | 						$links .= ', '; | ||||||
|  | 					} | ||||||
|  | 					$links .= '<' . $res->nextPageUrl() .'>; rel="prev"'; | ||||||
| 				} | 				} | ||||||
| 				$links .= '<' . $res->nextPageUrl() .'>; rel="next"'; |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			$headers = ['Link' => $links]; | 			$headers = ['Link' => $links]; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		$res = $res->map(function($status) use($user) { | 		$res = $res->map(function($status) use($pid, $napi) { | ||||||
| 			$account = AccountService::getMastodon($status->profile_id, true); | 			$account = $napi ? AccountService::get($status->profile_id, true) : AccountService::getMastodon($status->profile_id, true); | ||||||
| 			if(!$account) { | 			if(!$account) { | ||||||
| 				return false; | 				return false; | ||||||
| 			} | 			} | ||||||
| 			$account['follows'] = $status->profile_id == $user->profile_id ? null : FollowerService::follows($user->profile_id, $status->profile_id); | 			if($napi) { | ||||||
|  | 				$account['follows'] = $status->profile_id == $pid ? null : FollowerService::follows($pid, $status->profile_id); | ||||||
|  | 			} | ||||||
| 			return $account; | 			return $account; | ||||||
| 		}) | 		}) | ||||||
| 		->filter(function($account) { | 		->filter(function($account) { | ||||||
|  |  | ||||||
|  | @ -104,7 +104,7 @@ | ||||||
| 				isFetchingMore: false, | 				isFetchingMore: false, | ||||||
| 				likes: [], | 				likes: [], | ||||||
| 				ids: [], | 				ids: [], | ||||||
| 				page: undefined, | 				cursor: undefined, | ||||||
| 				isUpdatingFollowState: false, | 				isUpdatingFollowState: false, | ||||||
| 				followStateIndex: undefined, | 				followStateIndex: undefined, | ||||||
| 				user: window._sharedData.user | 				user: window._sharedData.user | ||||||
|  | @ -119,13 +119,14 @@ | ||||||
| 				this.isFetchingMore = false; | 				this.isFetchingMore = false; | ||||||
| 				this.likes = []; | 				this.likes = []; | ||||||
| 				this.ids = []; | 				this.ids = []; | ||||||
| 				this.page = undefined; | 				this.cursor = undefined; | ||||||
| 			}, | 			}, | ||||||
| 
 | 
 | ||||||
| 			fetchShares() { | 			fetchShares() { | ||||||
| 				axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { | 				axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { | ||||||
| 					params: { | 					params: { | ||||||
| 						limit: 40 | 						limit: 40, | ||||||
|  | 						'_pe': 1 | ||||||
| 					} | 					} | ||||||
| 				}) | 				}) | ||||||
| 				.then(res => { | 				.then(res => { | ||||||
|  | @ -133,19 +134,21 @@ | ||||||
| 					this.likes = res.data; | 					this.likes = res.data; | ||||||
| 					if(res.headers && res.headers.link) { | 					if(res.headers && res.headers.link) { | ||||||
| 						const links = parseLinkHeader(res.headers.link); | 						const links = parseLinkHeader(res.headers.link); | ||||||
| 						if(links.next) { | 						if(links.prev) { | ||||||
| 							this.page = links.next.cursor; | 							this.cursor = links.prev.cursor; | ||||||
| 							this.canLoadMore = true; | 							this.canLoadMore = true; | ||||||
| 						} else { | 						} else { | ||||||
| 							this.canLoadMore = false; | 							this.canLoadMore = false; | ||||||
| 						} | 						} | ||||||
|  | 					} else { | ||||||
|  | 						this.canLoadMore = false; | ||||||
| 					} | 					} | ||||||
| 					this.isLoading = false; | 					this.isLoading = false; | ||||||
| 				}); | 				}); | ||||||
| 			}, | 			}, | ||||||
| 
 | 
 | ||||||
| 			open() { | 			open() { | ||||||
| 				if(this.page) { | 				if(this.cursor) { | ||||||
| 					this.clear(); | 					this.clear(); | ||||||
| 				} | 				} | ||||||
| 				this.isOpen = true; | 				this.isOpen = true; | ||||||
|  | @ -163,7 +166,8 @@ | ||||||
| 				axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { | 				axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { | ||||||
| 					params: { | 					params: { | ||||||
| 						limit: 10, | 						limit: 10, | ||||||
| 						cursor: this.page | 						cursor: this.cursor, | ||||||
|  | 						'_pe': 1 | ||||||
| 					} | 					} | ||||||
| 				}).then(res => { | 				}).then(res => { | ||||||
| 					if(!res.data || !res.data.length) { | 					if(!res.data || !res.data.length) { | ||||||
|  | @ -179,11 +183,13 @@ | ||||||
| 					}) | 					}) | ||||||
| 					if(res.headers && res.headers.link) { | 					if(res.headers && res.headers.link) { | ||||||
| 						const links = parseLinkHeader(res.headers.link); | 						const links = parseLinkHeader(res.headers.link); | ||||||
| 						if(links.next) { | 						if(links.prev) { | ||||||
| 							this.page = links.next.cursor; | 							this.cursor = links.prev.cursor; | ||||||
| 						} else { | 						} else { | ||||||
| 							this.canLoadMore = false; | 							this.canLoadMore = false; | ||||||
| 						} | 						} | ||||||
|  | 					} else { | ||||||
|  | 						this.canLoadMore = false; | ||||||
| 					} | 					} | ||||||
| 					this.isFetchingMore = false; | 					this.isFetchingMore = false; | ||||||
| 				}) | 				}) | ||||||
|  |  | ||||||
|  | @ -401,40 +401,6 @@ | ||||||
| 				<b-spinner /> | 				<b-spinner /> | ||||||
| 			</div> | 			</div> | ||||||
| 		</b-modal> | 		</b-modal> | ||||||
| 		<b-modal ref="sharesModal" |  | ||||||
| 			id="s-modal" |  | ||||||
| 			hide-footer |  | ||||||
| 			centered |  | ||||||
| 			title="Shares" |  | ||||||
| 			body-class="list-group-flush py-3 px-0"> |  | ||||||
| 			<div class="list-group"> |  | ||||||
| 				<div class="list-group-item border-0 py-1" v-for="(user, index) in shares" :key="'modal_shares_'+index"> |  | ||||||
| 					<div class="media"> |  | ||||||
| 						<a :href="user.url"> |  | ||||||
| 							<img class="mr-3 rounded-circle box-shadow" :src="user.avatar" :alt="user.username + '’s avatar'" width="30px"> |  | ||||||
| 						</a> |  | ||||||
| 						<div class="media-body"> |  | ||||||
| 							<div class="d-inline-block"> |  | ||||||
| 								<p class="mb-0" style="font-size: 14px"> |  | ||||||
| 									<a :href="user.url" class="font-weight-bold text-dark"> |  | ||||||
| 										{{user.username}} |  | ||||||
| 									</a> |  | ||||||
| 								</p> |  | ||||||
| 								<p class="text-muted mb-0" style="font-size: 14px"> |  | ||||||
| 										{{user.display_name}} |  | ||||||
| 									</a> |  | ||||||
| 								</p> |  | ||||||
| 							</div> |  | ||||||
| 							<p class="float-right"><!-- <a class="btn btn-primary font-weight-bold py-1" href="#">Follow</a> --></p> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 				</div> |  | ||||||
| 				<infinite-loading @infinite="infiniteSharesHandler" spinner="spiral"> |  | ||||||
| 					<div slot="no-more"></div> |  | ||||||
| 					<div slot="no-results"></div> |  | ||||||
| 				</infinite-loading> |  | ||||||
| 			</div> |  | ||||||
| 		</b-modal> |  | ||||||
| 		<b-modal ref="lightboxModal" | 		<b-modal ref="lightboxModal" | ||||||
| 			id="lightbox" | 			id="lightbox" | ||||||
| 			:hide-header="true" | 			:hide-header="true" | ||||||
|  | @ -710,7 +676,6 @@ export default { | ||||||
| 						likesCanLoadMore: true, | 						likesCanLoadMore: true, | ||||||
| 						likedLoaded: false, | 						likedLoaded: false, | ||||||
| 						shares: [], | 						shares: [], | ||||||
| 						sharesPage: 1, |  | ||||||
| 						lightboxMedia: false, | 						lightboxMedia: false, | ||||||
| 						replyText: '', | 						replyText: '', | ||||||
| 						replyStatus: {}, | 						replyStatus: {}, | ||||||
|  | @ -853,7 +818,6 @@ export default { | ||||||
| 									let img = `<img draggable="false" class="emojione custom-emoji" alt="${emoji.shortcode}" title="${emoji.shortcode}" src="${emoji.url}" data-original="${emoji.url}" data-static="${emoji.static_url}" width="18" height="18" onerror="this.onerror=null;this.src='/storage/emoji/missing.png';" />`; | 									let img = `<img draggable="false" class="emojione custom-emoji" alt="${emoji.shortcode}" title="${emoji.shortcode}" src="${emoji.url}" data-original="${emoji.url}" data-static="${emoji.static_url}" width="18" height="18" onerror="this.onerror=null;this.src='/storage/emoji/missing.png';" />`; | ||||||
| 									self.content = self.content.replace(`:${emoji.shortcode}:`, img); | 									self.content = self.content.replace(`:${emoji.shortcode}:`, img); | ||||||
| 								}); | 								}); | ||||||
| 								self.sharesPage = 2; |  | ||||||
| 								self.showCaption = !response.data.status.sensitive; | 								self.showCaption = !response.data.status.sensitive; | ||||||
| 								if(self.status.comments_disabled == false) { | 								if(self.status.comments_disabled == false) { | ||||||
| 									self.showComments = true; | 									self.showComments = true; | ||||||
|  | @ -922,22 +886,6 @@ export default { | ||||||
| 				}) | 				}) | ||||||
| 			}, | 			}, | ||||||
| 
 | 
 | ||||||
| 			sharesModal() { |  | ||||||
| 				if(this.status.reblogs_count == 0 || $('body').hasClass('loggedIn') == false) { |  | ||||||
| 					window.location.href = '/login?next=' + encodeURIComponent('/p/' + this.status.shortcode); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
| 				if(this.shares.length) { |  | ||||||
| 					this.$refs.sharesModal.show(); |  | ||||||
| 					return; |  | ||||||
| 				} |  | ||||||
| 				axios.get('/api/v2/shares/profile/'+this.statusUsername+'/status/'+this.statusId) |  | ||||||
| 				.then(res => { |  | ||||||
| 					this.shares = res.data.data; |  | ||||||
| 					this.$refs.sharesModal.show(); |  | ||||||
| 				}); |  | ||||||
| 			}, |  | ||||||
| 
 |  | ||||||
| 			infiniteLikesHandler($state) { | 			infiniteLikesHandler($state) { | ||||||
| 				if(!this.likesCanLoadMore) { | 				if(!this.likesCanLoadMore) { | ||||||
| 					$state.complete(); | 					$state.complete(); | ||||||
|  | @ -976,22 +924,6 @@ export default { | ||||||
| 				}); | 				}); | ||||||
| 			}, | 			}, | ||||||
| 
 | 
 | ||||||
| 			infiniteSharesHandler($state) { |  | ||||||
| 				axios.get('/api/v2/shares/profile/'+this.statusUsername+'/status/'+this.statusId, { |  | ||||||
| 					params: { |  | ||||||
| 						page: this.sharesPage, |  | ||||||
| 					}, |  | ||||||
| 				}).then(({ data }) => { |  | ||||||
| 					if (data.data.length > 0) { |  | ||||||
| 						this.shares.push(...data.data); |  | ||||||
| 						this.sharesPage++; |  | ||||||
| 						$state.loaded(); |  | ||||||
| 					} else { |  | ||||||
| 						$state.complete(); |  | ||||||
| 					} |  | ||||||
| 				}); |  | ||||||
| 			}, |  | ||||||
| 
 |  | ||||||
| 			likeStatus(event) { | 			likeStatus(event) { | ||||||
| 				if($('body').hasClass('loggedIn') == false) { | 				if($('body').hasClass('loggedIn') == false) { | ||||||
| 					window.location.href = '/login?next=' + encodeURIComponent(window.location.pathname); | 					window.location.href = '/login?next=' + encodeURIComponent(window.location.pathname); | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 Daniel Supernault
						Daniel Supernault