| 'views' | '-views'
| 'likes' | '-likes'
| 'trending' | '-trending'
+
+export type CommentSortField = 'createdAt' | '-createdAt'
+ | 'totalReplies' | '-totalReplies'
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()
getVideoCommentThreads (parameters: {
videoId: number | string,
componentPagination: ComponentPagination,
- sort: VideoSortField
+ sort: CommentSortField
}): Observable<ResultList<VideoComment>> {
const { videoId, componentPagination, sort } = parameters
</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">
margin-right: 0;
}
+#dropdownSortComments {
+ font-weight: 600;
+ text-transform: uppercase;
+ border: none;
+}
+
my-feed {
display: inline-block;
margin-left: 5px;
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'
comments: VideoComment[] = []
highlightedThread: VideoComment
- sort: VideoSortField = '-createdAt'
+ sort: CommentSortField = '-createdAt'
componentPagination: ComponentPagination = {
currentPage: 1,
itemsPerPage: 10,
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)
}
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' ],
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)
SortType,
buildLocalAccountIdsIn,
getSort,
+ getCommentSort,
getVideoSort,
getBlacklistSort,
createSimilarityAttribute,
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'
const query = {
offset: start,
limit: count,
- order: getSort(sort),
+ order: getCommentSort(sort),
where: {
videoId,
inReplyToCommentId: null,