add some shiz (#1313)

* Update ru_RU.json

keeping russian lang actual

* ok

* Add gradient to lyric-footer

* *Commit en español Ñ (#1304)

* i hate my life (#1307)

* world is now a better place

* meltdown avoided

* meltdown avoided

* stylize new listen now childs

* full scale artwork, finally

* dynamic width for search categories

* hd all album work

* Update afterPack.js

* force hq quality

* oops

* attempt to fix

* misc cleanup

* why what

* what was i thinking

* fix duplicated text in listen now childs

* Paginate/infinite scroll for  albums, playlists (#1234)

* Infinite scroll, pagination to album, playlists

* move pagination below tracks

* Make page size configurable

* remove renderer

* Mitigate songs / album slow app issue.

* add ratings, library change to web remote (#1285)

* Add compact artist header option (#1308)

* Support compact artist header (optional)

* Add required term

Co-authored-by: h0ckerman <35598335+h0ckerman@users.noreply.github.com>
Co-authored-by: vapormusic <vietanhfat@gmail.com>
Co-authored-by: Monochromish <chillygamer7@gmail.com>
Co-authored-by: Gabriel Davila <56521591+mefsaal@users.noreply.github.com>
Co-authored-by: Core <64542347+coredev-uk@users.noreply.github.com>
Co-authored-by: Maikiwi <stella@mai.kiwi>
Co-authored-by: yazninja <yazlesean@gmail.com>
Co-authored-by: booploops <49113086+booploops@users.noreply.github.com>
Co-authored-by: Kendall Garner <17521368+kgarner7@users.noreply.github.com>
Co-authored-by: Pedro Galhardo <pgalhardo@icloud.com>
This commit is contained in:
cryptofyre 2022-07-26 10:59:36 -05:00 committed by GitHub
parent 2fe4b65747
commit c0cea76913
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 1230 additions and 366 deletions

View file

@ -2,8 +2,18 @@
<div v-observe-visibility="{callback: visibilityChanged}">
<template v-if="isVisible && recom.attributes.display.kind != 'MusicSuperHeroShelf'">
<div class="row">
<div class="col">
<h3 @click="navigateContent(recom?.relationships['primary-content']?.data[0] ?? recom?.attributes?.title?.contentIds[0] ?? '')" style="width: fit-content;" :class="{'item-navigate' : (recom?.attributes?.title?.contentIds?.length ?? 0) > 0 | recom?.relationships['primary-content']?.data?.length > 0}">
<div class="col" v-if="recom?.relationships['primary-content']?.data?.length > 0" style="display: flex; margin-block:1rem;">
<div @click="navigateContent(recom?.relationships['primary-content']?.data[0] ?? recom?.attributes?.title?.contentIds[0] ?? '')" class="listennow-chip" style="height: 40px;width: 40px;align-self: center;margin-right: 10px;" :class="{ 'circle': recom?.relationships['primary-content']?.data[0]?.type == 'artists' }">
<mediaitem-artwork v-if="recom?.relationships['primary-content']?.data[0]?.attributes?.artwork != null" :url="recom?.relationships['primary-content']?.data[0]?.attributes?.artwork?.url" :size="100"></mediaitem-artwork>
</div>
<div @click="navigateContent(recom?.relationships['primary-content']?.data[0] ?? recom?.attributes?.title?.contentIds[0] ?? '')" style="width: fit-content;" :class="{'item-navigate' : (recom?.attributes?.title?.contentIds?.length ?? 0) > 0 | recom?.relationships['primary-content']?.data?.length > 0}">
<span style="opacity: 0.5; font-weight: bold;"> {{ recom.attributes.titleWithoutName.stringForDisplay }} </span>
<h3 style="margin-block: 0"> {{ recom?.relationships['primary-content']?.data[0].attributes?.name ?? recom.attributes.title.stringForDisplay.replace(recom.attributes.titleWithoutName.stringForDisplay, '') }}</h3>
</div>
</div>
<div class="col" v-else style="display: flex; margin-block:1rem;">
<h3 @click="navigateContent(recom?.relationships['primary-content']?.data[0] ?? recom?.attributes?.title?.contentIds[0] ?? '')" style="width: fit-content; margin-block:0;" :class="{'item-navigate' : (recom?.attributes?.title?.contentIds?.length ?? 0) > 0 | recom?.relationships['primary-content']?.data?.length > 0}">
{{ recom.attributes.title ? recom.attributes.title.stringForDisplay : " "}}</h3>
</div>
<div class="col-auto cider-flex-center" v-if="recom.relationships.contents.data.length >= 10">

View file

@ -92,6 +92,11 @@
type: Boolean,
default: false,
required: false
},
imageformat: {
type: String,
default: 'cc',
required: false
},
'contextExt': { type: Object, required: false },
},
@ -242,11 +247,11 @@
getArtworkUrl(size = -1, includeUrl = false) {
let artwork = this.item?.attributes?.artwork ? this.item?.attributes?.artwork?.url : (this.item?.attributes?.editorialArtwork?.subscriptionCover?.url ?? '')
if (size != -1) {
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', ((size === 900) ? "sr" : "cc"))
artwork = artwork.replace('{w}', size).replace('{h}', size).replace('{f}', "webp").replace('{c}', (size === 900 || size === 380 || size === 600 ) ? "sr" : this.imageformat);
}
switch (this.kind) {
case "385":
artwork = this.item.attributes.editorialArtwork?.subscriptionHero?.url ?? (this.item.attributes.artwork?.url ?? (this.item.relationships?.contents?.data[0]?.attributes?.editorialArtwork?.subscriptionHero?.url ?? ''))
artwork = (this.item.attributes.editorialArtwork?.subscriptionHero?.url ?? (this.item.attributes.artwork?.url ?? (this.item.relationships?.contents?.data[0]?.attributes?.editorialArtwork?.subscriptionHero?.url ?? ''))).replace('{c}', (size === 900 || size === 380 || size === 600 ) ? "sr" : this.imageformat);
break;
}
if (!includeUrl) {

View file

@ -0,0 +1,175 @@
<script type="text/x-template" id="pagination">
<div class="row" style="margin-bottom: 16px" v-if="!isInfinite">
<button
class="col md-btn page-btn"
:disabled="effectivePage === 1"
@click="goToPage(1)"
>
<img class="md-ico-first"/>
</button>
<button
class="col md-btn page-btn prev"
:disabled="effectivePage === 1"
@click="goToPrevious()"
>
<img class="md-ico-prev"/>
</button>
<button
:class="`col md-btn page-btn${ isCurrentPage(page) ? ' md-btn-primary': ''}`"
@click="goToPage(page)"
v-for="page in pagesToShow"
>{{ page }}</button>
<button
class="col md-btn page-btn next"
:disabled="effectivePage === numPages"
@click="goToNext()"
>
<img class="md-ico-next"/>
</button>
<button
class="col md-btn page-btn last"
:disabled="effectivePage === numPages"
@click="goToEnd()"
>
<img class="md-ico-last"/>
</button>
<div class="col page-btn" style="min-width: 12em;">
<input type="number" min="1" :max="numPages" :value="effectivePage" @change="changePage" />
<span>/ {{ numPages }}</span>
</div>
</div>
</script>
<script>
Vue.component('pagination', {
template: "#pagination",
props: {
'length': { type: Number, required: true },
'pageSize': { type: Number, required: true },
'scroll': { type: String, required: true },
'scrollSelector': { type: String, required: true }
},
data: function () {
return { currentPage: 1 }
},
mounted() {
document.querySelector(this.scrollSelector)
.addEventListener("scroll", this.handleScroll)
},
destroyed() {
document.querySelector(this.scrollSelector)
.removeEventListener("scroll", this.handleScroll)
},
watch: {
'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;
this.$emit("onRangeChange", this.currentRange);
}
} else {
this.$emit("onRangeChange", this.currentRange);
}
},
'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;
this.$emit("onRangeChange", this.currentRange);
}
},
computed: {
isInfinite: function () {
return this.scroll === "infinite"
},
currentRange: function () {
if (this.isInfinite) {
return [0, this.currentPage * this.pageSize];
} else {
const startingPage = Math.min(this.numPages, this.currentPage);
return [
(startingPage - 1) * this.pageSize,
startingPage * this.pageSize
];
}
},
effectivePage: function () {
return Math.min(this.currentPage, this.numPages)
},
numPages: function () {
return Math.ceil(this.length / this.pageSize) || 1;
},
pagesToShow: function () {
let start = this.currentPage - 2;
let end = this.currentPage + 2;
if (start < 1) {
end += (1 - start);
start = 1;
}
const endDifference = end - this.numPages;
if (endDifference > 0) {
end = this.numPages;
start = Math.max(1, start - endDifference);
}
const array = [];
for (let idx = start; idx <= end; idx++) {
array.push(idx);
}
return array;
}
},
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;
this.$emit("onRangeChange", this.currentRange);
}
},
// Pagination
isCurrentPage: function (idx) {
return idx === this.currentPage ||
(idx === this.numPages && this.currentPage > this.numPages);
},
changePage: function (event) {
const value = event.target.valueAsNumber;
if (!isNaN(value) && value >= 1 && value <= this.numPages) {
this.currentPage = value;
this.$emit("onRangeChange", this.currentRange);
}
},
goToPage: function (page) {
this.currentPage = page;
this.$emit("onRangeChange", this.currentRange);
},
goToPrevious: function () {
if (this.currentPage > 1) {
this.currentPage -= 1;
this.$emit("onRangeChange", this.currentRange);
}
},
goToNext: function () {
if (this.currentPage < this.numPages) {
this.currentPage += 1;
this.$emit("onRangeChange", this.currentRange);
}
},
goToEnd: function () {
this.currentPage = this.numPages;
this.$emit("onRangeChange", this.currentRange);
}
}
})
</script>

