mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-29 09:43:16 +00:00
Update ApiV1Controller, fix link header pagination in /api/v1/statuses/{id}/favourited_by
This commit is contained in:
parent
1f4f8252f2
commit
adc82ecab3
5 changed files with 109 additions and 39 deletions
|
@ -2658,13 +2658,17 @@ class ApiV1Controller extends Controller
|
|||
abort_if(!$request->user(), 403);
|
||||
|
||||
$this->validate($request, [
|
||||
'limit' => 'nullable|integer|min:1|max:100'
|
||||
'limit' => 'nullable|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 ||
|
||||
|
@ -2674,7 +2678,7 @@ 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);
|
||||
}
|
||||
|
@ -2696,29 +2700,39 @@ 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($like) use($user) {
|
||||
$account = AccountService::getMastodon($like->profile_id, true);
|
||||
$res = $res->map(function($like) use($pid, $napi) {
|
||||
$account = $napi ? AccountService::get($like->profile_id, true) : AccountService::getMastodon($like->profile_id, true);
|
||||
if(!$account) {
|
||||
return false;
|
||||
}
|
||||
$account['follows'] = $like->profile_id == $user->profile_id ? null : FollowerService::follows($user->profile_id, $like->profile_id);
|
||||
|
||||
if($napi) {
|
||||
$account['follows'] = $like->profile_id == $pid ? null : FollowerService::follows($pid, $like->profile_id);
|
||||
}
|
||||
return $account;
|
||||
})
|
||||
->filter(function($account) use($user) {
|
||||
->filter(function($account) {
|
||||
return $account && isset($account['id']);
|
||||
})
|
||||
->values();
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
||||
fetchLikes() {
|
||||
axios.get('/api/v1/statuses/'+this.status.id+'/favourited_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+'/favourited_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;
|
||||
})
|
||||
|
|
|
@ -151,6 +151,8 @@
|
|||
} else {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
} else {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
this.feed.push(...res.data);
|
||||
this.isLoaded = true;
|
||||
|
|
|
@ -149,6 +149,8 @@
|
|||
} else {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
} else {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
this.feed.push(...res.data);
|
||||
this.isLoaded = true;
|
||||
|
|
|
@ -371,7 +371,7 @@
|
|||
centered
|
||||
title="Likes"
|
||||
body-class="list-group-flush py-3 px-0">
|
||||
<div class="list-group">
|
||||
<div v-if="likedLoaded" class="list-group">
|
||||
<div class="list-group-item border-0 py-1" v-for="(user, index) in likes" :key="'modal_likes_'+index">
|
||||
<div class="media">
|
||||
<a :href="user.url">
|
||||
|
@ -392,11 +392,14 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<infinite-loading @infinite="infiniteLikesHandler" spinner="spiral">
|
||||
<infinite-loading v-if="likesCanLoadMore" @infinite="infiniteLikesHandler" spinner="spiral">
|
||||
<div slot="no-more"></div>
|
||||
<div slot="no-results"></div>
|
||||
</infinite-loading>
|
||||
</div>
|
||||
<div v-else class="d-flex justify-content-center align-items-center h-100">
|
||||
<b-spinner />
|
||||
</div>
|
||||
</b-modal>
|
||||
<b-modal ref="sharesModal"
|
||||
id="s-modal"
|
||||
|
@ -667,6 +670,7 @@ import VueTribute from 'vue-tribute';
|
|||
import PollCard from './partials/PollCard.vue';
|
||||
import CommentFeed from './partials/CommentFeed.vue';
|
||||
import StatusCard from './partials/StatusCard.vue';
|
||||
import { parseLinkHeader } from '@web3-storage/parse-link-header';
|
||||
|
||||
pixelfed.postComponent = {};
|
||||
|
||||
|
@ -702,7 +706,9 @@ export default {
|
|||
shared: false
|
||||
},
|
||||
likes: [],
|
||||
likesPage: 1,
|
||||
likesCursor: null,
|
||||
likesCanLoadMore: true,
|
||||
likedLoaded: false,
|
||||
shares: [],
|
||||
sharesPage: 1,
|
||||
lightboxMedia: false,
|
||||
|
@ -847,7 +853,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';" />`;
|
||||
self.content = self.content.replace(`:${emoji.shortcode}:`, img);
|
||||
});
|
||||
self.likesPage = 2;
|
||||
self.sharesPage = 2;
|
||||
self.showCaption = !response.data.status.sensitive;
|
||||
if(self.status.comments_disabled == false) {
|
||||
|
@ -886,15 +891,35 @@ export default {
|
|||
window.location.href = '/login?next=' + encodeURIComponent('/p/' + this.status.shortcode);
|
||||
return;
|
||||
}
|
||||
if(this.likes.length) {
|
||||
if(this.likes && this.likes.length) {
|
||||
this.$refs.likesModal.show();
|
||||
return;
|
||||
}
|
||||
axios.get('/api/v2/likes/profile/'+this.statusUsername+'/status/'+this.statusId)
|
||||
axios.get('/api/v1/statuses/'+ this.statusId + '/favourited_by', {
|
||||
params: {
|
||||
limit: 40,
|
||||
'_pe': 1
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
this.likes = res.data.data;
|
||||
this.likes = res.data;
|
||||
|
||||
if(res.headers && res.headers.link) {
|
||||
const links = parseLinkHeader(res.headers.link);
|
||||
if(links.prev) {
|
||||
this.likesCursor = links.prev.cursor;
|
||||
this.likesCanLoadMore = true;
|
||||
} else {
|
||||
this.likesCanLoadMore = false;
|
||||
}
|
||||
} else {
|
||||
this.likesCanLoadMore = false;
|
||||
}
|
||||
this.$refs.likesModal.show();
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
setTimeout(() => { this.likedLoaded = true }, 1000);
|
||||
})
|
||||
},
|
||||
|
||||
sharesModal() {
|
||||
|
@ -914,15 +939,36 @@ export default {
|
|||
},
|
||||
|
||||
infiniteLikesHandler($state) {
|
||||
let api = '/api/v2/likes/profile/'+this.statusUsername+'/status/'+this.statusId;
|
||||
axios.get(api, {
|
||||
if(!this.likesCanLoadMore) {
|
||||
$state.complete();
|
||||
return;
|
||||
}
|
||||
|
||||
axios.get('/api/v1/statuses/'+ this.statusId + '/favourited_by', {
|
||||
params: {
|
||||
page: this.likesPage,
|
||||
cursor: this.likesCursor,
|
||||
limit: 20,
|
||||
'_pe': 1
|
||||
},
|
||||
}).then(({ data }) => {
|
||||
if (data.data.length > 0) {
|
||||
this.likes.push(...data.data);
|
||||
this.likesPage++;
|
||||
}).then(res => {
|
||||
if (res && res.data.length) {
|
||||
this.likes.push(...res.data);
|
||||
}
|
||||
|
||||
if(res.headers && res.headers.link) {
|
||||
const links = parseLinkHeader(res.headers.link);
|
||||
if(links.prev) {
|
||||
this.likesCursor = links.prev.cursor;
|
||||
this.likesCanLoadMore = true;
|
||||
} else {
|
||||
this.likesCanLoadMore = false;
|
||||
}
|
||||
} else {
|
||||
this.likesCanLoadMore = false;
|
||||
}
|
||||
return this.likesCanLoadMore;
|
||||
}).then(res => {
|
||||
if(res) {
|
||||
$state.loaded();
|
||||
} else {
|
||||
$state.complete();
|
||||
|
|
Loading…
Reference in a new issue