Support is live filter
This commit is contained in:
parent
4e3e8c59db
commit
20c72fc6d5
2
PeerTube
2
PeerTube
|
@ -1 +1 @@
|
||||||
Subproject commit 969e59d17d584baf695cf9a7d6122283518386a7
|
Subproject commit f676e0e32112821255b70018282d59207932d987
|
|
@ -49,7 +49,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form v-if="displayFilters" class="filters-content">
|
<form v-if="displayFilters" class="filters-content">
|
||||||
<div class="form-group">
|
<div class="form-group small-height">
|
||||||
<div class="radio-label label-container">
|
<div class="radio-label label-container">
|
||||||
<label v-translate>Display sensitive content</label>
|
<label v-translate>Display sensitive content</label>
|
||||||
|
|
||||||
|
@ -69,6 +69,26 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group small-height">
|
||||||
|
<div class="radio-label label-container">
|
||||||
|
<label v-translate>Display only</label>
|
||||||
|
|
||||||
|
<button v-translate class="reset-button" v-on:click="resetField('isLive')" v-if="formIsLive !== undefined">
|
||||||
|
Reset
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radio-container">
|
||||||
|
<input type="radio" name="isLive" id="isLiveYes" value="both" v-model="formIsLive">
|
||||||
|
<label v-translate for="isLiveYes" class="radio">Live videos</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radio-container">
|
||||||
|
<input type="radio" name="isLive" id="isLiveNo" value="false" v-model="formIsLive">
|
||||||
|
<label v-translate for="isLiveNo" class="radio">VOD videos</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="radio-label label-container">
|
<div class="radio-label label-container">
|
||||||
<label v-translate>Published date</label>
|
<label v-translate>Published date</label>
|
||||||
|
@ -344,6 +364,10 @@
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-group.small-height {
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
.radio-container {
|
.radio-container {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin: 0 10px 5px 0;
|
margin: 0 10px 5px 0;
|
||||||
|
@ -478,6 +502,8 @@
|
||||||
formTagsAllOf: [],
|
formTagsAllOf: [],
|
||||||
formTagsOneOf: [],
|
formTagsOneOf: [],
|
||||||
|
|
||||||
|
formIsLive: undefined,
|
||||||
|
|
||||||
activeFilters: 0
|
activeFilters: 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -730,6 +756,7 @@
|
||||||
search: this.formSearch,
|
search: this.formSearch,
|
||||||
sort: this.formSort,
|
sort: this.formSort,
|
||||||
nsfw: this.formNSFW,
|
nsfw: this.formNSFW,
|
||||||
|
isLive: this.formIsLive,
|
||||||
publishedDateRange: this.formPublishedDateRange,
|
publishedDateRange: this.formPublishedDateRange,
|
||||||
durationRange: this.formDurationRange,
|
durationRange: this.formDurationRange,
|
||||||
categoryOneOf: this.formCategoryOneOf,
|
categoryOneOf: this.formCategoryOneOf,
|
||||||
|
@ -776,6 +803,9 @@
|
||||||
if (query.sort) this.formSort = query.sort
|
if (query.sort) this.formSort = query.sort
|
||||||
else this.formSort = '-match'
|
else this.formSort = '-match'
|
||||||
|
|
||||||
|
if (query.isLive) this.formIsLive = query.isLive
|
||||||
|
else this.formIsLive = undefined
|
||||||
|
|
||||||
if (query.page && this.currentPage !== query.page) {
|
if (query.page && this.currentPage !== query.page) {
|
||||||
this.currentPage = parseInt(query.page + '')
|
this.currentPage = parseInt(query.page + '')
|
||||||
} else {
|
} else {
|
||||||
|
@ -810,6 +840,8 @@
|
||||||
tagsOneOf: this.formTagsOneOf.map(t => t.text),
|
tagsOneOf: this.formTagsOneOf.map(t => t.text),
|
||||||
tagsAllOf: this.formTagsAllOf.map(t => t.text),
|
tagsAllOf: this.formTagsAllOf.map(t => t.text),
|
||||||
|
|
||||||
|
isLive: this.formIsLive !== undefined ? this.formIsLive : undefined,
|
||||||
|
|
||||||
start,
|
start,
|
||||||
count,
|
count,
|
||||||
sort: this.formSort
|
sort: this.formSort
|
||||||
|
@ -906,6 +938,7 @@
|
||||||
else if (field === 'categoryOneOf') this.formCategoryOneOf = undefined
|
else if (field === 'categoryOneOf') this.formCategoryOneOf = undefined
|
||||||
else if (field === 'licenceOneOf') this.formLicenceOneOf = undefined
|
else if (field === 'licenceOneOf') this.formLicenceOneOf = undefined
|
||||||
else if (field === 'languageOneOf') this.formLanguageOneOf = undefined
|
else if (field === 'languageOneOf') this.formLanguageOneOf = undefined
|
||||||
|
else if (field === 'isLive') this.formIsLive = undefined
|
||||||
else if (field === 'tagsAllOf') this.formTagsAllOf = []
|
else if (field === 'tagsAllOf') this.formTagsAllOf = []
|
||||||
else if (field === 'tagsOneOf') this.formTagsOneOf = []
|
else if (field === 'tagsOneOf') this.formTagsOneOf = []
|
||||||
},
|
},
|
||||||
|
@ -924,6 +957,7 @@
|
||||||
if (this.formCategoryOneOf) count++
|
if (this.formCategoryOneOf) count++
|
||||||
if (this.formLicenceOneOf) count++
|
if (this.formLicenceOneOf) count++
|
||||||
if (this.formLanguageOneOf) count++
|
if (this.formLanguageOneOf) count++
|
||||||
|
if (this.formIsLive) count++
|
||||||
if (this.formTagsAllOf && this.formTagsAllOf.length !== 0) count++
|
if (this.formTagsAllOf && this.formTagsAllOf.length !== 0) count++
|
||||||
if (this.formTagsOneOf && this.formTagsOneOf.length !== 0) count++
|
if (this.formTagsOneOf && this.formTagsOneOf.length !== 0) count++
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
|
||||||
import { Avatar } from '@shared/models'
|
import { ActorImage } from '@shared/models'
|
||||||
import { buildUrl } from '../helpers/utils'
|
import { buildUrl } from '../helpers/utils'
|
||||||
|
|
||||||
function formatAvatarForAPI (obj: { avatar?: Avatar & { url: string } }) {
|
function formatAvatarForAPI (obj: { avatar?: ActorImage & { url: string } }) {
|
||||||
if (!obj.avatar) return null
|
if (!obj.avatar) return null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -13,7 +13,7 @@ function formatAvatarForAPI (obj: { avatar?: Avatar & { url: string } }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatAvatarForDB (obj: { avatar?: Avatar, host: string }) {
|
function formatAvatarForDB (obj: { avatar?: ActorImage, host: string }) {
|
||||||
if (!obj.avatar) return null
|
if (!obj.avatar) return null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { difference } from 'lodash'
|
import { difference } from 'lodash'
|
||||||
|
import { exists } from '../helpers/custom-validators/misc'
|
||||||
import { buildIndex, buildSort, elasticSearch, extractQueryResult, indexDocuments } from '../helpers/elastic-search'
|
import { buildIndex, buildSort, elasticSearch, extractQueryResult, indexDocuments } from '../helpers/elastic-search'
|
||||||
import { logger } from '../helpers/logger'
|
import { logger } from '../helpers/logger'
|
||||||
import { buildUrl } from '../helpers/utils'
|
import { buildUrl } from '../helpers/utils'
|
||||||
|
@ -252,6 +253,14 @@ async function queryVideos (search: VideosSearchQuery) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exists(search.isLive)) {
|
||||||
|
filter.push({
|
||||||
|
term: {
|
||||||
|
isLive: search.isLive
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
Object.assign(bool, { filter })
|
Object.assign(bool, { filter })
|
||||||
|
|
||||||
if (mustNot.length !== 0) {
|
if (mustNot.length !== 0) {
|
||||||
|
|
|
@ -48,6 +48,9 @@ const commonVideosFiltersValidator = [
|
||||||
check('nsfw')
|
check('nsfw')
|
||||||
.optional()
|
.optional()
|
||||||
.custom(isNSFWQueryValid).withMessage('Should have a valid NSFW attribute'),
|
.custom(isNSFWQueryValid).withMessage('Should have a valid NSFW attribute'),
|
||||||
|
check('isLive')
|
||||||
|
.optional()
|
||||||
|
.toBoolean(),
|
||||||
|
|
||||||
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
(req: express.Request, res: express.Response, next: express.NextFunction) => {
|
||||||
if (areValidationErrors(req, res)) return
|
if (areValidationErrors(req, res)) return
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { IndexableDoc } from './elastic-search.model'
|
import { IndexableDoc } from './elastic-search.model'
|
||||||
import { VideoChannel, VideoChannelSummary, Avatar, Account } from '../../PeerTube/shared/models'
|
import { VideoChannel, VideoChannelSummary, ActorImage, Account } from '../../PeerTube/shared/models'
|
||||||
|
|
||||||
export interface IndexableChannel extends VideoChannel, IndexableDoc {
|
export interface IndexableChannel extends VideoChannel, IndexableDoc {
|
||||||
url: string
|
url: string
|
||||||
|
@ -10,9 +10,9 @@ export interface DBChannel extends Omit<VideoChannel, 'isLocal'> {
|
||||||
handle: string
|
handle: string
|
||||||
url: string
|
url: string
|
||||||
|
|
||||||
ownerAccount?: Account & { handle: string, avatar: Avatar & { url: string } }
|
ownerAccount?: Account & { handle: string, avatar: ActorImage & { url: string } }
|
||||||
|
|
||||||
avatar?: Avatar & { url: string }
|
avatar?: ActorImage & { url: string }
|
||||||
|
|
||||||
score?: number
|
score?: number
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { VideosSearchQuery as PeerTubeVideosSearchQuery} from '../../PeerTube/shared/models/search/videos-search-query.model'
|
import { VideosSearchQuery as PeerTubeVideosSearchQuery } from '../../PeerTube/shared/models/search/videos-search-query.model'
|
||||||
import { CommonSearch } from './common-search.model'
|
import { CommonSearch } from './common-search.model'
|
||||||
|
|
||||||
export type VideosSearchQuery = Omit<PeerTubeVideosSearchQuery, 'skipCount' | 'filter'> & CommonSearch & { boostLanguages: string[] }
|
export type VideosSearchQuery = Omit<PeerTubeVideosSearchQuery, 'skipCount' | 'filter'> & CommonSearch & { boostLanguages: string[] }
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
import { Account, AccountSummary, Avatar, Video, VideoChannel, VideoChannelSummary, VideoDetails } from '../../PeerTube/shared/models'
|
import { Account, AccountSummary, ActorImage, Video, VideoChannel, VideoChannelSummary, VideoDetails } from '../../PeerTube/shared/models'
|
||||||
import { IndexableDoc } from './elastic-search.model'
|
import { IndexableDoc } from './elastic-search.model'
|
||||||
|
|
||||||
type ActorExtended = {
|
type ActorExtended = {
|
||||||
handle: string
|
handle: string
|
||||||
avatar: Avatar & { url: string }
|
avatar: ActorImage & { url: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexableVideo extends Video, IndexableDoc {
|
export interface IndexableVideo extends Video, IndexableDoc {
|
||||||
|
|
Loading…
Reference in New Issue