FreeTube/src/renderer/views/UserPlaylists/UserPlaylists.js

248 lines
8.6 KiB
JavaScript

import { defineComponent } from 'vue'
import { mapActions } from 'vuex'
import debounce from 'lodash.debounce'
import FtCard from '../../components/ft-card/ft-card.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtTooltip from '../../components/ft-tooltip/ft-tooltip.vue'
import FtLoader from '../../components/ft-loader/ft-loader.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
import FtSelect from '../../components/ft-select/ft-select.vue'
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
import FtInput from '../../components/ft-input/ft-input.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 = {
NameAscending: 'name_ascending',
NameDescending: 'name_descending',
LatestCreatedFirst: 'latest_created_first',
EarliestCreatedFirst: 'earliest_created_first',
LatestUpdatedFirst: 'latest_updated_first',
EarliestUpdatedFirst: 'earliest_updated_first',
LatestPlayedFirst: 'latest_played_first',
EarliestPlayedFirst: 'earliest_played_first',
}
export default defineComponent({
name: 'UserPlaylists',
components: {
'ft-card': FtCard,
'ft-flex-box': FtFlexBox,
'ft-tooltip': FtTooltip,
'ft-loader': FtLoader,
'ft-button': FtButton,
'ft-select': FtSelect,
'ft-element-list': FtElementList,
'ft-icon-button': FtIconButton,
'ft-input': FtInput,
'ft-toggle-switch': FtToggleSwitch,
},
data: function () {
return {
isLoading: false,
dataLimit: 100,
searchDataLimit: 100,
showLoadMoreButton: false,
query: '',
doSearchPlaylistsWithMatchingVideos: false,
activeData: [],
sortBy: SORT_BY_VALUES.LatestPlayedFirst,
}
},
computed: {
locale: function () {
return this.$i18n.locale.replace('_', '-')
},
allPlaylists: function () {
const playlists = this.$store.getters.getAllPlaylists
return [].concat(playlists).sort((a, b) => {
switch (this.sortBy) {
case SORT_BY_VALUES.NameAscending:
return a.playlistName.localeCompare(b.playlistName, this.locale)
case SORT_BY_VALUES.NameDescending:
return b.playlistName.localeCompare(a.playlistName, this.locale)
case SORT_BY_VALUES.LatestCreatedFirst: {
if (a.createdAt > b.createdAt) { return -1 }
if (a.createdAt < b.createdAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
case SORT_BY_VALUES.EarliestCreatedFirst: {
if (a.createdAt < b.createdAt) { return -1 }
if (a.createdAt > b.createdAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
case SORT_BY_VALUES.LatestUpdatedFirst: {
if (a.lastUpdatedAt > b.lastUpdatedAt) { return -1 }
if (a.lastUpdatedAt < b.lastUpdatedAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
case SORT_BY_VALUES.EarliestUpdatedFirst: {
if (a.lastUpdatedAt < b.lastUpdatedAt) { return -1 }
if (a.lastUpdatedAt > b.lastUpdatedAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
case SORT_BY_VALUES.LatestPlayedFirst: {
if (a.lastPlayedAt == null && b.lastPlayedAt == null) {
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
// Never played playlist = move to last
if (a.lastPlayedAt == null) { return 1 }
if (b.lastPlayedAt == null) { return -1 }
if (a.lastPlayedAt > b.lastPlayedAt) { return -1 }
if (a.lastPlayedAt < b.lastPlayedAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
case SORT_BY_VALUES.EarliestPlayedFirst: {
// Never played playlist = first
if (a.lastPlayedAt == null && b.lastPlayedAt == null) {
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
// Never played playlist = move to first
if (a.lastPlayedAt == null) { return -1 }
if (b.lastPlayedAt == null) { return 1 }
if (a.lastPlayedAt < b.lastPlayedAt) { return -1 }
if (a.lastPlayedAt > b.lastPlayedAt) { return 1 }
return a.playlistName.localeCompare(b.playlistName, this.locale)
}
default:
console.error(`Unknown sortBy: ${this.sortBy}`)
return 0
}
})
},
fullData: function () {
const data = this.allPlaylists
if (this.allPlaylists.length < this.dataLimit) {
return data
} else {
return data.slice(0, this.dataLimit)
}
},
lowerCaseQuery: function() {
return this.query.toLowerCase()
},
sortBySelectNames() {
return Object.values(SORT_BY_VALUES).map((k) => {
switch (k) {
case SORT_BY_VALUES.NameAscending:
return this.$t('User Playlists.Sort By.NameAscending')
case SORT_BY_VALUES.NameDescending:
return this.$t('User Playlists.Sort By.NameDescending')
case SORT_BY_VALUES.LatestCreatedFirst:
return this.$t('User Playlists.Sort By.LatestCreatedFirst')
case SORT_BY_VALUES.EarliestCreatedFirst:
return this.$t('User Playlists.Sort By.EarliestCreatedFirst')
case SORT_BY_VALUES.LatestUpdatedFirst:
return this.$t('User Playlists.Sort By.LatestUpdatedFirst')
case SORT_BY_VALUES.EarliestUpdatedFirst:
return this.$t('User Playlists.Sort By.EarliestUpdatedFirst')
case SORT_BY_VALUES.LatestPlayedFirst:
return this.$t('User Playlists.Sort By.LatestPlayedFirst')
case SORT_BY_VALUES.EarliestPlayedFirst:
return this.$t('User Playlists.Sort By.EarliestPlayedFirst')
default:
console.error(`Unknown sortBy: ${k}`)
return k
}
})
},
sortBySelectValues() {
return Object.values(SORT_BY_VALUES)
},
},
watch: {
lowerCaseQuery() {
this.searchDataLimit = 100
this.filterPlaylistAsync()
},
doSearchPlaylistsWithMatchingVideos() {
this.searchDataLimit = 100
this.filterPlaylistAsync()
},
fullData() {
this.activeData = this.fullData
this.filterPlaylist()
},
sortBy() {
sessionStorage.setItem('UserPlaylists/sortBy', this.sortBy)
},
},
mounted: function () {
const limit = sessionStorage.getItem('favoritesLimit')
if (limit !== null) {
this.dataLimit = limit
}
const sortBy = sessionStorage.getItem('UserPlaylists/sortBy')
if (sortBy != null) {
this.sortBy = sortBy
}
this.activeData = this.fullData
this.showLoadMoreButton = this.activeData.length < this.allPlaylists.length
this.filterPlaylistDebounce = debounce(this.filterPlaylist, 500)
},
methods: {
increaseLimit: function () {
if (this.query !== '') {
this.searchDataLimit += 100
this.filterPlaylist()
} else {
this.dataLimit += 100
sessionStorage.setItem('favoritesLimit', this.dataLimit)
}
},
filterPlaylistAsync: function() {
// Updating list on every char input could be wasting resources on rendering
// So run it with delay (to be cancelled when more input received within time)
this.filterPlaylistDebounce()
},
filterPlaylist: function() {
if (this.lowerCaseQuery === '') {
this.activeData = this.fullData
this.showLoadMoreButton = this.allPlaylists.length > this.activeData.length
return
}
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 () {
this.showCreatePlaylistPrompt({
title: '',
})
},
...mapActions([
'showCreatePlaylistPrompt'
])
}
})