[web] Fix genre not being displayed correctly depending on the media kind

The genre is not displayed depending on the media kind and not only for the "music" kind.
This commit is contained in:
Alain Nussbaumer 2023-07-24 19:51:00 +02:00
parent ca30b82e9a
commit a264efe2bb
16 changed files with 179 additions and 87 deletions

View File

@ -26,9 +26,8 @@
</template> </template>
<teleport to="#app"> <teleport to="#app">
<modal-dialog-artist <modal-dialog-artist
:show="show_details_modal"
:artist="selected_artist" :artist="selected_artist"
:media_kind="media_kind" :show="show_details_modal"
@close="show_details_modal = false" @close="show_details_modal = false"
/> />
</teleport> </teleport>
@ -41,7 +40,7 @@ export default {
name: 'ListArtists', name: 'ListArtists',
components: { ModalDialogArtist }, components: { ModalDialogArtist },
props: ['artists', 'media_kind', 'hide_group_title'], props: ['artists', 'hide_group_title'],
data() { data() {
return { return {
@ -50,23 +49,12 @@ export default {
} }
}, },
computed: {
media_kind_resolved() {
return this.media_kind ? this.media_kind : this.selected_artist.media_kind
}
},
methods: { methods: {
open_artist(artist) { open_artist(artist) {
this.selected_artist = artist this.selected_artist = artist
if (this.media_kind_resolved === 'audiobook') { const route =
this.$router.push({ artist.media_kind === 'audiobook' ? 'audiobooks-artist' : 'music-artist'
name: 'audiobooks-artist', this.$router.push({ name: route, params: { id: artist.id } })
params: { id: artist.id }
})
} else {
this.$router.push({ name: 'music-artist', params: { id: artist.id } })
}
}, },
open_dialog(artist) { open_dialog(artist) {

View File

@ -28,6 +28,7 @@
<modal-dialog-genre <modal-dialog-genre
:show="show_details_modal" :show="show_details_modal"
:genre="selected_genre" :genre="selected_genre"
:media_kind="media_kind"
@close="show_details_modal = false" @close="show_details_modal = false"
/> />
</teleport> </teleport>
@ -40,7 +41,7 @@ export default {
name: 'ListGenres', name: 'ListGenres',
components: { ModalDialogGenre }, components: { ModalDialogGenre },
props: ['genres', 'media_kind', 'hide_group_title'], props: ['genres', 'hide_group_title', 'media_kind'],
data() { data() {
return { return {
@ -49,17 +50,14 @@ export default {
} }
}, },
computed: {
media_kind_resolved() {
return this.media_kind ? this.media_kind : this.selected_genre.media_kind
}
},
methods: { methods: {
open_genre(genre) { open_genre(genre) {
this.$router.push({ name: 'music-genre', params: { name: genre.name } }) this.$router.push({
name: 'genre-albums',
params: { name: genre.name },
query: { media_kind: this.media_kind }
})
}, },
open_dialog(genre) { open_dialog(genre) {
this.selected_genre = genre this.selected_genre = genre
this.show_details_modal = true this.show_details_modal = true

View File

@ -62,37 +62,36 @@ import webapi from '@/webapi'
export default { export default {
name: 'ModalDialogGenre', name: 'ModalDialogGenre',
props: ['show', 'genre'], props: ['genre', 'media_kind', 'show'],
emits: ['close'], emits: ['close'],
computed: {
expression() {
return `genre is "${this.genre.name}" and media_kind is ${this.media_kind}`
}
},
methods: { methods: {
play() { play() {
this.$emit('close') this.$emit('close')
webapi.player_play_expression( webapi.player_play_expression(this.expression, false)
'genre is "' + this.genre.name + '" and media_kind is music',
false
)
}, },
queue_add() { queue_add() {
this.$emit('close') this.$emit('close')
webapi.queue_expression_add( webapi.queue_expression_add(this.expression)
'genre is "' + this.genre.name + '" and media_kind is music'
)
}, },
queue_add_next() { queue_add_next() {
this.$emit('close') this.$emit('close')
webapi.queue_expression_add_next( webapi.queue_expression_add_next(this.expression)
'genre is "' + this.genre.name + '" and media_kind is music'
)
}, },
open_genre() { open_genre() {
this.$emit('close') this.$emit('close')
this.$router.push({ this.$router.push({
name: 'music-genre', name: 'genre-albums',
params: { name: this.genre.name } params: { name: this.genre.name },
query: { media_kind: this.media_kind }
}) })
} }
} }

View File

@ -208,12 +208,12 @@ export default {
}, },
open_album() { open_album() {
if (this.media_kind === 'podcast') { if (this.item.media_kind === 'podcast') {
this.$router.push({ this.$router.push({
name: 'podcast', name: 'podcast',
params: { id: this.item.album_id } params: { id: this.item.album_id }
}) })
} else if (this.media_kind === 'audiobook') { } else if (this.item.media_kind === 'audiobook') {
this.$router.push({ this.$router.push({
name: 'audiobooks-album', name: 'audiobooks-album',
params: { id: this.item.album_id } params: { id: this.item.album_id }
@ -235,8 +235,9 @@ export default {
open_genre() { open_genre() {
this.$router.push({ this.$router.push({
name: 'music-genre', name: 'genre-albums',
params: { name: this.item.genre } params: { name: this.item.genre },
query: { media_kind: this.item.media_kind }
}) })
}, },

View File

@ -270,8 +270,9 @@ export default {
open_genre() { open_genre() {
this.$router.push({ this.$router.push({
name: 'music-genre', name: 'genre-albums',
params: { name: this.track.genre } params: { name: this.track.genre },
query: { media_kind: this.track.media_kind }
}) })
}, },

View File

@ -33,6 +33,18 @@
</a> </a>
</li> </li>
</router-link> </router-link>
<router-link
v-slot="{ navigate, isActive }"
:to="{ name: 'audiobooks-genres' }"
custom
>
<li :class="{ 'is-active': isActive }">
<a @click="navigate" @keypress.enter="navigate">
<mdicon class="icon is-small" name="speaker" size="16" />
<span v-text="$t('page.audiobooks.tabs.genres')" />
</a>
</li>
</router-link>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -313,7 +313,8 @@
}, },
"tabs": { "tabs": {
"authors": "Autoren", "authors": "Autoren",
"audiobooks": "Hörbücher" "audiobooks": "Hörbücher",
"genres": "Genres"
} }
}, },
"browse": { "browse": {

View File

@ -313,7 +313,8 @@
}, },
"tabs": { "tabs": {
"authors": "Authors", "authors": "Authors",
"audiobooks": "Audiobooks" "audiobooks": "Audiobooks",
"genres": "Genres"
} }
}, },
"browse": { "browse": {

View File

@ -313,7 +313,8 @@
}, },
"tabs": { "tabs": {
"authors": "Auteurs", "authors": "Auteurs",
"audiobooks": "Livres audio" "audiobooks": "Livres audio",
"genres": "Genres"
} }
}, },
"browse": { "browse": {

View File

@ -313,7 +313,8 @@
}, },
"tabs": { "tabs": {
"authors": "作者", "authors": "作者",
"audiobooks": "有声读物" "audiobooks": "有声读物",
"genres": "流派"
} }
}, },
"browse": { "browse": {

View File

@ -0,0 +1,72 @@
<template>
<div class="fd-page-with-tabs">
<tabs-audiobooks />
<content-with-heading>
<template #options>
<index-button-list :index="genres.indexList" />
</template>
<template #heading-left>
<p class="title is-4" v-text="$t('page.genres.title')" />
<p
class="heading"
v-text="$t('page.genres.count', { count: genres.total })"
/>
</template>
<template #content>
<list-genres :genres="genres" :media_kind="'audiobook'" />
</template>
</content-with-heading>
</div>
</template>
<script>
import { GroupByList, byName } from '@/lib/GroupByList'
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import IndexButtonList from '@/components/IndexButtonList.vue'
import ListGenres from '@/components/ListGenres.vue'
import TabsAudiobooks from '@/components/TabsAudiobooks.vue'
import webapi from '@/webapi'
const dataObject = {
load(to) {
return webapi.library_genres('audiobook')
},
set(vm, response) {
vm.genres = response.data
vm.genres = new GroupByList(response.data)
vm.genres.group(byName('name_sort'))
}
}
export default {
name: 'PageAudiobookGenres',
components: {
ContentWithHeading,
IndexButtonList,
ListGenres,
TabsAudiobooks
},
beforeRouteEnter(to, from, next) {
dataObject.load(to).then((response) => {
next((vm) => dataObject.set(vm, response))
})
},
beforeRouteUpdate(to, from, next) {
const vm = this
dataObject.load(to).then((response) => {
dataObject.set(vm, response)
next()
})
},
data() {
return {
genres: new GroupByList()
}
}
}
</script>
<style></style>

View File

@ -35,8 +35,9 @@
</p> </p>
<list-albums :albums="albums_list" /> <list-albums :albums="albums_list" />
<modal-dialog-genre <modal-dialog-genre
:show="show_genre_details_modal"
:genre="genre" :genre="genre"
:media_kind="media_kind"
:show="show_genre_details_modal"
@close="show_genre_details_modal = false" @close="show_genre_details_modal = false"
/> />
</template> </template>
@ -45,8 +46,8 @@
</template> </template>
<script> <script>
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import { GroupByList, byName } from '@/lib/GroupByList' import { GroupByList, byName } from '@/lib/GroupByList'
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import IndexButtonList from '@/components/IndexButtonList.vue' import IndexButtonList from '@/components/IndexButtonList.vue'
import ListAlbums from '@/components/ListAlbums.vue' import ListAlbums from '@/components/ListAlbums.vue'
import ModalDialogGenre from '@/components/ModalDialogGenre.vue' import ModalDialogGenre from '@/components/ModalDialogGenre.vue'
@ -55,8 +56,8 @@ import webapi from '@/webapi'
const dataObject = { const dataObject = {
load(to) { load(to) {
return Promise.all([ return Promise.all([
webapi.library_genre(to.params.name), webapi.library_genre(to.params.name, to.query.media_kind),
webapi.library_genre_albums(to.params.name) webapi.library_genre_albums(to.params.name, to.query.media_kind)
]) ])
}, },
@ -68,14 +69,13 @@ const dataObject = {
} }
export default { export default {
name: 'PageGenreAlbum', name: 'PageGenreAlbums',
components: { components: {
ContentWithHeading, ContentWithHeading,
IndexButtonList, IndexButtonList,
ListAlbums, ListAlbums,
ModalDialogGenre ModalDialogGenre
}, },
beforeRouteEnter(to, from, next) { beforeRouteEnter(to, from, next) {
dataObject.load(to).then((response) => { dataObject.load(to).then((response) => {
next((vm) => dataObject.set(vm, response)) next((vm) => dataObject.set(vm, response))
@ -92,28 +92,31 @@ export default {
next() next()
}) })
}, },
data() { data() {
return { return {
genre: {}, genre: {},
albums_list: new GroupByList(), albums_list: new GroupByList(),
show_genre_details_modal: false show_genre_details_modal: false
} }
}, },
computed: {
media_kind() {
return this.$route.query.media_kind
}
},
methods: { methods: {
open_tracks() { open_tracks() {
this.show_details_modal = false this.show_details_modal = false
this.$router.push({ this.$router.push({
name: 'music-genre-tracks', name: 'genre-tracks',
params: { name: this.genre.name } params: { name: this.genre.name },
query: { media_kind: this.media_kind }
}) })
}, },
play() { play() {
webapi.player_play_expression( webapi.player_play_expression(
'genre is "' + this.genre.name + '" and media_kind is music', `genre is "${this.genre.name}" and media_kind is ${this.media_kind}`,
true true
) )
} }

View File

@ -46,6 +46,7 @@
<modal-dialog-genre <modal-dialog-genre
:show="show_genre_details_modal" :show="show_genre_details_modal"
:genre="genre" :genre="genre"
:media_kind="media_kind"
@close="show_genre_details_modal = false" @close="show_genre_details_modal = false"
/> />
</template> </template>
@ -55,9 +56,9 @@
<script> <script>
import * as types from '@/store/mutation_types' import * as types from '@/store/mutation_types'
import { GroupByList, byName, byRating } from '@/lib/GroupByList'
import ContentWithHeading from '@/templates/ContentWithHeading.vue' import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import ControlDropdown from '@/components/ControlDropdown.vue' import ControlDropdown from '@/components/ControlDropdown.vue'
import { GroupByList, byName, byRating } from '@/lib/GroupByList'
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'
@ -66,8 +67,8 @@ import webapi from '@/webapi'
const dataObject = { const dataObject = {
load(to) { load(to) {
return Promise.all([ return Promise.all([
webapi.library_genre(to.params.name), webapi.library_genre(to.params.name, to.query.media_kind),
webapi.library_genre_tracks(to.params.name) webapi.library_genre_tracks(to.params.name, to.query.media_kind)
]) ])
}, },
@ -124,7 +125,10 @@ export default {
computed: { computed: {
expression() { expression() {
return 'genre is "' + this.genre.name + '" and media_kind is music' return `genre is "${this.genre.name}" and media_kind is ${this.media_kind}`
},
media_kind() {
return this.$route.query.media_kind
}, },
selected_groupby_option_id: { selected_groupby_option_id: {
get() { get() {
@ -147,8 +151,9 @@ export default {
open_genre() { open_genre() {
this.show_details_modal = false this.show_details_modal = false
this.$router.push({ this.$router.push({
name: 'music-genre', name: 'genre-albums',
params: { name: this.genre.name } params: { name: this.genre.name },
query: { media_kind: this.media_kind }
}) })
}, },

View File

@ -13,15 +13,15 @@
/> />
</template> </template>
<template #content> <template #content>
<list-genres :genres="genres" /> <list-genres :genres="genres" :media_kind="'music'" />
</template> </template>
</content-with-heading> </content-with-heading>
</div> </div>
</template> </template>
<script> <script>
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import { GroupByList, byName } from '@/lib/GroupByList' import { GroupByList, byName } from '@/lib/GroupByList'
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import IndexButtonList from '@/components/IndexButtonList.vue' import IndexButtonList from '@/components/IndexButtonList.vue'
import ListGenres from '@/components/ListGenres.vue' import ListGenres from '@/components/ListGenres.vue'
import TabsMusic from '@/components/TabsMusic.vue' import TabsMusic from '@/components/TabsMusic.vue'
@ -43,9 +43,9 @@ export default {
name: 'PageGenres', name: 'PageGenres',
components: { components: {
ContentWithHeading, ContentWithHeading,
TabsMusic,
IndexButtonList, IndexButtonList,
ListGenres ListGenres,
TabsMusic
}, },
beforeRouteEnter(to, from, next) { beforeRouteEnter(to, from, next) {

View File

@ -12,6 +12,7 @@ import PageAudiobooksAlbum from '@/pages/PageAudiobooksAlbum.vue'
import PageAudiobooksAlbums from '@/pages/PageAudiobooksAlbums.vue' import PageAudiobooksAlbums from '@/pages/PageAudiobooksAlbums.vue'
import PageAudiobooksArtist from '@/pages/PageAudiobooksArtist.vue' import PageAudiobooksArtist from '@/pages/PageAudiobooksArtist.vue'
import PageAudiobooksArtists from '@/pages/PageAudiobooksArtists.vue' import PageAudiobooksArtists from '@/pages/PageAudiobooksArtists.vue'
import PageAudiobooksGenres from '@/pages/PageAudiobooksGenres.vue'
import PageBrowse from '@/pages/PageBrowse.vue' import PageBrowse from '@/pages/PageBrowse.vue'
import PageBrowseRecentlyAdded from '@/pages/PageBrowseRecentlyAdded.vue' import PageBrowseRecentlyAdded from '@/pages/PageBrowseRecentlyAdded.vue'
import PageBrowseRecentlyPlayed from '@/pages/PageBrowseRecentlyPlayed.vue' import PageBrowseRecentlyPlayed from '@/pages/PageBrowseRecentlyPlayed.vue'
@ -22,7 +23,7 @@ import PageComposerAlbums from '@/pages/PageComposerAlbums.vue'
import PageComposerTracks from '@/pages/PageComposerTracks.vue' import PageComposerTracks from '@/pages/PageComposerTracks.vue'
import PageComposers from '@/pages/PageComposers.vue' import PageComposers from '@/pages/PageComposers.vue'
import PageFiles from '@/pages/PageFiles.vue' import PageFiles from '@/pages/PageFiles.vue'
import PageGenreAlbum from '@/pages/PageGenreAlbum.vue' import PageGenreAlbums from '@/pages/PageGenreAlbums.vue'
import PageGenreTracks from '@/pages/PageGenreTracks.vue' import PageGenreTracks from '@/pages/PageGenreTracks.vue'
import PageGenres from '@/pages/PageGenres.vue' import PageGenres from '@/pages/PageGenres.vue'
import PagePlaylistFolder from '@/pages/PagePlaylistFolder.vue' import PagePlaylistFolder from '@/pages/PagePlaylistFolder.vue'
@ -115,6 +116,12 @@ export const router = createRouter({
name: 'audiobooks-artists', name: 'audiobooks-artists',
path: '/audiobooks/artists' path: '/audiobooks/artists'
}, },
{
component: PageAudiobooksGenres,
meta: { has_index: true, has_tabs: true, show_progress: true },
name: 'audiobooks-genres',
path: '/audiobooks/genres'
},
{ {
name: 'audiobooks', name: 'audiobooks',
path: '/audiobooks', path: '/audiobooks',
@ -186,22 +193,22 @@ export const router = createRouter({
path: '/files' path: '/files'
}, },
{ {
component: PageGenreAlbum, component: PageGenreAlbums,
meta: { has_index: true, show_progress: true }, meta: { has_index: true, show_progress: true },
path: '/music/genres/:name/albums', name: 'genre-albums',
name: 'music-genre' path: '/genres/:name/albums'
}, },
{ {
component: PageGenreTracks, component: PageGenreTracks,
meta: { has_index: true, show_progress: true }, meta: { has_index: true, show_progress: true },
name: 'music-genre-tracks', name: 'genre-tracks',
path: '/music/genres/:name/tracks' path: '/genres/:name/tracks'
}, },
{ {
component: PageGenres, component: PageGenres,
meta: { has_index: true, has_tabs: true, show_progress: true }, meta: { has_index: true, has_tabs: true, show_progress: true },
path: '/music/genres', name: 'music-genres',
name: 'music-genres' path: '/music/genres'
}, },
{ {
component: PageNowPlaying, component: PageNowPlaying,

View File

@ -304,24 +304,26 @@ export default {
}) })
}, },
library_genre(genre) { library_genre(genre, media_kind = undefined) {
return axios.get(`./api/library/genres/${encodeURIComponent(genre)}`) return axios.get(`./api/library/genres/${encodeURIComponent(genre)}`, {
params: { media_kind: media_kind }
})
}, },
library_genre_albums(genre) { library_genre_albums(genre, media_kind) {
const genreParams = { const genreParams = {
type: 'albums', expression: `genre is "${genre}" and media_kind is ${media_kind}`,
expression: `genre is "${genre}" and media_kind is music` type: 'albums'
} }
return axios.get('./api/search', { return axios.get('./api/search', {
params: genreParams params: genreParams
}) })
}, },
library_genre_tracks(genre) { library_genre_tracks(genre, media_kind) {
const genreParams = { const genreParams = {
type: 'tracks', expression: `genre is "${genre}" and media_kind is ${media_kind}`,
expression: `genre is "${genre}" and media_kind is music` type: 'tracks'
} }
return axios.get('./api/search', { return axios.get('./api/search', {
params: genreParams params: genreParams