Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ export default defineComponent({
newPlaylistDefaultProperties: function () {
return this.$store.getters.getNewPlaylistDefaultProperties
},

locale: function () {
Comment thread
ChunkyProgrammer marked this conversation as resolved.
return this.$i18n.locale.replace('_', '-')
},
processedQuery: function() {
return this.query.trim().toLowerCase()
},
Expand Down
1 change: 1 addition & 0 deletions src/renderer/store/modules/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ const state = {
thumbnailPreference: '',
blurThumbnails: false,
useProxy: false,
userPlaylistSortOrder: 'date_added_descending',
useRssFeeds: false,
useSponsorBlock: false,
videoVolumeMouseScroll: false,
Expand Down
84 changes: 80 additions & 4 deletions src/renderer/views/Playlist/Playlist.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import PlaylistInfo from '../../components/playlist-info/playlist-info.vue'
import FtListVideoNumbered from '../../components/ft-list-video-numbered/ft-list-video-numbered.vue'
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
import FtButton from '../../components/ft-button/ft-button.vue'
import FtSelect from '../../components/ft-select/ft-select.vue'
import FtAutoLoadNextPageWrapper from '../../components/ft-auto-load-next-page-wrapper/ft-auto-load-next-page-wrapper.vue'
import {
getLocalPlaylist,
Expand All @@ -16,6 +17,16 @@ import {
import { extractNumberFromString, setPublishedTimestampsInvidious, showToast } from '../../helpers/utils'
import { invidiousGetPlaylistInfo, youtubeImageUrlToInvidious } from '../../helpers/api/invidious'

const SORT_BY_VALUES = {
DateAddedNewest: 'date_added_descending',
DateAddedOldest: 'date_added_ascending',
AuthorAscending: 'author_ascending',
AuthorDescending: 'author_descending',
VideoTitleAscending: 'video_title_ascending',
VideoTitleDescending: 'video_title_descending',
Custom: 'custom',
}

export default defineComponent({
name: 'Playlist',
components: {
Expand All @@ -25,6 +36,7 @@ export default defineComponent({
'ft-list-video-numbered': FtListVideoNumbered,
'ft-flex-box': FtFlexBox,
'ft-button': FtButton,
'ft-select': FtSelect,
'ft-auto-load-next-page-wrapper': FtAutoLoadNextPageWrapper,
},
beforeRouteLeave(to, from, next) {
Expand Down Expand Up @@ -77,6 +89,12 @@ export default defineComponent({
currentInvidiousInstance: function () {
return this.$store.getters.getCurrentInvidiousInstance
},
userPlaylistSortOrder: function () {
return this.$store.getters.getUserPlaylistSortOrder
},
sortOrder: function () {
return this.isUserPlaylistRequested ? this.userPlaylistSortOrder : SORT_BY_VALUES.Custom
},
currentLocale: function () {
return this.$i18n.locale.replace('_', '-')
},
Expand Down Expand Up @@ -138,10 +156,10 @@ export default defineComponent({
},

sometimesFilteredUserPlaylistItems() {
if (!this.isUserPlaylistRequested) { return this.playlistItems }
if (this.processedVideoSearchQuery === '') { return this.playlistItems }
if (!this.isUserPlaylistRequested) { return this.sortedPlaylistItems }
if (this.processedVideoSearchQuery === '') { return this.sortedPlaylistItems }

return this.playlistItems.filter((v) => {
return this.sortedPlaylistItems.filter((v) => {
if (typeof (v.title) === 'string' && v.title.toLowerCase().includes(this.processedVideoSearchQuery)) {
return true
} else if (typeof (v.author) === 'string' && v.author.toLowerCase().includes(this.processedVideoSearchQuery)) {
Expand All @@ -151,10 +169,41 @@ export default defineComponent({
return false
})
},
sortByValues() {
return Object.values(SORT_BY_VALUES)
},
isSortOrderCustom() {
return this.sortOrder === SORT_BY_VALUES.Custom
},
sortedPlaylistItems: function () {
if (this.sortOrder === SORT_BY_VALUES.Custom) {
return this.playlistItems
}

return this.playlistItems.toSorted((a, b) => {
switch (this.sortOrder) {
case SORT_BY_VALUES.DateAddedNewest:
return b.timeAdded - a.timeAdded
case SORT_BY_VALUES.DateAddedOldest:
return a.timeAdded - b.timeAdded
case SORT_BY_VALUES.VideoTitleAscending:
return a.title.localeCompare(b.title, this.currentLocale)
case SORT_BY_VALUES.VideoTitleDescending:
return b.title.localeCompare(a.title, this.currentLocale)
case SORT_BY_VALUES.AuthorAscending:
return a.author.localeCompare(b.author, this.currentLocale)
case SORT_BY_VALUES.AuthorDescending:
return b.author.localeCompare(a.author, this.currentLocale)
default:
console.error(`Unknown sortOrder: ${this.sortOrder}`)
return 0
}
})
},
visiblePlaylistItems: function () {
if (!this.isUserPlaylistRequested) {
// No filtering for non user playlists yet
return this.playlistItems
return this.sortedPlaylistItems
}

if (this.userPlaylistVisibleLimit < this.sometimesFilteredUserPlaylistItems.length) {
Expand All @@ -166,6 +215,32 @@ export default defineComponent({
processedVideoSearchQuery() {
return this.videoSearchQuery.trim().toLowerCase()
},
sortBySelectNames() {
return this.sortByValues.map((k) => {
switch (k) {
case SORT_BY_VALUES.Custom:
return this.$t('Playlist.Sort By.Custom')
case SORT_BY_VALUES.DateAddedNewest:
return this.$t('Playlist.Sort By.DateAddedNewest')
case SORT_BY_VALUES.DateAddedOldest:
return this.$t('Playlist.Sort By.DateAddedOldest')
case SORT_BY_VALUES.VideoTitleAscending:
return this.$t('Playlist.Sort By.VideoTitleAscending')
case SORT_BY_VALUES.VideoTitleDescending:
return this.$t('Playlist.Sort By.VideoTitleDescending')
case SORT_BY_VALUES.AuthorAscending:
return this.$t('Playlist.Sort By.AuthorAscending')
case SORT_BY_VALUES.AuthorDescending:
return this.$t('Playlist.Sort By.AuthorDescending')
default:
console.error(`Unknown sort: ${k}`)
return k
}
})
},
sortBySelectValues() {
return this.sortByValues
},
},
watch: {
$route () {
Expand Down Expand Up @@ -485,6 +560,7 @@ export default defineComponent({
...mapActions([
'updateSubscriptionDetails',
'updatePlaylist',
'updateUserPlaylistSortOrder',
'removeVideo',
]),

Expand Down
7 changes: 7 additions & 0 deletions src/renderer/views/Playlist/Playlist.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@
max-block-size: 7vh;
}

.sortSelect {
/* Put it on the right */
margin-inline-start: auto;
/* Align with 'More Options' dropdown button */
margin-inline-end: 20px;
}

:deep(.videoThumbnail) {
margin-block-start: auto;
margin-block-end: auto;
Expand Down
13 changes: 11 additions & 2 deletions src/renderer/views/Playlist/Playlist.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@
<template
v-if="playlistItems.length > 0"
>
<ft-select
v-if="isUserPlaylistRequested && playlistItems.length > 1"
class="sortSelect"
:value="sortOrder"
:select-names="sortBySelectNames"
:select-values="sortBySelectValues"
:placeholder="$t('Playlist.Sort By.Sort By')"
@change="updateUserPlaylistSortOrder"
/>
<template
v-if="visiblePlaylistItems.length > 0"
>
Expand All @@ -62,8 +71,8 @@
appearance="result"
:always-show-add-to-playlist-button="true"
:quick-bookmark-button-enabled="quickBookmarkButtonEnabled"
:can-move-video-up="index > 0 && !playlistInVideoSearchMode"
:can-move-video-down="index < playlistItems.length - 1 && !playlistInVideoSearchMode"
:can-move-video-up="index > 0 && !playlistInVideoSearchMode && isSortOrderCustom"
:can-move-video-down="index < playlistItems.length - 1 && !playlistInVideoSearchMode && isSortOrderCustom"
:can-remove-from-playlist="true"
:video-index="playlistInVideoSearchMode ? playlistItems.findIndex(i => i === item) : index"
:initial-visible-state="index < 10"
Expand Down
10 changes: 9 additions & 1 deletion static/locales/en-US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ User Playlists:

LatestPlayedFirst: 'Recently Played'
EarliestPlayedFirst: 'Earliest Played'

SinglePlaylistView:
Search for Videos: Search for Videos

Expand Down Expand Up @@ -872,6 +871,15 @@ Playlist:
View: View
Views: Views
Last Updated On: Last Updated On
Sort By:
Sort By: Sort By
DateAddedNewest: Latest added first
DateAddedOldest: Earliest added first
AuthorAscending: Author (A-Z)
AuthorDescending: Author (Z-A)
VideoTitleAscending: Title (A-Z)
VideoTitleDescending: Title (Z-A)
Custom: Custom

# On Video Watch Page
#* Published
Expand Down