Verified Commit f1f9f935 authored by heyarne's avatar heyarne Committed by Georg Krause
Browse files

Make playing tracks in their playlist the default

parent 5d745fea
Make "play in list" the default when interacting with individual tracks (#1274)
<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')
},
......
<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;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment