459 lines
15 KiB
Vue
459 lines
15 KiB
Vue
<template>
|
|
<div class="filters-content">
|
|
<div class="form-group small-height">
|
|
<div class="radio-label label-container">
|
|
<label>{{ $gettext('Display sensitive content') }}</label>
|
|
|
|
<button v-if="formNSFW !== undefined" class="reset-button" @click="resetField('nsfw')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
</div>
|
|
|
|
<div class="peertube-radio-container">
|
|
<input id="sensitiveContentYes" v-model="formNSFW" type="radio" name="sensitiveContent" value="both">
|
|
<label for="sensitiveContentYes" class="radio">{{ $gettext('Yes') }}</label>
|
|
</div>
|
|
|
|
<div class="peertube-radio-container">
|
|
<input id="sensitiveContentNo" v-model="formNSFW" type="radio" name="sensitiveContent" value="false">
|
|
<label for="sensitiveContentNo" class="radio">{{ $gettext('No') }}</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group small-height">
|
|
<div class="radio-label label-container">
|
|
<label>{{ $gettext('Display only') }}</label>
|
|
|
|
<button v-if="formIsLive !== undefined" class="reset-button" @click="resetField('isLive')">{{ $gettext('Reset') }}</button>
|
|
</div>
|
|
|
|
<div class="peertube-radio-container">
|
|
<input id="isLiveYes" v-model="formIsLive" type="radio" name="isLive" value="both">
|
|
<label for="isLiveYes" class="radio">{{ $gettext('Live videos') }}</label>
|
|
</div>
|
|
|
|
<div class="peertube-radio-container">
|
|
<input id="isLiveNo" v-model="formIsLive" type="radio" name="isLive" value="false">
|
|
<label for="isLiveNo" class="radio">{{ $gettext('VOD videos') }}</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="radio-label label-container">
|
|
<label>{{ $gettext('Published date') }}</label>
|
|
|
|
<button v-if="formPublishedDateRange !== undefined" class="reset-button" @click="resetField('publishedDateRange')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
</div>
|
|
|
|
<div v-for="date in publishedDateRanges" :key="date.id" class="peertube-radio-container">
|
|
<input :id="date.id" v-model="formPublishedDateRange" type="radio" name="publishedDateRange" :value="date.id">
|
|
<label :for="date.id" class="radio">{{ date.label }}</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="radio-label label-container">
|
|
<label>{{ $gettext('Duration') }}</label>
|
|
<button v-if="formDurationRange !== undefined" class="reset-button" @click="resetField('durationRange')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
</div>
|
|
|
|
<div v-for="duration in durationRanges" :key="duration.id" class="peertube-radio-container">
|
|
<input :id="duration.id" v-model="formDurationRange" type="radio" name="durationRange" :value="duration.id">
|
|
<label :for="duration.id" class="radio">{{ duration.label }}</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="category">{{ $gettext('Category') }}</label>
|
|
<button v-if="formCategoryOneOf !== undefined" class="reset-button" @click="resetField('categoryOneOf')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
|
|
<div class="select-container">
|
|
<select id="category" v-model="formCategoryOneOf" name="category">
|
|
<option :value="undefined">
|
|
{{ $gettext('Display all categories') }}
|
|
</option>
|
|
|
|
<option v-for="category in videoCategories" :key="category.id" :value="category.id">
|
|
{{ category.label }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="licence">{{ $gettext('Licence') }}</label>
|
|
<button v-if="formLicenceOneOf !== undefined" class="reset-button" @click="resetField('licenceOneOf')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
|
|
<div class="select-container">
|
|
<select id="licence" v-model="formLicenceOneOf" name="licence">
|
|
<option :value="undefined">
|
|
{{ $gettext('Display all licenses') }}
|
|
</option>
|
|
|
|
<option v-for="licence in videoLicences" :key="licence.id" :value="licence.id">
|
|
{{ licence.label }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="language">{{ $gettext('Language') }}</label>
|
|
<button v-if="formLanguageOneOf !== undefined" class="reset-button" @click="resetField('languageOneOf')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
|
|
<div class="select-container">
|
|
<select id="language" v-model="formLanguageOneOf" name="language">
|
|
<option :value="undefined">
|
|
{{ $gettext('Display all languages') }}
|
|
</option>
|
|
|
|
<option v-for="language in videoLanguages" :key="language.id" :value="language.id">
|
|
{{ language.label }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="host">{{ $gettext('PeerTube instance') }}</label>
|
|
|
|
<input id="host" v-model="formHost" type="text" name="host" class="classic-input-text" />
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="tagsAllOf">{{ $gettext('All of these tags') }}</label>
|
|
<button v-if="formTagsAllOf.length !== 0" class="reset-button" @click="resetField('tagsAllOf')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
|
|
<vue-tags-input
|
|
v-model="formTagAllOf" :placeholder="tagsPlaceholder" :tags="formTagsAllOf"
|
|
@tags-changed="newTags => formTagsAllOf = newTags"
|
|
/>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="tagsOneOf">{{ $gettext('One of these tags') }}</label>
|
|
<button v-if="formTagsOneOf.length !== 0" class="reset-button" @click="resetField('tagsOneOf')">
|
|
{{ $gettext('Reset') }}
|
|
</button>
|
|
|
|
<vue-tags-input
|
|
v-model="formTagOneOf" :placeholder="tagsPlaceholder" :tags="formTagsOneOf"
|
|
@tags-changed="newTags => formTagsOneOf = newTags"
|
|
/>
|
|
</div>
|
|
|
|
<div class="button-block mt-3">
|
|
<router-link class="peertube-button peertube-button-link peertube-primary-button" :to="{ path: '/search', query: { ...getUrlQuery() } }">
|
|
{{ applyFiltersLabel }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent } from 'vue'
|
|
import VueTagsInput from '@sipec/vue3-tags-input'
|
|
import { SearchUrl } from '@/models/search-url.model'
|
|
import { extractTagsFromQuery } from '@/shared/utils'
|
|
|
|
export default defineComponent({
|
|
components: {
|
|
'vue-tags-input': VueTagsInput,
|
|
},
|
|
|
|
data () {
|
|
return {
|
|
formNSFW: undefined,
|
|
formHost: '',
|
|
formPublishedDateRange: undefined,
|
|
formDurationRange: undefined,
|
|
formCategoryOneOf: undefined,
|
|
formLicenceOneOf: undefined,
|
|
formLanguageOneOf: undefined,
|
|
|
|
formTagAllOf: '',
|
|
formTagOneOf: '',
|
|
formTagsAllOf: [],
|
|
formTagsOneOf: [],
|
|
|
|
formIsLive: undefined,
|
|
|
|
activeFilters: 0
|
|
}
|
|
},
|
|
|
|
computed: {
|
|
applyFiltersLabel (): string {
|
|
return this.$gettext('Apply filters')
|
|
},
|
|
|
|
inputPlaceholder (): string {
|
|
return this.$gettext('Keyword, channel, video, playlist, etc.')
|
|
},
|
|
|
|
tagsPlaceholder (): string {
|
|
return this.$gettext('Add tag')
|
|
},
|
|
|
|
publishedDateRanges (): { id: string, label: string }[] {
|
|
return [
|
|
{
|
|
id: 'any_published_date',
|
|
label: this.$gettext('Any')
|
|
},
|
|
{
|
|
id: 'today',
|
|
label: this.$gettext('Today')
|
|
},
|
|
{
|
|
id: 'last_7days',
|
|
label: this.$gettext('Last 7 days')
|
|
},
|
|
{
|
|
id: 'last_30days',
|
|
label: this.$gettext('Last 30 days')
|
|
},
|
|
{
|
|
id: 'last_365days',
|
|
label: this.$gettext('Last 365 days')
|
|
}
|
|
]
|
|
},
|
|
|
|
durationRanges (): { id: string, label: string }[] {
|
|
return [
|
|
{
|
|
id: 'any_duration',
|
|
label: this.$gettext('Any')
|
|
},
|
|
{
|
|
id: 'short',
|
|
label: this.$gettext('Short (< 4 min)')
|
|
},
|
|
{
|
|
id: 'medium',
|
|
label: this.$gettext('Medium (4-10 min)')
|
|
},
|
|
{
|
|
id: 'long',
|
|
label: this.$gettext('Long (> 10 min)')
|
|
}
|
|
]
|
|
},
|
|
|
|
videoCategories (): { id: string, label: string }[] {
|
|
return [
|
|
{ id: '1', label: this.$gettext('Music') },
|
|
{ id: '2', label: this.$gettext('Films') },
|
|
{ id: '3', label: this.$gettext('Vehicles') },
|
|
{ id: '4', label: this.$gettext('Art') },
|
|
{ id: '5', label: this.$gettext('Sports') },
|
|
{ id: '6', label: this.$gettext('Travels') },
|
|
{ id: '7', label: this.$gettext('Gaming') },
|
|
{ id: '8', label: this.$gettext('People') },
|
|
{ id: '9', label: this.$gettext('Comedy') },
|
|
{ id: '10', label: this.$gettext('Entertainment') },
|
|
{ id: '11', label: this.$gettext('News & Politics') },
|
|
{ id: '12', label: this.$gettext('How To') },
|
|
{ id: '13', label: this.$gettext('Education') },
|
|
{ id: '14', label: this.$gettext('Activism') },
|
|
{ id: '15', label: this.$gettext('Science & Technology') },
|
|
{ id: '16', label: this.$gettext('Animals') },
|
|
{ id: '17', label: this.$gettext('Kids') },
|
|
{ id: '18', label: this.$gettext('Food') }
|
|
]
|
|
},
|
|
|
|
videoLicences (): { id: string, label: string }[] {
|
|
return [
|
|
{ id: '1', label: this.$gettext('Attribution') },
|
|
{ id: '2', label: this.$gettext('Attribution - Share Alike') },
|
|
{ id: '3', label: this.$gettext('Attribution - No Derivatives') },
|
|
{ id: '4', label: this.$gettext('Attribution - Non Commercial') },
|
|
{ id: '5', label: this.$gettext('Attribution - Non Commercial - Share Alike') },
|
|
{ id: '6', label: this.$gettext('Attribution - Non Commercial - No Derivatives') },
|
|
{ id: '7', label: this.$gettext('Public Domain Dedication') }
|
|
]
|
|
},
|
|
|
|
videoLanguages (): { id: string, label: string }[] {
|
|
return [
|
|
{ id: 'en', label: this.$gettext('English') },
|
|
{ id: 'fr', label: this.$gettext('Français') },
|
|
{ id: 'ja', label: this.$gettext('日本語') },
|
|
{ id: 'eu', label: this.$gettext('Euskara') },
|
|
{ id: 'ca', label: this.$gettext('Català') },
|
|
{ id: 'cs', label: this.$gettext('Čeština') },
|
|
{ id: 'eo', label: this.$gettext('Esperanto') },
|
|
{ id: 'el', label: this.$gettext('ελληνικά') },
|
|
{ id: 'de', label: this.$gettext('Deutsch') },
|
|
{ id: 'it', label: this.$gettext('Italiano') },
|
|
{ id: 'nl', label: this.$gettext('Nederlands') },
|
|
{ id: 'es', label: this.$gettext('Español') },
|
|
{ id: 'oc', label: this.$gettext('Occitan') },
|
|
{ id: 'gd', label: this.$gettext('Gàidhlig') },
|
|
{ id: 'zh', label: this.$gettext('简体中文(中国)') },
|
|
{ id: 'pt', label: this.$gettext('Português (Portugal)') },
|
|
{ id: 'sv', label: this.$gettext('svenska') },
|
|
{ id: 'pl', label: this.$gettext('Polski') },
|
|
{ id: 'fi', label: this.$gettext('suomi') },
|
|
{ id: 'ru', label: this.$gettext('русский') }
|
|
]
|
|
}
|
|
},
|
|
|
|
mounted () {
|
|
this.loadUrl()
|
|
},
|
|
|
|
methods: {
|
|
getUrlQuery (): SearchUrl {
|
|
return {
|
|
...this.$route.query,
|
|
|
|
nsfw: this.formNSFW,
|
|
host: this.formHost || undefined,
|
|
isLive: this.formIsLive,
|
|
publishedDateRange: this.formPublishedDateRange,
|
|
durationRange: this.formDurationRange,
|
|
categoryOneOf: this.formCategoryOneOf,
|
|
licenceOneOf: this.formLicenceOneOf,
|
|
languageOneOf: this.formLanguageOneOf,
|
|
tagsAllOf: this.formTagsAllOf.map(t => t.text),
|
|
tagsOneOf: this.formTagsOneOf.map(t => t.text)
|
|
}
|
|
},
|
|
|
|
loadUrl () {
|
|
const query = this.$route.query as SearchUrl
|
|
|
|
if (query.nsfw) this.formNSFW = query.nsfw
|
|
else this.formNSFW = undefined
|
|
|
|
if (query.publishedDateRange) this.formPublishedDateRange = query.publishedDateRange
|
|
else this.formPublishedDateRange = undefined
|
|
|
|
if (query.durationRange) this.formDurationRange = query.durationRange
|
|
else this.formDurationRange = undefined
|
|
|
|
if (query.categoryOneOf) this.formCategoryOneOf = query.categoryOneOf
|
|
else this.formCategoryOneOf = undefined
|
|
|
|
if (query.licenceOneOf) this.formLicenceOneOf = query.licenceOneOf
|
|
else this.formLicenceOneOf = undefined
|
|
|
|
if (query.languageOneOf) this.formLanguageOneOf = query.languageOneOf
|
|
else this.formLanguageOneOf = undefined
|
|
|
|
if (query.tagsAllOf) this.formTagsAllOf = extractTagsFromQuery(query.tagsAllOf)
|
|
else this.formTagsAllOf = []
|
|
|
|
if (query.tagsOneOf) this.formTagsOneOf = extractTagsFromQuery(query.tagsOneOf)
|
|
else this.formTagsOneOf = []
|
|
|
|
if (query.isLive) this.formIsLive = query.isLive
|
|
else this.formIsLive = undefined
|
|
|
|
if (query.host) this.formHost = query.host
|
|
else this.formHost = ''
|
|
},
|
|
|
|
resetField (field: string) {
|
|
if (field === 'nsfw') this.formNSFW = undefined
|
|
else if (field === 'publishedDateRange') this.formPublishedDateRange = undefined
|
|
else if (field === 'durationRange') this.formDurationRange = undefined
|
|
else if (field === 'categoryOneOf') this.formCategoryOneOf = undefined
|
|
else if (field === 'licenceOneOf') this.formLicenceOneOf = undefined
|
|
else if (field === 'languageOneOf') this.formLanguageOneOf = undefined
|
|
else if (field === 'isLive') this.formIsLive = undefined
|
|
else if (field === 'tagsAllOf') this.formTagsAllOf = []
|
|
else if (field === 'tagsOneOf') this.formTagsOneOf = []
|
|
else if (field === 'host') this.formHost = ''
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
@use 'sass:math';
|
|
|
|
@import '../scss/_variables';
|
|
|
|
.filters-content {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin-top: 1.25rem;
|
|
|
|
.form-group:nth-child(2n-1) {
|
|
padding-right: 20px;
|
|
}
|
|
|
|
.form-group {
|
|
width: 50%;
|
|
min-height: 60px;
|
|
display: inline-block;
|
|
margin: 10px 0;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
@media screen and (max-width: $small-view) {
|
|
.form-group {
|
|
width: 100%;
|
|
padding-right: 0;
|
|
}
|
|
}
|
|
|
|
.form-group > label,
|
|
.label-container label {
|
|
font-weight: $font-semibold;
|
|
}
|
|
|
|
.form-group > label,
|
|
.label-container {
|
|
display: inline-block;
|
|
margin-bottom: 5px;
|
|
}
|
|
|
|
.form-group.small-height {
|
|
min-height: 30px;
|
|
}
|
|
|
|
.peertube-radio-container {
|
|
display: inline-block;
|
|
margin: 0 10px 5px 0;
|
|
}
|
|
|
|
.button-block {
|
|
width: 100%;
|
|
text-align: right;
|
|
}
|
|
|
|
.radio-label {
|
|
display: block;
|
|
}
|
|
|
|
.reset-button {
|
|
background: none;
|
|
border: none;
|
|
font-weight: 600;
|
|
font-size: 0.7rem;
|
|
opacity: 0.7;
|
|
margin-left: 5px;
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
</style>
|