Commit 6ceb8826 authored by Agate's avatar Agate 💬

Merge branch 'develop' of dev.funkwhale.audio:funkwhale/funkwhale into develop

parents 12951446 90f3c67b
More consistent search UX on /albums, /artists, /radios and /playlists (#1131)
\ No newline at end of file
Confirm email without requiring the user to validate the form manually (#407)
\ No newline at end of file
......@@ -89,7 +89,6 @@
<tr
:id="'queue-item-' + index"
role="button"
tabindex="0"
v-if="track.sources.length > 0"
:key="index"
:class="[{active: index === currentIndex}]"
......
......@@ -107,10 +107,12 @@ export default {
return this.track.uploads && this.track.uploads.length > 0
} else if (this.artist && this.artist.tracks_count) {
return this.artist.tracks_count > 0
} else if (this.artist && this.artist.albums) {
} else if (this.artist && this.artist.albums) {
return this.artist.albums.filter((a) => {
return a.is_playable === true
}).length > 0
} else if (this.album) {
return this.album.is_playable
} else if (this.tracks) {
return this.tracks.filter((t) => {
return t.uploads && t.uploads.length > 0
......@@ -229,6 +231,7 @@ export default {
jQuery(self.$el).find('.ui.dropdown').dropdown('hide')
},
addNext (next) {
console.log('CLICKED')
let self = this
let wasEmpty = this.$store.state.queue.tracks.length === 0
this.getPlayableTracks().then((tracks) => {
......@@ -253,7 +256,6 @@ export default {
},
watch: {
clicked () {
let self = this
this.$nextTick(() => {
jQuery(this.$el).find('.ui.dropdown').dropdown({
......
......@@ -40,7 +40,7 @@
<translate translate-context="*/Login/*/Verb">Reset your password</translate>
</router-link>
</label>
<password-input :index="2" required v-model="credentials.password" />
<password-input required v-model="credentials.password" />
</div>
</template>
......
......@@ -3,7 +3,6 @@
<input
required
name="password"
:tabindex="index"
:type="passwordInputType"
@input="$emit('input', $event.target.value)"
:value="value">
......@@ -30,7 +29,7 @@ function copyStringToClipboard (str) {
}
export default {
props: ['value', 'index', 'defaultShow', 'copyButton'],
props: ['value', 'defaultShow', 'copyButton'],
data () {
return {
showPassword: this.defaultShow || false,
......
......@@ -169,13 +169,16 @@ export default {
methods: {
async fetchData() {
this.isLoading = true
let tracksResponse = axios.get(`tracks/`, {params: {ordering: 'disc_number,position', album: this.id, page_size: 100}})
let albumResponse = await axios.get(`albums/${this.id}/`, {params: {refresh: 'true'}})
let artistResponse = await axios.get(`artists/${albumResponse.data.artist.id}/`)
this.artist = artistResponse.data
if (this.artist.channel) {
this.artist.channel.artist = this.artist
}
this.object = backend.Album.clean(albumResponse.data)
tracksResponse = await tracksResponse
this.object = albumResponse.data
this.object.tracks = tracksResponse.data.results
this.discs = this.object.tracks.reduce(groupByDisc, [])
this.isLoading = false
......
......@@ -4,13 +4,18 @@
<h2 class="ui header">
<translate translate-context="Content/Album/Title">Browsing albums</translate>
</h2>
<div :class="['ui', {'loading': isLoading}, 'form']">
<form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields">
<div class="field">
<label>
<translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
</label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div>
<div class="field">
<label><translate translate-context="*/*/*/Noun">Tags</translate></label>
......@@ -40,7 +45,7 @@
</select>
</div>
</div>
</div>
</form>
<div class="ui hidden divider"></div>
<div
v-if="result"
......@@ -144,7 +149,7 @@ export default {
}
},
methods: {
updateQueryString: _.debounce(function() {
updateQueryString: function() {
history.pushState(
{},
null,
......@@ -157,8 +162,8 @@ export default {
ordering: this.getOrderingAsString()
}).toString()
)
}, 500),
fetchData: _.debounce(function() {
},
fetchData: function() {
var self = this
this.isLoading = true
let url = FETCH_URL
......@@ -187,7 +192,7 @@ export default {
self.result = null
self.isLoading = false
})
}, 500),
},
selectPage: function(page) {
this.page = page
}
......@@ -197,26 +202,6 @@ export default {
this.updateQueryString()
this.fetchData()
},
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
},
tags() {
this.updateQueryString()
this.fetchData()
},
"$store.state.moderation.lastUpdate": function () {
this.fetchData()
}
......
......@@ -195,9 +195,7 @@ export default {
self.nextAlbumsUrl = response.data.next
self.totalAlbums = response.data.count
let parsed = JSON.parse(JSON.stringify(response.data.results))
self.albums = parsed.map(album => {
return backend.Album.clean(album)
})
self.albums = parsed
})
await trackPromise
......
......@@ -4,13 +4,18 @@
<h2 class="ui header">
<translate translate-context="Content/Artist/Title">Browsing artists</translate>
</h2>
<div :class="['ui', {'loading': isLoading}, 'form']">
<form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields">
<div class="field">
<label>
<translate translate-context="Content/Search/Input.Label/Noun">Search</translate>
</label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div>
<div class="field">
<label><translate translate-context="*/*/*/Noun">Tags</translate></label>
......@@ -40,7 +45,7 @@
</select>
</div>
</div>
</div>
</form>
<div class="ui hidden divider"></div>
<div v-if="result && result.results.length > 0" class="ui five app-cards cards">
<div v-if="isLoading" class="ui inverted active dimmer">
......@@ -134,7 +139,7 @@ export default {
}
},
methods: {
updateQueryString: _.debounce(function() {
updateQueryString: function() {
history.pushState(
{},
null,
......@@ -147,8 +152,8 @@ export default {
ordering: this.getOrderingAsString()
}).toString()
)
}, 500),
fetchData: _.debounce(function() {
},
fetchData: function() {
var self = this
this.isLoading = true
let url = FETCH_URL
......@@ -178,7 +183,7 @@ export default {
self.result = null
self.isLoading = false
})
}, 500),
},
selectPage: function(page) {
this.page = page
}
......@@ -188,26 +193,6 @@ export default {
this.updateQueryString()
this.fetchData()
},
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
},
tags() {
this.updateQueryString()
this.fetchData()
},
"$store.state.moderation.lastUpdate": function () {
this.fetchData()
}
......
......@@ -25,11 +25,16 @@
<translate translate-context="Content/Radio/Button.Label/Verb">Create your own radio</translate>
</router-link>
<div class="ui hidden divider"></div>
<div :class="['ui', {'loading': isLoading}, 'form']">
<form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields">
<div class="field">
<label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
<input name="search" type="text" v-model="query" :placeholder="labels.searchPlaceholder"/>
<div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div>
<div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
......@@ -59,7 +64,7 @@
</select>
</div>
</div>
</div>
</form>
<div class="ui hidden divider"></div>
<div v-if="result && !result.results.length > 0" class="ui placeholder segment">
<div class="ui icon header">
......@@ -157,7 +162,7 @@ export default {
},
},
methods: {
updateQueryString: _.debounce(function() {
updateQueryString: function() {
history.pushState(
{},
null,
......@@ -169,8 +174,8 @@ export default {
ordering: this.getOrderingAsString()
}).toString()
)
}, 500),
fetchData: _.debounce(function() {
},
fetchData: function() {
var self = this
this.isLoading = true
let url = FETCH_URL
......@@ -186,7 +191,7 @@ export default {
self.result = response.data
self.isLoading = false
})
}, 500),
},
selectPage: function(page) {
this.page = page
}
......@@ -196,22 +201,6 @@ export default {
this.updateQueryString()
this.fetchData()
},
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
}
}
}
</script>
......@@ -52,6 +52,11 @@ export default {
}
}
},
mounted () {
if (this.key) {
this.submit()
}
},
methods: {
submit() {
let self = this
......
......@@ -2,17 +2,22 @@
<main v-title="labels.playlists">
<section class="ui vertical stripe segment">
<h2 class="ui header"><translate translate-context="Content/Playlist/Title">Browsing playlists</translate></h2>
<div :class="['ui', {'loading': isLoading}, 'form']">
<template v-if="$store.state.auth.authenticated">
<button
@click="$store.commit('playlists/chooseTrack', null)"
class="ui basic success button"><translate translate-context="Content/Playlist/Button.Label/Verb">Manage your playlists</translate></button>
<div class="ui hidden divider"></div>
</template>
<template v-if="$store.state.auth.authenticated">
<button
@click="$store.commit('playlists/chooseTrack', null)"
class="ui basic success button"><translate translate-context="Content/Playlist/Button.Label/Verb">Manage your playlists</translate></button>
<div class="ui hidden divider"></div>
</template>
<form :class="['ui', {'loading': isLoading}, 'form']" @submit.prevent="updateQueryString();fetchData()">
<div class="fields">
<div class="field">
<label><translate translate-context="Content/Search/Input.Label/Noun">Search</translate></label>
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<div class="ui action input">
<input type="text" name="search" v-model="query" :placeholder="labels.searchPlaceholder"/>
<button class="ui icon button" type="submit" :aria-label="$pgettext('Content/Search/Input.Label/Noun', 'Search')">
<i class="search icon"></i>
</button>
</div>
</div>
<div class="field">
<label><translate translate-context="Content/Search/Dropdown.Label/Noun">Ordering</translate></label>
......@@ -38,7 +43,7 @@
</select>
</div>
</div>
</div>
</form>
<div class="ui hidden divider"></div>
<playlist-card-list v-if="result && result.results.length > 0" :playlists="result.results"></playlist-card-list>
<div v-else-if="result && !result.results.length > 0" class="ui placeholder segment sixteen wide column" style="text-align: center; display: flex; align-items: center">
......@@ -124,7 +129,7 @@ export default {
}
},
methods: {
updateQueryString: _.debounce(function() {
updateQueryString: function() {
history.pushState(
{},
null,
......@@ -136,8 +141,8 @@ export default {
ordering: this.getOrderingAsString()
}).toString()
)
}, 250),
fetchData: _.debounce(function() {
},
fetchData: function() {
var self = this
this.isLoading = true
let url = FETCH_URL
......@@ -153,7 +158,7 @@ export default {
self.result = response.data
self.isLoading = false
})
}, 500),
},
selectPage: function(page) {
this.page = page
}
......@@ -163,22 +168,6 @@ export default {
this.updateQueryString()
this.fetchData()
},
paginateBy() {
this.updateQueryString()
this.fetchData()
},
ordering() {
this.updateQueryString()
this.fetchData()
},
orderingDirection() {
this.updateQueryString()
this.fetchData()
},
query() {
this.updateQueryString()
this.fetchData()
}
}
}
</script>
Markdown is supported
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