mirror of https://github.com/Chocobozzz/PeerTube
Add comment filtering by reply count
parent
6f79be110d
commit
c1125bcadc
|
@ -5,3 +5,6 @@ export type VideoSortField = 'name' | '-name'
|
|||
| 'views' | '-views'
|
||||
| 'likes' | '-likes'
|
||||
| 'trending' | '-trending'
|
||||
|
||||
export type CommentSortField = 'createdAt' | '-createdAt'
|
||||
| 'totalReplies' | '-totalReplies'
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
import { environment } from '../../../../environments/environment'
|
||||
import { RestExtractor, RestService } from '../../../shared/rest'
|
||||
import { ComponentPagination } from '../../../shared/rest/component-pagination.model'
|
||||
import { VideoSortField } from '../../../shared/video/sort-field.type'
|
||||
import { CommentSortField } from '../../../shared/video/sort-field.type'
|
||||
import { VideoComment } from './video-comment.model'
|
||||
|
||||
@Injectable()
|
||||
|
@ -51,7 +51,7 @@ export class VideoCommentService {
|
|||
getVideoCommentThreads (parameters: {
|
||||
videoId: number | string,
|
||||
componentPagination: ComponentPagination,
|
||||
sort: VideoSortField
|
||||
sort: CommentSortField
|
||||
}): Observable<ResultList<VideoComment>> {
|
||||
const { videoId, componentPagination, sort } = parameters
|
||||
|
||||
|
|
|
@ -10,6 +10,16 @@
|
|||
</div>
|
||||
|
||||
<my-feed [syndicationItems]="syndicationItems"></my-feed>
|
||||
|
||||
<div ngbDropdown class="d-inline-block ml-4">
|
||||
<button class="btn btn-sm btn-outline-secondary" id="dropdownSortComments" ngbDropdownToggle i18n>
|
||||
Sort by
|
||||
</button>
|
||||
<div ngbDropdownMenu aria-labelledby="dropdownSortComments">
|
||||
<button (click)="handleSortChange('-createdAt')" ngbDropdownItem i18n>Most recent first (default)</button>
|
||||
<button (click)="handleSortChange('-totalReplies')" ngbDropdownItem i18n>Most replies first</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ng-template [ngIf]="video.commentsEnabled === true">
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
margin-right: 0;
|
||||
}
|
||||
|
||||
#dropdownSortComments {
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
border: none;
|
||||
}
|
||||
|
||||
my-feed {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/v
|
|||
import { AuthService } from '../../../core/auth'
|
||||
import { ComponentPagination, hasMoreItems } from '../../../shared/rest/component-pagination.model'
|
||||
import { User } from '../../../shared/users'
|
||||
import { VideoSortField } from '../../../shared/video/sort-field.type'
|
||||
import { CommentSortField } from '../../../shared/video/sort-field.type'
|
||||
import { VideoDetails } from '../../../shared/video/video-details.model'
|
||||
import { VideoComment } from './video-comment.model'
|
||||
import { VideoCommentService } from './video-comment.service'
|
||||
|
@ -28,7 +28,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
|
||||
comments: VideoComment[] = []
|
||||
highlightedThread: VideoComment
|
||||
sort: VideoSortField = '-createdAt'
|
||||
sort: CommentSortField = '-createdAt'
|
||||
componentPagination: ComponentPagination = {
|
||||
currentPage: 1,
|
||||
itemsPerPage: 10,
|
||||
|
@ -152,6 +152,13 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
|
|||
this.viewReplies(commentTree.comment.id)
|
||||
}
|
||||
|
||||
handleSortChange (sort: CommentSortField) {
|
||||
if (this.sort === sort) return
|
||||
|
||||
this.sort = sort
|
||||
this.resetVideo()
|
||||
}
|
||||
|
||||
handleTimestampClicked (timestamp: number) {
|
||||
this.timestampClicked.emit(timestamp)
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ const SORTABLE_COLUMNS = {
|
|||
VIDEO_ABUSES: [ 'id', 'createdAt', 'state' ],
|
||||
VIDEO_CHANNELS: [ 'id', 'name', 'updatedAt', 'createdAt' ],
|
||||
VIDEO_IMPORTS: [ 'createdAt' ],
|
||||
VIDEO_COMMENT_THREADS: [ 'createdAt' ],
|
||||
VIDEO_COMMENT_THREADS: [ 'createdAt', 'totalReplies' ],
|
||||
VIDEO_RATES: [ 'createdAt' ],
|
||||
BLACKLISTS: [ 'id', 'name', 'duration', 'views', 'likes', 'dislikes', 'uuid', 'createdAt' ],
|
||||
FOLLOWERS: [ 'createdAt', 'state', 'score' ],
|
||||
|
|
|
@ -22,6 +22,19 @@ function getSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderIt
|
|||
return [ [ finalField, direction ], lastSort ]
|
||||
}
|
||||
|
||||
function getCommentSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||||
const { direction, field } = buildDirectionAndField(value)
|
||||
|
||||
if (field === 'totalReplies') {
|
||||
return [
|
||||
[ Sequelize.literal('"totalReplies"'), direction ],
|
||||
lastSort
|
||||
]
|
||||
}
|
||||
|
||||
return getSort(value, lastSort)
|
||||
}
|
||||
|
||||
function getVideoSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||||
const { direction, field } = buildDirectionAndField(value)
|
||||
|
||||
|
@ -167,6 +180,7 @@ export {
|
|||
SortType,
|
||||
buildLocalAccountIdsIn,
|
||||
getSort,
|
||||
getCommentSort,
|
||||
getVideoSort,
|
||||
getBlacklistSort,
|
||||
createSimilarityAttribute,
|
||||
|
|
|
@ -6,7 +6,7 @@ import { isActivityPubUrlValid } from '../../helpers/custom-validators/activityp
|
|||
import { CONSTRAINTS_FIELDS, WEBSERVER } from '../../initializers/constants'
|
||||
import { AccountModel } from '../account/account'
|
||||
import { ActorModel } from '../activitypub/actor'
|
||||
import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils'
|
||||
import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getCommentSort, throwIfNotValid } from '../utils'
|
||||
import { VideoModel } from './video'
|
||||
import { VideoChannelModel } from './video-channel'
|
||||
import { getServerActor } from '../../helpers/utils'
|
||||
|
@ -259,7 +259,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
|
|||
const query = {
|
||||
offset: start,
|
||||
limit: count,
|
||||
order: getSort(sort),
|
||||
order: getCommentSort(sort),
|
||||
where: {
|
||||
videoId,
|
||||
inReplyToCommentId: null,
|
||||
|
|
Loading…
Reference in New Issue