[web-src] Refactor ListItemAlbum to be a functional component

This should improve performance of long album lists.
This commit is contained in:
chme 2018-12-16 09:17:43 +01:00
parent 6cd714a4f8
commit 382036687a
9 changed files with 68 additions and 46 deletions

View File

@ -1,8 +1,8 @@
<template> <template functional>
<div class="media" :id="'index_' + anchor"> <div class="media" :id="'index_' + props.anchor">
<div class="media-content fd-has-action is-clipped" v-on:click="open_album"> <div class="media-content fd-has-action is-clipped" @click="listeners.click">
<h1 class="title is-6">{{ album.name }}</h1> <h1 class="title is-6">{{ props.album.name }}</h1>
<h2 class="subtitle is-7 has-text-grey"><b>{{ album.artist }}</b></h2> <h2 class="subtitle is-7 has-text-grey"><b>{{ props.album.artist }}</b></h2>
</div> </div>
<div class="media-right"> <div class="media-right">
<slot name="actions"></slot> <slot name="actions"></slot>
@ -13,28 +13,7 @@
<script> <script>
export default { export default {
name: 'ListItemAlbum', name: 'ListItemAlbum',
components: {}, props: ['album', 'media_kind', 'anchor']
props: ['album', 'media_kind', 'anchor'],
data () {
return {
show_details_modal: false
}
},
methods: {
open_album: function () {
this.show_details_modal = false
if (this.media_kind === 'podcast') {
this.$router.push({ path: '/podcasts/' + this.album.id })
} else if (this.media_kind === 'audiobook') {
this.$router.push({ path: '/audiobooks/' + this.album.id })
} else {
this.$router.push({ path: '/music/albums/' + this.album.id })
}
}
}
} }
</script> </script>

View File

@ -19,7 +19,12 @@
</a> </a>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="(album, index) in albums.items" :key="album.id" :album="album" :anchor="anchor(album, index)" v-if="!hide_singles || album.track_count > 2"> <list-item-album v-for="(album, index) in albums.items"
:key="album.id"
:album="album"
:anchor="anchor(album, index)"
@click="open_album(album)"
v-if="!hide_singles || album.track_count > 2">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -49,6 +54,9 @@ const albumsData = {
set: function (vm, response) { set: function (vm, response) {
vm.albums = response.data vm.albums = response.data
vm.index_list = [...new Set(vm.albums.items
.filter(album => !vm.$store.state.hide_singles || album.track_count > 2)
.map(album => album.name_sort.charAt(0).toUpperCase()))]
} }
} }
@ -60,6 +68,7 @@ export default {
data () { data () {
return { return {
albums: { items: [] }, albums: { items: [] },
index_list: [],
show_details_modal: false, show_details_modal: false,
selected_album: {} selected_album: {}
@ -69,12 +78,6 @@ export default {
computed: { computed: {
hide_singles () { hide_singles () {
return this.$store.state.hide_singles return this.$store.state.hide_singles
},
index_list () {
return [...new Set(this.albums.items
.filter(album => !this.$store.state.hide_singles || album.track_count > 2)
.map(album => album.name_sort.charAt(0).toUpperCase()))]
} }
}, },
@ -87,10 +90,22 @@ export default {
return album.name_sort.charAt(0).toUpperCase() return album.name_sort.charAt(0).toUpperCase()
}, },
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true
} }
},
watch: {
'hide_singles' () {
this.index_list = [...new Set(this.albums.items
.filter(album => !this.$store.state.hide_singles || album.track_count > 2)
.map(album => album.name_sort.charAt(0).toUpperCase()))]
}
} }
} }
</script> </script>

View File