View file

@ -547,6 +547,14 @@
:disabled="app.cfg.visual.customAccentColor" switch/>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.visual.compactArtistHeader')}}
</div>
<div class="md-option-segment_auto">
<input type="checkbox" v-model="app.cfg.visual.compactArtistHeader" switch/>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.visual.hardwareAcceleration')}}<br>
@ -771,19 +779,19 @@
<option value='afrikaans'>Afrikaans</option>
<option value='albanian'>Albanian</option>
<option value='arab'>Arabic</option>
<option value='armenian'>Armenian</option>
<option value='armenian'>Armenian</option>
<option value='azerbaijani'>Azerbaijani</option>
<option value='bengali'>Bengali</option>
<option value='bosnian'>Bosnian</option>
<option value='brazilian'>Brazilian</option>
<option value='bulgarian'>Bulgarian</option>
<option value='brazilian'>Brazilian</option>
<option value='bulgarian'>Bulgarian</option>
<option value='chinese'>Chinese (Simplified)</option>
<option value='chinese-trad'>Chinese (Traditional)</option>
<option value='chinese-trad'>Chinese (Traditional)</option>
<option value='chinese-romaji'>Romanized Chinese</option>
<option value='croatian'>Croatian</option>
<option value='czech'>Czech</option>
<option value='danish'>Danish</option>
<option value='dutch'>Dutch</option>
<option value='danish'>Danish</option>
<option value='dutch'>Dutch</option>
<option value='estonian'>Estonian</option>
<option value='english'>English</option>
<option value='farsi'>Farsi</option>
@ -1247,6 +1255,27 @@
</label>
</div>
</div>
<div class="md-option-line">
<div class="md-option-segment">
{{$root.getLz('settings.option.general.pagination')}}<br>
<small>
{{$root.getLz('settings.options.general.pagination.description')}}<br>
</small>
</div>
<div class="md-option-segment md-option-segment_auto">
<label>
<select class="md-select" style="width:180px;"
v-model.number="$root.cfg.libraryPrefs.pageSize" type="number">
<option value="50">50</option>
<option value="100">100</option>
<option value="250">250</option>
<option value="500">500</option>
<option value="1000">1000</option>
</select>
</label>
</div>
</div>
</div>
</div>
</div>

