From e346b675d4b95353fc6eaa79bc7ff66ed46695bf Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Sun, 5 Mar 2023 00:21:42 -0700 Subject: [PATCH] Update ApiV1Controller, fix link header pagination in /api/v1/statuses/{id}/reblogged_by --- app/Http/Controllers/Api/ApiV1Controller.php | 50 +++++++++----- .../components/partials/post/ShareModal.vue | 24 ++++--- .../assets/js/components/PostComponent.vue | 68 ------------------- 3 files changed, 48 insertions(+), 94 deletions(-) diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index 8957f6e28..cb2a31bb9 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -527,7 +527,7 @@ class ApiV1Controller extends Controller } 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()) { - $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); $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(); + $pid = $user->profile_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( !$status->type || @@ -2598,10 +2602,14 @@ class ApiV1Controller extends Controller if(!$author) { 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 { abort_if(!in_array($status->scope, ['public','unlisted']), 403); } + + if($request->has('cursor')) { + return $this->json([]); + } } $res = Status::where('reblog_of_id', $status->id) @@ -2616,26 +2624,34 @@ class ApiV1Controller extends Controller $headers = []; if($author && $res->hasPages()) { $links = ''; - if($res->previousPageUrl()) { - $links = '<' . $res->previousPageUrl() .'>; rel="prev"'; - } - - if($res->nextPageUrl()) { - if(!empty($links)) { - $links .= ', '; + 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 .= ', '; + } + $links .= '<' . $res->nextPageUrl() .'>; rel="prev"'; } - $links .= '<' . $res->nextPageUrl() .'>; rel="next"'; } $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) { 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; }) ->filter(function($account) { diff --git a/resources/assets/components/partials/post/ShareModal.vue b/resources/assets/components/partials/post/ShareModal.vue index f9301d2b4..cc77b83cb 100644 --- a/resources/assets/components/partials/post/ShareModal.vue +++ b/resources/assets/components/partials/post/ShareModal.vue @@ -104,7 +104,7 @@ isFetchingMore: false, likes: [], ids: [], - page: undefined, + cursor: undefined, isUpdatingFollowState: false, followStateIndex: undefined, user: window._sharedData.user @@ -119,13 +119,14 @@ this.isFetchingMore = false; this.likes = []; this.ids = []; - this.page = undefined; + this.cursor = undefined; }, fetchShares() { axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { params: { - limit: 40 + limit: 40, + '_pe': 1 } }) .then(res => { @@ -133,19 +134,21 @@ this.likes = res.data; if(res.headers && 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; } else { this.canLoadMore = false; } + } else { + this.canLoadMore = false; } this.isLoading = false; }); }, open() { - if(this.page) { + if(this.cursor) { this.clear(); } this.isOpen = true; @@ -163,7 +166,8 @@ axios.get('/api/v1/statuses/'+this.status.id+'/reblogged_by', { params: { limit: 10, - cursor: this.page + cursor: this.cursor, + '_pe': 1 } }).then(res => { if(!res.data || !res.data.length) { @@ -179,11 +183,13 @@ }) if(res.headers && 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 { this.canLoadMore = false; } + } else { + this.canLoadMore = false; } this.isFetchingMore = false; }) diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index 073eaa996..9aec62985 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -401,40 +401,6 @@ - -
-
-
- - - -
-
-

- - {{user.username}} - -

-

- {{user.display_name}} - -

-
-

-
-
-
- -
-
-
-
-
`; self.content = self.content.replace(`:${emoji.shortcode}:`, img); }); - self.sharesPage = 2; self.showCaption = !response.data.status.sensitive; if(self.status.comments_disabled == false) { 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) { if(!this.likesCanLoadMore) { $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) { if($('body').hasClass('loggedIn') == false) { window.location.href = '/login?next=' + encodeURIComponent(window.location.pathname);