mirror of https://github.com/FreeTubeApp/FreeTube
Add search playlists with matching videos function (#4537)
* * Update user playlists page to add search playlists with matching videos function * * Update add videos to playlists prompt to add search playlists with matching videos function * * Update UI & label text * * Click on playlist link with search matching video enabled now also search for video when view switched * * Only auto enable search video mode for playlists with video(s) * * Make new toggle vertically align center * * Make new toggle vertically align center
This commit is contained in:
parent
68c74ea2b6
commit
65a5b0c045
|
@ -33,7 +33,12 @@ export default defineComponent({
|
||||||
hideForbiddenTitles: {
|
hideForbiddenTitles: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
}
|
},
|
||||||
|
searchQueryText: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
listType: function () {
|
listType: function () {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
:show-video-with-last-viewed-playlist="showVideoWithLastViewedPlaylist"
|
:show-video-with-last-viewed-playlist="showVideoWithLastViewedPlaylist"
|
||||||
:use-channels-hidden-preference="useChannelsHiddenPreference"
|
:use-channels-hidden-preference="useChannelsHiddenPreference"
|
||||||
:hide-forbidden-titles="hideForbiddenTitles"
|
:hide-forbidden-titles="hideForbiddenTitles"
|
||||||
|
:search-query-text="searchQueryText"
|
||||||
/>
|
/>
|
||||||
</ft-auto-grid>
|
</ft-auto-grid>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -47,6 +47,11 @@ export default defineComponent({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
|
searchQueryText: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
v-else-if="finalDataType === 'playlist'"
|
v-else-if="finalDataType === 'playlist'"
|
||||||
:appearance="appearance"
|
:appearance="appearance"
|
||||||
:data="data"
|
:data="data"
|
||||||
|
:search-query-text="searchQueryText"
|
||||||
/>
|
/>
|
||||||
<ft-community-post
|
<ft-community-post
|
||||||
v-else-if="finalDataType === 'community'"
|
v-else-if="finalDataType === 'community'"
|
||||||
|
|
|
@ -15,7 +15,12 @@ export default defineComponent({
|
||||||
appearance: {
|
appearance: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
}
|
},
|
||||||
|
searchQueryText: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
@ -79,6 +84,7 @@ export default defineComponent({
|
||||||
path: `/playlist/${this.playlistId}`,
|
path: `/playlist/${this.playlistId}`,
|
||||||
query: {
|
query: {
|
||||||
playlistType: this.isUserPlaylist ? 'user' : '',
|
playlistType: this.isUserPlaylist ? 'user' : '',
|
||||||
|
searchQueryText: this.searchQueryText,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,6 +16,36 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchInputsRow {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
/* 2 columns */
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
column-gap: 16px;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.searchInputsRow {
|
||||||
|
/* Switch to 2 rows from 2 columns */
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: auto auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.optionsRow {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.optionsRow {
|
||||||
|
/* Switch to 2 rows from 2 columns */
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: auto auto;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.sortSelect {
|
.sortSelect {
|
||||||
/* Put it on the right */
|
/* Put it on the right */
|
||||||
margin-inline-start: auto;
|
margin-inline-start: auto;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import FtButton from '../ft-button/ft-button.vue'
|
||||||
import FtPlaylistSelector from '../ft-playlist-selector/ft-playlist-selector.vue'
|
import FtPlaylistSelector from '../ft-playlist-selector/ft-playlist-selector.vue'
|
||||||
import FtInput from '../../components/ft-input/ft-input.vue'
|
import FtInput from '../../components/ft-input/ft-input.vue'
|
||||||
import FtSelect from '../../components/ft-select/ft-select.vue'
|
import FtSelect from '../../components/ft-select/ft-select.vue'
|
||||||
|
import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue'
|
||||||
import {
|
import {
|
||||||
showToast,
|
showToast,
|
||||||
} from '../../helpers/utils'
|
} from '../../helpers/utils'
|
||||||
|
@ -31,12 +32,14 @@ export default defineComponent({
|
||||||
'ft-playlist-selector': FtPlaylistSelector,
|
'ft-playlist-selector': FtPlaylistSelector,
|
||||||
'ft-input': FtInput,
|
'ft-input': FtInput,
|
||||||
'ft-select': FtSelect,
|
'ft-select': FtSelect,
|
||||||
|
'ft-toggle-switch': FtToggleSwitch,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
selectedPlaylistIdList: [],
|
selectedPlaylistIdList: [],
|
||||||
createdSincePromptShownPlaylistIdList: [],
|
createdSincePromptShownPlaylistIdList: [],
|
||||||
query: '',
|
query: '',
|
||||||
|
doSearchPlaylistsWithMatchingVideos: false,
|
||||||
updateQueryDebounce: function() {},
|
updateQueryDebounce: function() {},
|
||||||
lastShownAt: Date.now(),
|
lastShownAt: Date.now(),
|
||||||
lastActiveElement: null,
|
lastActiveElement: null,
|
||||||
|
@ -115,6 +118,12 @@ export default defineComponent({
|
||||||
return this.allPlaylists.filter((playlist) => {
|
return this.allPlaylists.filter((playlist) => {
|
||||||
if (typeof (playlist.playlistName) !== 'string') { return false }
|
if (typeof (playlist.playlistName) !== 'string') { return false }
|
||||||
|
|
||||||
|
if (this.doSearchPlaylistsWithMatchingVideos) {
|
||||||
|
if (playlist.videos.some((v) => v.title.toLowerCase().includes(this.processedQuery))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return playlist.playlistName.toLowerCase().includes(this.processedQuery)
|
return playlist.playlistName.toLowerCase().includes(this.processedQuery)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,23 +12,37 @@
|
||||||
playlistCount: selectedPlaylistCount,
|
playlistCount: selectedPlaylistCount,
|
||||||
}) }}
|
}) }}
|
||||||
</p>
|
</p>
|
||||||
<ft-input
|
<div
|
||||||
ref="searchBar"
|
class="searchInputsRow"
|
||||||
:placeholder="$t('User Playlists.AddVideoPrompt.Search in Playlists')"
|
>
|
||||||
:show-clear-text-button="true"
|
<ft-input
|
||||||
:show-action-button="false"
|
ref="searchBar"
|
||||||
@input="(input) => updateQueryDebounce(input)"
|
:placeholder="$t('User Playlists.AddVideoPrompt.Search in Playlists')"
|
||||||
@clear="updateQueryDebounce('')"
|
:show-clear-text-button="true"
|
||||||
/>
|
:show-action-button="false"
|
||||||
<ft-select
|
@input="(input) => updateQueryDebounce(input)"
|
||||||
v-if="allPlaylists.length > 1"
|
@clear="updateQueryDebounce('')"
|
||||||
class="sortSelect"
|
/>
|
||||||
:value="sortBy"
|
</div>
|
||||||
:select-names="sortBySelectNames"
|
<div
|
||||||
:select-values="sortBySelectValues"
|
class="optionsRow"
|
||||||
:placeholder="$t('User Playlists.Sort By.Sort By')"
|
>
|
||||||
@change="sortBy = $event"
|
<ft-toggle-switch
|
||||||
/>
|
:label="$t('User Playlists.Playlists with Matching Videos')"
|
||||||
|
:compact="true"
|
||||||
|
:default-value="doSearchPlaylistsWithMatchingVideos"
|
||||||
|
@change="doSearchPlaylistsWithMatchingVideos = !doSearchPlaylistsWithMatchingVideos"
|
||||||
|
/>
|
||||||
|
<ft-select
|
||||||
|
v-if="allPlaylists.length > 1"
|
||||||
|
class="sortSelect"
|
||||||
|
:value="sortBy"
|
||||||
|
:select-names="sortBySelectNames"
|
||||||
|
:select-values="sortBySelectValues"
|
||||||
|
:placeholder="$t('User Playlists.Sort By.Sort By')"
|
||||||
|
@change="sortBy = $event"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div class="playlists-container">
|
<div class="playlists-container">
|
||||||
<ft-flex-box>
|
<ft-flex-box>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -83,6 +83,18 @@ export default defineComponent({
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
searchVideoModeAllowed: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
searchVideoModeEnabled: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
searchQueryText: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
@ -239,6 +251,12 @@ export default defineComponent({
|
||||||
this.newTitle = this.title
|
this.newTitle = this.title
|
||||||
this.newDescription = this.description
|
this.newDescription = this.description
|
||||||
|
|
||||||
|
if (this.videoCount > 0) {
|
||||||
|
// Only enable search video mode when viewing non empty playlists
|
||||||
|
this.searchVideoMode = this.searchVideoModeEnabled
|
||||||
|
this.query = this.searchQueryText
|
||||||
|
}
|
||||||
|
|
||||||
this.updateQueryDebounce = debounce(this.updateQuery, 500)
|
this.updateQueryDebounce = debounce(this.updateQuery, 500)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
|
|
||||||
<div class="playlistOptions">
|
<div class="playlistOptions">
|
||||||
<ft-icon-button
|
<ft-icon-button
|
||||||
v-if="isUserPlaylist && videoCount > 0 && !editMode"
|
v-if="searchVideoModeAllowed && videoCount > 0 && !editMode"
|
||||||
ref="enableSearchModeButton"
|
ref="enableSearchModeButton"
|
||||||
:title="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
:title="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
||||||
:icon="['fas', 'search']"
|
:icon="['fas', 'search']"
|
||||||
|
@ -198,7 +198,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="isUserPlaylist && searchVideoMode"
|
v-if="searchVideoModeAllowed && searchVideoMode"
|
||||||
class="searchInputsRow"
|
class="searchInputsRow"
|
||||||
>
|
>
|
||||||
<ft-input
|
<ft-input
|
||||||
|
@ -207,11 +207,11 @@
|
||||||
:placeholder="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
:placeholder="$t('User Playlists.SinglePlaylistView.Search for Videos')"
|
||||||
:show-clear-text-button="true"
|
:show-clear-text-button="true"
|
||||||
:show-action-button="false"
|
:show-action-button="false"
|
||||||
|
:value="query"
|
||||||
@input="(input) => updateQueryDebounce(input)"
|
@input="(input) => updateQueryDebounce(input)"
|
||||||
@clear="updateQueryDebounce('')"
|
@clear="updateQueryDebounce('')"
|
||||||
/>
|
/>
|
||||||
<ft-icon-button
|
<ft-icon-button
|
||||||
v-if="isUserPlaylist && searchVideoMode"
|
|
||||||
:title="$t('User Playlists.Cancel')"
|
:title="$t('User Playlists.Cancel')"
|
||||||
:icon="['fas', 'times']"
|
:icon="['fas', 'times']"
|
||||||
theme="secondary"
|
theme="secondary"
|
||||||
|
|
|
@ -113,6 +113,17 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
searchVideoModeAllowed() {
|
||||||
|
return this.isUserPlaylistRequested
|
||||||
|
},
|
||||||
|
searchQueryTextRequested() {
|
||||||
|
return this.$route.query.searchQueryText
|
||||||
|
},
|
||||||
|
searchQueryTextPresent() {
|
||||||
|
const searchQueryText = this.searchQueryTextRequested
|
||||||
|
return typeof searchQueryText === 'string' && searchQueryText !== ''
|
||||||
|
},
|
||||||
|
|
||||||
isUserPlaylistRequested: function () {
|
isUserPlaylistRequested: function () {
|
||||||
return this.$route.query.playlistType === 'user'
|
return this.$route.query.playlistType === 'user'
|
||||||
},
|
},
|
||||||
|
@ -181,6 +192,11 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
created: function () {
|
created: function () {
|
||||||
this.getPlaylistInfoDebounce = debounce(this.getPlaylistInfo, 100)
|
this.getPlaylistInfoDebounce = debounce(this.getPlaylistInfo, 100)
|
||||||
|
|
||||||
|
if (this.searchVideoModeAllowed && this.searchQueryTextPresent) {
|
||||||
|
this.playlistInVideoSearchMode = true
|
||||||
|
this.videoSearchQuery = this.searchQueryTextRequested
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.getPlaylistInfoDebounce()
|
this.getPlaylistInfoDebounce()
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
:view-count="viewCount"
|
:view-count="viewCount"
|
||||||
:info-source="infoSource"
|
:info-source="infoSource"
|
||||||
:more-video-data-available="moreVideoDataAvailable"
|
:more-video-data-available="moreVideoDataAvailable"
|
||||||
|
:search-video-mode-allowed="searchVideoModeAllowed"
|
||||||
|
:search-video-mode-enabled="playlistInVideoSearchMode"
|
||||||
|
:search-query-text="searchQueryTextRequested"
|
||||||
class="playlistInfo"
|
class="playlistInfo"
|
||||||
:class="{
|
:class="{
|
||||||
promptOpen,
|
promptOpen,
|
||||||
|
|
|
@ -16,6 +16,36 @@
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.searchInputsRow {
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
/* 2 columns */
|
||||||
|
grid-template-columns: 1fr auto;
|
||||||
|
column-gap: 16px;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.searchInputsRow {
|
||||||
|
/* Switch to 2 rows from 2 columns */
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: auto auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.optionsRow {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 800px) {
|
||||||
|
.optionsRow {
|
||||||
|
/* Switch to 2 rows from 2 columns */
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: auto auto;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.sortSelect {
|
.sortSelect {
|
||||||
/* Put it on the right */
|
/* Put it on the right */
|
||||||
margin-inline-start: auto;
|
margin-inline-start: auto;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import FtSelect from '../../components/ft-select/ft-select.vue'
|
||||||
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
||||||
import FtInput from '../../components/ft-input/ft-input.vue'
|
import FtInput from '../../components/ft-input/ft-input.vue'
|
||||||
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
|
import FtIconButton from '../../components/ft-icon-button/ft-icon-button.vue'
|
||||||
|
import FtToggleSwitch from '../../components/ft-toggle-switch/ft-toggle-switch.vue'
|
||||||
|
|
||||||
const SORT_BY_VALUES = {
|
const SORT_BY_VALUES = {
|
||||||
NameAscending: 'name_ascending',
|
NameAscending: 'name_ascending',
|
||||||
|
@ -37,6 +38,7 @@ export default defineComponent({
|
||||||
'ft-element-list': FtElementList,
|
'ft-element-list': FtElementList,
|
||||||
'ft-icon-button': FtIconButton,
|
'ft-icon-button': FtIconButton,
|
||||||
'ft-input': FtInput,
|
'ft-input': FtInput,
|
||||||
|
'ft-toggle-switch': FtToggleSwitch,
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
@ -45,6 +47,7 @@ export default defineComponent({
|
||||||
searchDataLimit: 100,
|
searchDataLimit: 100,
|
||||||
showLoadMoreButton: false,
|
showLoadMoreButton: false,
|
||||||
query: '',
|
query: '',
|
||||||
|
doSearchPlaylistsWithMatchingVideos: false,
|
||||||
activeData: [],
|
activeData: [],
|
||||||
sortBy: SORT_BY_VALUES.LatestPlayedFirst,
|
sortBy: SORT_BY_VALUES.LatestPlayedFirst,
|
||||||
}
|
}
|
||||||
|
@ -165,6 +168,10 @@ export default defineComponent({
|
||||||
this.searchDataLimit = 100
|
this.searchDataLimit = 100
|
||||||
this.filterPlaylistAsync()
|
this.filterPlaylistAsync()
|
||||||
},
|
},
|
||||||
|
doSearchPlaylistsWithMatchingVideos() {
|
||||||
|
this.searchDataLimit = 100
|
||||||
|
this.filterPlaylistAsync()
|
||||||
|
},
|
||||||
fullData() {
|
fullData() {
|
||||||
this.activeData = this.fullData
|
this.activeData = this.fullData
|
||||||
this.filterPlaylist()
|
this.filterPlaylist()
|
||||||
|
@ -209,15 +216,22 @@ export default defineComponent({
|
||||||
if (this.lowerCaseQuery === '') {
|
if (this.lowerCaseQuery === '') {
|
||||||
this.activeData = this.fullData
|
this.activeData = this.fullData
|
||||||
this.showLoadMoreButton = this.allPlaylists.length > this.activeData.length
|
this.showLoadMoreButton = this.allPlaylists.length > this.activeData.length
|
||||||
} else {
|
return
|
||||||
const filteredPlaylists = this.allPlaylists.filter((playlist) => {
|
|
||||||
if (typeof (playlist.playlistName) !== 'string') { return false }
|
|
||||||
|
|
||||||
return playlist.playlistName.toLowerCase().includes(this.lowerCaseQuery)
|
|
||||||
})
|
|
||||||
this.showLoadMoreButton = filteredPlaylists.length > this.searchDataLimit
|
|
||||||
this.activeData = filteredPlaylists.length < this.searchDataLimit ? filteredPlaylists : filteredPlaylists.slice(0, this.searchDataLimit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const filteredPlaylists = this.allPlaylists.filter((playlist) => {
|
||||||
|
if (typeof (playlist.playlistName) !== 'string') { return false }
|
||||||
|
|
||||||
|
if (this.doSearchPlaylistsWithMatchingVideos) {
|
||||||
|
if (playlist.videos.some((v) => v.title.toLowerCase().includes(this.lowerCaseQuery))) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return playlist.playlistName.toLowerCase().includes(this.lowerCaseQuery)
|
||||||
|
})
|
||||||
|
this.showLoadMoreButton = filteredPlaylists.length > this.searchDataLimit
|
||||||
|
this.activeData = filteredPlaylists.length < this.searchDataLimit ? filteredPlaylists : filteredPlaylists.slice(0, this.searchDataLimit)
|
||||||
},
|
},
|
||||||
|
|
||||||
createNewPlaylist: function () {
|
createNewPlaylist: function () {
|
||||||
|
|
|
@ -19,24 +19,39 @@
|
||||||
class="newPlaylistButton"
|
class="newPlaylistButton"
|
||||||
@click="createNewPlaylist"
|
@click="createNewPlaylist"
|
||||||
/>
|
/>
|
||||||
<ft-input
|
<div
|
||||||
v-if="fullData.length > 1"
|
v-if="fullData.length > 1"
|
||||||
ref="searchBar"
|
class="searchInputsRow"
|
||||||
:placeholder="$t('User Playlists.Search bar placeholder')"
|
>
|
||||||
:show-clear-text-button="true"
|
<ft-input
|
||||||
:show-action-button="false"
|
ref="searchBar"
|
||||||
@input="(input) => query = input"
|
:placeholder="$t('User Playlists.Search bar placeholder')"
|
||||||
@clear="query = ''"
|
:show-clear-text-button="true"
|
||||||
/>
|
:show-action-button="false"
|
||||||
<ft-select
|
@input="(input) => query = input"
|
||||||
v-if="fullData.length > 1"
|
@clear="query = ''"
|
||||||
class="sortSelect"
|
/>
|
||||||
:value="sortBy"
|
</div>
|
||||||
:select-names="sortBySelectNames"
|
<div
|
||||||
:select-values="sortBySelectValues"
|
class="optionsRow"
|
||||||
:placeholder="$t('User Playlists.Sort By.Sort By')"
|
>
|
||||||
@change="sortBy = $event"
|
<ft-toggle-switch
|
||||||
/>
|
v-if="fullData.length > 1"
|
||||||
|
:label="$t('User Playlists.Playlists with Matching Videos')"
|
||||||
|
:compact="true"
|
||||||
|
:default-value="doSearchPlaylistsWithMatchingVideos"
|
||||||
|
@change="doSearchPlaylistsWithMatchingVideos = !doSearchPlaylistsWithMatchingVideos"
|
||||||
|
/>
|
||||||
|
<ft-select
|
||||||
|
v-if="fullData.length > 1"
|
||||||
|
class="sortSelect"
|
||||||
|
:value="sortBy"
|
||||||
|
:select-names="sortBySelectNames"
|
||||||
|
:select-values="sortBySelectValues"
|
||||||
|
:placeholder="$t('User Playlists.Sort By.Sort By')"
|
||||||
|
@change="sortBy = $event"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ft-flex-box
|
<ft-flex-box
|
||||||
v-if="fullData.length === 0"
|
v-if="fullData.length === 0"
|
||||||
|
@ -56,6 +71,7 @@
|
||||||
v-else-if="activeData.length > 0 && !isLoading"
|
v-else-if="activeData.length > 0 && !isLoading"
|
||||||
:data="activeData"
|
:data="activeData"
|
||||||
:data-type="'playlist'"
|
:data-type="'playlist'"
|
||||||
|
:search-query-text="doSearchPlaylistsWithMatchingVideos ? lowerCaseQuery : ''"
|
||||||
:use-channels-hidden-preference="false"
|
:use-channels-hidden-preference="false"
|
||||||
:hide-forbidden-titles="false"
|
:hide-forbidden-titles="false"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -143,7 +143,8 @@ User Playlists:
|
||||||
it listed here
|
it listed here
|
||||||
You have no playlists. Click on the create new playlist button to create a new one.: You have no playlists. Click on the create new playlist button to create a new one.
|
You have no playlists. Click on the create new playlist button to create a new one.: You have no playlists. Click on the create new playlist button to create a new one.
|
||||||
Empty Search Message: There are no videos in this playlist that matches your search
|
Empty Search Message: There are no videos in this playlist that matches your search
|
||||||
Search bar placeholder: Search in Playlist
|
Search bar placeholder: Search for Playlists
|
||||||
|
Playlists with Matching Videos: Playlists with Matching Videos
|
||||||
|
|
||||||
This playlist currently has no videos.: This playlist currently has no videos.
|
This playlist currently has no videos.: This playlist currently has no videos.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue