165 lines
6.1 KiB
Markdown
165 lines
6.1 KiB
Markdown
|
# Пагинация комментариев
|
|||
|
|
|||
|
## Обзор
|
|||
|
|
|||
|
Реализована система пагинации комментариев по веткам, которая позволяет эффективно загружать и отображать вложенные ветки обсуждений. Основные преимущества:
|
|||
|
|
|||
|
1. Загрузка только необходимых комментариев, а не всего дерева
|
|||
|
2. Снижение нагрузки на сервер и клиент
|
|||
|
3. Возможность эффективной навигации по большим обсуждениям
|
|||
|
4. Предзагрузка первых N ответов для улучшения UX
|
|||
|
|
|||
|
## API для иерархической загрузки комментариев
|
|||
|
|
|||
|
### GraphQL запрос `load_comments_branch`
|
|||
|
|
|||
|
```graphql
|
|||
|
query LoadCommentsBranch(
|
|||
|
$shout: Int!,
|
|||
|
$parentId: Int,
|
|||
|
$limit: Int,
|
|||
|
$offset: Int,
|
|||
|
$sort: ReactionSort,
|
|||
|
$childrenLimit: Int,
|
|||
|
$childrenOffset: Int
|
|||
|
) {
|
|||
|
load_comments_branch(
|
|||
|
shout: $shout,
|
|||
|
parent_id: $parentId,
|
|||
|
limit: $limit,
|
|||
|
offset: $offset,
|
|||
|
sort: $sort,
|
|||
|
children_limit: $childrenLimit,
|
|||
|
children_offset: $childrenOffset
|
|||
|
) {
|
|||
|
id
|
|||
|
body
|
|||
|
created_at
|
|||
|
created_by {
|
|||
|
id
|
|||
|
name
|
|||
|
slug
|
|||
|
pic
|
|||
|
}
|
|||
|
kind
|
|||
|
reply_to
|
|||
|
stat {
|
|||
|
rating
|
|||
|
commented
|
|||
|
}
|
|||
|
first_replies {
|
|||
|
id
|
|||
|
body
|
|||
|
created_at
|
|||
|
created_by {
|
|||
|
id
|
|||
|
name
|
|||
|
slug
|
|||
|
pic
|
|||
|
}
|
|||
|
kind
|
|||
|
reply_to
|
|||
|
stat {
|
|||
|
rating
|
|||
|
commented
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### Параметры запроса
|
|||
|
|
|||
|
| Параметр | Тип | По умолчанию | Описание |
|
|||
|
|----------|-----|--------------|----------|
|
|||
|
| shout | Int! | - | ID статьи, к которой относятся комментарии |
|
|||
|
| parent_id | Int | null | ID родительского комментария. Если null, загружаются корневые комментарии |
|
|||
|
| limit | Int | 10 | Максимальное количество комментариев для загрузки |
|
|||
|
| offset | Int | 0 | Смещение для пагинации |
|
|||
|
| sort | ReactionSort | newest | Порядок сортировки: newest, oldest, like |
|
|||
|
| children_limit | Int | 3 | Максимальное количество дочерних комментариев для каждого родительского |
|
|||
|
| children_offset | Int | 0 | Смещение для пагинации дочерних комментариев |
|
|||
|
|
|||
|
### Поля в ответе
|
|||
|
|
|||
|
Каждый комментарий содержит следующие основные поля:
|
|||
|
|
|||
|
- `id`: ID комментария
|
|||
|
- `body`: Текст комментария
|
|||
|
- `created_at`: Время создания
|
|||
|
- `created_by`: Информация об авторе
|
|||
|
- `kind`: Тип реакции (COMMENT)
|
|||
|
- `reply_to`: ID родительского комментария (null для корневых)
|
|||
|
- `first_replies`: Первые N дочерних комментариев
|
|||
|
- `stat`: Статистика комментария, включающая:
|
|||
|
- `commented`: Количество ответов на комментарий
|
|||
|
- `rating`: Рейтинг комментария
|
|||
|
|
|||
|
## Примеры использования
|
|||
|
|
|||
|
### Загрузка корневых комментариев с первыми ответами
|
|||
|
|
|||
|
```javascript
|
|||
|
const { data } = await client.query({
|
|||
|
query: LOAD_COMMENTS_BRANCH,
|
|||
|
variables: {
|
|||
|
shout: 222,
|
|||
|
limit: 10,
|
|||
|
offset: 0,
|
|||
|
sort: "newest",
|
|||
|
childrenLimit: 3
|
|||
|
}
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
### Загрузка ответов на конкретный комментарий
|
|||
|
|
|||
|
```javascript
|
|||
|
const { data } = await client.query({
|
|||
|
query: LOAD_COMMENTS_BRANCH,
|
|||
|
variables: {
|
|||
|
shout: 222,
|
|||
|
parentId: 123, // ID комментария, для которого загружаем ответы
|
|||
|
limit: 10,
|
|||
|
offset: 0,
|
|||
|
sort: "oldest" // Сортируем ответы от старых к новым
|
|||
|
}
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
### Пагинация дочерних комментариев
|
|||
|
|
|||
|
Для загрузки дополнительных ответов на комментарий:
|
|||
|
|
|||
|
```javascript
|
|||
|
const { data } = await client.query({
|
|||
|
query: LOAD_COMMENTS_BRANCH,
|
|||
|
variables: {
|
|||
|
shout: 222,
|
|||
|
parentId: 123,
|
|||
|
limit: 10,
|
|||
|
offset: 0,
|
|||
|
childrenLimit: 5,
|
|||
|
childrenOffset: 3 // Пропускаем первые 3 комментария (уже загруженные)
|
|||
|
}
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
## Рекомендации по клиентской реализации
|
|||
|
|
|||
|
1. Для эффективной работы со сложными ветками обсуждений рекомендуется:
|
|||
|
|
|||
|
- Сначала загружать только корневые комментарии с первыми N ответами
|
|||
|
- При наличии дополнительных ответов (когда `stat.commented > first_replies.length`)
|
|||
|
добавить кнопку "Показать все ответы"
|
|||
|
- При нажатии на кнопку загружать дополнительные ответы с помощью запроса с указанным `parentId`
|
|||
|
|
|||
|
2. Для сортировки:
|
|||
|
- По умолчанию использовать `newest` для отображения свежих обсуждений
|
|||
|
- Предусмотреть переключатель сортировки для всего дерева комментариев
|
|||
|
- При изменении сортировки перезагружать данные с новым параметром `sort`
|
|||
|
|
|||
|
3. Для улучшения производительности:
|
|||
|
- Кешировать результаты запросов на клиенте
|
|||
|
- Использовать оптимистичные обновления при добавлении/редактировании комментариев
|
|||
|
- При необходимости загружать комментарии порциями (ленивая загрузка)
|