@ -10,7 +10,7 @@
</template> </template>
<template slot="content"> <template slot="content">
<p class="heading has-text-centered-mobile">{{ artist.album_count }} albums | <a class="has-text-link" @click="open_tracks">{{ artist.track_count }} tracks</a></p> <p class="heading has-text-centered-mobile">{{ artist.album_count }} albums | <a class="has-text-link" @click="open_tracks">{{ artist.track_count }} tracks</a></p>
<list-item-album v-for="album in albums.items" :key="album.id" :album="album"> <list-item-album v-for="album in albums.items" :key="album.id" :album="album" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -67,6 +67,10 @@ export default {
webapi.player_play_uri(this.albums.items.map(a => a.uri).join(','), true) webapi.player_play_uri(this.albums.items.map(a => a.uri).join(','), true)
}, },
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true

View File

@ -6,7 +6,7 @@
<p class="heading">{{ albums.total }} audiobooks</p> <p class="heading">{{ albums.total }} audiobooks</p>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'audiobook'"> <list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'audiobook'" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -51,6 +51,10 @@ export default {
}, },
methods: { methods: {
open_album: function (album) {
this.$router.push({ path: '/audiobooks/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true

View File

@ -9,7 +9,7 @@
<p class="heading">albums</p> <p class="heading">albums</p>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album"> <list-item-album v-for="album in recently_added.items" :key="album.id" :album="album" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_album_dialog(album)"> <a @click="open_album_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -106,6 +106,10 @@ export default {
this.show_track_details_modal = true this.show_track_details_modal = true
}, },
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_album_dialog: function (album) { open_album_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_album_details_modal = true this.show_album_details_modal = true

View File

@ -8,7 +8,7 @@
<p class="heading">albums</p> <p class="heading">albums</p>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in recently_added.items" :key="album.id" :album="album"> <list-item-album v-for="album in recently_added.items" :key="album.id" :album="album" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -58,6 +58,10 @@ export default {
}, },
methods: { methods: {
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true

View File

@ -11,7 +11,7 @@
</template> </template>
<template slot="content"> <template slot="content">
<p class="heading has-text-centered-mobile">{{ genreAlbums.total }} albums | <a class="has-text-link" @click="open_tracks">tracks</a></p> <p class="heading has-text-centered-mobile">{{ genreAlbums.total }} albums | <a class="has-text-link" @click="open_tracks">tracks</a></p>
<list-item-albums v-for="album in genreAlbums.items" :key="album.id" :album="album" :links="links"> <list-item-albums v-for="album in genreAlbums.items" :key="album.id" :album="album" :links="links" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -83,6 +83,10 @@ export default {
webapi.player_play_uri(this.genreAlbums.items.map(a => a.uri).join(','), true) webapi.player_play_uri(this.genreAlbums.items.map(a => a.uri).join(','), true)
}, },
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true

View File

@ -6,7 +6,7 @@
<p class="heading">{{ albums.total }} podcasts</p> <p class="heading">{{ albums.total }} podcasts</p>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'podcast'"> <list-item-album v-for="album in albums.items" :key="album.id" :album="album" :media_kind="'podcast'" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_dialog(album)"> <a @click="open_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -51,6 +51,10 @@ export default {
}, },
methods: { methods: {
open_album: function (album) {
this.$router.push({ path: '/podcasts/' + album.id })
},
open_dialog: function (album) { open_dialog: function (album) {
this.selected_album = album this.selected_album = album
this.show_details_modal = true this.show_details_modal = true

View File

@ -81,7 +81,7 @@
<p class="title is-4">Albums</p> <p class="title is-4">Albums</p>
</template> </template>
<template slot="content"> <template slot="content">
<list-item-album v-for="album in albums.items" :key="album.id" :album="album"> <list-item-album v-for="album in albums.items" :key="album.id" :album="album" @click="open_album(album)">
<template slot="actions"> <template slot="actions">
<a @click="open_album_dialog(album)"> <a @click="open_album_dialog(album)">
<span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span> <span class="icon has-text-dark"><i class="mdi mdi-dots-vertical mdi-18px"></i></span>
@ -282,6 +282,10 @@ export default {
}) })
}, },
open_album: function (album) {
this.$router.push({ path: '/music/albums/' + album.id })
},
open_recent_search: function (query) { open_recent_search: function (query) {
this.search_query = query this.search_query = query
this.new_search() this.new_search()