Merge branch 'main' of https://github.com/Apple-Music-Electron/Cider
This commit is contained in:
commit
cc8cd78ef9
13 changed files with 304 additions and 89 deletions
|
@ -79,9 +79,14 @@ const app = new Vue({
|
|||
showingPlaylist: [],
|
||||
artistPage: {
|
||||
data: {},
|
||||
topSongsExpanded: false
|
||||
},
|
||||
library: {
|
||||
downloadNotification: {
|
||||
show: false,
|
||||
message: "",
|
||||
total: 0,
|
||||
progress: 0
|
||||
},
|
||||
songs: {
|
||||
sortingOptions: {
|
||||
"albumName": "Album",
|
||||
|
@ -289,17 +294,28 @@ const app = new Vue({
|
|||
}
|
||||
return hash;
|
||||
},
|
||||
getArtistPalette(artist) {
|
||||
if (artist["attributes"]["artwork"]) {
|
||||
return {
|
||||
"background": "#" + artist["attributes"]["artwork"]["bgColor"],
|
||||
"color": "#" + artist["attributes"]["artwork"]["textColor1"],
|
||||
playAnimatedArtwork(url) {
|
||||
if (Hls.isSupported()) {
|
||||
var video = document.querySelector(`[vid="${app.hashCode(url)}"] > video`)
|
||||
console.log('supported');
|
||||
var hls = new Hls();
|
||||
// bind them together
|
||||
if (video) {
|
||||
hls.attachMedia(video);
|
||||
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
|
||||
console.log('video and hls.js are now bound together !');
|
||||
hls.loadSource(url);
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
|
||||
video.play();
|
||||
return "";
|
||||
});
|
||||
});
|
||||
} else {
|
||||
console.log("hso");
|
||||
return "";
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
"background": "#000000",
|
||||
"color": "#ffffff",
|
||||
}
|
||||
return "";
|
||||
}
|
||||
},
|
||||
routeView(item) {
|
||||
|
@ -432,7 +448,24 @@ const app = new Vue({
|
|||
sortSongs()
|
||||
} else {
|
||||
this.library.songs.displayListing = this.library.songs.listing.filter(item => {
|
||||
if (item.attributes.name.toLowerCase().includes(this.library.songs.search.toLowerCase())) {
|
||||
let itemName = item.attributes.name.toLowerCase()
|
||||
let searchTerm = this.library.songs.search.toLowerCase()
|
||||
let artistName = ""
|
||||
let albumName = ""
|
||||
if (item.attributes.artistName != null) {
|
||||
artistName = item.attributes.artistName.toLowerCase()
|
||||
}
|
||||
if (item.attributes.albumName != null) {
|
||||
albumName = item.attributes.albumName.toLowerCase()
|
||||
}
|
||||
|
||||
// remove any non-alphanumeric characters and spaces from search term and item name
|
||||
searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "")
|
||||
itemName = itemName.replace(/[^a-z0-9 ]/gi, "")
|
||||
artistName = artistName.replace(/[^a-z0-9 ]/gi, "")
|
||||
albumName = albumName.replace(/[^a-z0-9 ]/gi, "")
|
||||
|
||||
if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
@ -497,7 +530,24 @@ const app = new Vue({
|
|||
sortAlbums()
|
||||
} else {
|
||||
this.library.albums.displayListing = this.library.albums.listing.filter(item => {
|
||||
if (item.attributes.name.toLowerCase().includes(this.library.albums.search.toLowerCase())) {
|
||||
let itemName = item.attributes.name.toLowerCase()
|
||||
let searchTerm = this.library.albums.search.toLowerCase()
|
||||
let artistName = ""
|
||||
let albumName = ""
|
||||
if (item.attributes.artistName != null) {
|
||||
artistName = item.attributes.artistName.toLowerCase()
|
||||
}
|
||||
if (item.attributes.albumName != null) {
|
||||
albumName = item.attributes.albumName.toLowerCase()
|
||||
}
|
||||
|
||||
// remove any non-alphanumeric characters and spaces from search term and item name
|
||||
searchTerm = searchTerm.replace(/[^a-z0-9 ]/gi, "")
|
||||
itemName = itemName.replace(/[^a-z0-9 ]/gi, "")
|
||||
artistName = artistName.replace(/[^a-z0-9 ]/gi, "")
|
||||
albumName = albumName.replace(/[^a-z0-9 ]/gi, "")
|
||||
|
||||
if (itemName.includes(searchTerm) || artistName.includes(searchTerm) || albumName.includes(searchTerm)) {
|
||||
return item
|
||||
}
|
||||
})
|
||||
|
@ -542,7 +592,10 @@ const app = new Vue({
|
|||
let self = this
|
||||
let library = []
|
||||
let downloaded = null;
|
||||
if ((this.library.songs.downloadState == 2 || this.library.songs.downloadState == 1) && !force) {
|
||||
if ((this.library.songs.downloadState == 2) && !force) {
|
||||
return
|
||||
}
|
||||
if(this.library.songs.downloadState == 1) {
|
||||
return
|
||||
}
|
||||
if (localStorage.getItem("librarySongs") != null) {
|
||||
|
@ -553,6 +606,8 @@ const app = new Vue({
|
|||
return
|
||||
}
|
||||
this.library.songs.downloadState = 1
|
||||
this.library.downloadNotification.show = true
|
||||
this.library.downloadNotification.message = "Updating library songs..."
|
||||
|
||||
function downloadChunk() {
|
||||
self.library.songs.downloadState = 1
|
||||
|
@ -570,8 +625,11 @@ const app = new Vue({
|
|||
function processChunk(response) {
|
||||
downloaded = response
|
||||
library = library.concat(downloaded.data)
|
||||
self.library.songs.meta.total = downloaded.meta.total
|
||||
self.library.songs.meta.progress = library.length
|
||||
self.library.downloadNotification.show = true
|
||||
self.library.downloadNotification.message = "Updating library songs..."
|
||||
self.library.downloadNotification.total = downloaded.meta.total
|
||||
self.library.downloadNotification.progress = library.length
|
||||
|
||||
if (downloaded.meta.total == 0) {
|
||||
self.library.songs.downloadState = 3
|
||||
return
|
||||
|
@ -580,6 +638,7 @@ const app = new Vue({
|
|||
console.log("downloaded.next is undefined")
|
||||
self.library.songs.listing = library
|
||||
self.library.songs.downloadState = 2
|
||||
self.library.downloadNotification.show = false
|
||||
self.searchLibrarySongs()
|
||||
localStorage.setItem("librarySongs", JSON.stringify(library))
|
||||
}
|
||||
|
@ -589,6 +648,7 @@ const app = new Vue({
|
|||
} else {
|
||||
self.library.songs.listing = library
|
||||
self.library.songs.downloadState = 2
|
||||
self.library.downloadNotification.show = false
|
||||
self.searchLibrarySongs()
|
||||
localStorage.setItem("librarySongs", JSON.stringify(library))
|
||||
console.log(library)
|
||||
|
@ -613,10 +673,11 @@ const app = new Vue({
|
|||
return
|
||||
}
|
||||
this.library.albums.downloadState = 1
|
||||
this.library.songs.downloadState = 1
|
||||
this.library.downloadNotification.show = true
|
||||
this.library.downloadNotification.message = "Updating library albums..."
|
||||
|
||||
function downloadChunk() {
|
||||
self.library.songs.downloadState = 1
|
||||
self.library.albums.downloadState = 1
|
||||
if (downloaded == null) {
|
||||
app.mk.api.library.albums("", {limit: 100}, {includeResponseMeta: !0}).then((response) => {
|
||||
processChunk(response)
|
||||
|
@ -631,10 +692,11 @@ const app = new Vue({
|
|||
function processChunk(response) {
|
||||
downloaded = response
|
||||
library = library.concat(downloaded.data)
|
||||
self.library.songs.meta.total = downloaded.meta.total
|
||||
self.library.songs.meta.progress = library.length
|
||||
self.library.downloadNotification.show = true
|
||||
self.library.downloadNotification.message = "Updating library albums..."
|
||||
self.library.downloadNotification.total = downloaded.meta.total
|
||||
self.library.downloadNotification.progress = library.length
|
||||
if (downloaded.meta.total == 0) {
|
||||
self.library.songs.downloadState = 3
|
||||
self.library.albums.downloadState = 3
|
||||
return
|
||||
}
|
||||
|
@ -642,7 +704,7 @@ const app = new Vue({
|
|||
console.log("downloaded.next is undefined")
|
||||
self.library.albums.listing = library
|
||||
self.library.albums.downloadState = 2
|
||||
self.library.songs.downloadState = 2
|
||||
self.library.downloadNotification.show = false
|
||||
localStorage.setItem("libraryAlbums", JSON.stringify(library))
|
||||
self.searchLibraryAlbums()
|
||||
}
|
||||
|
@ -653,7 +715,7 @@ const app = new Vue({
|
|||
} else {
|
||||
self.library.albums.listing = library
|
||||
self.library.albums.downloadState = 2
|
||||
self.library.songs.downloadState = 2
|
||||
self.library.downloadNotification.show = false
|
||||
localStorage.setItem("libraryAlbums", JSON.stringify(library))
|
||||
self.searchLibraryAlbums()
|
||||
console.log(library)
|
||||
|
@ -751,6 +813,12 @@ const app = new Vue({
|
|||
})
|
||||
}
|
||||
},
|
||||
addToLibrary(id) {
|
||||
let self = this
|
||||
this.mk.addToLibrary(id).then((data)=>{
|
||||
self.getLibrarySongsFull(true)
|
||||
})
|
||||
},
|
||||
loadMXM() {
|
||||
let attempt = 0;
|
||||
const track = encodeURIComponent((this.mk.nowPlayingItem != null) ? this.mk.nowPlayingItem.title ?? '' : '');
|
||||
|
@ -1364,4 +1432,3 @@ var checkIfScrollIsStatic = setInterval(() => {
|
|||
}
|
||||
|
||||
}, 50);
|
||||
|
||||
|
|
|
@ -1358,6 +1358,28 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
|||
|
||||
/* Cider */
|
||||
|
||||
.reload-btn {
|
||||
background: rgb(86 86 86 / 52%);
|
||||
border-radius: 100%;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: 0px;
|
||||
appearance: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.reload-btn:hover {
|
||||
background: rgb(86 86 86 / 80%);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.reload-btn>svg {
|
||||
height: 50%;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
.wr-btn {
|
||||
font-family: inherit;
|
||||
appearance: none;
|
||||
|
@ -1448,6 +1470,34 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
|
|||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.playlist-display .playlist-info .playlist-desc-expanded {
|
||||
box-sizing: border-box;
|
||||
font-size: 14px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.playlist-display .playlist-info .playlist-desc-expanded .more-btn {
|
||||
appearance: none;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 5px;
|
||||
font-size: 14px;
|
||||
color: var(--keyColor);
|
||||
background-color: transparent;
|
||||
border: 0px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: flex-end;
|
||||
font-weight: 600;
|
||||
font-family: inherit;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.playlist-time {
|
||||
font-size: 0.9em;
|
||||
margin: 6px;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
<script type="text/x-template" id="mediaitem-list-item">
|
||||
<template>
|
||||
<div
|
||||
@click="app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url)"
|
||||
v-observe-visibility="{callback: visibilityChanged}"
|
||||
<div v-observe-visibility="{callback: visibilityChanged}"
|
||||
class="cd-mediaitem-list-item">
|
||||
<template v-if="isVisible">
|
||||
<div class="isLibrary" v-if="showLibraryStatus == true">
|
||||
<button v-if="!app.isInLibrary(item.attributes.playParams)">🖤</button>
|
||||
<button @click="addToLibrary()" v-if="!app.isInLibrary(item.attributes.playParams) && !addedToLibrary">🖤</button>
|
||||
<button v-else>❤️</button>
|
||||
</div>
|
||||
<div class="artwork" v-if="showArtwork == true">
|
||||
|
@ -15,7 +13,7 @@
|
|||
size="34"
|
||||
:type="item.type"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="info-rect" :style="{'padding-left': (showArtwork ? '' : '16px')}">
|
||||
<div class="info-rect" :style="{'padding-left': (showArtwork ? '' : '16px')}" @click="playTrack()">
|
||||
<div class="title text-overflow-elipsis">
|
||||
{{ item.attributes.name }}
|
||||
</div>
|
||||
|
@ -28,18 +26,19 @@
|
|||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-rating" v-if="item.attributes.contentRating">
|
||||
<div class="content-rating" v-if="item.attributes.contentRating" @click="playTrack()">
|
||||
{{ item.attributes.contentRating }}
|
||||
</div>
|
||||
<template v-if="showMetaData == true">
|
||||
<template v-if="showMetaData == true" @click="playTrack()">
|
||||
<div class="metainfo">
|
||||
{{ item.attributes.releaseDate ? new Date(item.attributes.releaseDate).toLocaleDateString() : "" }}
|
||||
{{ item.attributes.releaseDate ? new Date(item.attributes.releaseDate).toLocaleDateString()
|
||||
: "" }}
|
||||
</div>
|
||||
<div class="metainfo">
|
||||
{{ item.attributes.genreNames[0] ?? "" }}
|
||||
</div>
|
||||
</template>
|
||||
<div class="duration" v-if="showDuration">
|
||||
<div class="duration" v-if="showDuration" @click="playTrack()">
|
||||
{{ msToMinSec(item.attributes.durationInMillis ?? 0) }}
|
||||
</div>
|
||||
</template>
|
||||
|
@ -52,7 +51,8 @@
|
|||
template: '#mediaitem-list-item',
|
||||
data: function () {
|
||||
return {
|
||||
isVisible: false
|
||||
isVisible: false,
|
||||
addedToLibrary: false
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
@ -65,6 +65,22 @@
|
|||
methods: {
|
||||
visibilityChanged: function (isVisible, entry) {
|
||||
this.isVisible = isVisible
|
||||
},
|
||||
addToLibrary() {
|
||||
let item = this.item
|
||||
if(item.attributes.playParams.id) {
|
||||
console.log('adding to library', item.attributes.playParams.id)
|
||||
app.addToLibrary(item.attributes.playParams.id.toString())
|
||||
this.addedToLibrary = true
|
||||
}else if(item.id) {
|
||||
console.log('adding to library', item.id)
|
||||
app.addToLibrary(item.id.toString())
|
||||
this.addedToLibrary = true
|
||||
}
|
||||
},
|
||||
playTrack() {
|
||||
let item = this.item
|
||||
app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cd-mediaitem-square-large-overlay" @click.self='app.routeView(item)'>
|
||||
<div class="cd-mediaitem-square-large-overlay" @click.self='app.routeView(item)' tabindex="0">
|
||||
<div class="button" style="
|
||||
border-radius: 50%;
|
||||
background: rgba(50,50,50,0.7);"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="cd-mediaitem-square-large-overlay" @click.self='app.routeView(item)'>
|
||||
<div class="cd-mediaitem-square-large-overlay" @click.self='app.routeView(item)' tabindex="0">
|
||||
<div class="button" style="
|
||||
border-radius: 50%;
|
||||
background: rgba(50,50,50,0.7);"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script type="text/x-template" id="mediaitem-square">
|
||||
<template>
|
||||
<div @click="app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url)"
|
||||
<div tabindex="0" @click="app.playMediaItemById(item.attributes.playParams.id ?? item.id, item.attributes.playParams.kind ?? item.type, item.attributes.playParams.isLibrary ?? false, item.attributes.url)"
|
||||
class="cd-mediaitem-square">
|
||||
<div class="artwork">
|
||||
<mediaitem-artwork
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
<div class="app-sidebar-header-text">
|
||||
Library
|
||||
</div>
|
||||
<sidebar-library-item name="Recently Added" page="library-recentlyadded"></sidebar-library-item>
|
||||
<sidebar-library-item name="Songs" page="library-songs"></sidebar-library-item>
|
||||
<sidebar-library-item name="Albums" page="library-albums"></sidebar-library-item>
|
||||
<sidebar-library-item name="Artists" page="library-artists"></sidebar-library-item>
|
||||
|
@ -193,19 +194,21 @@
|
|||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="app-sidebar-notification" v-if="library.songs.downloadState == 1">
|
||||
<div>Updating your library...</div>
|
||||
<div>{{ library.songs.meta.progress }} / {{ library.songs.meta.total }}</div>
|
||||
<div class="app-sidebar-notification" v-if="library.downloadNotification.show">
|
||||
<div>{{ library.downloadNotification.message }}</div>
|
||||
<div>{{ library.downloadNotification.progress }} / {{ library.downloadNotification.total }}</div>
|
||||
<div style="width: 100%">
|
||||
<progress style="width: 80%;" :value="library.songs.meta.progress"
|
||||
:max="library.songs.meta.total"></progress>
|
||||
<progress style="width: 80%;" :value="library.downloadNotification.progress"
|
||||
:max="library.downloadNotification.total"></progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="app-content">
|
||||
<!-- Artist Page -->
|
||||
<transition name="wpfade">
|
||||
<%- include('pages/artist') %>
|
||||
<template v-if="page == 'artist-page' && artistPage.data.attributes">
|
||||
<cider-artist :data="artistPage.data"></cider-artist>
|
||||
</template>
|
||||
</transition>
|
||||
<transition name="wpfade">
|
||||
<%- include('pages/webview') %>
|
||||
|
@ -226,6 +229,7 @@
|
|||
<transition name="wpfade">
|
||||
<template v-if="page == 'browse'">
|
||||
<div class="content-inner">
|
||||
|
||||
<button id="apple-music-authorize" class="md-btn md-btn-primary" @click="init()">Start
|
||||
MusicKit
|
||||
</button>
|
||||
|
@ -386,6 +390,9 @@
|
|||
<!-- Playlists / Albums -->
|
||||
<%- include('pages/cider-playlist') %>
|
||||
|
||||
<!-- Artist Page -->
|
||||
<%- include('pages/artist') %>
|
||||
|
||||
<!-- Search -->
|
||||
<%- include('pages/search') %>
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
<template v-if="page == 'artist-page' && artistPage.data.attributes">
|
||||
<script type="text/x-template" id="cider-artist">
|
||||
<div class="content-inner artist-page">
|
||||
<div class="artist-header" :style="getArtistPalette(artistPage.data)">
|
||||
<div class="artist-header" :style="getArtistPalette(data)">
|
||||
<animatedartwork-view
|
||||
v-if="app.artistPage.data.attributes.editorialVideo && (app.artistPage.data.attributes.editorialVideo.motionArtistWide16x9 || app.artistPage.data.attributes.editorialVideo.motionArtistFullscreen16x9)"
|
||||
:video="app.artistPage.data.attributes.editorialVideo.motionArtistWide16x9.video ?? (app.artistPage.data.attributes.editorialVideo.motionArtistFullscreen16x9.video ?? '')">
|
||||
v-if="data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)"
|
||||
:video="data.attributes.editorialVideo.motionArtistWide16x9.video ?? (data.attributes.editorialVideo.motionArtistFullscreen16x9.video ?? '')">
|
||||
</animatedartwork-view>
|
||||
<div class="row">
|
||||
<div class="col-sm" style="width: auto;">
|
||||
<div class="artist-image">
|
||||
<mediaitem-artwork
|
||||
:url="artistPage.data.attributes.artwork ? artistPage.data.attributes.artwork.url : ''"
|
||||
:url="data.attributes.artwork ? data.attributes.artwork.url : ''"
|
||||
size="220" type="artists"></mediaitem-artwork>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col flex-center">
|
||||
<h1>{{ artistPage.data.attributes.name }}</h1>
|
||||
<h1>{{ data.attributes.name }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -22,22 +22,22 @@
|
|||
<div class="row well">
|
||||
<div class="col">
|
||||
<div class="row">
|
||||
<div class="col-auto" v-if="artistPage.data.views['latest-release'].data.length != 0">
|
||||
<div class="col-auto" v-if="data.views['latest-release'].data.length != 0">
|
||||
<h3>Latest Release</h3>
|
||||
<div style="width: auto;margin: 0 auto;">
|
||||
<mediaitem-square-sp v-for="song in artistPage.data.views['latest-release'].data"
|
||||
<mediaitem-square-sp v-for="song in data.views['latest-release'].data"
|
||||
:item="song">
|
||||
</mediaitem-square-sp>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col" v-if="artistPage.data.views['top-songs']">
|
||||
<div class="col" v-if="data.views['top-songs']">
|
||||
<h3>Top Songs</h3>
|
||||
<mediaitem-list-item
|
||||
v-for="song in artistPage.data.views['top-songs'].data.limit(artistPage.topSongsExpanded ? 10 : 5)"
|
||||
v-for="song in data.views['top-songs'].data.limit(topSongsExpanded ? 10 : 5)"
|
||||
:item="song"></mediaitem-list-item>
|
||||
<button class="showmoreless"
|
||||
@click="artistPage.topSongsExpanded = !artistPage.topSongsExpanded">
|
||||
<template v-if="!artistPage.topSongsExpanded">
|
||||
@click="topSongsExpanded = !topSongsExpanded">
|
||||
<template v-if="!topSongsExpanded">
|
||||
Show more
|
||||
</template>
|
||||
<template v-else>
|
||||
|
@ -50,34 +50,34 @@
|
|||
</div>
|
||||
<div class="row well">
|
||||
<div class="col">
|
||||
<template v-for="(view) in artistPage.data.meta.views.order"
|
||||
v-if="(artistPage.data.views[view].data.length != 0) && (view != 'latest-release') && (view != 'top-songs')">
|
||||
<template v-for="(view) in data.meta.views.order"
|
||||
v-if="(data.views[view].data.length != 0) && (view != 'latest-release') && (view != 'top-songs')">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{ artistPage.data.views[view].attributes.title ?
|
||||
artistPage.data.views[view].attributes.title : "???"}}
|
||||
<h3>{{ data.views[view].attributes.title ?
|
||||
data.views[view].attributes.title : "???"}}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="artistPage.data.views[view].data.length >= 10">
|
||||
<div class="col-auto flex-center" v-if="data.views[view].data.length >= 10">
|
||||
<button class="cd-btn-seeall">See All</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large :items="artistPage.data.views[view].data.limit(10)">
|
||||
<mediaitem-scroller-horizontal-large :items="data.views[view].data.limit(10)">
|
||||
</mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<div class="row">
|
||||
<div class="col" v-if="artistPage.data.attributes.artistBio">
|
||||
<h3>About {{ artistPage.data.attributes.name }}</h3>
|
||||
<p v-html="artistPage.data.attributes.artistBio"></p>
|
||||
<div class="col" v-if="data.attributes.artistBio">
|
||||
<h3>About {{ data.attributes.name }}</h3>
|
||||
<p v-html="data.attributes.artistBio"></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div v-if="artistPage.data.attributes.origin">
|
||||
<h3>{{ artistPage.data.attributes.isGroup ? "Origin" : "Hometown" }}</h3>
|
||||
{{ artistPage.data.attributes.origin }}
|
||||
<div v-if="data.attributes.origin">
|
||||
<h3>{{ data.attributes.isGroup ? "Origin" : "Hometown" }}</h3>
|
||||
{{ data.attributes.origin }}
|
||||
</div>
|
||||
<div v-if="artistPage.data.attributes.bornOrFormed">
|
||||
<h3>{{ artistPage.data.attributes.isGroup ? "Born" : "Formed" }}</h3>
|
||||
{{ artistPage.data.attributes.bornOrFormed }}
|
||||
<div v-if="data.attributes.bornOrFormed">
|
||||
<h3>{{ data.attributes.isGroup ? "Born" : "Formed" }}</h3>
|
||||
{{ data.attributes.bornOrFormed }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,4 +85,37 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</script>
|
||||
<script>
|
||||
Vue.component('cider-artist', {
|
||||
template: "#cider-artist",
|
||||
props: ['data'],
|
||||
data: function () {
|
||||
return {
|
||||
topSongsExpanded: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getArtistPalette(artist) {
|
||||
if (artist["attributes"]["artwork"]) {
|
||||
return {
|
||||
"background": "#" + artist["attributes"]["artwork"]["bgColor"],
|
||||
"color": "#" + artist["attributes"]["artwork"]["textColor1"],
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
"background": "#000000",
|
||||
"color": "#ffffff",
|
||||
}
|
||||
}
|
||||
},
|
||||
getTopResult() {
|
||||
if (this.search.results["meta"]) {
|
||||
return this.search.results[this.search.results.meta.results.order[0]]["data"][0]
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -16,18 +16,40 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="col playlist-info">
|
||||
<div class="playlist-name">{{data.attributes ? (data.attributes.name ?? (data.attributes.title ?? '') ?? '') : ''}}</div>
|
||||
<div class="playlist-artist" v-if="data.attributes && data.attributes.artistName">{{data.attributes ? (data.attributes.artistName ?? '') :''}}
|
||||
<template v-if="!editorialNotesExpanded">
|
||||
<div>
|
||||
<div class="playlist-name">{{data.attributes ? (data.attributes.name ??
|
||||
(data.attributes.title ?? '') ?? '') : ''}}
|
||||
</div>
|
||||
<div class="playlist-artist" v-if="data.attributes && data.attributes.artistName">
|
||||
{{data.attributes ? (data.attributes.artistName ?? '') :''}}
|
||||
</div>
|
||||
<div class="playlist-desc" v-if="data.attributes.editorialNotes">
|
||||
<div class="content" v-html="((data.attributes.editorialNotes) ? (data.attributes.editorialNotes.short ?? (data.attributes.editorialNotes.standard ?? '') ) : (data.attributes.description ? (data.attributes.description.short ?? (data.attributes.description.standard ?? '')) : ''))"></div>
|
||||
<button class="more-btn">More</button>
|
||||
<div class="content"
|
||||
v-html="((data.attributes.editorialNotes) ? (data.attributes.editorialNotes.standard ?? (data.attributes.editorialNotes.short ?? '') ) : (data.attributes.description ? (data.attributes.description.standard ?? (data.attributes.description.short ?? '')) : ''))"></div>
|
||||
<button class="more-btn" @click="editorialNotesExpanded = !editorialNotesExpanded">
|
||||
More
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="editorialNotesExpanded">
|
||||
<div class="playlist-desc-expanded">
|
||||
<div class="content"
|
||||
v-html="((data.attributes.editorialNotes) ? (data.attributes.editorialNotes.standard ?? (data.attributes.editorialNotes.short ?? '') ) : (data.attributes.description ? (data.attributes.description.standard ?? (data.attributes.description.short ?? '')) : ''))"></div>
|
||||
<button class="more-btn" @click="editorialNotesExpanded = !editorialNotesExpanded">Less
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="playlist-controls">
|
||||
<button class="wr-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 0;app.playMediaItemById(data.attributes.playParams.id ?? data.id, data.attributes.playParams.kind ?? data.type, data.attributes.playParams.isLibrary ?? false, data.attributes.url)">Play</button>
|
||||
@click="app.mk.shuffleMode = 0;app.playMediaItemById(data.attributes.playParams.id ?? data.id, data.attributes.playParams.kind ?? data.type, data.attributes.playParams.isLibrary ?? false, data.attributes.url)">
|
||||
Play
|
||||
</button>
|
||||
<button class="wr-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 1;app.playMediaItemById(data.attributes.playParams.id ?? data.id, data.attributes.playParams.kind ?? data.type, data.attributes.playParams.isLibrary ?? false, data.attributes.url)">Shuffle</button>
|
||||
@click="app.mk.shuffleMode = 1;app.playMediaItemById(data.attributes.playParams.id ?? data.id, data.attributes.playParams.kind ?? data.type, data.attributes.playParams.isLibrary ?? false, data.attributes.url)">
|
||||
Shuffle
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,6 +67,11 @@
|
|||
<script>
|
||||
Vue.component('cider-playlist', {
|
||||
template: "#cider-playlist",
|
||||
props: ["data"]
|
||||
props: ["data"],
|
||||
data: function () {
|
||||
return {
|
||||
editorialNotesExpanded: false,
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
|
@ -1,6 +1,13 @@
|
|||
<template v-if="page == 'library-albums'">
|
||||
<div class="content-inner">
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0px;">
|
||||
<h1 class="header-text">Albums</h1>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button v-if="library.albums.downloadState == 2" @click="getLibraryAlbumsFull(true)" class="reload-btn"><%- include('../svg/redo.svg') %></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0px;">
|
||||
<div class="search-input-container" style="width:100%;margin: 16px 0px;">
|
||||
|
|
|
@ -1,6 +1,13 @@
|
|||
<template v-if="page == 'library-songs'">
|
||||
<div class="content-inner">
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0px;">
|
||||
<h1 class="header-text">Songs</h1>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button v-if="library.songs.downloadState == 2" @click="getLibrarySongsFull(true)" class="reload-btn"><%- include('../svg/redo.svg') %></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" style="padding:0px;">
|
||||
<div class="search-input-container" style="width:100%;margin: 16px 0px;">
|
||||
|
|
1
resources/cider-ui-tests/views/svg/redo.svg
Normal file
1
resources/cider-ui-tests/views/svg/redo.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M500.33 0h-47.41a12 12 0 0 0-12 12.57l4 82.76A247.42 247.42 0 0 0 256 8C119.34 8 7.9 119.53 8 256.19 8.1 393.07 119.1 504 256 504a247.1 247.1 0 0 0 166.18-63.91 12 12 0 0 0 .48-17.43l-34-34a12 12 0 0 0-16.38-.55A176 176 0 1 1 402.1 157.8l-101.53-4.87a12 12 0 0 0-12.57 12v47.41a12 12 0 0 0 12 12h200.33a12 12 0 0 0 12-12V12a12 12 0 0 0-12-12z"/></svg>
|
After Width: | Height: | Size: 622 B |
Loading…
Add table
Add a link
Reference in a new issue