[web] Refactor hero template

This commit is contained in:
Alain Nussbaumer 2025-03-15 13:55:14 +01:00
parent 2e38df1c40
commit 9e2c9fddcb
6 changed files with 100 additions and 87 deletions

View File

@ -0,0 +1,27 @@
<template>
<div class="title is-5" v-text="content.title" />
<div class="subtitle is-6">
<a @click="content.handler" v-text="content.subtitle" />
</div>
<div
class="is-size-7 is-uppercase has-text-centered-mobile"
v-text="content.count"
/>
<div class="buttons is-centered-mobile mt-5">
<control-button
v-for="(action, index) in content.actions"
:key="index"
:button="action"
/>
</div>
</template>
<script>
import ControlButton from '@/components/ControlButton.vue'
export default {
name: 'HeadingHero',
components: { ControlButton },
props: { content: { required: true, type: Object } }
}
</script>

View File

@ -1,25 +1,10 @@
<template>
<div>
<content-with-hero>
<template #heading-left>
<div class="title is-5" v-text="album.name" />
<div class="subtitle is-6">
<a @click="openArtist" v-text="album.artist" />
</div>
<div
class="is-size-7 is-uppercase has-text-centered-mobile"
v-text="$t('count.tracks', { count: album.track_count })"
/>
<div class="buttons is-centered-mobile mt-5">
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
</div>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #heading-right>
<template #image>
<control-image
:url="album.artwork_url"
:artist="album.artist"
@ -42,9 +27,9 @@
<script>
import ContentWithHero from '@/templates/ContentWithHero.vue'
import ControlButton from '@/components/ControlButton.vue'
import ControlImage from '@/components/ControlImage.vue'
import { GroupedList } from '@/lib/GroupedList'
import HeadingHero from '@/components/HeadingHero.vue'
import ListTracks from '@/components/ListTracks.vue'
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
import webapi from '@/webapi'
@ -56,7 +41,6 @@ const dataObject = {
webapi.library_album_tracks(to.params.id)
])
},
set(vm, response) {
vm.album = response[0].data
vm.tracks = new GroupedList(response[1].data, {
@ -73,8 +57,8 @@ export default {
name: 'PageAlbum',
components: {
ContentWithHero,
ControlButton,
ControlImage,
HeadingHero,
ListTracks,
ModalDialogAlbum
},
@ -90,6 +74,20 @@ export default {
tracks: new GroupedList()
}
},
computed: {
heading() {
return {
count: this.$t('count.tracks', { count: this.album.track_count }),
handler: this.openArtist,
subtitle: this.album.artist,
title: this.album.name,
actions: [
{ handler: this.play, icon: 'shuffle', key: 'actions.shuffle' },
{ handler: this.openDetails, icon: 'dots-horizontal' }
]
}
}
},
methods: {
openArtist() {
this.showDetailsModal = false

View File

@ -1,25 +1,10 @@
<template>
<div>
<content-with-hero>
<template #heading-left>
<div class="title is-5" v-text="album.name" />
<div class="subtitle is-6">
<a @click="openArtist" v-text="album.artists[0].name" />
</div>
<div
class="is-size-7 is-uppercase has-text-centered-mobile"
v-text="$t('count.tracks', { count: album.tracks.total })"
/>
<div class="buttons is-centered-mobile mt-5">
<control-button
:button="{ handler: play, icon: 'shuffle', key: 'actions.shuffle' }"
/>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
</div>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #heading-right>
<template #image>
<control-image
:url="album.images?.[0]?.url ?? ''"
:artist="album.artists[0].name"
@ -42,8 +27,8 @@
<script>
import ContentWithHero from '@/templates/ContentWithHero.vue'
import ControlButton from '@/components/ControlButton.vue'
import ControlImage from '@/components/ControlImage.vue'
import HeadingHero from '@/components/HeadingHero.vue'
import ListTracksSpotify from '@/components/ListTracksSpotify.vue'
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
import SpotifyWebApi from 'spotify-web-api-js'
@ -67,8 +52,8 @@ export default {
name: 'PageAlbumSpotify',
components: {
ContentWithHero,
ControlButton,
ControlImage,
HeadingHero,
ListTracksSpotify,
ModalDialogAlbumSpotify
},
@ -87,6 +72,18 @@ export default {
}
},
computed: {
heading() {
return {
count: this.$t('count.tracks', { count: this.album.tracks.total }),
handler: this.openArtist,
subtitle: this.album.artists[0].name,
title: this.album.name,
actions: [
{ handler: this.play, icon: 'shuffle', key: 'actions.shuffle' },
{ handler: this.openDetails, icon: 'dots-horizontal' }
]
}
},
tracks() {
const { album } = this
if (album.tracks.total) {

View File

@ -1,29 +1,10 @@
<template>
<div>
<content-with-hero>
<template #heading-left>
<div class="title is-5" v-text="album.name" />
<div class="subtitle is-6">
<a @click="openArtist" v-text="album.artist" />
</div>
<div
class="is-size-7 is-uppercase has-text-centered-mobile"
v-text="$t('count.tracks', { count: album.track_count })"
/>
<div class="buttons is-centered-mobile mt-5">
<control-button
:button="{
handler: play,
icon: 'play',
key: 'actions.play'
}"
/>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
</div>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #heading-right>
<template #image>
<control-image
:url="album.artwork_url"
:artist="album.artist"
@ -47,9 +28,9 @@
<script>
import ContentWithHero from '@/templates/ContentWithHero.vue'
import ControlButton from '@/components/ControlButton.vue'
import ControlImage from '@/components/ControlImage.vue'
import { GroupedList } from '@/lib/GroupedList'
import HeadingHero from '@/components/HeadingHero.vue'
import ListTracks from '@/components/ListTracks.vue'
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
import webapi from '@/webapi'
@ -71,8 +52,8 @@ export default {
name: 'PageAudiobooksAlbum',
components: {
ContentWithHero,
ControlButton,
ControlImage,
HeadingHero,
ListTracks,
ModalDialogAlbum
},
@ -88,6 +69,20 @@ export default {
tracks: new GroupedList()
}
},
computed: {
heading() {
return {
count: this.$t('count.tracks', { count: this.album.track_count }),
handler: this.openArtist,
subtitle: this.album.artist,
title: this.album.name,
actions: [
{ handler: this.play, icon: 'play', key: 'actions.play' },
{ handler: this.openDetails, icon: 'dots-horizontal' }
]
}
}
},
methods: {
openArtist() {
this.showDetailsModal = false

View File

@ -1,25 +1,10 @@
<template>
<div>
<content-with-hero>
<template #heading-left>
<div class="title is-5" v-text="album.name" />
<div class="subtitle is-6">
<br />
</div>
<div
class="is-size-7 is-uppercase has-text-centered-mobile"
v-text="$t('count.tracks', { count: album.track_count })"
/>
<div class="buttons is-centered-mobile mt-5">
<control-button
:button="{ handler: play, icon: 'play', key: 'actions.play' }"
/>
<control-button
:button="{ handler: openDetails, icon: 'dots-horizontal' }"
/>
</div>
<template #heading>
<heading-hero :content="heading" />
</template>
<template #heading-right>
<template #image>
<control-image
:url="album.artwork_url"
:artist="album.artist"
@ -67,9 +52,9 @@
<script>
import ContentWithHero from '@/templates/ContentWithHero.vue'
import ControlButton from '@/components/ControlButton.vue'
import ControlImage from '@/components/ControlImage.vue'
import { GroupedList } from '@/lib/GroupedList'
import HeadingHero from '@/components/HeadingHero.vue'
import ListTracks from '@/components/ListTracks.vue'
import ModalDialog from '@/components/ModalDialog.vue'
import ModalDialogAlbum from '@/components/ModalDialogAlbum.vue'
@ -92,8 +77,8 @@ export default {
name: 'PagePodcast',
components: {
ContentWithHero,
ControlButton,
ControlImage,
HeadingHero,
ListTracks,
ModalDialog,
ModalDialogAlbum
@ -126,6 +111,17 @@ export default {
key: this.$t('page.podcast.remove')
}
]
},
heading() {
return {
count: this.$t('count.tracks', { count: this.album.track_count }),
subtitle: '',
title: this.album.name,
actions: [
{ handler: this.play, icon: 'play', key: 'actions.play' },
{ handler: this.openDetails, icon: 'dots-horizontal' }
]
}
}
},
methods: {

View File

@ -5,10 +5,10 @@
<div class="column is-four-fifths">
<div class="columns is-flex-direction-row-reverse">
<div class="column is-flex has-image">
<slot name="heading-right" />
<slot name="image" />
</div>
<div class="column m-auto is-three-fifths has-text-centered-mobile">
<slot name="heading-left" />
<slot name="heading" />
</div>
</div>
</div>