mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-28 08:05:56 -05:00
Merge pull request #1595 from hacketiwack/feature-1473
[web] #1473 Add sort by rating for composer, genre, and artist tracks.
This commit is contained in:
commit
cad4f0b89a
File diff suppressed because one or more lines are too long
@ -1,40 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<template v-for="track in tracks" :key="track.itemId">
|
||||||
v-for="(track, index) in tracks"
|
<div v-if="!track.isItem" class="mt-6 mb-5 py-2">
|
||||||
:id="'index_' + track.title_sort.charAt(0).toUpperCase()"
|
<span
|
||||||
:key="track.id"
|
:id="'index_' + track.groupKey"
|
||||||
class="media"
|
class="tag is-info is-light is-small has-text-weight-bold"
|
||||||
:class="{ 'with-progress': show_progress }"
|
v-text="track.groupKey"
|
||||||
@click="play_track(index, track)"
|
|
||||||
>
|
|
||||||
<figure v-if="show_icon" class="media-left fd-has-action">
|
|
||||||
<span class="icon"><mdicon name="file-outline" size="16" /></span>
|
|
||||||
</figure>
|
|
||||||
<div class="media-content fd-has-action is-clipped">
|
|
||||||
<h1
|
|
||||||
class="title is-6"
|
|
||||||
:class="{
|
|
||||||
'has-text-grey':
|
|
||||||
track.media_kind === 'podcast' && track.play_count > 0
|
|
||||||
}"
|
|
||||||
v-text="track.title"
|
|
||||||
/>
|
|
||||||
<h2 class="subtitle is-7 has-text-grey" v-text="track.artist" />
|
|
||||||
<h2 class="subtitle is-7 has-text-grey" v-text="track.album" />
|
|
||||||
<progress-bar
|
|
||||||
v-if="show_progress"
|
|
||||||
:max="track.length_ms"
|
|
||||||
:value="track.seek_ms"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<div
|
||||||
<a @click.prevent.stop="open_dialog(track)">
|
v-else-if="track.isItem"
|
||||||
<span class="icon has-text-dark"
|
class="media"
|
||||||
><mdicon name="dots-vertical" size="16"
|
:class="{ 'with-progress': show_progress }"
|
||||||
/></span>
|
@click="play_track(index, track.item)"
|
||||||
</a>
|
>
|
||||||
|
<figure v-if="show_icon" class="media-left fd-has-action">
|
||||||
|
<span class="icon"><mdicon name="file-outline" size="16" /></span>
|
||||||
|
</figure>
|
||||||
|
<div class="media-content fd-has-action is-clipped">
|
||||||
|
<h1
|
||||||
|
class="title is-6"
|
||||||
|
:class="{
|
||||||
|
'has-text-grey':
|
||||||
|
track.item.media_kind === 'podcast' && track.item.play_count > 0
|
||||||
|
}"
|
||||||
|
v-text="track.item.title"
|
||||||
|
/>
|
||||||
|
<h2 class="subtitle is-7 has-text-grey" v-text="track.item.artist" />
|
||||||
|
<h2 class="subtitle is-7 has-text-grey" v-text="track.item.album" />
|
||||||
|
<progress-bar
|
||||||
|
v-if="show_progress"
|
||||||
|
:max="track.item.length_ms"
|
||||||
|
:value="track.item.seek_ms"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="media-right">
|
||||||
|
<a @click.prevent.stop="open_dialog(track.item)">
|
||||||
|
<span class="icon has-text-dark"
|
||||||
|
><mdicon name="dots-vertical" size="16"
|
||||||
|
/></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<teleport to="#app">
|
<teleport to="#app">
|
||||||
<modal-dialog-track
|
<modal-dialog-track
|
||||||
:show="show_details_modal"
|
:show="show_details_modal"
|
||||||
|
@ -31,7 +31,6 @@ export function byName(field, defaultValue = '_') {
|
|||||||
compareFn: (a, b) => {
|
compareFn: (a, b) => {
|
||||||
const fieldA = a[field] || defaultValue
|
const fieldA = a[field] || defaultValue
|
||||||
const fieldB = b[field] || defaultValue
|
const fieldB = b[field] || defaultValue
|
||||||
|
|
||||||
return fieldA.localeCompare(fieldB, locale.value)
|
return fieldA.localeCompare(fieldB, locale.value)
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -42,12 +41,27 @@ export function byName(field, defaultValue = '_') {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function byRating(field, { direction = 'asc', defaultValue = 0 }) {
|
||||||
|
return {
|
||||||
|
compareFn: (a, b) => {
|
||||||
|
const fieldA = a[field] || defaultValue
|
||||||
|
const fieldB = b[field] || defaultValue
|
||||||
|
const result = fieldA - fieldB
|
||||||
|
return direction === 'asc' ? result : result * -1
|
||||||
|
},
|
||||||
|
|
||||||
|
groupKeyFn: (item) => {
|
||||||
|
const fieldValue = item[field] || defaultValue
|
||||||
|
return Math.floor(fieldValue / 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function byYear(field, { direction = 'asc', defaultValue = '0000' }) {
|
export function byYear(field, { direction = 'asc', defaultValue = '0000' }) {
|
||||||
return {
|
return {
|
||||||
compareFn: (a, b) => {
|
compareFn: (a, b) => {
|
||||||
const fieldA = a[field] || defaultValue
|
const fieldA = a[field] || defaultValue
|
||||||
const fieldB = b[field] || defaultValue
|
const fieldB = b[field] || defaultValue
|
||||||
|
|
||||||
const result = fieldA.localeCompare(fieldB, locale.value)
|
const result = fieldA.localeCompare(fieldB, locale.value)
|
||||||
return direction === 'asc' ? result : result * -1
|
return direction === 'asc' ? result : result * -1
|
||||||
},
|
},
|
||||||
@ -64,19 +78,15 @@ export function byDateSinceToday(field, defaultValue = '0000') {
|
|||||||
compareFn: (a, b) => {
|
compareFn: (a, b) => {
|
||||||
const fieldA = a[field] || defaultValue
|
const fieldA = a[field] || defaultValue
|
||||||
const fieldB = b[field] || defaultValue
|
const fieldB = b[field] || defaultValue
|
||||||
|
|
||||||
return fieldB.localeCompare(fieldA, locale.value)
|
return fieldB.localeCompare(fieldA, locale.value)
|
||||||
},
|
},
|
||||||
|
|
||||||
groupKeyFn: (item) => {
|
groupKeyFn: (item) => {
|
||||||
const fieldValue = item[field]
|
const fieldValue = item[field]
|
||||||
|
|
||||||
if (!fieldValue) {
|
if (!fieldValue) {
|
||||||
return defaultValue
|
return defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
const diff = new Date().getTime() - new Date(fieldValue).getTime()
|
const diff = new Date().getTime() - new Date(fieldValue).getTime()
|
||||||
|
|
||||||
if (diff < 86400000) {
|
if (diff < 86400000) {
|
||||||
// 24h
|
// 24h
|
||||||
return t('group-by-list.today')
|
return t('group-by-list.today')
|
||||||
@ -143,14 +153,6 @@ export class GroupByList {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
next: () => {
|
next: () => {
|
||||||
/*
|
|
||||||
console.log(
|
|
||||||
'[group-by-list] itemIndex=' +
|
|
||||||
itemIndex +
|
|
||||||
', groupIndex=' +
|
|
||||||
groupIndex
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
if (this.isEmpty()) {
|
if (this.isEmpty()) {
|
||||||
return { done: true }
|
return { done: true }
|
||||||
} else if (groupIndex >= this.indexList.length) {
|
} else if (groupIndex >= this.indexList.length) {
|
||||||
@ -159,11 +161,6 @@ export class GroupByList {
|
|||||||
// This should never happen, as the we already
|
// This should never happen, as the we already
|
||||||
// return "done" after we reached the last item
|
// return "done" after we reached the last item
|
||||||
// of the last group
|
// of the last group
|
||||||
/*
|
|
||||||
console.log(
|
|
||||||
'[group-by-list] done! (groupIndex >= this.indexList.length)'
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
return { done: true }
|
return { done: true }
|
||||||
} else if (groupIndex < 0) {
|
} else if (groupIndex < 0) {
|
||||||
// We start iterating
|
// We start iterating
|
||||||
@ -224,11 +221,6 @@ export class GroupByList {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No group left, we are done iterating
|
// No group left, we are done iterating
|
||||||
/*
|
|
||||||
console.log(
|
|
||||||
'[group-by-list] done! (groupIndex >= this.indexList.length)'
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
return { done: true }
|
return { done: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,6 +270,7 @@
|
|||||||
"sort-by": {
|
"sort-by": {
|
||||||
"title": "Sortieren nach",
|
"title": "Sortieren nach",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"rating": "Bewertung",
|
||||||
"release-date": "Erscheinungsdatum"
|
"release-date": "Erscheinungsdatum"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -333,7 +334,12 @@
|
|||||||
"composer": {
|
"composer": {
|
||||||
"album-count": "{count} Alben",
|
"album-count": "{count} Alben",
|
||||||
"shuffle": "Zufallswiedergabe",
|
"shuffle": "Zufallswiedergabe",
|
||||||
"track-count": "{count} Tracks"
|
"track-count": "{count} Tracks",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Sortieren nach",
|
||||||
|
"name": "Name",
|
||||||
|
"rating": "Bewertung"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"composers": {
|
"composers": {
|
||||||
"count": "{count} Komponisten",
|
"count": "{count} Komponisten",
|
||||||
@ -346,7 +352,12 @@
|
|||||||
"genre": {
|
"genre": {
|
||||||
"album-count": "{count} Alben",
|
"album-count": "{count} Alben",
|
||||||
"shuffle": "Zufallswiedergabe",
|
"shuffle": "Zufallswiedergabe",
|
||||||
"track-count": "{count} Tracks"
|
"track-count": "{count} Tracks",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Sortieren nach",
|
||||||
|
"name": "Name",
|
||||||
|
"rating": "Bewertung"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"genres": {
|
"genres": {
|
||||||
"count": "{count} Genres",
|
"count": "{count} Genres",
|
||||||
|
@ -270,6 +270,7 @@
|
|||||||
"sort-by": {
|
"sort-by": {
|
||||||
"title": "Sort by",
|
"title": "Sort by",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
|
"rating": "Rating",
|
||||||
"release-date": "Release date"
|
"release-date": "Release date"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -333,7 +334,12 @@
|
|||||||
"composer": {
|
"composer": {
|
||||||
"album-count": "{count} albums",
|
"album-count": "{count} albums",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
"track-count": "{count} tracks"
|
"track-count": "{count} tracks",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Sort by",
|
||||||
|
"name": "Name",
|
||||||
|
"rating": "Rating"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"composers": {
|
"composers": {
|
||||||
"count": "{count} composers",
|
"count": "{count} composers",
|
||||||
@ -346,7 +352,12 @@
|
|||||||
"genre": {
|
"genre": {
|
||||||
"album-count": "{count} albums",
|
"album-count": "{count} albums",
|
||||||
"shuffle": "Shuffle",
|
"shuffle": "Shuffle",
|
||||||
"track-count": "{count} tracks"
|
"track-count": "{count} tracks",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Sort by",
|
||||||
|
"name": "Name",
|
||||||
|
"rating": "Rating"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"genres": {
|
"genres": {
|
||||||
"count": "{count} genres",
|
"count": "{count} genres",
|
||||||
|
@ -270,6 +270,7 @@
|
|||||||
"sort-by": {
|
"sort-by": {
|
||||||
"title": "Trier par",
|
"title": "Trier par",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
|
"rating": "Classement",
|
||||||
"release-date": "Date de sortie"
|
"release-date": "Date de sortie"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -333,7 +334,12 @@
|
|||||||
"composer": {
|
"composer": {
|
||||||
"album-count": "{count} albums",
|
"album-count": "{count} albums",
|
||||||
"shuffle": "Lecture aléatoire",
|
"shuffle": "Lecture aléatoire",
|
||||||
"track-count": "{count} pistes"
|
"track-count": "{count} pistes",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Trier par",
|
||||||
|
"name": "Nom",
|
||||||
|
"rating": "Classement"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"composers": {
|
"composers": {
|
||||||
"count": "{count} compositeurs",
|
"count": "{count} compositeurs",
|
||||||
@ -346,7 +352,12 @@
|
|||||||
"genre": {
|
"genre": {
|
||||||
"album-count": "{count} albums",
|
"album-count": "{count} albums",
|
||||||
"shuffle": "Lecture aléatoire",
|
"shuffle": "Lecture aléatoire",
|
||||||
"track-count": "{count} pistes"
|
"track-count": "{count} pistes",
|
||||||
|
"sort-by": {
|
||||||
|
"title": "Trier par",
|
||||||
|
"name": "Nom",
|
||||||
|
"rating": "Classement"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"genres": {
|
"genres": {
|
||||||
"count": "{count} genres",
|
"count": "{count} genres",
|
||||||
|
@ -49,6 +49,7 @@ import ListTracks from '@/components/ListTracks.vue'
|
|||||||
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -60,7 +61,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.album = response[0].data
|
vm.album = response[0].data
|
||||||
vm.tracks = response[1].data.items
|
vm.tracks = new GroupByList(response[1].data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,8 +85,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: [],
|
tracks: new GroupByList(),
|
||||||
|
|
||||||
show_album_details_modal: false
|
show_album_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,20 @@
|
|||||||
<div>
|
<div>
|
||||||
<content-with-heading>
|
<content-with-heading>
|
||||||
<template #options>
|
<template #options>
|
||||||
<index-button-list :index="index_list" />
|
<index-button-list :index="tracks.indexList" />
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p
|
||||||
|
class="heading"
|
||||||
|
style="margin-bottom: 24px"
|
||||||
|
v-text="$t('page.artist.sort-by.title')"
|
||||||
|
/>
|
||||||
|
<dropdown-menu
|
||||||
|
v-model="selected_groupby_option_id"
|
||||||
|
:options="groupby_options"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #heading-left>
|
<template #heading-left>
|
||||||
<p class="title is-4" v-text="artist.name" />
|
<p class="title is-4" v-text="artist.name" />
|
||||||
@ -39,7 +52,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<list-tracks :tracks="tracks.items" :uris="track_uris" />
|
<list-tracks :tracks="tracks" :uris="track_uris" />
|
||||||
<modal-dialog-artist
|
<modal-dialog-artist
|
||||||
:show="show_artist_details_modal"
|
:show="show_artist_details_modal"
|
||||||
:artist="artist"
|
:artist="artist"
|
||||||
@ -52,10 +65,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
|
import DropdownMenu from '@/components/DropdownMenu.vue'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
import ModalDialogArtist from '@/components/ModalDialogArtist.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import * as types from '@/store/mutation_types'
|
||||||
|
import { byName, byRating, GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -67,7 +83,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.artist = response[0].data
|
vm.artist = response[0].data
|
||||||
vm.tracks = response[1].data.tracks
|
vm.tracks_list = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +91,9 @@ export default {
|
|||||||
name: 'PageArtistTracks',
|
name: 'PageArtistTracks',
|
||||||
components: {
|
components: {
|
||||||
ContentWithHeading,
|
ContentWithHeading,
|
||||||
ListTracks,
|
DropdownMenu,
|
||||||
IndexButtonList,
|
IndexButtonList,
|
||||||
|
ListTracks,
|
||||||
ModalDialogArtist
|
ModalDialogArtist
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -96,25 +113,43 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
artist: {},
|
artist: {},
|
||||||
tracks: { items: [] },
|
groupby_options: [
|
||||||
|
{
|
||||||
show_artist_details_modal: false
|
id: 1,
|
||||||
|
name: this.$t('page.artist.sort-by.name'),
|
||||||
|
options: byName('title_sort')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: this.$t('page.artist.sort-by.rating'),
|
||||||
|
options: byRating('rating', {
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
],
|
||||||
|
show_artist_details_modal: false,
|
||||||
|
tracks_list: new GroupByList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
index_list() {
|
selected_groupby_option_id: {
|
||||||
return [
|
get() {
|
||||||
...new Set(
|
return this.$store.state.artist_tracks_sort
|
||||||
this.tracks.items.map((track) =>
|
},
|
||||||
track.title_sort.charAt(0).toUpperCase()
|
set(value) {
|
||||||
)
|
this.$store.commit(types.ARTIST_TRACKS_SORT, value)
|
||||||
)
|
}
|
||||||
]
|
},
|
||||||
|
tracks() {
|
||||||
|
const groupBy = this.groupby_options.find(
|
||||||
|
(o) => o.id === this.selected_groupby_option_id
|
||||||
|
)
|
||||||
|
this.tracks_list.group(groupBy.options)
|
||||||
|
return this.tracks_list
|
||||||
},
|
},
|
||||||
|
|
||||||
track_uris() {
|
track_uris() {
|
||||||
return this.tracks.items.map((a) => a.uri).join(',')
|
return this.tracks_list.items.map((a) => a.uri).join(',')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -125,10 +160,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_uri(
|
webapi.player_play_uri(this.tracks_list.map((a) => a.uri).join(','), true)
|
||||||
this.tracks.items.map((a) => a.uri).join(','),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ import ListTracks from '@/components/ListTracks.vue'
|
|||||||
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -63,7 +64,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.album = response[0].data
|
vm.album = response[0].data
|
||||||
vm.tracks = response[1].data.items
|
vm.tracks = new GroupByList(response[1].data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +88,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: [],
|
tracks: new GroupByList(),
|
||||||
|
|
||||||
show_album_details_modal: false
|
show_album_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
<p class="heading" v-text="$t('page.browse.tracks')" />
|
<p class="heading" v-text="$t('page.browse.tracks')" />
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<list-tracks :tracks="recently_played.items" />
|
<list-tracks :tracks="recently_played" />
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<nav class="level">
|
<nav class="level">
|
||||||
@ -77,7 +77,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.recently_added = new GroupByList(response[0].data.albums)
|
vm.recently_added = new GroupByList(response[0].data.albums)
|
||||||
vm.recently_played = response[1].data.tracks
|
vm.recently_played = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
<p class="heading" v-text="$t('page.browse.recently-played.tracks')" />
|
<p class="heading" v-text="$t('page.browse.recently-played.tracks')" />
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<list-tracks :tracks="recently_played.items" />
|
<list-tracks :tracks="recently_played" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -21,6 +21,7 @@ import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
|||||||
import TabsMusic from '@/components/TabsMusic.vue'
|
import TabsMusic from '@/components/TabsMusic.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -33,7 +34,7 @@ const dataObject = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.recently_played = response.data.tracks
|
vm.recently_played = new GroupByList(response.data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<content-with-heading>
|
<content-with-heading>
|
||||||
|
<template #options>
|
||||||
|
<index-button-list :index="tracks.indexList" />
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p
|
||||||
|
class="heading"
|
||||||
|
style="margin-bottom: 24px"
|
||||||
|
v-text="$t('page.artist.sort-by.title')"
|
||||||
|
/>
|
||||||
|
<dropdown-menu
|
||||||
|
v-model="selected_groupby_option_id"
|
||||||
|
:options="groupby_options"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #heading-left>
|
<template #heading-left>
|
||||||
<p class="title is-4" v-text="composer.name" />
|
<p class="title is-4" v-text="composer.name" />
|
||||||
</template>
|
</template>
|
||||||
@ -38,7 +54,7 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<list-tracks :tracks="tracks.items" :expression="play_expression" />
|
<list-tracks :tracks="tracks" :expression="expression" />
|
||||||
<modal-dialog-composer
|
<modal-dialog-composer
|
||||||
:show="show_composer_details_modal"
|
:show="show_composer_details_modal"
|
||||||
:composer="composer"
|
:composer="composer"
|
||||||
@ -51,9 +67,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
|
import DropdownMenu from '@/components/DropdownMenu.vue'
|
||||||
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogComposer from '@/components/ModalDialogComposer.vue'
|
import ModalDialogComposer from '@/components/ModalDialogComposer.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import * as types from '@/store/mutation_types'
|
||||||
|
import { byName, byRating, GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -65,7 +85,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.composer = response[0].data
|
vm.composer = response[0].data
|
||||||
vm.tracks = response[1].data.tracks
|
vm.tracks_list = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,6 +93,8 @@ export default {
|
|||||||
name: 'PageComposerTracks',
|
name: 'PageComposerTracks',
|
||||||
components: {
|
components: {
|
||||||
ContentWithHeading,
|
ContentWithHeading,
|
||||||
|
DropdownMenu,
|
||||||
|
IndexButtonList,
|
||||||
ListTracks,
|
ListTracks,
|
||||||
ModalDialogComposer
|
ModalDialogComposer
|
||||||
},
|
},
|
||||||
@ -92,16 +114,44 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tracks: { items: [] },
|
groupby_options: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: this.$t('page.composer.sort-by.name'),
|
||||||
|
options: byName('title_sort')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: this.$t('page.composer.sort-by.rating'),
|
||||||
|
options: byRating('rating', {
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
],
|
||||||
composer: {},
|
composer: {},
|
||||||
|
show_composer_details_modal: false,
|
||||||
show_composer_details_modal: false
|
tracks_list: new GroupByList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
play_expression() {
|
expression() {
|
||||||
return 'composer is "' + this.composer.name + '" and media_kind is music'
|
return 'composer is "' + this.composer.name + '" and media_kind is music'
|
||||||
|
},
|
||||||
|
selected_groupby_option_id: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.composer_tracks_sort
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit(types.COMPOSER_TRACKS_SORT, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tracks() {
|
||||||
|
const groupBy = this.groupby_options.find(
|
||||||
|
(o) => o.id === this.selected_groupby_option_id
|
||||||
|
)
|
||||||
|
this.tracks_list.group(groupBy.options)
|
||||||
|
return this.tracks_list
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -115,7 +165,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
play: function () {
|
play: function () {
|
||||||
webapi.player_play_expression(this.play_expression, true)
|
webapi.player_play_expression(this.expression, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,16 +22,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<list-directories :directories="files.directories" />
|
<list-directories :directories="dirs" />
|
||||||
<list-playlists :playlists="playlists_list" />
|
<list-playlists :playlists="playlists" />
|
||||||
<list-tracks
|
<list-tracks
|
||||||
:tracks="files.tracks.items"
|
:tracks="tracks"
|
||||||
:expression="play_expression"
|
:expression="play_expression"
|
||||||
:show_icon="true"
|
:show_icon="true"
|
||||||
/>
|
/>
|
||||||
<modal-dialog-directory
|
<modal-dialog-directory
|
||||||
:show="show_details_modal"
|
:show="show_details_modal"
|
||||||
:directory="{ path: current_directory }"
|
:directory="current_directory"
|
||||||
@close="show_details_modal = false"
|
@close="show_details_modal = false"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@ -58,16 +58,15 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
if (response) {
|
if (response) {
|
||||||
vm.files = response.data
|
vm.dirs = response.data.directories
|
||||||
vm.playlists_list = new GroupByList(response.data.playlists)
|
vm.playlists = new GroupByList(response.data.playlists)
|
||||||
|
vm.tracks = new GroupByList(response.data.tracks)
|
||||||
} else {
|
} else {
|
||||||
vm.files = {
|
vm.dirs = vm.$store.state.config.directories.map((dir) => {
|
||||||
directories: vm.$store.state.config.directories.map((dir) => {
|
return { path: dir }
|
||||||
return { path: dir }
|
})
|
||||||
}),
|
vm.playlists = new GroupByList()
|
||||||
tracks: { items: [] },
|
vm.tracks = new GroupByList()
|
||||||
playlists: { items: [] }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,12 +96,9 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
files: {
|
dirs: [],
|
||||||
directories: [],
|
playlists: new GroupByList(),
|
||||||
tracks: { items: [] },
|
tracks: new GroupByList(),
|
||||||
playlists: { items: [] }
|
|
||||||
},
|
|
||||||
playlists_list: new GroupByList(),
|
|
||||||
show_details_modal: false
|
show_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,20 @@
|
|||||||
<div>
|
<div>
|
||||||
<content-with-heading>
|
<content-with-heading>
|
||||||
<template #options>
|
<template #options>
|
||||||
<index-button-list :index="index_list" />
|
<index-button-list :index="tracks.indexList" />
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<p
|
||||||
|
class="heading"
|
||||||
|
style="margin-bottom: 24px"
|
||||||
|
v-text="$t('page.genre.sort-by.title')"
|
||||||
|
/>
|
||||||
|
<dropdown-menu
|
||||||
|
v-model="selected_groupby_option_id"
|
||||||
|
:options="groupby_options"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #heading-left>
|
<template #heading-left>
|
||||||
<p class="title is-4" v-text="genre.name" />
|
<p class="title is-4" v-text="genre.name" />
|
||||||
@ -35,7 +48,7 @@
|
|||||||
v-text="$t('page.genre.track-count', { count: genre.track_count })"
|
v-text="$t('page.genre.track-count', { count: genre.track_count })"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<list-tracks :tracks="tracks.items" :expression="expression" />
|
<list-tracks :tracks="tracks" :expression="expression" />
|
||||||
<modal-dialog-genre
|
<modal-dialog-genre
|
||||||
:show="show_genre_details_modal"
|
:show="show_genre_details_modal"
|
||||||
:genre="genre"
|
:genre="genre"
|
||||||
@ -48,10 +61,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
|
import DropdownMenu from '@/components/DropdownMenu.vue'
|
||||||
import IndexButtonList from '@/components/IndexButtonList.vue'
|
import IndexButtonList from '@/components/IndexButtonList.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogGenre from '@/components/ModalDialogGenre.vue'
|
import ModalDialogGenre from '@/components/ModalDialogGenre.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import * as types from '@/store/mutation_types'
|
||||||
|
import { byName, byRating, GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -63,7 +79,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.genre = response[0].data
|
vm.genre = response[0].data
|
||||||
vm.tracks = response[1].data.tracks
|
vm.tracks_list = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,8 +87,9 @@ export default {
|
|||||||
name: 'PageGenreTracks',
|
name: 'PageGenreTracks',
|
||||||
components: {
|
components: {
|
||||||
ContentWithHeading,
|
ContentWithHeading,
|
||||||
ListTracks,
|
DropdownMenu,
|
||||||
IndexButtonList,
|
IndexButtonList,
|
||||||
|
ListTracks,
|
||||||
ModalDialogGenre
|
ModalDialogGenre
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -91,26 +108,44 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tracks: { items: [] },
|
genre: {},
|
||||||
genre: '',
|
groupby_options: [
|
||||||
|
{
|
||||||
show_genre_details_modal: false
|
id: 1,
|
||||||
|
name: this.$t('page.genre.sort-by.name'),
|
||||||
|
options: byName('title_sort')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: this.$t('page.genre.sort-by.rating'),
|
||||||
|
options: byRating('rating', {
|
||||||
|
direction: 'desc'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
],
|
||||||
|
show_genre_details_modal: false,
|
||||||
|
tracks_list: new GroupByList()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
index_list() {
|
|
||||||
return [
|
|
||||||
...new Set(
|
|
||||||
this.tracks.items.map((track) =>
|
|
||||||
track.title_sort.charAt(0).toUpperCase()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
expression() {
|
expression() {
|
||||||
return 'genre is "' + this.genre.name + '" and media_kind is music'
|
return 'genre is "' + this.genre.name + '" and media_kind is music'
|
||||||
|
},
|
||||||
|
selected_groupby_option_id: {
|
||||||
|
get() {
|
||||||
|
return this.$store.state.genre_tracks_sort
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.$store.commit(types.GENRE_TRACKS_SORT, value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tracks() {
|
||||||
|
const groupBy = this.groupby_options.find(
|
||||||
|
(o) => o.id === this.selected_groupby_option_id
|
||||||
|
)
|
||||||
|
this.tracks_list.group(groupBy.options)
|
||||||
|
return this.tracks_list
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<template #content>
|
<template #content>
|
||||||
<p
|
<p
|
||||||
class="heading has-text-centered-mobile"
|
class="heading has-text-centered-mobile"
|
||||||
v-text="$t('page.playlist.length', { length: tracks.length })"
|
v-text="$t('page.playlist.count', { count: tracks.count })"
|
||||||
/>
|
/>
|
||||||
<list-tracks :tracks="tracks" :uris="uris" />
|
<list-tracks :tracks="tracks" :uris="uris" />
|
||||||
<modal-dialog-playlist
|
<modal-dialog-playlist
|
||||||
@ -38,6 +38,7 @@ import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
|||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import ModalDialogPlaylist from '@/components/ModalDialogPlaylist.vue'
|
import ModalDialogPlaylist from '@/components/ModalDialogPlaylist.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -49,7 +50,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.playlist = response[0].data
|
vm.playlist = response[0].data
|
||||||
vm.tracks = response[1].data.items
|
vm.tracks = new GroupByList(response[1].data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +74,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
playlist: {},
|
playlist: {},
|
||||||
tracks: [],
|
tracks: new GroupByList(),
|
||||||
|
|
||||||
show_playlist_details_modal: false
|
show_playlist_details_modal: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -61,6 +61,7 @@ import ListTracks from '@/components/ListTracks.vue'
|
|||||||
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
|
||||||
import ModalDialog from '@/components/ModalDialog.vue'
|
import ModalDialog from '@/components/ModalDialog.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -72,7 +73,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.album = response[0].data
|
vm.album = response[0].data
|
||||||
vm.tracks = response[1].data.tracks.items
|
vm.tracks = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,10 +102,8 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: {},
|
album: {},
|
||||||
tracks: [],
|
tracks: new GroupByList(),
|
||||||
|
|
||||||
show_album_details_modal: false,
|
show_album_details_modal: false,
|
||||||
|
|
||||||
show_remove_podcast_modal: false,
|
show_remove_podcast_modal: false,
|
||||||
rss_playlist_to_remove: {}
|
rss_playlist_to_remove: {}
|
||||||
}
|
}
|
||||||
@ -112,7 +111,7 @@ export default {
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
new_tracks() {
|
new_tracks() {
|
||||||
return this.tracks.filter((track) => track.play_count === 0).length
|
return this.tracks.items.filter((track) => track.play_count === 0).length
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -149,7 +148,7 @@ export default {
|
|||||||
|
|
||||||
reload_tracks: function () {
|
reload_tracks: function () {
|
||||||
webapi.library_podcast_episodes(this.album.id).then(({ data }) => {
|
webapi.library_podcast_episodes(this.album.id).then(({ data }) => {
|
||||||
this.tracks = data.tracks.items
|
this.tracks = new GroupByList(data.tracks)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<list-tracks
|
<list-tracks
|
||||||
:tracks="new_episodes.items"
|
:tracks="new_episodes"
|
||||||
:show_progress="true"
|
:show_progress="true"
|
||||||
@play-count-changed="reload_new_episodes"
|
@play-count-changed="reload_new_episodes"
|
||||||
/>
|
/>
|
||||||
@ -75,7 +75,7 @@ const dataObject = {
|
|||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.albums = new GroupByList(response[0].data)
|
vm.albums = new GroupByList(response[0].data)
|
||||||
vm.new_episodes = response[1].data.tracks
|
vm.new_episodes = new GroupByList(response[1].data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ export default {
|
|||||||
|
|
||||||
reload_new_episodes: function () {
|
reload_new_episodes: function () {
|
||||||
webapi.library_podcasts_new_episodes().then(({ data }) => {
|
webapi.library_podcasts_new_episodes().then(({ data }) => {
|
||||||
this.new_episodes = data.tracks
|
this.new_episodes = new GroupByList(data.tracks)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
class="heading has-text-centered-mobile"
|
class="heading has-text-centered-mobile"
|
||||||
v-text="$t('page.radio.count', { count: tracks.total })"
|
v-text="$t('page.radio.count', { count: tracks.total })"
|
||||||
/>
|
/>
|
||||||
<list-tracks :tracks="tracks.items" />
|
<list-tracks :tracks="tracks" />
|
||||||
</template>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
@ -19,6 +19,7 @@
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListTracks from '@/components/ListTracks.vue'
|
import ListTracks from '@/components/ListTracks.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
import { GroupByList } from '@/lib/GroupByList'
|
||||||
|
|
||||||
const dataObject = {
|
const dataObject = {
|
||||||
load: function (to) {
|
load: function (to) {
|
||||||
@ -26,7 +27,7 @@ const dataObject = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
set: function (vm, response) {
|
set: function (vm, response) {
|
||||||
vm.tracks = response.data.tracks
|
vm.tracks = new GroupByList(response.data.tracks)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
tracks: { items: [] }
|
tracks: new GroupByList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<p class="title is-4" v-text="$t('page.search.tracks')" />
|
<p class="title is-4" v-text="$t('page.search.tracks')" />
|
||||||
</template>
|
</template>
|
||||||
<template #content>
|
<template #content>
|
||||||
<list-tracks :tracks="tracks.items" />
|
<list-tracks :tracks="tracks" />
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<nav v-if="show_all_tracks_button" class="level">
|
<nav v-if="show_all_tracks_button" class="level">
|
||||||
@ -275,7 +275,7 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
search_query: '',
|
search_query: '',
|
||||||
tracks: { items: [], total: 0 },
|
tracks: new GroupByList(),
|
||||||
artists: new GroupByList(),
|
artists: new GroupByList(),
|
||||||
albums: new GroupByList(),
|
albums: new GroupByList(),
|
||||||
composers: new GroupByList(),
|
composers: new GroupByList(),
|
||||||
@ -407,7 +407,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
webapi.search(searchParams).then(({ data }) => {
|
webapi.search(searchParams).then(({ data }) => {
|
||||||
this.tracks = data.tracks ? data.tracks : { items: [], total: 0 }
|
this.tracks = new GroupByList(data.tracks)
|
||||||
this.artists = new GroupByList(data.artists)
|
this.artists = new GroupByList(data.artists)
|
||||||
this.albums = new GroupByList(data.albums)
|
this.albums = new GroupByList(data.albums)
|
||||||
this.composers = new GroupByList(data.composers)
|
this.composers = new GroupByList(data.composers)
|
||||||
|
@ -53,10 +53,13 @@ export default createStore({
|
|||||||
search_path: '/search/library',
|
search_path: '/search/library',
|
||||||
recent_searches: [],
|
recent_searches: [],
|
||||||
|
|
||||||
|
composer_tracks_sort: 1,
|
||||||
|
genre_tracks_sort: 1,
|
||||||
hide_singles: false,
|
hide_singles: false,
|
||||||
hide_spotify: false,
|
hide_spotify: false,
|
||||||
artists_sort: 1,
|
artists_sort: 1,
|
||||||
artist_albums_sort: 1,
|
artist_albums_sort: 1,
|
||||||
|
artist_tracks_sort: 1,
|
||||||
albums_sort: 1,
|
albums_sort: 1,
|
||||||
show_only_next_items: false,
|
show_only_next_items: false,
|
||||||
show_burger_menu: false,
|
show_burger_menu: false,
|
||||||
@ -234,6 +237,12 @@ export default createStore({
|
|||||||
state.recent_searches.pop()
|
state.recent_searches.pop()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[types.COMPOSER_TRACKS_SORT](state, sort) {
|
||||||
|
state.composer_tracks_sort = sort
|
||||||
|
},
|
||||||
|
[types.GENRE_TRACKS_SORT](state, sort) {
|
||||||
|
state.genre_tracks_sort = sort
|
||||||
|
},
|
||||||
[types.HIDE_SINGLES](state, hideSingles) {
|
[types.HIDE_SINGLES](state, hideSingles) {
|
||||||
state.hide_singles = hideSingles
|
state.hide_singles = hideSingles
|
||||||
},
|
},
|
||||||
@ -246,6 +255,9 @@ export default createStore({
|
|||||||
[types.ARTIST_ALBUMS_SORT](state, sort) {
|
[types.ARTIST_ALBUMS_SORT](state, sort) {
|
||||||
state.artist_albums_sort = sort
|
state.artist_albums_sort = sort
|
||||||
},
|
},
|
||||||
|
[types.ARTIST_TRACKS_SORT](state, sort) {
|
||||||
|
state.artist_tracks_sort = sort
|
||||||
|
},
|
||||||
[types.ALBUMS_SORT](state, sort) {
|
[types.ALBUMS_SORT](state, sort) {
|
||||||
state.albums_sort = sort
|
state.albums_sort = sort
|
||||||
},
|
},
|
||||||
|
@ -21,10 +21,13 @@ export const DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'
|
|||||||
export const SEARCH_PATH = 'SEARCH_PATH'
|
export const SEARCH_PATH = 'SEARCH_PATH'
|
||||||
export const ADD_RECENT_SEARCH = 'ADD_RECENT_SEARCH'
|
export const ADD_RECENT_SEARCH = 'ADD_RECENT_SEARCH'
|
||||||
|
|
||||||
|
export const COMPOSER_TRACKS_SORT = 'COMPOSER_TRACKS_SORT'
|
||||||
|
export const GENRE_TRACKS_SORT = 'GENRE_TRACKS_SORT'
|
||||||
export const HIDE_SINGLES = 'HIDE_SINGLES'
|
export const HIDE_SINGLES = 'HIDE_SINGLES'
|
||||||
export const HIDE_SPOTIFY = 'HIDE_SPOTIFY'
|
export const HIDE_SPOTIFY = 'HIDE_SPOTIFY'
|
||||||
export const ARTISTS_SORT = 'ARTISTS_SORT'
|
export const ARTISTS_SORT = 'ARTISTS_SORT'
|
||||||
export const ARTIST_ALBUMS_SORT = 'ARTIST_ALBUMS_SORT'
|
export const ARTIST_ALBUMS_SORT = 'ARTIST_ALBUMS_SORT'
|
||||||
|
export const ARTIST_TRACKS_SORT = 'ARTIST_TRACKS_SORT'
|
||||||
export const ALBUMS_SORT = 'ALBUMS_SORT'
|
export const ALBUMS_SORT = 'ALBUMS_SORT'
|
||||||
export const SHOW_ONLY_NEXT_ITEMS = 'SHOW_ONLY_NEXT_ITEMS'
|
export const SHOW_ONLY_NEXT_ITEMS = 'SHOW_ONLY_NEXT_ITEMS'
|
||||||
export const SHOW_BURGER_MENU = 'SHOW_BURGER_MENU'
|
export const SHOW_BURGER_MENU = 'SHOW_BURGER_MENU'
|
||||||
|
Loading…
Reference in New Issue
Block a user