From 3cfb42a0f0d349e3595769f4e91c3a29f3cbebb6 Mon Sep 17 00:00:00 2001 From: nanaya Date: Tue, 11 Jul 2023 20:55:45 +0900 Subject: [PATCH 1/2] Support after_id parameter for comment pagination --- app/Http/Controllers/CommentsController.php | 11 ++++++----- app/Libraries/CommentBundle.php | 14 +++++++++++--- app/Libraries/CommentBundleParams.php | 2 ++ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php index c17d77b199e..6b8bcd23114 100644 --- a/app/Http/Controllers/CommentsController.php +++ b/app/Http/Controllers/CommentsController.php @@ -67,11 +67,12 @@ public function destroy($id) * * `pinned_comments` is only included when `commentable_type` and `commentable_id` are specified. * - * @queryParam commentable_type The type of resource to get comments for. - * @queryParam commentable_id The id of the resource to get comments for. - * @queryParam cursor Pagination option. See [CommentSort](#commentsort) for detail. The format follows [Cursor](#cursor) except it's not currently included in the response. - * @queryParam parent_id Limit to comments which are reply to the specified id. Specify 0 to get top level comments. - * @queryParam sort Sort option as defined in [CommentSort](#commentsort). Defaults to `new` for guests and user-specified default when authenticated. + * @queryParam after_id Return comments which come after the specified comment id as per sort option. No-example + * @queryParam commentable_type The type of resource to get comments for. Example: beatmapset + * @queryParam commentable_id The id of the resource to get comments for. Example: 1 + * @queryParam cursor Pagination option. See [CommentSort](#commentsort) for detail. The format follows [Cursor](#cursor) except it's not currently included in the response. No-example + * @queryParam parent_id Limit to comments which are reply to the specified id. Specify 0 to get top level comments. Example: 1 + * @queryParam sort Sort option as defined in [CommentSort](#commentsort). Defaults to `new` for guests and user-specified default when authenticated. Example: new */ public function index() { diff --git a/app/Libraries/CommentBundle.php b/app/Libraries/CommentBundle.php index 7404eb0f023..764398762dc 100644 --- a/app/Libraries/CommentBundle.php +++ b/app/Libraries/CommentBundle.php @@ -171,7 +171,9 @@ public function countForPaginator() private function getComments($query, $isChildren = true, $pinnedOnly = false) { - $sortOrCursorHelper = $pinnedOnly ? 'new' : $this->params->cursorHelper; + $cursorHelper = $pinnedOnly + ? Comment::makeDbCursorHelper('new') + : $this->params->cursorHelper; $queryLimit = $this->params->limit; if (!$isChildren) { @@ -180,14 +182,20 @@ private function getComments($query, $isChildren = true, $pinnedOnly = false) } $queryLimit++; - $cursor = $this->params->cursor; + + if ($this->params->afterId === null) { + $cursor = $this->params->cursor; + } else { + $lastComment = Comment::findOrFail($this->params->afterId); + $cursor = $cursorHelper->next([$lastComment]); + } if ($cursor === null) { $query->offset(max_offset($this->params->page, $this->params->limit)); } } - $query->cursorSort($sortOrCursorHelper, $cursor ?? null); + $query->cursorSort($cursorHelper, $cursor ?? null); if (!$this->includeDeleted) { $query->whereNull('deleted_at'); diff --git a/app/Libraries/CommentBundleParams.php b/app/Libraries/CommentBundleParams.php index 8b7a0fbab63..b727b17d382 100644 --- a/app/Libraries/CommentBundleParams.php +++ b/app/Libraries/CommentBundleParams.php @@ -13,6 +13,7 @@ class CommentBundleParams const DEFAULT_PAGE = 1; const DEFAULT_LIMIT = 50; + public ?int $afterId = null; public $userId; public $commentableId; public $commentableType; @@ -64,6 +65,7 @@ public function setAll($params) $this->cursorHelper = Comment::makeDbCursorHelper($params['sort'] ?? $this->sort); $this->cursor = get_arr($params['cursor'] ?? null); $this->sort = $this->cursorHelper->getSortName(); + $this->afterId = get_int($params['after_id'] ?? null); } public function filterByParentId() From 7d9bd08e96b25ff8f16b824841ad012a68773142 Mon Sep 17 00:00:00 2001 From: nanaya Date: Tue, 11 Jul 2023 21:17:32 +0900 Subject: [PATCH 2/2] Call it `after` instead to match existing parameter --- app/Http/Controllers/CommentsController.php | 2 +- app/Libraries/CommentBundle.php | 4 ++-- app/Libraries/CommentBundleParams.php | 4 ++-- resources/js/components/comment-show-more.tsx | 7 +------ 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/Http/Controllers/CommentsController.php b/app/Http/Controllers/CommentsController.php index 6b8bcd23114..b89ce074b41 100644 --- a/app/Http/Controllers/CommentsController.php +++ b/app/Http/Controllers/CommentsController.php @@ -67,7 +67,7 @@ public function destroy($id) * * `pinned_comments` is only included when `commentable_type` and `commentable_id` are specified. * - * @queryParam after_id Return comments which come after the specified comment id as per sort option. No-example + * @queryParam after Return comments which come after the specified comment id as per sort option. No-example * @queryParam commentable_type The type of resource to get comments for. Example: beatmapset * @queryParam commentable_id The id of the resource to get comments for. Example: 1 * @queryParam cursor Pagination option. See [CommentSort](#commentsort) for detail. The format follows [Cursor](#cursor) except it's not currently included in the response. No-example diff --git a/app/Libraries/CommentBundle.php b/app/Libraries/CommentBundle.php index 764398762dc..359d3380cec 100644 --- a/app/Libraries/CommentBundle.php +++ b/app/Libraries/CommentBundle.php @@ -183,10 +183,10 @@ private function getComments($query, $isChildren = true, $pinnedOnly = false) $queryLimit++; - if ($this->params->afterId === null) { + if ($this->params->after === null) { $cursor = $this->params->cursor; } else { - $lastComment = Comment::findOrFail($this->params->afterId); + $lastComment = Comment::findOrFail($this->params->after); $cursor = $cursorHelper->next([$lastComment]); } diff --git a/app/Libraries/CommentBundleParams.php b/app/Libraries/CommentBundleParams.php index b727b17d382..2c84fa2e469 100644 --- a/app/Libraries/CommentBundleParams.php +++ b/app/Libraries/CommentBundleParams.php @@ -13,7 +13,7 @@ class CommentBundleParams const DEFAULT_PAGE = 1; const DEFAULT_LIMIT = 50; - public ?int $afterId = null; + public ?int $after = null; public $userId; public $commentableId; public $commentableType; @@ -65,7 +65,7 @@ public function setAll($params) $this->cursorHelper = Comment::makeDbCursorHelper($params['sort'] ?? $this->sort); $this->cursor = get_arr($params['cursor'] ?? null); $this->sort = $this->cursorHelper->getSortName(); - $this->afterId = get_int($params['after_id'] ?? null); + $this->after = get_int($params['after'] ?? null); } public function filterByParentId() diff --git a/resources/js/components/comment-show-more.tsx b/resources/js/components/comment-show-more.tsx index aa36b60742a..05aa699957c 100644 --- a/resources/js/components/comment-show-more.tsx +++ b/resources/js/components/comment-show-more.tsx @@ -67,12 +67,7 @@ export default class CommentShowMore extends React.Component { const lastComment = last(this.props.comments); if (lastComment != null) { - // TODO: convert to plain after_id params of some sort instead of cursor - params.cursor = { - created_at: lastComment.createdAt, - id: lastComment.id, - votes_count: lastComment.votesCount, - }; + params.after = lastComment.id; } this.xhr = $.ajax(route('comments.index'), { data: params, dataType: 'json' });