mirror of
https://github.com/owntone/owntone-server.git
synced 2025-05-22 10:01:53 -04:00
[web] Refactor the Spotify track item page
This commit is contained in:
parent
aa5ae7993a
commit
0f3f8d5a36
@ -14,13 +14,14 @@
|
|||||||
v-text="item.name"
|
v-text="item.name"
|
||||||
/>
|
/>
|
||||||
<h2
|
<h2
|
||||||
class="subtitle is-7"
|
class="subtitle is-7 has-text-weight-bold"
|
||||||
:class="{
|
:class="{
|
||||||
'has-text-grey': item.is_playable,
|
'has-text-grey': item.is_playable,
|
||||||
'has-text-grey-light': !item.is_playable
|
'has-text-grey-light': !item.is_playable
|
||||||
}"
|
}"
|
||||||
v-text="item.artists[0].name"
|
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">
|
<h2 v-if="!item.is_playable" class="subtitle is-7">
|
||||||
(<span v-text="$t('list.spotify.not-playable-track')" />
|
(<span v-text="$t('list.spotify.not-playable-track')" />
|
||||||
<span
|
<span
|
||||||
@ -34,21 +35,35 @@
|
|||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="media-right">
|
<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>
|
||||||
</div>
|
</div>
|
||||||
|
<teleport to="#app">
|
||||||
|
<modal-dialog-track-spotify
|
||||||
|
:show="show_details_modal"
|
||||||
|
:track="item"
|
||||||
|
@close="show_details_modal = false"
|
||||||
|
/>
|
||||||
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ListItemTrackSpotify',
|
name: 'ListItemTrackSpotify',
|
||||||
|
components: { ModalDialogTrackSpotify },
|
||||||
props: {
|
props: {
|
||||||
context_uri: { required: true, type: String },
|
context_uri: { required: true, type: String },
|
||||||
item: { required: true, type: Object },
|
item: { required: true, type: Object },
|
||||||
position: { required: true, type: Number }
|
position: { required: true, type: Number }
|
||||||
},
|
},
|
||||||
|
data() {
|
||||||
|
return { show_details_modal: false }
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
play() {
|
play() {
|
||||||
if (this.item.is_playable) {
|
if (this.item.is_playable) {
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
<a
|
<a
|
||||||
class="title is-6 has-text-link"
|
class="title is-6 has-text-link"
|
||||||
@click="open_album"
|
@click="open_album"
|
||||||
v-text="album.name"
|
v-text="track.album.name"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@ -27,7 +27,7 @@
|
|||||||
<a
|
<a
|
||||||
class="title is-6 has-text-link"
|
class="title is-6 has-text-link"
|
||||||
@click="open_artist"
|
@click="open_artist"
|
||||||
v-text="album.artists[0].name"
|
v-text="track.artists[0].name"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="title is-6"
|
class="title is-6"
|
||||||
v-text="$filters.date(album.release_date)"
|
v-text="$filters.date(track.album.release_date)"
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@ -106,47 +106,37 @@ import webapi from '@/webapi'
|
|||||||
export default {
|
export default {
|
||||||
name: 'ModalDialogTrackSpotify',
|
name: 'ModalDialogTrackSpotify',
|
||||||
props: {
|
props: {
|
||||||
album: {
|
|
||||||
default() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
type: Object
|
|
||||||
},
|
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
track: { required: true, type: Object }
|
track: { required: true, type: Object }
|
||||||
},
|
},
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
|
|
||||||
methods: {
|
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() {
|
open_album() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'music-spotify-album',
|
name: 'music-spotify-album',
|
||||||
params: { id: this.album.id }
|
params: { id: this.track.album.id }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
open_artist() {
|
open_artist() {
|
||||||
this.$emit('close')
|
this.$emit('close')
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
name: 'music-spotify-artist',
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,33 +40,17 @@
|
|||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<list-item-track-spotify
|
<list-item-track-spotify
|
||||||
v-for="(track, index) in album.tracks.items"
|
v-for="(track, index) in tracks"
|
||||||
:key="track.id"
|
:key="track.id"
|
||||||
:item="track"
|
:item="track"
|
||||||
:position="index"
|
:position="index"
|
||||||
:context_uri="album.uri"
|
: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
|
<modal-dialog-album-spotify
|
||||||
:show="show_details_modal"
|
:show="show_details_modal"
|
||||||
:album="album"
|
:album="album"
|
||||||
@close="show_details_modal = false"
|
@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>
|
</template>
|
||||||
</content-with-hero>
|
</content-with-hero>
|
||||||
</div>
|
</div>
|
||||||
@ -77,7 +61,6 @@ import ContentWithHero from '@/templates/ContentWithHero.vue'
|
|||||||
import CoverArtwork from '@/components/CoverArtwork.vue'
|
import CoverArtwork from '@/components/CoverArtwork.vue'
|
||||||
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
||||||
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
import ModalDialogAlbumSpotify from '@/components/ModalDialogAlbumSpotify.vue'
|
||||||
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
|
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
import webapi from '@/webapi'
|
import webapi from '@/webapi'
|
||||||
@ -102,8 +85,7 @@ export default {
|
|||||||
ContentWithHero,
|
ContentWithHero,
|
||||||
CoverArtwork,
|
CoverArtwork,
|
||||||
ListItemTrackSpotify,
|
ListItemTrackSpotify,
|
||||||
ModalDialogAlbumSpotify,
|
ModalDialogAlbumSpotify
|
||||||
ModalDialogTrackSpotify
|
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeRouteEnter(to, from, next) {
|
beforeRouteEnter(to, from, next) {
|
||||||
@ -122,12 +104,19 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
album: { artists: [{}], tracks: {} },
|
album: { artists: [{}], tracks: {} },
|
||||||
selected_track: {},
|
show_details_modal: false
|
||||||
show_details_modal: false,
|
|
||||||
show_track_details_modal: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
tracks() {
|
||||||
|
const { album } = this
|
||||||
|
if (album.tracks.total) {
|
||||||
|
return album.tracks.items.map((track) => ({ ...track, album }))
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
artwork_url(album) {
|
artwork_url(album) {
|
||||||
return album.images?.[0]?.url ?? ''
|
return album.images?.[0]?.url ?? ''
|
||||||
@ -138,10 +127,6 @@ export default {
|
|||||||
params: { id: this.album.artists[0].id }
|
params: { id: this.album.artists[0].id }
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
open_track_dialog(track) {
|
|
||||||
this.selected_track = track
|
|
||||||
this.show_track_details_modal = true
|
|
||||||
},
|
|
||||||
play() {
|
play() {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
webapi.player_play_uri(this.album.uri, true)
|
webapi.player_play_uri(this.album.uri, true)
|
||||||
|
@ -10,17 +10,7 @@
|
|||||||
v-for="album in new_releases"
|
v-for="album in new_releases"
|
||||||
:key="album.id"
|
:key="album.id"
|
||||||
:item="album"
|
: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>
|
</template>
|
||||||
</content-with-heading>
|
</content-with-heading>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,17 +31,7 @@
|
|||||||
:item="track"
|
:item="track"
|
||||||
:position="track.position"
|
:position="track.position"
|
||||||
:context_uri="playlist.uri"
|
: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">
|
<VueEternalLoading v-if="offset < total" :load="load_next">
|
||||||
<template #loading>
|
<template #loading>
|
||||||
<div class="columns is-centered">
|
<div class="columns is-centered">
|
||||||
@ -52,12 +42,6 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #no-more> </template>
|
<template #no-more> </template>
|
||||||
</VueEternalLoading>
|
</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
|
<modal-dialog-playlist-spotify
|
||||||
:show="show_playlist_details_modal"
|
:show="show_playlist_details_modal"
|
||||||
:playlist="playlist"
|
:playlist="playlist"
|
||||||
@ -72,7 +56,6 @@
|
|||||||
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
import ContentWithHeading from '@/templates/ContentWithHeading.vue'
|
||||||
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
||||||
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
import ModalDialogPlaylistSpotify from '@/components/ModalDialogPlaylistSpotify.vue'
|
||||||
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
|
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
||||||
import store from '@/store'
|
import store from '@/store'
|
||||||
@ -109,7 +92,6 @@ export default {
|
|||||||
ContentWithHeading,
|
ContentWithHeading,
|
||||||
ListItemTrackSpotify,
|
ListItemTrackSpotify,
|
||||||
ModalDialogPlaylistSpotify,
|
ModalDialogPlaylistSpotify,
|
||||||
ModalDialogTrackSpotify,
|
|
||||||
VueEternalLoading
|
VueEternalLoading
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -130,9 +112,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
playlist: { tracks: {} },
|
playlist: { tracks: {} },
|
||||||
selected_track: {},
|
|
||||||
show_playlist_details_modal: false,
|
show_playlist_details_modal: false,
|
||||||
show_track_details_modal: false,
|
|
||||||
total: 0,
|
total: 0,
|
||||||
tracks: []
|
tracks: []
|
||||||
}
|
}
|
||||||
@ -171,10 +151,6 @@ export default {
|
|||||||
loaded(data.items.length, PAGE_SIZE)
|
loaded(data.items.length, PAGE_SIZE)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
open_track_dialog(track) {
|
|
||||||
this.selected_track = track
|
|
||||||
this.show_track_details_modal = true
|
|
||||||
},
|
|
||||||
play() {
|
play() {
|
||||||
this.show_details_modal = false
|
this.show_details_modal = false
|
||||||
webapi.player_play_uri(this.playlist.uri, true)
|
webapi.player_play_uri(this.playlist.uri, true)
|
||||||
|
@ -46,17 +46,7 @@
|
|||||||
:item="track"
|
:item="track"
|
||||||
:position="0"
|
:position="0"
|
||||||
:context_uri="track.uri"
|
: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
|
<VueEternalLoading
|
||||||
v-if="query.type === 'track'"
|
v-if="query.type === 'track'"
|
||||||
:load="search_tracks_next"
|
:load="search_tracks_next"
|
||||||
@ -70,12 +60,6 @@
|
|||||||
</template>
|
</template>
|
||||||
<template #no-more> </template>
|
<template #no-more> </template>
|
||||||
</VueEternalLoading>
|
</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>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<nav v-if="show_all_button(tracks)" class="level">
|
<nav v-if="show_all_button(tracks)" class="level">
|
||||||
@ -108,8 +92,7 @@
|
|||||||
v-for="artist in artists.items"
|
v-for="artist in artists.items"
|
||||||
:key="artist.id"
|
:key="artist.id"
|
||||||
:item="artist"
|
:item="artist"
|
||||||
>
|
/>
|
||||||
</list-item-artist-spotify>
|
|
||||||
<VueEternalLoading
|
<VueEternalLoading
|
||||||
v-if="query.type === 'artist'"
|
v-if="query.type === 'artist'"
|
||||||
:load="search_artists_next"
|
:load="search_artists_next"
|
||||||
@ -155,8 +138,7 @@
|
|||||||
v-for="album in albums.items"
|
v-for="album in albums.items"
|
||||||
:key="album.id"
|
:key="album.id"
|
||||||
:item="album"
|
:item="album"
|
||||||
>
|
/>
|
||||||
</list-item-album-spotify>
|
|
||||||
<VueEternalLoading
|
<VueEternalLoading
|
||||||
v-if="query.type === 'album'"
|
v-if="query.type === 'album'"
|
||||||
:load="search_albums_next"
|
:load="search_albums_next"
|
||||||
@ -202,8 +184,7 @@
|
|||||||
v-for="playlist in playlists.items"
|
v-for="playlist in playlists.items"
|
||||||
:key="playlist.id"
|
:key="playlist.id"
|
||||||
:item="playlist"
|
:item="playlist"
|
||||||
>
|
/>
|
||||||
</list-item-playlist-spotify>
|
|
||||||
<VueEternalLoading
|
<VueEternalLoading
|
||||||
v-if="query.type === 'playlist'"
|
v-if="query.type === 'playlist'"
|
||||||
:load="search_playlists_next"
|
:load="search_playlists_next"
|
||||||
@ -249,7 +230,6 @@ import ListItemAlbumSpotify from '@/components/ListItemAlbumSpotify.vue'
|
|||||||
import ListItemArtistSpotify from '@/components/ListItemArtistSpotify.vue'
|
import ListItemArtistSpotify from '@/components/ListItemArtistSpotify.vue'
|
||||||
import ListItemPlaylistSpotify from '@/components/ListItemPlaylistSpotify.vue'
|
import ListItemPlaylistSpotify from '@/components/ListItemPlaylistSpotify.vue'
|
||||||
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
import ListItemTrackSpotify from '@/components/ListItemTrackSpotify.vue'
|
||||||
import ModalDialogTrackSpotify from '@/components/ModalDialogTrackSpotify.vue'
|
|
||||||
import SpotifyWebApi from 'spotify-web-api-js'
|
import SpotifyWebApi from 'spotify-web-api-js'
|
||||||
import TabsSearch from '@/components/TabsSearch.vue'
|
import TabsSearch from '@/components/TabsSearch.vue'
|
||||||
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
import { VueEternalLoading } from '@ts-pro/vue-eternal-loading'
|
||||||
@ -266,7 +246,6 @@ export default {
|
|||||||
ListItemArtistSpotify,
|
ListItemArtistSpotify,
|
||||||
ListItemPlaylistSpotify,
|
ListItemPlaylistSpotify,
|
||||||
ListItemTrackSpotify,
|
ListItemTrackSpotify,
|
||||||
ModalDialogTrackSpotify,
|
|
||||||
TabsSearch,
|
TabsSearch,
|
||||||
VueEternalLoading
|
VueEternalLoading
|
||||||
},
|
},
|
||||||
@ -279,8 +258,6 @@ export default {
|
|||||||
query: {},
|
query: {},
|
||||||
search_param: {},
|
search_param: {},
|
||||||
search_query: '',
|
search_query: '',
|
||||||
selected_track: {},
|
|
||||||
show_track_details_modal: false,
|
|
||||||
tracks: { items: [], total: 0 },
|
tracks: { items: [], total: 0 },
|
||||||
validSearchTypes: ['track', 'artist', 'album', 'playlist']
|
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() {
|
reset() {
|
||||||
this.tracks = { items: [], total: 0 }
|
this.tracks = { items: [], total: 0 }
|
||||||
this.artists = { items: [], total: 0 }
|
this.artists = { items: [], total: 0 }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user