Bläddra i källkod

Update ApiV1Controller, fix link header pagination in /api/v1/statuses/{id}/reblogged_by

Daniel Supernault 2 år sedan
förälder
incheckning
e346b675d4

+ 32 - 16
app/Http/Controllers/Api/ApiV1Controller.php

@@ -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()) {
-				$links = '<' . $res->previousPageUrl() .'>; rel="prev"';
-			}
+			if($res->onFirstPage()) {
+				if($res->nextPageUrl()) {
+					$links = '<' . $res->nextPageUrl() .'>; rel="prev"';
+				}
+			} else {
+				if($res->previousPageUrl()) {
+					$links = '<' . $res->previousPageUrl() .'>; rel="next"';
+				}
 
 
-			if($res->nextPageUrl()) {
-				if(!empty($links)) {
-					$links .= ', ';
+				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) {
-			$account = AccountService::getMastodon($status->profile_id, true);
+		$res = $res->map(function($status) use($pid, $napi) {
+			$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) {

+ 15 - 9
resources/assets/components/partials/post/ShareModal.vue

@@ -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) {
-							this.page = links.next.cursor;
+						if(links.prev) {
+							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) {
-							this.page = links.next.cursor;
+						if(links.prev) {
+							this.cursor = links.prev.cursor;
 						} else {
 						} else {
 							this.canLoadMore = false;
 							this.canLoadMore = false;
 						}
 						}
+					} else {
+						this.canLoadMore = false;
 					}
 					}
 					this.isFetchingMore = false;
 					this.isFetchingMore = false;
 				})
 				})

+ 0 - 68
resources/assets/js/components/PostComponent.vue

@@ -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);