[web] Refactor the Spotify track item page

This commit is contained in:
Alain Nussbaumer 2024-03-25 14:00:42 +01:00
parent aa5ae7993a
commit 0f3f8d5a36
6 changed files with 53 additions and 124 deletions

View File

@ -14,13 +14,14 @@
v-text="item.name"
/>
<h2
class="subtitle is-7"
class="subtitle is-7 has-text-weight-bold"
:class="{
'has-text-grey': item.is_playable,
'has-text-grey-light': !item.is_playable
}"
v-text="item.artists[0].name"
/>
<h2 class="subtitle is-7 has-text-grey" v-text="item.album.name" />
<h2 v-if="!item.is_playable" class="subtitle is-7">
(<span v-text="$t('list.spotify.not-playable-track')" />
<span
@ -34,21 +35,35 @@
</h2>
</div>
<div class="media-right">
<slot name="actions" />
<a @click.prevent.stop="show_details_modal = true">
<mdicon class="icon has-text-dark" name="dots-vertical" size="16" />
</a>
</div>
</div>
<teleport to="#app">
<modal-dialog-track-spotify
:show="show_details_modal"
:track="item"
@close="show_details_modal = false"
/>
</teleport>
</template>
<script>
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
import webapi from '@/webapi'
export default {
name: 'ListItemTrackSpotify',
components: { ModalDialogTrackSpotify },
props: {
context_uri: { required: true, type: String },
item: { required: true, type: Object },
position: { required: true, type: Number }
},
data() {
return { show_details_modal: false }
},
methods: {
play() {
if (this.item.is_playable) {

View File

@ -16,7 +16,7 @@
<a
class="title is-6 has-text-link"
@click="open_album"
v-text="album.name"
v-text="track.album.name"
/>
</p>
<p>
@ -27,7 +27,7 @@
<a
class="title is-6 has-text-link"
@click="open_artist"
v-text="album.artists[0].name"
v-text="track.artists[0].name"
/>
</p>
<p>
@ -37,7 +37,7 @@
/>
<span
class="title is-6"
v-text="$filters.date(album.release_date)"
v-text="$filters.date(track.album.release_date)"
/>
</p>
<p>
@ -106,47 +106,37 @@ import webapi from '@/webapi'
export default {
name: 'ModalDialogTrackSpotify',
props: {
album: {
default() {
return {}
},
type: Object
},
show: Boolean,
track: { required: true, type: Object }
},
emits: ['close'],
methods: {
play() {
this.$emit('close')
webapi.player_play_uri(this.track.uri, false)
},
queue_add() {
this.$emit('close')
webapi.queue_add(this.track.uri)
},
queue_add_next() {
this.$emit('close')
webapi.queue_add_next(this.track.uri)
},
open_album() {
this.$emit('close')
this.$router.push({
name: 'music-spotify-album',
params: { id: this.album.id }
params: { id: this.track.album.id }
})
},
open_artist() {
this.$emit('close')
this.$router.push({
name: 'music-spotify-artist',
params: { id: this.album.artists[0].id }
params: { id: this.track.artists[0].id }
})
},
play() {
this.$emit('close')
webapi.player_play_uri(this.track.uri, false)
},
queue_add() {
this.$emit('close')
webapi.queue_add(this.track.uri)
},
queue_add_next() {
this.$emit('close')
webapi.queue_add_next(this.track.uri)
}
}
}

View File

@ -40,33 +40,17 @@
"
/>
<list-item-track-spotify
v-for="(track, index) in album.tracks.items"
v-for="(track, index) in tracks"
:key="track.id"
:item="track"
:position="index"
:context_uri="album.uri"
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(track)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
</a>
</template>
</list-item-track-spotify>
/>
<modal-dialog-album-spotify
:show="show_details_modal"
:album="album"
@close="show_details_modal = false"
/>
<modal-dialog-track-spotify
:show="show_track_details_modal"
:track="selected_track"
:album="album"
@close="show_track_details_modal = false"
/>
</template>
</content-with-hero>
</div>
@ -77,7 +61,6 @@ import ContentWithHero from '@/templates/ContentWithHero.vue'
import CoverArtwork from '@/components/CoverArtwork.vue'
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
import SpotifyWebApi from 'spotify-web-api-js'
import store from '@/store'
import webapi from '@/webapi'
@ -102,8 +85,7 @@ export default {
ContentWithHero,
CoverArtwork,
ListItemTrackSpotify,
ModalDialogAlbumSpotify,
ModalDialogTrackSpotify
ModalDialogAlbumSpotify
},
beforeRouteEnter(to, from, next) {
@ -122,12 +104,19 @@ export default {
data() {
return {
album: { artists: [{}], tracks: {} },
selected_track: {},
show_details_modal: false,
show_track_details_modal: false
show_details_modal: false
}
},
computed: {
tracks() {
const { album } = this
if (album.tracks.total) {
return album.tracks.items.map((track) => ({ ...track, album }))
}
return {}
}
},
methods: {
artwork_url(album) {
return album.images?.[0]?.url ?? ''
@ -138,10 +127,6 @@ export default {
params: { id: this.album.artists[0].id }
})
},
open_track_dialog(track) {
this.selected_track = track
this.show_track_details_modal = true
},
play() {
this.show_details_modal = false
webapi.player_play_uri(this.album.uri, true)

View File

@ -10,17 +10,7 @@
v-for="album in new_releases"
:key="album.id"
:item="album"
>
<template #actions>
<a @click.prevent.stop="open_album_dialog(album)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
</a>
</template>
</list-item-album-spotify>
/>
</template>
</content-with-heading>
</div>

View File

@ -31,17 +31,7 @@
:item="track"
:position="track.position"
:context_uri="playlist.uri"
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(track)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
</a>
</template>
</list-item-track-spotify>
/>
<VueEternalLoading v-if="offset < total" :load="load_next">
<template #loading>
<div class="columns is-centered">
@ -52,12 +42,6 @@
</template>
<template #no-more>&nbsp;</template>
</VueEternalLoading>
<modal-dialog-track-spotify
:show="show_track_details_modal"
:track="selected_track"
:album="selected_track.album"
@close="show_track_details_modal = false"
/>
<modal-dialog-playlist-spotify
:show="show_playlist_details_modal"
:playlist="playlist"
@ -72,7 +56,6 @@
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
import SpotifyWebApi from 'spotify-web-api-js'
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
import store from '@/store'
@ -109,7 +92,6 @@ export default {
ContentWithHeading,
ListItemTrackSpotify,
ModalDialogPlaylistSpotify,
ModalDialogTrackSpotify,
VueEternalLoading
},
@ -130,9 +112,7 @@ export default {
return {
offset: 0,
playlist: { tracks: {} },
selected_track: {},
show_playlist_details_modal: false,
show_track_details_modal: false,
total: 0,
tracks: []
}
@ -171,10 +151,6 @@ export default {
loaded(data.items.length, PAGE_SIZE)
})
},
open_track_dialog(track) {
this.selected_track = track
this.show_track_details_modal = true
},
play() {
this.show_details_modal = false
webapi.player_play_uri(this.playlist.uri, true)

View File

@ -46,17 +46,7 @@
:item="track"
:position="0"
:context_uri="track.uri"
>
<template #actions>
<a @click.prevent.stop="open_track_dialog(track)">
<mdicon
class="icon has-text-dark"
name="dots-vertical"
size="16"
/>
</a>
</template>
</list-item-track-spotify>
/>
<VueEternalLoading
v-if="query.type === 'track'"
:load="search_tracks_next"
@ -70,12 +60,6 @@
</template>
<template #no-more>&nbsp;</template>
</VueEternalLoading>
<modal-dialog-track-spotify
:show="show_track_details_modal"
:track="selected_track"
:album="selected_track.album"
@close="show_track_details_modal = false"
/>
</template>
<template #footer>
<nav v-if="show_all_button(tracks)" class="level">
@ -108,8 +92,7 @@
v-for="artist in artists.items"
:key="artist.id"
:item="artist"
>
</list-item-artist-spotify>
/>
<VueEternalLoading
v-if="query.type === 'artist'"
:load="search_artists_next"
@ -155,8 +138,7 @@
v-for="album in albums.items"
:key="album.id"
:item="album"
>
</list-item-album-spotify>
/>
<VueEternalLoading
v-if="query.type === 'album'"
:load="search_albums_next"
@ -202,8 +184,7 @@
v-for="playlist in playlists.items"
:key="playlist.id"
:item="playlist"
>
</list-item-playlist-spotify>
/>
<VueEternalLoading
v-if="query.type === 'playlist'"
:load="search_playlists_next"
@ -249,7 +230,6 @@ import ListItemAlbumSpotify from '@/components/ListItemAlbumSpotify.vue'
import ListItemArtistSpotify from '@/components/ListItemArtistSpotify.vue'
import ListItemPlaylistSpotify from '@/components/ListItemPlaylistSpotify.vue'
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
import SpotifyWebApi from 'spotify-web-api-js'
import TabsSearch from '@/components/TabsSearch.vue'
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
@ -266,7 +246,6 @@ export default {
ListItemArtistSpotify,
ListItemPlaylistSpotify,
ListItemTrackSpotify,
ModalDialogTrackSpotify,
TabsSearch,
VueEternalLoading
},
@ -279,8 +258,6 @@ export default {
query: {},
search_param: {},
search_query: '',
selected_track: {},
show_track_details_modal: false,
tracks: { items: [], total: 0 },
validSearchTypes: ['track', 'artist', 'album', 'playlist']
}
@ -335,10 +312,6 @@ export default {
}
})
},
open_track_dialog(track) {
this.selected_track = track
this.show_track_details_modal = true
},
reset() {
this.tracks = { items: [], total: 0 }
this.artists = { items: [], total: 0 }