View file

@ -1,7 +1,7 @@
<script type="text/x-template" id="cider-artist">
<div class="content-inner artist-page"
:class="[(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9) || hasHero()) ? 'animated' : '']">
<div class="artist-header" :key="data.id" v-observe-visibility="{callback: isHeaderVisible}">
<div :class="['artist-header', { 'artist-header-compact': app.cfg.visual.compactArtistHeader }]" :key="data.id" v-observe-visibility="{callback: isHeaderVisible}">
<animatedartwork-view
:priority="true"
v-if="hasAnimated()"

View file

@ -107,6 +107,12 @@
<img :class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{app.getLz('term.confirm')}}
</button>
<select v-if="shouldPaginate" 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 style="display: flex; float: right;">
<button :style="{ 'background': '#' + hasHeroObject()?.textColor4 ?? '' }" :class="['search-btn', showSearch ? 'active' : '']" @click="toggleSearch()" :aria-label="showSearch ? app.getLz('term.hideSearch') : app.getLz('term.showSearch')">
<svg-icon :style="{ 'width': '15px', 'background-color': '#' + hasHeroObject()?.bgColor ?? '' }" :url="showSearch ? './assets/search-alt.svg' : './assets/search.svg'">
@ -161,6 +167,12 @@
<img :class="(!inLibrary) ? 'md-ico-add' : 'md-ico-remove'">
{{app.getLz('term.confirm')}}
</button>
<select v-if="shouldPaginate" 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 class="col-auto cider-flex-center">
@ -172,7 +184,7 @@
</div>
<div class="playlist-body scrollbody">
<b-tabs pills class="track-pills pilldim fancy-pills" align="center" content-class="mt-3" :nav-wrapper-class="navClass(data)">
<b-tab :title="$root.getLz('term.tracks')">
<b-tab :title="$root.getLz('term.tracks')" id="songList">
<div @wheel="minClass(true)" @scroll="minClass(true)">
<div class="">
<div style="width:100%" @click="minClass(true)">
@ -186,18 +198,27 @@
class="search-input"
ref="search-bar">
</div>
<pagination
v-if="shouldPaginate"
style="margin-top: 10px"
:length="hasNestedPlaylist ? nestedDisplayLength: displayListing.length"
:pageSize="pageSize"
:scroll="prefs.scroll"
scrollSelector="#songList"
@onRangeChange="onRangeChange"
/>
<draggable :options="{disabled: !editing}"
v-model="data.relationships.tracks.data" @start="drag=true"
@end="drag=false;put()">
<template v-if="!hasNestedPlaylist">
<mediaitem-list-item :item="item" :parent="getItemParent(data)" :index="index"
<mediaitem-list-item :item="item" :parent="getItemParent(data)" :index="index + start"
:showIndex="true"
:showIndexPlaylist="(data.attributes.playParams?.kind ?? data.type ?? '').includes('playlist')"
:context-ext="buildContextMenu()"
v-for="(item,index) in displayListing"></mediaitem-list-item>
v-for="(item,index) in currentSlice"></mediaitem-list-item>
</template>
<template v-else>
<div v-for="disc in nestedPlaylist">
<div v-for="disc in nestedSlices">
<div class="playlist-time">{{($root.getLz("term.discNumber") ??
"").replace("${discNumber}",disc.disc)}}
</div>
@ -278,6 +299,7 @@
props: ["data"],
data: function () {
const pageSize = this.$root.cfg.libraryPrefs.pageSize;
return {
editorialNotesExpanded: false,
drag: false,
@ -291,6 +313,7 @@
headerVisible: true,
useArtistChip: false,
nestedPlaylist: [],
nestedDisplayLength: 0,
classes: [],
editing: false,
inPlaylist: false,
@ -298,6 +321,10 @@
displayListing: [],
hasNestedPlaylist: false,
showSearch: false,
pageSize: pageSize,
start: 0,
end: pageSize,
prefs: this.$root.cfg.libraryPrefs.playlists
}
},
mounted: function () {
@ -346,7 +373,48 @@
deep: true
}
},
computed: {
currentSlice() {
return this.displayListing.slice(this.start, this.end);
},
nestedSlices() {
if (this.shouldPaginate) {
let songsSeen = 0;
const discs = [];
for (const disc of this.nestedPlaylist) {
songsSeen += disc.tracks.length;
if (songsSeen >= this.end) {
discs.push({
disc: disc.disc,
tracks: disc.tracks.slice(0, this.end + disc.tracks.length - songsSeen)
})
break;
} else if (songsSeen > this.start) {
discs.push({
disc: disc.disc,
tracks: disc.tracks.slice(this.start - songsSeen)
})
}
}
return discs;
} else {
return this.nestedPlaylist
}
},
shouldPaginate() {
const result = this.data.relationships.tracks.data.length > this.pageSize
console.log(result)
return result
}
},
methods: {
onRangeChange(newRange) {
this.start = newRange[0];
this.end = newRange[1];
},
isAlbum() {
return (this.data.attributes?.playParams?.kind ?? this.data.type ?? '').includes('album')
},
@ -372,6 +440,8 @@
},
generateNestedPlaylist(songlists) {
this.nestedPlaylist = [];
this.nestedDisplayLength = songlists.length;
if (this.data?.type?.includes("album")) {
let discs = songlists.map(x => {
return x.attributes.discNumber

View file

@ -46,17 +46,33 @@
</optgroup>
</select>
</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>
<pagination
:length="app.library.albums.displayListing.length
"
:pageSize="pageSize"
:scroll="prefs.scroll"
scrollSelector="#app-content"
@onRangeChange="onRangeChange"
/>
<div class="well">
<div class="albums-square-container">
<div>
<mediaitem-square v-if="prefs.viewAs == 'covers'" :size="'300'" :item="item" v-for="item in library.albums.displayListing">
<mediaitem-square v-if="prefs.viewAs == 'covers'" :size="'300'" :item="item" v-for="item in currentSlice">
</mediaitem-square>
</div>
</div>
<mediaitem-list-item v-if="prefs.viewAs == 'list'" :show-duration="false" :show-meta-data="true" :show-library-status="false" :item="item" v-for="item in library.albums.displayListing">
<mediaitem-list-item v-if="prefs.viewAs == 'list'" :show-duration="false" :show-meta-data="true" :show-library-status="false" :item="item" v-for="item in currentSlice">
</mediaitem-list-item>
</div>
</div>
@ -65,21 +81,34 @@
Vue.component('cider-library-albums', {
template: '#cider-library-albums',
data: function () {
const pageSize = this.$root.cfg.libraryPrefs.pageSize;
return {
library: this.$root.library,
mediaItemSize: "compact",
prefs: this.$root.cfg.libraryPrefs.albums,
app : this.$root
app: this.$root,
pageSize: pageSize,
start: 0,
end: pageSize
}
},
mounted() {
this.$root.getLibraryAlbumsFull(null, 1);
this.$root.getAlbumSort();
this.$root.searchLibraryAlbums(1);
this.$root.getLibrarySongsFull() ;
this.$root.getLibrarySongsFull();
this.$root.searchLibraryAlbums(1);
},
computed: {
currentSlice: function () {
return this.library.albums.displayListing.slice(this.start, this.end);
}
},
methods: {
onRangeChange: function (newRange) {
this.start = newRange[0];
this.end = newRange[1];
}
}
});
</script>

View file

@ -64,45 +64,13 @@
</button>
</div>
</div>
<div class="row" style="margin-bottom: 16px" v-if="!isInfinite">
<button
class="col md-btn page-btn"
:disabled="currentPage === 1"
@click="goToPage(1)"
>
<img class="md-ico-first"/>
</button>
<button
class="col md-btn page-btn prev"
:disabled="currentPage === 1"
@click="goToPrevious()"
>
<img class="md-ico-prev"/>
</button>
<button
:class="`col md-btn page-btn${ isCurrentPage(page) ? ' md-btn-primary': ''}`"
@click="goToPage(page)"
v-for="page in pagesToShow"
>{{ page }}</button>
<button
class="col md-btn page-btn next"
:disabled="currentPage === numPages"
@click="goToNext()"
>
<img class="md-ico-next"/>
</button>
<button
class="col md-btn page-btn last"
:disabled="currentPage === numPages"
@click="goToEnd()"
>
<img class="md-ico-last"/>
</button>
<div class="col page-btn" style="min-width: 12em;">
<input type="number" min="1" :max="numPages" :value="currentPage" @change="changePage" />
<span>/ {{ numPages }}</span>
</div>
</div>
<pagination
:length="library.songs.displayListing.length"
:pageSize="pageSize"
:scroll="prefs.scroll"
scrollSelector="#app-content"
@onRangeChange="onRangeChange"
/>
</div>
<div v-if="library.songs.downloadState == 3">Library contains no songs.</div>
@ -119,125 +87,31 @@
Vue.component('cider-library-songs', {
template: '#cider-library-songs',
data: function () {
const pageSize = this.$root.cfg.libraryPrefs.pageSize;
return {
// currentPage is oneIndexed
currentPage: 1,
library: this.$root.library,
mediaItemSize: "compact",
pageSize: 250,
prefs: this.$root.cfg.libraryPrefs.songs,
app: this.$root
app: this.$root,
pageSize: pageSize,
start: 0,
end: pageSize
}
},
mounted() {
document.querySelector("#app-content")
.addEventListener("scroll", this.handleScroll)
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: {
isInfinite: function () {
return this.prefs.scroll === "infinite"
},
currentSlice: function () {
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(
(startingPage - 1) * this.pageSize,
startingPage * this.pageSize
);
}
},
numPages: function () {
return Math.ceil(this.library.songs.displayListing.length / this.pageSize) || 1;
},
pagesToShow: function () {
let start = this.currentPage - 2;
let end = this.currentPage + 2;
if (start < 1) {
end += (1 - start);
start = 1;
}
const endDifference = end - this.numPages;
if (endDifference > 0) {
end = this.numPages;
start = Math.max(1, start - endDifference);
}
const array = [];
for (let idx = start; idx <= end; idx++) {
array.push(idx);
}
return array;
return this.library.songs.displayListing.slice(this.start, this.end);
}
},
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;
}
onRangeChange: function (newRange) {
this.start = newRange[0];
this.end = newRange[1];
},
// Pagination
isCurrentPage: function (idx) {
return idx === this.currentPage ||
(idx === this.numPages && this.currentPage > this.numPages);
},
changePage: function (event) {
const value = event.target.valueAsNumber;
if (!isNaN(value) && value >= 1 && value <= this.numPages) {
this.currentPage = value;
}
},
goToPage: function (page) {
this.currentPage = page;
},
goToPrevious: function () {
if (this.currentPage > 1) {
this.currentPage -= 1;
}
},
goToNext: function () {
if (this.currentPage < this.numPages) {
this.currentPage += 1;
}
},
goToEnd: function () {
this.currentPage = this.numPages;
},
// Miscellaneous
play: function () {
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {

View file

@ -119,7 +119,7 @@
</div>
</template>
</div>
<div v-else>
<div v-else >
<div v-if="categoriesReady || getCategories()">
<div>
<div class="col" v-if="categoriesView != null && categoriesView != [] && categoriesView[0].attributes != null && categoriesView[0].attributes.title != null">
@ -131,7 +131,9 @@
<!-- <mediaitem-square :kind="'385'" size="600" v-for="item in recentlyPlayed.limit(10)" :item="item" :imagesize="800"></mediaitem-square>-->
<h3>{{categoriesView[0].attributes.title.stringForDisplay ?? ""}}</h3>
</div>
<mediaitem-square :kind="'385'" size="600"
</div>
<div class="categories">
<mediaitem-square :kind="'385'" :imageformat="'bb'" size="600"
:item="item ? (item.attributes.kind ? item : ((item.relationships && item.relationships.contents ) ? item.relationships.contents.data[0] : item)) : []"
:imagesize="800"
v-for="item of getFlattenedCategories()">