Verified Commit 6da85ce0 authored by Agate's avatar Agate 💬

Fix #719: Added a "load more" button on artist pages to load more tracks/albums

parent 51d94a13
Pipeline #4013 passed with stages
in 2 minutes and 47 seconds
Added a "load more" button on artist pages to load more tracks/albums (#719)
......@@ -19,14 +19,18 @@
:track="track"
:artist="artist"
:key="index + '-' + track.id"
v-for="(track, index) in tracks"></track-row>
v-for="(track, index) in allTracks"></track-row>
</tbody>
</table>
<button :class="['ui', {loading: isLoadingMore}, 'button']" v-if="loadMoreUrl" @click="loadMore(loadMoreUrl)">
<translate translate-context="Content/*/Button.Label">Load more…</translate>
</button>
</div>
</template>
<script>
import backend from '@/audio/backend'
import axios from 'axios'
import TrackRow from '@/components/audio/track/Row'
import Modal from '@/components/semantic/Modal'
......@@ -35,6 +39,7 @@ export default {
props: {
tracks: {type: Array, required: true},
playable: {type: Boolean, required: false, default: false},
nextUrl: {type: String, required: false, default: null},
artist: {type: Object, required: false},
displayPosition: {type: Boolean, default: false}
},
......@@ -44,7 +49,29 @@ export default {
},
data () {
return {
backend: backend
backend: backend,
loadMoreUrl: this.nextUrl,
isLoadingMore: false,
additionalTracks: []
}
},
computed: {
allTracks () {
return this.tracks.concat(this.additionalTracks)
}
},
methods: {
loadMore (url) {
let self = this
self.isLoadingMore = true
axios.get(url).then((response) => {
self.additionalTracks = self.additionalTracks.concat(response.data.results)
self.loadMoreUrl = response.data.next
self.isLoadingMore = false
}, (error) => {
self.isLoadingMore = false
})
}
}
}
......
......@@ -3,7 +3,7 @@
<div v-if="isLoading" class="ui vertical segment">
<div :class="['ui', 'centered', 'active', 'inline', 'loader']"></div>
</div>
<template v-if="object">
<template v-if="object && !isLoading">
<section :class="['ui', 'head', {'with-background': cover}, 'vertical', 'center', 'aligned', 'stripe', 'segment']" :style="headerStyle" v-title="object.name">
<div class="segment-content">
<h2 class="ui center aligned icon header">
......@@ -98,7 +98,15 @@
</div>
</div>
</section>
<router-view v-if="object" :tracks="tracks" :albums="albums" :is-loading-albums="isLoadingAlbums" @libraries-loaded="libraries = $event" :object="object" object-type="artist" :key="$route.fullPath"></router-view>
<router-view
:tracks="tracks"
:next-tracks-url="nextTracksUrl"
:next-albums-url="nextAlbumsUrl"
:albums="albums"
:is-loading-albums="isLoadingAlbums"
@libraries-loaded="libraries = $event"
:object="object" object-type="artist"
:key="$route.fullPath"></router-view>
</template>
</main>
</template>
......@@ -132,38 +140,45 @@ export default {
libraries: [],
showEmbedModal: false,
tracks: [],
nextAlbumsUrl: null,
nextTracksUrl: null,
totalAlbums: null,
totalTracks: null,
}
},
created() {
this.fetchData()
async created() {
await this.fetchData()
},
methods: {
fetchData() {
async fetchData() {
var self = this
this.isLoading = true
logger.default.debug('Fetching artist "' + this.id + '"')
axios.get("tracks/", { params: { artist: this.id, hidden: '' } }).then(response => {
let trackPromise = axios.get("tracks/", { params: { artist: this.id, hidden: '' } }).then(response => {
self.tracks = response.data.results
self.nextTracksUrl = response.data.next
self.totalTracks = response.data.count
})
axios.get("artists/" + this.id + "/").then(response => {
self.object = response.data
self.isLoading = false
self.isLoadingAlbums = true
axios
.get("albums/", {
params: { artist: self.id, ordering: "-release_date", hidden: '' }
})
.then(response => {
self.totalAlbums = response.data.count
let parsed = JSON.parse(JSON.stringify(response.data.results))
self.albums = parsed.map(album => {
return backend.Album.clean(album)
})
let albumPromise = axios.get("albums/", {
params: { artist: self.id, ordering: "-release_date", hidden: '' }
}).then(response => {
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.isLoadingAlbums = false
})
})
let artistPromise = axios.get("artists/" + this.id + "/").then(response => {
self.object = response.data
})
await trackPromise
await albumPromise
await artistPromise
self.isLoadingAlbums = false
self.isLoading = false
}
},
computed: {
......
......@@ -21,15 +21,19 @@
<h2>
<translate translate-context="Content/Artist/Title">Albums by this artist</translate>
</h2>
<div class="ui cards" >
<album-card :mode="'rich'" :album="album" :key="album.id" v-for="album in albums"></album-card>
<div class="ui cards">
<album-card :mode="'rich'" :album="album" :key="album.id" v-for="album in allAlbums"></album-card>
</div>
<div class="ui hidden divider"></div>
<button :class="['ui', {loading: isLoadingMoreAlbums}, 'button']" v-if="nextAlbumsUrl && loadMoreAlbumsUrl" @click="loadMoreAlbums(loadMoreAlbumsUrl)">
<translate translate-context="Content/*/Button.Label">Load more…</translate>
</button>
</section>
<section v-if="tracks.length > 0" class="ui vertical stripe segment">
<h2>
<translate translate-context="Content/Artist/Title">Tracks by this artist</translate>
</h2>
<track-table :display-position="true" :tracks="tracks"></track-table>
<track-table :display-position="true" :tracks="tracks" :next-url="nextTracksUrl"></track-table>
</section>
<section class="ui vertical stripe segment">
<h2>
......@@ -52,23 +56,42 @@ import TrackTable from "@/components/audio/track/Table"
import LibraryWidget from "@/components/federation/LibraryWidget"
export default {
props: ["object", "tracks", "albums", "isLoadingAlbums"],
props: ["object", "tracks", "albums", "isLoadingAlbums", "nextTracksUrl", "nextAlbumsUrl"],
components: {
AlbumCard,
TrackTable,
LibraryWidget,
},
data () {
return {
loadMoreAlbumsUrl: this.nextAlbumsUrl,
additionalAlbums: [],
isLoadingMoreAlbums: false
}
},
computed: {
contentFilter () {
let self = this
return this.$store.getters['moderation/artistFilters']().filter((e) => {
return e.target.id === this.object.id
})[0]
},
allAlbums () {
return this.albums.concat(this.additionalAlbums)
}
},
watch: {
id() {
this.fetchData()
methods: {
loadMoreAlbums (url) {
let self = this
self.isLoadingMoreAlbums = true
axios.get(url).then((response) => {
self.additionalAlbums = self.additionalAlbums.concat(response.data.results)
self.loadMoreAlbumsUrl = response.data.next
self.isLoadingMoreAlbums = false
}, (error) => {
self.isLoadingMoreAlbums = false
})
}
}
}
......
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