mirror of https://github.com/Chocobozzz/PeerTube
147 lines
3.8 KiB
TypeScript
147 lines
3.8 KiB
TypeScript
|
import { literal, OrderItem, Sequelize } from 'sequelize'
|
||
|
|
||
|
// Translate for example "-name" to [ [ 'name', 'DESC' ], [ 'id', 'ASC' ] ]
|
||
|
function getSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
let finalField: string | ReturnType<typeof Sequelize.col>
|
||
|
|
||
|
if (field.toLowerCase() === 'match') { // Search
|
||
|
finalField = Sequelize.col('similarity')
|
||
|
} else {
|
||
|
finalField = field
|
||
|
}
|
||
|
|
||
|
return [ [ finalField, direction ], lastSort ]
|
||
|
}
|
||
|
|
||
|
function getAdminUsersSort (value: string): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
let finalField: string | ReturnType<typeof Sequelize.col>
|
||
|
|
||
|
if (field === 'videoQuotaUsed') { // Users list
|
||
|
finalField = Sequelize.col('videoQuotaUsed')
|
||
|
} else {
|
||
|
finalField = field
|
||
|
}
|
||
|
|
||
|
const nullPolicy = direction === 'ASC'
|
||
|
? 'NULLS FIRST'
|
||
|
: 'NULLS LAST'
|
||
|
|
||
|
// FIXME: typings
|
||
|
return [ [ finalField as any, direction, nullPolicy ], [ 'id', 'ASC' ] ]
|
||
|
}
|
||
|
|
||
|
function getPlaylistSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
if (field.toLowerCase() === 'name') {
|
||
|
return [ [ 'displayName', direction ], lastSort ]
|
||
|
}
|
||
|
|
||
|
return getSort(value, lastSort)
|
||
|
}
|
||
|
|
||
|
function getVideoSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
if (field.toLowerCase() === 'trending') { // Sort by aggregation
|
||
|
return [
|
||
|
[ Sequelize.fn('COALESCE', Sequelize.fn('SUM', Sequelize.col('VideoViews.views')), '0'), direction ],
|
||
|
|
||
|
[ Sequelize.col('VideoModel.views'), direction ],
|
||
|
|
||
|
lastSort
|
||
|
]
|
||
|
} else if (field === 'publishedAt') {
|
||
|
return [
|
||
|
[ 'ScheduleVideoUpdate', 'updateAt', direction + ' NULLS LAST' ],
|
||
|
|
||
|
[ Sequelize.col('VideoModel.publishedAt'), direction ],
|
||
|
|
||
|
lastSort
|
||
|
]
|
||
|
}
|
||
|
|
||
|
let finalField: string | ReturnType<typeof Sequelize.col>
|
||
|
|
||
|
// Alias
|
||
|
if (field.toLowerCase() === 'match') { // Search
|
||
|
finalField = Sequelize.col('similarity')
|
||
|
} else {
|
||
|
finalField = field
|
||
|
}
|
||
|
|
||
|
const firstSort: OrderItem = typeof finalField === 'string'
|
||
|
? finalField.split('.').concat([ direction ]) as OrderItem
|
||
|
: [ finalField, direction ]
|
||
|
|
||
|
return [ firstSort, lastSort ]
|
||
|
}
|
||
|
|
||
|
function getBlacklistSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
const videoFields = new Set([ 'name', 'duration', 'views', 'likes', 'dislikes', 'uuid' ])
|
||
|
|
||
|
if (videoFields.has(field)) {
|
||
|
return [
|
||
|
[ literal(`"Video.${field}" ${direction}`) ],
|
||
|
lastSort
|
||
|
] as OrderItem[]
|
||
|
}
|
||
|
|
||
|
return getSort(value, lastSort)
|
||
|
}
|
||
|
|
||
|
function getInstanceFollowsSort (value: string, lastSort: OrderItem = [ 'id', 'ASC' ]): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
|
||
|
if (field === 'redundancyAllowed') {
|
||
|
return [
|
||
|
[ 'ActorFollowing.Server.redundancyAllowed', direction ],
|
||
|
lastSort
|
||
|
]
|
||
|
}
|
||
|
|
||
|
return getSort(value, lastSort)
|
||
|
}
|
||
|
|
||
|
function getChannelSyncSort (value: string): OrderItem[] {
|
||
|
const { direction, field } = buildSortDirectionAndField(value)
|
||
|
if (field.toLowerCase() === 'videochannel') {
|
||
|
return [
|
||
|
[ literal('"VideoChannel.name"'), direction ]
|
||
|
]
|
||
|
}
|
||
|
return [ [ field, direction ] ]
|
||
|
}
|
||
|
|
||
|
function buildSortDirectionAndField (value: string) {
|
||
|
let field: string
|
||
|
let direction: 'ASC' | 'DESC'
|
||
|
|
||
|
if (value.substring(0, 1) === '-') {
|
||
|
direction = 'DESC'
|
||
|
field = value.substring(1)
|
||
|
} else {
|
||
|
direction = 'ASC'
|
||
|
field = value
|
||
|
}
|
||
|
|
||
|
return { direction, field }
|
||
|
}
|
||
|
|
||
|
export {
|
||
|
buildSortDirectionAndField,
|
||
|
getPlaylistSort,
|
||
|
getSort,
|
||
|
getAdminUsersSort,
|
||
|
getVideoSort,
|
||
|
getBlacklistSort,
|
||
|
getChannelSyncSort,
|
||
|
getInstanceFollowsSort
|
||
|
}
|