Merge branch 'cherry-pick-develop' into 'master'
Cherry pick develop See merge request funkwhale/funkwhale!802
This commit is contained in:
commit
c95c573a35
|
@ -226,7 +226,7 @@ class Command(BaseCommand):
|
||||||
urllib.parse.urlencode([("import", reference)]),
|
urllib.parse.urlencode([("import", reference)]),
|
||||||
)
|
)
|
||||||
self.stdout.write(
|
self.stdout.write(
|
||||||
"For details, please refer to import refrence '{}' or URL {}".format(
|
"For details, please refer to import reference '{}' or URL {}".format(
|
||||||
reference, import_url
|
reference, import_url
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -246,7 +246,7 @@ class Command(BaseCommand):
|
||||||
self.stderr.write("- {}: {}".format(path, error))
|
self.stderr.write("- {}: {}".format(path, error))
|
||||||
|
|
||||||
self.stdout.write(
|
self.stdout.write(
|
||||||
"For details, please refer to import refrence '{}' or URL {}".format(
|
"For details, please refer to import reference '{}' or URL {}".format(
|
||||||
reference, import_url
|
reference, import_url
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Added button to search for objects on Discogs (#368)
|
|
@ -0,0 +1 @@
|
||||||
|
Favorites radio will not be visible if the user does not have any favorites (#419)
|
|
@ -0,0 +1 @@
|
||||||
|
Aligned search headers with search results in the sidebar (#708)
|
|
@ -0,0 +1 @@
|
||||||
|
Clicking on the currently selected playlist in the Playlist popup will now close the popup (#807)
|
|
@ -0,0 +1 @@
|
||||||
|
The currently playing track is now highlighted with an orange play icon (#832)
|
|
@ -0,0 +1 @@
|
||||||
|
Redirect from / to /library when user is logged in (#864)
|
|
@ -147,7 +147,19 @@ export default {
|
||||||
let msg = this.$pgettext('Content/Home/List item/Verb', 'Get quality metadata about your music thanks to <a href="%{ url }" target="_blank">MusicBrainz</a>')
|
let msg = this.$pgettext('Content/Home/List item/Verb', 'Get quality metadata about your music thanks to <a href="%{ url }" target="_blank">MusicBrainz</a>')
|
||||||
return this.$gettextInterpolate(msg, {url: this.musicbrainzUrl})
|
return this.$gettextInterpolate(msg, {url: this.musicbrainzUrl})
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'$store.state.auth.authenticated': {
|
||||||
|
handler (v) {
|
||||||
|
if (v) {
|
||||||
|
console.log('Authenticated, redirecting to /library…')
|
||||||
|
this.$router.push('/library')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -466,6 +466,12 @@ $sidebar-color: #3d3e3f;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.ui.search .results {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.ui.search .name {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.ui.tiny.avatar.image {
|
.ui.tiny.avatar.image {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="track in tracks">
|
<tr v-for="track in tracks">
|
||||||
<td class="play-cell">
|
<td class="play-cell">
|
||||||
<play-button class="basic icon" :track="track" :discrete="true"></play-button>
|
<play-button :class="['basic', {orange: isPlaying && track.id === currentTrack.id}, 'icon']" :discrete="true" :track="track"></play-button>
|
||||||
</td>
|
</td>
|
||||||
<td class="content-cell" colspan="5">
|
<td class="content-cell" colspan="5">
|
||||||
<track-favorite-icon :track="track"></track-favorite-icon>
|
<track-favorite-icon :track="track"></track-favorite-icon>
|
||||||
|
@ -57,6 +57,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters } from "vuex"
|
||||||
import backend from '@/audio/backend'
|
import backend from '@/audio/backend'
|
||||||
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
||||||
import PlayButton from '@/components/audio/PlayButton'
|
import PlayButton from '@/components/audio/PlayButton'
|
||||||
|
@ -64,7 +65,7 @@ import PlayButton from '@/components/audio/PlayButton'
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
album: {type: Object},
|
album: {type: Object},
|
||||||
mode: {type: String, default: 'rich'}
|
mode: {type: String, default: 'rich'},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
TrackFavoriteIcon,
|
TrackFavoriteIcon,
|
||||||
|
@ -84,6 +85,12 @@ export default {
|
||||||
}
|
}
|
||||||
return this.album.tracks.slice(0, this.initialTracks)
|
return this.album.tracks.slice(0, this.initialTracks)
|
||||||
},
|
},
|
||||||
|
...mapGetters({
|
||||||
|
currentTrack: "queue/currentTrack",
|
||||||
|
}),
|
||||||
|
isPlaying () {
|
||||||
|
return this.$store.state.player.playing
|
||||||
|
},
|
||||||
tracksWithAlbum () {
|
tracksWithAlbum () {
|
||||||
// needed to include album data (especially cover)
|
// needed to include album data (especially cover)
|
||||||
// with tracks appended in queue (#795)
|
// with tracks appended in queue (#795)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<play-button class="basic icon" :discrete="true" :is-playable="playable" :track="track"></play-button>
|
<play-button :class="['basic', {orange: isPlaying && track.id === currentTrack.id}, 'icon']" :discrete="true" :is-playable="playable" :track="track"></play-button>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<img class="ui mini image" v-if="track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
|
<img class="ui mini image" v-if="track.album.cover.original" v-lazy="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { mapGetters } from "vuex"
|
||||||
import time from '@/utils/time'
|
import time from '@/utils/time'
|
||||||
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
import TrackFavoriteIcon from '@/components/favorites/TrackFavoriteIcon'
|
||||||
import TrackPlaylistIcon from '@/components/playlists/TrackPlaylistIcon'
|
import TrackPlaylistIcon from '@/components/playlists/TrackPlaylistIcon'
|
||||||
|
@ -74,13 +74,19 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
...mapGetters({
|
||||||
|
currentTrack: "queue/currentTrack",
|
||||||
|
}),
|
||||||
|
isPlaying () {
|
||||||
|
return this.$store.state.player.playing
|
||||||
|
},
|
||||||
albumArtist () {
|
albumArtist () {
|
||||||
if (this.artist) {
|
if (this.artist) {
|
||||||
return this.artist
|
return this.artist
|
||||||
} else {
|
} else {
|
||||||
return this.track.album.artist
|
return this.track.album.artist
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
1 favorite
|
1 favorite
|
||||||
</translate>
|
</translate>
|
||||||
</h2>
|
</h2>
|
||||||
<radio-button type="favorites"></radio-button>
|
<radio-button v-if="hasFavorites" type="favorites"></radio-button>
|
||||||
</section>
|
</section>
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
<div :class="['ui', {'loading': isLoading}, 'form']">
|
<div :class="['ui', {'loading': isLoading}, 'form']">
|
||||||
|
@ -115,7 +115,10 @@ export default {
|
||||||
return {
|
return {
|
||||||
title: this.$pgettext('Head/Favorites/Title', 'Your Favorites')
|
title: this.$pgettext('Head/Favorites/Title', 'Your Favorites')
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
hasFavorites () {
|
||||||
|
return this.$store.state.favorites.count > 0
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateQueryString: function() {
|
updateQueryString: function() {
|
||||||
|
|
|
@ -61,7 +61,11 @@
|
||||||
<i class="external icon"></i>
|
<i class="external icon"></i>
|
||||||
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
||||||
</a>
|
</a>
|
||||||
<router-link
|
<a :href="discogsUrl" target="_blank" rel="noreferrer noopener" class="basic item">
|
||||||
|
<i class="external icon"></i>
|
||||||
|
<translate translate-context="Content/*/Button.Label/Verb">Search on Discogs</translate>
|
||||||
|
</a>
|
||||||
|
<router-link
|
||||||
v-if="object.is_local"
|
v-if="object.is_local"
|
||||||
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
:to="{name: 'library.albums.edit', params: {id: object.id }}"
|
||||||
class="basic item">
|
class="basic item">
|
||||||
|
@ -168,6 +172,13 @@ export default {
|
||||||
return "https://musicbrainz.org/release/" + this.object.mbid
|
return "https://musicbrainz.org/release/" + this.object.mbid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
discogsUrl() {
|
||||||
|
return (
|
||||||
|
"https://discogs.com/search/?type=release&title=" +
|
||||||
|
encodeURI(this.object.title) + "&artist=" +
|
||||||
|
encodeURI(this.object.artist.name)
|
||||||
|
)
|
||||||
|
},
|
||||||
headerStyle() {
|
headerStyle() {
|
||||||
if (!this.object.cover.original) {
|
if (!this.object.cover.original) {
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -72,6 +72,10 @@
|
||||||
<i class="external icon"></i>
|
<i class="external icon"></i>
|
||||||
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
||||||
</a>
|
</a>
|
||||||
|
<a :href="discogsUrl" target="_blank" rel="noreferrer noopener" class="basic item">
|
||||||
|
<i class="external icon"></i>
|
||||||
|
<translate translate-context="Content/*/Button.Label/Verb">Search on Discogs</translate>
|
||||||
|
</a>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="object.is_local"
|
v-if="object.is_local"
|
||||||
:to="{name: 'library.artists.edit', params: {id: object.id }}"
|
:to="{name: 'library.artists.edit', params: {id: object.id }}"
|
||||||
|
@ -205,6 +209,12 @@ export default {
|
||||||
return "https://musicbrainz.org/artist/" + this.object.mbid
|
return "https://musicbrainz.org/artist/" + this.object.mbid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
discogsUrl() {
|
||||||
|
return (
|
||||||
|
"https://discogs.com/search/?type=artist&title=" +
|
||||||
|
encodeURI(this.object.name)
|
||||||
|
)
|
||||||
|
},
|
||||||
cover() {
|
cover() {
|
||||||
return this.object.albums
|
return this.object.albums
|
||||||
.filter(album => {
|
.filter(album => {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<translate translate-context="Content/Radio/Title">Instance radios</translate>
|
<translate translate-context="Content/Radio/Title">Instance radios</translate>
|
||||||
</h3>
|
</h3>
|
||||||
<div class="ui cards">
|
<div class="ui cards">
|
||||||
<radio-card v-if="$store.state.auth.authenticated" :type="'favorites'"></radio-card>
|
<radio-card v-if="isAuthenticated && hasFavorites" :type="'favorites'"></radio-card>
|
||||||
<radio-card :type="'random'"></radio-card>
|
<radio-card :type="'random'"></radio-card>
|
||||||
<radio-card v-if="$store.state.auth.authenticated" :type="'less-listened'"></radio-card>
|
<radio-card v-if="$store.state.auth.authenticated" :type="'less-listened'"></radio-card>
|
||||||
</div>
|
</div>
|
||||||
|
@ -144,7 +144,13 @@ export default {
|
||||||
searchPlaceholder,
|
searchPlaceholder,
|
||||||
title
|
title
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
isAuthenticated () {
|
||||||
|
return this.$store.state.auth.authenticated
|
||||||
|
},
|
||||||
|
hasFavorites () {
|
||||||
|
return this.$store.state.favorites.count > 0
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
updateQueryString: _.debounce(function() {
|
updateQueryString: _.debounce(function() {
|
||||||
|
|
|
@ -76,6 +76,10 @@
|
||||||
<i class="external icon"></i>
|
<i class="external icon"></i>
|
||||||
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
<translate translate-context="Content/*/*/Clickable, Verb">View on MusicBrainz</translate>
|
||||||
</a>
|
</a>
|
||||||
|
<a :href="discogsUrl" target="_blank" rel="noreferrer noopener" class="basic item">
|
||||||
|
<i class="external icon"></i>
|
||||||
|
<translate translate-context="Content/*/Button.Label/Verb">Search on Discogs</translate>
|
||||||
|
</a>
|
||||||
<router-link
|
<router-link
|
||||||
v-if="track.is_local"
|
v-if="track.is_local"
|
||||||
:to="{name: 'library.tracks.edit', params: {id: track.id }}"
|
:to="{name: 'library.tracks.edit', params: {id: track.id }}"
|
||||||
|
@ -180,6 +184,14 @@ export default {
|
||||||
return "https://musicbrainz.org/recording/" + this.track.mbid
|
return "https://musicbrainz.org/recording/" + this.track.mbid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
discogsUrl() {
|
||||||
|
return (
|
||||||
|
"https://discogs.com/search/?type=release&title=" +
|
||||||
|
encodeURI(this.track.album.title) + "&artist=" +
|
||||||
|
encodeURI(this.track.artist.name) + "&track=" +
|
||||||
|
encodeURI(this.track.title)
|
||||||
|
)
|
||||||
|
},
|
||||||
downloadUrl() {
|
downloadUrl() {
|
||||||
let u = this.$store.getters["instance/absoluteUrl"](
|
let u = this.$store.getters["instance/absoluteUrl"](
|
||||||
this.upload.listen_url
|
this.upload.listen_url
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
:to="{name: 'library.playlists.detail', params: {id: playlist.id }, query: {mode: 'edit'}}"><i class="ui pencil icon"></i></router-link>
|
:to="{name: 'library.playlists.detail', params: {id: playlist.id }, query: {mode: 'edit'}}"><i class="ui pencil icon"></i></router-link>
|
||||||
</td>
|
</td>
|
||||||
<td :title="playlist.name">
|
<td :title="playlist.name">
|
||||||
<router-link :to="{name: 'library.playlists.detail', params: {id: playlist.id }}">{{ playlist.name }}</router-link></td>
|
<router-link v-on:click.native="update(false)" :to="{name: 'library.playlists.detail', params: {id: playlist.id }}">{{ playlist.name }}</router-link></td>
|
||||||
<td><human-date :date="playlist.modification_date"></human-date></td>
|
<td><human-date :date="playlist.modification_date"></human-date></td>
|
||||||
<td>{{ playlist.tracks_count }}</td>
|
<td>{{ playlist.tracks_count }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
Loading…
Reference in New Issue