both infinite and paging

This commit is contained in:
Kendall Garner 2022-07-01 14:00:23 -04:00
parent 147033b5dd
commit 83f920359e
No known key found for this signature in database
GPG key ID: 18D2767419676C87
3 changed files with 63 additions and 11 deletions

View file

@ -88,6 +88,9 @@
"term.size": "Size", "term.size": "Size",
"term.size.normal": "Normal", "term.size.normal": "Normal",
"term.size.compact": "Compact", "term.size.compact": "Compact",
"term.scroll": "Scroll Mode",
"term.scroll.infinite": "Infinite",
"term.scroll.paged": "${songsPerPage} per page",
"term.enable": "Enable", "term.enable": "Enable",
"term.disable": "Disable", "term.disable": "Disable",
"term.enabled": "Enabled", "term.enabled": "Enabled",

View file

@ -146,6 +146,7 @@ export class Store {
}, },
"libraryPrefs": { "libraryPrefs": {
"songs": { "songs": {
"scroll": "infinite",
"sort": "name", "sort": "name",
"sortOrder": "asc", "sortOrder": "asc",
"size": "normal" "size": "normal"

View file

@ -46,6 +46,14 @@
</optgroup> </optgroup>
</select> </select>
</div> </div>
<div class="col">
<select class="md-select" v-model="prefs.scroll">
<optgroup :label="app.getLz('term.scroll')">
<option value="infinite">{{app.getLz('term.scroll.infinite')}}</option>
<option value="paged">{{app.getLz('term.scroll.paged').replace("${songsPerPage}", pageSize)}}</option>
</optgroup>
</select>
</div>
</div> </div>
</div> </div>
<div class="col-auto flex-center"> <div class="col-auto flex-center">
@ -56,7 +64,7 @@
</button> </button>
</div> </div>
</div> </div>
<div class="row" style="margin-bottom: 16px"> <div class="row" style="margin-bottom: 16px" v-if="!isInfinite">
<button <button
class="col md-btn page-btn" class="col md-btn page-btn"
:disabled="currentPage === 1" :disabled="currentPage === 1"
@ -104,7 +112,6 @@
<div class="well" :key="2" v-else> <div class="well" :key="2" v-else>
<mediaitem-list-item :item="item" :parent="'librarysongs'" :index="index" :show-meta-data="true" :show-library-status="false" v-for="(item, index) in currentSlice"></mediaitem-list-item> <mediaitem-list-item :item="item" :parent="'librarysongs'" :index="index" :show-meta-data="true" :show-library-status="false" v-for="(item, index) in currentSlice"></mediaitem-list-item>
</div> </div>
</div> </div>
</script> </script>
@ -123,20 +130,53 @@
} }
}, },
mounted() { mounted() {
document.querySelector("#app-content")
.addEventListener("scroll", this.handleScroll)
this.$root.getLibrarySongsFull() this.$root.getLibrarySongsFull()
}, },
destroyed() {
document.querySelector("#app-content")
.removeEventListener("scroll", this.handleScroll)
},
watch: {
'library.songs.displayListing.length': function () {
if (this.isInfinite) {
// If a search reduces the number of things to show, we want to limit
// the number of songs shown as well. This is to prevent you scrolling
// to load your entire library, searching for one song, and then having
// th re-render the entire library
if (this.currentPage > this.numPages) {
this.currentPage = this.numPages;
}
}
},
'prefs.scroll': function () {
// When changing modes, set the page to 1. This is primarily to
// prevent going to a high page (e.g., 50) and then switching to infinite
// and showing 12.5k songs
this.currentPage = 1;
}
},
computed: { computed: {
isInfinite: function () {
return this.prefs.scroll === "infinite"
},
currentSlice: function () { currentSlice: function () {
const startingPage = Math.min(this.numPages, this.currentPage); if (this.isInfinite) {
return this.library.songs.displayListing.slice(
0, this.currentPage * this.pageSize
);
} else {
const startingPage = Math.min(this.numPages, this.currentPage);
return this.library.songs.displayListing.slice( return this.library.songs.displayListing.slice(
(startingPage - 1) * this.pageSize, (startingPage - 1) * this.pageSize,
startingPage * this.pageSize startingPage * this.pageSize
); );
}
}, },
numPages: function () { numPages: function () {
return Math.ceil(this.library.songs.displayListing.length / this.pageSize) || 1; return Math.ceil(this.library.songs.displayListing.length / this.pageSize) || 1;
}, },
pagesToShow: function () { pagesToShow: function () {
let start = this.currentPage - 2; let start = this.currentPage - 2;
@ -148,7 +188,6 @@
} }
const endDifference = end - this.numPages; const endDifference = end - this.numPages;
if (endDifference > 0) { if (endDifference > 0) {
end = this.numPages; end = this.numPages;
start = Math.max(1, start - endDifference); start = Math.max(1, start - endDifference);
@ -158,14 +197,22 @@
for (let idx = start; idx <= end; idx++) { for (let idx = start; idx <= end; idx++) {
array.push(idx); array.push(idx);
} }
return array; return array;
} }
}, },
methods: { methods: {
// Infinite Scrolling
handleScroll: function (event) {
if (this.isInfinite &&
this.currentPage < this.numPages &&
event.target.scrollTop >= event.target.scrollHeight - event.target.clientHeight) {
this.currentPage += 1;
}
},
// Pagination
isCurrentPage: function (idx) { isCurrentPage: function (idx) {
return idx === this.currentPage || return idx === this.currentPage ||
idx === this.numPages && this.currentPage > this.numPages; (idx === this.numPages && this.currentPage > this.numPages);
}, },
changePage: function (event) { changePage: function (event) {
const value = event.target.valueAsNumber; const value = event.target.valueAsNumber;
@ -190,6 +237,7 @@
goToEnd: function () { goToEnd: function () {
this.currentPage = this.numPages; this.currentPage = this.numPages;
}, },
// Miscellaneous
play: function () { play: function () {
function shuffleArray(array) { function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) { for (var i = array.length - 1; i > 0; i--) {