Make playing tracks in their playlist the default
This commit is contained in:
parent
5d745fea6f
commit
f1f9f935cf
|
@ -0,0 +1 @@
|
|||
Make "play in list" the default when interacting with individual tracks (#1274)
|
|
@ -1,14 +1,12 @@
|
|||
<template>
|
||||
<div class="album-entries">
|
||||
<div :class="[{active: currentTrack && isPlaying && track.id === currentTrack.id}, 'album-entry']" v-for="track in tracks" :key="track.id">
|
||||
<div :class="[{active: currentTrack && isPlaying && track.id === currentTrack.id}, 'album-entry']" @click.prevent="replacePlay(tracks, index)" v-for="(track, index) in tracks" :key="track.id">
|
||||
<div class="actions">
|
||||
<play-button class="basic circular icon" :button-classes="['circular inverted vibrant icon button']" :discrete="true" :icon-only="true" :track="track"></play-button>
|
||||
<play-button class="basic circular icon" :button-classes="['circular inverted vibrant icon button']" :discrete="true" :icon-only="true" :track="track" :tracks="tracks"></play-button>
|
||||
</div>
|
||||
<div class="position">{{ prettyPosition(track.position) }}</div>
|
||||
<div class="content ellipsis">
|
||||
<router-link :to="{name: 'library.tracks.detail', params: {id: track.id}}" class="discrete link">
|
||||
<strong>{{ track.title }}</strong><br>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="meta">
|
||||
<template v-if="$store.state.auth.authenticated && $store.getters['favorites/isFavorite'](track.id)">
|
||||
|
@ -54,7 +52,13 @@ export default {
|
|||
var s = String(position);
|
||||
while (s.length < (size || 2)) {s = "0" + s;}
|
||||
return s;
|
||||
}
|
||||
},
|
||||
replacePlay (tracks, trackIndex) {
|
||||
this.$store.dispatch('queue/clean')
|
||||
this.$store.dispatch('queue/appendMany', {tracks: tracks}).then(() => {
|
||||
this.$store.dispatch('queue/currentIndex', trackIndex)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</button>
|
||||
<button
|
||||
v-if="!discrete && !iconOnly"
|
||||
@click.prevent="clicked = true"
|
||||
@click.stop.prevent="clicked = true"
|
||||
:class="['ui', {disabled: !playable && !filterableArtist}, 'floating', 'dropdown', {'icon': !dropdownOnly}, {'button': !dropdownOnly}]">
|
||||
<i :class="dropdownIconClasses.concat(['icon'])" :title="title" ></i>
|
||||
<div class="menu" v-if="clicked">
|
||||
|
@ -27,6 +27,9 @@
|
|||
<button v-if="track" class="item basic" :disabled="!playable" @click.stop.prevent="$store.dispatch('radios/start', {type: 'similar', objectId: track.id})" :title="labels.startRadio">
|
||||
<i class="feed icon"></i><translate translate-context="*/Queue/Button.Label/Short, Verb">Play radio</translate>
|
||||
</button>
|
||||
<button v-if="track" class="item basic" @click.stop.prevent="$router.push(`/library/tracks/${track.id}/`)">
|
||||
<i class="info icon"></i><translate translate-context="*/Queue/Dropdown/Button/Label/Short">Track details</translate>
|
||||
</button>
|
||||
<div class="divider"></div>
|
||||
<button v-if="filterableArtist" ref="filterArtist" data-ref="filterArtist" class="item basic" :disabled="!filterableArtist" @click.stop.prevent="filterArtist" :title="labels.hideArtist">
|
||||
<i class="eye slash outline icon"></i><translate translate-context="*/Queue/Dropdown/Button/Label/Short">Hide content from this artist</translate>
|
||||
|
@ -143,7 +146,6 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
filterArtist () {
|
||||
this.$store.dispatch('moderation/hide', {type: 'artist', target: this.filterableArtist})
|
||||
},
|
||||
|
@ -175,7 +177,9 @@ export default {
|
|||
let self = this
|
||||
this.isLoading = true
|
||||
let getTracks = new Promise((resolve, reject) => {
|
||||
if (self.track) {
|
||||
if (self.tracks) {
|
||||
resolve(self.tracks)
|
||||
} else if (self.track) {
|
||||
if (!self.track.uploads || self.track.uploads.length === 0) {
|
||||
// fetch uploads from api
|
||||
axios.get(`tracks/${self.track.id}/`).then((response) => {
|
||||
|
@ -184,8 +188,6 @@ export default {
|
|||
} else {
|
||||
resolve([self.track])
|
||||
}
|
||||
} else if (self.tracks) {
|
||||
resolve(self.tracks)
|
||||
} else if (self.playlist) {
|
||||
let url = 'playlists/' + self.playlist.id + '/'
|
||||
axios.get(url + 'tracks/').then((response) => {
|
||||
|
@ -236,7 +238,14 @@ export default {
|
|||
let self = this
|
||||
self.$store.dispatch('queue/clean')
|
||||
this.getPlayableTracks().then((tracks) => {
|
||||
self.$store.dispatch('queue/appendMany', {tracks: tracks}).then(() => self.addMessage(tracks))
|
||||
self.$store.dispatch('queue/appendMany', {tracks: tracks}).then(() => {
|
||||
if (self.track) {
|
||||
// set queue position to selected track
|
||||
const trackIndex = self.tracks.findIndex(track => track.id === self.track.id)
|
||||
self.$store.dispatch('queue/currentIndex', trackIndex)
|
||||
}
|
||||
self.addMessage(tracks)
|
||||
})
|
||||
})
|
||||
jQuery(self.$el).find('.ui.dropdown').dropdown('hide')
|
||||
},
|
||||
|
|
|
@ -1,19 +1,24 @@
|
|||
<template>
|
||||
<tr>
|
||||
<td>
|
||||
<play-button :class="['basic', {vibrant: currentTrack && isPlaying && track.id === currentTrack.id}, 'icon']" :discrete="true" :is-playable="playable" :track="track"></play-button>
|
||||
<play-button :class="['basic', {vibrant: currentTrack && isPlaying && track.id === currentTrack.id}, 'icon']"
|
||||
:discrete="true"
|
||||
:is-playable="playable"
|
||||
:track="track"
|
||||
:track-index="trackIndex"
|
||||
:tracks="tracks"></play-button>
|
||||
</td>
|
||||
<td>
|
||||
<img alt="" class="ui mini image" v-if="track.album && track.album.cover && track.album.cover.urls.original" v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.urls.medium_square_crop)">
|
||||
<img alt="" class="ui mini image" v-else src="../../../assets/audio/default-cover.png">
|
||||
</td>
|
||||
<td colspan="6">
|
||||
<router-link class="track" :to="{name: 'library.tracks.detail', params: {id: track.id }}">
|
||||
<button class="track" @click.stop="playSong()">
|
||||
<template v-if="displayPosition && track.position">
|
||||
{{ track.position }}.
|
||||
</template>
|
||||
{{ track.title|truncate(40) }}
|
||||
</router-link>
|
||||
</button>
|
||||
</td>
|
||||
<td colspan="4">
|
||||
<router-link class="artist discrete link" :to="{name: 'library.artists.detail', params: {id: track.artist.id }}">
|
||||
|
@ -56,6 +61,8 @@ import PlayButton from '@/components/audio/PlayButton'
|
|||
export default {
|
||||
props: {
|
||||
track: {type: Object, required: true},
|
||||
trackIndex: {type: Number, required: true},
|
||||
tracks: {type: Array, required: false},
|
||||
artist: {type: Object, required: false},
|
||||
displayPosition: {type: Boolean, default: false},
|
||||
displayActions: {type: Boolean, default: true},
|
||||
|
@ -80,6 +87,16 @@ export default {
|
|||
return this.track.album.artist
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
playSong () {
|
||||
this.$store.dispatch('queue/clean')
|
||||
this.$store.dispatch('queue/appendMany', {
|
||||
tracks: this.tracks
|
||||
}).then(() => {
|
||||
this.$store.dispatch('queue/currentIndex', this.trackIndex)
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
:display-position="displayPosition"
|
||||
:display-actions="displayActions"
|
||||
:track="track"
|
||||
:track-index="index"
|
||||
:tracks="allTracks"
|
||||
:artist="artist"
|
||||
:key="index + '-' + track.id"
|
||||
v-for="(track, index) in allTracks"></track-row>
|
||||
|
|
|
@ -11,4 +11,9 @@
|
|||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.track {
|
||||
display: block;
|
||||
line-height: 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,6 +75,18 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.album-entry:hover {
|
||||
cursor: pointer;
|
||||
|
||||
// explicitly style the button as if it was hovered itself
|
||||
.ui.inverted.vibrant.button {
|
||||
background-color: var(--vibrant-hover-color);
|
||||
color: white;
|
||||
box-shadow: 0 0 0 2px var(--vibrant-color) inset;
|
||||
}
|
||||
}
|
||||
|
||||
.album-entry, .channel-entry-card {
|
||||
border-radius: 5px;
|
||||
padding: 0.5em;
|
||||
|
|
Loading…
Reference in New Issue