Merge branch 'upcoming' into upcoming
This commit is contained in:
commit
7bc77b2b1d
26 changed files with 1390 additions and 353 deletions
37
src/renderer/views/components/artwork-material.ejs
Normal file
37
src/renderer/views/components/artwork-material.ejs
Normal file
|
@ -0,0 +1,37 @@
|
|||
<script type="text/x-template" id="artwork-material">
|
||||
<div class="artworkMaterial">
|
||||
<img :src="src" v-for="image in images"/>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('artwork-material', {
|
||||
template: '#artwork-material',
|
||||
data: function () {
|
||||
return {
|
||||
src: ""
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.src = app.getMediaItemArtwork(this.url, this.size)
|
||||
},
|
||||
props: {
|
||||
url: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: '32'
|
||||
},
|
||||
images: {
|
||||
type: [String, Number],
|
||||
required: false,
|
||||
default: '2'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
});
|
||||
</script>
|
0
src/renderer/views/components/mediaitem-info.ejs
Normal file
0
src/renderer/views/components/mediaitem-info.ejs
Normal file
|
@ -1,6 +1,7 @@
|
|||
<script type="text/x-template" id="mediaitem-scroller-horizontal">
|
||||
<template>
|
||||
<div class="cd-hmedia-scroller" :class="kind">
|
||||
<slot></slot>
|
||||
<mediaitem-square :kind="kind" :item="item"
|
||||
v-for="item in items"></mediaitem-square>
|
||||
</div>
|
||||
|
@ -13,7 +14,7 @@
|
|||
props: {
|
||||
'items': {
|
||||
type: Array,
|
||||
required: true
|
||||
required: false
|
||||
},
|
||||
'kind': {
|
||||
type: String,
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
<div tabindex="0"
|
||||
class="cd-mediaitem-square" :class="getClasses()" @contextmenu="contextMenu"
|
||||
v-observe-visibility="{callback: visibilityChanged}"
|
||||
:style="{'--spcolor': getBgColor()}"
|
||||
@click.self='app.routeView(item)'>
|
||||
:style="{'--spcolor': getBgColor()}">
|
||||
<template v-if="isVisible">
|
||||
<div class="artwork-container">
|
||||
<div class="artwork" @click='app.routeView(item)'>
|
||||
|
|
|
@ -72,10 +72,10 @@
|
|||
style["top"] = this.event.clientY + "px";
|
||||
// make sure the menu panel isnt off the screen
|
||||
if (this.event.clientX + this.size[0] > window.innerWidth) {
|
||||
style["left"] = (window.innerWidth - this.size[0]) + "px";
|
||||
style["left"] = (this.event.clientX - this.size[0]) + "px";
|
||||
}
|
||||
if (this.event.clientY + this.size[1] > window.innerHeight) {
|
||||
style["top"] = (window.innerHeight - this.size[1]) + "px";
|
||||
style["top"] = (this.event.clientY - this.size[1]) + "px";
|
||||
}
|
||||
}
|
||||
return style
|
||||
|
|
|
@ -82,10 +82,12 @@
|
|||
<mediaitem-artwork :url="currentArtUrl"></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="playback-info">
|
||||
<div class="song-name">
|
||||
<div class="song-name" style="-webkit-box-orient: horizontal;"
|
||||
:style="[mk.nowPlayingItem['attributes']['contentRating'] == 'explicit' ? {'margin-left' : '23px'} : {'margin-left' : '0px'} ]">
|
||||
{{ mk.nowPlayingItem["attributes"]["name"] }}
|
||||
<div class="explicit-icon" v-if="mk.nowPlayingItem['attributes']['contentRating'] == 'explicit'" style="display: inline-block"></div>
|
||||
</div>
|
||||
<div class="song-artist "
|
||||
<div class="song-artist"
|
||||
style="display: inline-block; -webkit-box-orient: horizontal; white-space: nowrap;">
|
||||
<div class="item-navigate song-artist" style="display: inline-block"
|
||||
:style="[chrome.progresshover ? {'opacity': '0'} : {'opacity' : '1'} ]"
|
||||
|
@ -94,7 +96,7 @@
|
|||
</div>
|
||||
<div class="song-artist item-navigate" style="display: inline-block"
|
||||
:style="[chrome.progresshover ? {'opacity': '0'} : {'opacity' : '1'}]"
|
||||
@click="getNowPlayingItemDetailed('album')">
|
||||
@click="getNowPlayingItemDetailed('album')" v-if="mk.nowPlayingItem['attributes']['albumName'] != ''">
|
||||
<div class="separator" style="display: inline-block;">{{"—"}}</div>
|
||||
{{(mk.nowPlayingItem["attributes"]["albumName"]) ?
|
||||
(mk.nowPlayingItem["attributes"]["albumName"]) : "" }}
|
||||
|
@ -115,11 +117,11 @@
|
|||
</div>
|
||||
</div>
|
||||
<template v-if="mk.nowPlayingItem['attributes']['playParams']">
|
||||
<div class="actions"
|
||||
v-if="isInLibrary(mk.nowPlayingItem['attributes']['playParams'])">
|
||||
❤️
|
||||
<div class="actions">
|
||||
<button class="lcdMenu" @click="nowPlayingContextMenu">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="actions" v-else>🖤</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
|
@ -290,8 +292,8 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="app-chrome-item volume">
|
||||
<div class="app-chrome-item volume-icon"></div>
|
||||
<div class="input-container">
|
||||
<div class="app-chrome-item volume-icon"></div>
|
||||
<input type="range" class="" @wheel="volumeWheel" step="0.01" min="0" max="1"
|
||||
v-model="mk.volume"
|
||||
v-if="typeof mk.volume != 'undefined'">
|
||||
|
@ -661,6 +663,8 @@
|
|||
</button>
|
||||
</script>
|
||||
|
||||
<!-- Artwork Material -->
|
||||
<%- include('components/artwork-material') %>
|
||||
<!-- Menu Panel -->
|
||||
<%- include('components/menu-panel') %>
|
||||
<!-- Playlist Listing -->
|
||||
|
@ -712,5 +716,6 @@
|
|||
<script src="index.js?v=1"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/resonance-audio/build/resonance-audio.min.js"></script>
|
||||
<script src="/audio/audio.js?v=1"></script>
|
||||
<script src="/WSAPI_Interop.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,5 +1,30 @@
|
|||
<script type="text/x-template" id="cider-artist-feed">
|
||||
<div class="content-inner">
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="row nopadding">
|
||||
<div class="col nopadding">
|
||||
<h3>Followed Artists</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="well">
|
||||
<mediaitem-scroller-horizontal>
|
||||
<div v-for="artist in artists" style="margin: 6px;">
|
||||
<mediaitem-square :item="artist" kind="small"></mediaitem-square>
|
||||
<button @click="unfollow(artist.id)" class="md-btn md-btn-glyph" style="display:flex;">
|
||||
<div class="sidebar-icon">
|
||||
<div class="svg-icon" :style="{'--url': 'url(./assets/feather/x-circle.svg)'}"></div>
|
||||
</div> Unfollow
|
||||
</button>
|
||||
</div>
|
||||
</mediaitem-scroller-horizontal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
@ -30,6 +55,7 @@
|
|||
app: this.$root,
|
||||
followedArtists: this.$root.cfg.home.followedArtists,
|
||||
artistFeed: [],
|
||||
artists: []
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -37,11 +63,26 @@
|
|||
await this.getArtistFeed()
|
||||
},
|
||||
methods: {
|
||||
unfollow(id) {
|
||||
let index = this.followedArtists.indexOf(id)
|
||||
if (index > -1) {
|
||||
this.followedArtists.splice(index, 1)
|
||||
}
|
||||
let artist = this.artists.find(a => a.id == id)
|
||||
let index2 = this.artists.indexOf(artist)
|
||||
if (index2 > -1) {
|
||||
this.artists.splice(index2, 1)
|
||||
}
|
||||
this.getArtistFeed()
|
||||
},
|
||||
async getArtistFeed() {
|
||||
let artists = this.followedArtists
|
||||
let self = this
|
||||
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see&extend=artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero&extend[playlists]=trackCount&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=20&art[url]=f`).then(artistData => {
|
||||
this.artists = []
|
||||
this.artistFeed = []
|
||||
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f`).then(artistData => {
|
||||
artistData.data.data.forEach(item => {
|
||||
self.artists.push(item)
|
||||
if (item.views["latest-release"].data.length != 0) {
|
||||
self.artistFeed.push(item.views["latest-release"].data[0])
|
||||
}
|
||||
|
|
|
@ -1,42 +1,59 @@
|
|||
<script type="text/x-template" id="cider-artist">
|
||||
<div class="content-inner artist-page">
|
||||
<div class="artist-header" :style="getArtistPalette(data)" :key="data.id">
|
||||
<div class="artist-header" :key="data.id" v-observe-visibility="{callback: isHeaderVisible}">
|
||||
<animatedartwork-view
|
||||
:priority="true"
|
||||
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" v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))">
|
||||
<mediaitem-artwork
|
||||
shadow="large"
|
||||
:url="data.attributes.artwork ? data.attributes.artwork.url : ''"
|
||||
size="190" type="artists"></mediaitem-artwork>
|
||||
<button class="overlay-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
<div class="header-content">
|
||||
<div class="row">
|
||||
<div class="col-sm" style="width: auto;">
|
||||
<div class="artist-image" v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))">
|
||||
<mediaitem-artwork
|
||||
shadow="large"
|
||||
:url="data.attributes.artwork ? data.attributes.artwork.url : ''"
|
||||
size="190" type="artists"></mediaitem-artwork>
|
||||
<button class="overlay-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
app.mk.play()
|
||||
})">
|
||||
<%- include("../svg/play.svg") %>
|
||||
</button>
|
||||
<%- include("../svg/play.svg") %>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col flex-center artist-title"
|
||||
:class="{'artist-animation-on': (data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)) }"
|
||||
>
|
||||
<button class="artist-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
<div class="col flex-center artist-title"
|
||||
:class="{'artist-animation-on': (data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9)) }"
|
||||
>
|
||||
<button class="artist-play" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
app.mk.play()
|
||||
})"><%- include("../svg/play.svg") %></button>
|
||||
<h1>{{ data.attributes.name }}</h1>
|
||||
<h1>{{ data.attributes.name }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<button class="more-btn-round" @click="artistMenu">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="artworkContainer" v-if="!(data.attributes.editorialVideo && (data.attributes.editorialVideo.motionArtistWide16x9 || data.attributes.editorialVideo.motionArtistFullscreen16x9))">
|
||||
<artwork-material :url="data.attributes.artwork.url" size="190" images="1"></artwork-material>
|
||||
</div>
|
||||
</div>
|
||||
<div class="floating-header" :style="{opacity: (headerVisible ? 0 : 1),'pointer-events': (headerVisible ? 'none' : '')}">
|
||||
<div class="row">
|
||||
<div class="col-auto flex-center">
|
||||
<button class="artist-play" style="display:block;" @click="app.mk.setStationQueue({artist:'a-'+data.id}).then(()=>{
|
||||
app.mk.play()
|
||||
})"><%- include("../svg/play.svg") %></button>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>{{ data.attributes.name }}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="more-btn-round" @click="artistMenu">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="artist-more" @click="artistMenu">
|
||||
<div style=" margin-top: -1px;
|
||||
margin-left: -5px;
|
||||
width: 36px;
|
||||
height: 36px;">
|
||||
<%- include("../svg/more.svg") %>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="artist-body">
|
||||
<div class="row well">
|
||||
|
@ -115,6 +132,10 @@
|
|||
<h3>{{ data.attributes.isGroup ? "Formed" : "Born" }}</h3>
|
||||
{{ data.attributes.bornOrFormed }}
|
||||
</div>
|
||||
<div v-if="data.attributes.genreNames">
|
||||
<h3>Genre</h3>
|
||||
{{ data.attributes.genreNames.join(', ') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -129,10 +150,14 @@
|
|||
data: function () {
|
||||
return {
|
||||
topSongsExpanded: false,
|
||||
app: this.$root
|
||||
app: this.$root,
|
||||
headerVisible: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isHeaderVisible(visible) {
|
||||
this.headerVisible = visible
|
||||
},
|
||||
artistMenu (event) {
|
||||
let self = this
|
||||
let followAction = "follow"
|
||||
|
|
|
@ -7,81 +7,118 @@
|
|||
</div>
|
||||
</template>
|
||||
<template v-if="app.playlists.loadingState == 1">
|
||||
<div class="playlist-display row"
|
||||
<div class="playlist-display"
|
||||
:style="{
|
||||
background: (data.attributes.artwork != null && data.attributes.artwork['bgColor'] != null) ? ('#' + data.attributes.artwork.bgColor) : '',
|
||||
color: (data.attributes.artwork != null && data.attributes.artwork['textColor1'] != null) ? ('#' + data.attributes.artwork.textColor1) : ''
|
||||
'--bgColor': (data.attributes.artwork != null && data.attributes.artwork['bgColor'] != null) ? ('#' + data.attributes.artwork.bgColor) : '',
|
||||
'--textColor': (data.attributes.artwork != null && data.attributes.artwork['textColor1'] != null) ? ('#' + data.attributes.artwork.textColor1) : ''
|
||||
}">
|
||||
<div class="col-auto flex-center">
|
||||
<div style="width: 260px;height:260px;">
|
||||
<mediaitem-artwork
|
||||
:video-priority="true"
|
||||
:url="(data.attributes != null && data.attributes.artwork != null) ? data.attributes.artwork.url : ((data.relationships != null && data.relationships.tracks.data.length > 0 && data.relationships.tracks.data[0].attributes != null) ? ((data.relationships.tracks.data[0].attributes.artwork != null)? data.relationships.tracks.data[0].attributes.artwork.url : ''):'')"
|
||||
:video="(data.attributes != null && data.attributes.editorialVideo != null) ? (data.attributes.editorialVideo.motionDetailSquare ? data.attributes.editorialVideo.motionDetailSquare.video : (data.attributes.editorialVideo.motionSquareVideo1x1 ? data.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' "
|
||||
size="260"
|
||||
></mediaitem-artwork>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col playlist-info">
|
||||
<template v-if="!editorialNotesExpanded">
|
||||
<div>
|
||||
<div class="playlist-name" @click="editPlaylistName()" v-show="!nameEditing">
|
||||
{{data.attributes ? (data.attributes.name ??
|
||||
(data.attributes.title ?? '') ?? '') : ''}}
|
||||
<div class="playlistInfo">
|
||||
<div class="row">
|
||||
<div class="col-auto flex-center">
|
||||
<div style="width: 260px;height:260px;">
|
||||
<mediaitem-artwork
|
||||
shadow="large"
|
||||
:video-priority="true"
|
||||
:url="(data.attributes != null && data.attributes.artwork != null) ? data.attributes.artwork.url : ((data.relationships != null && data.relationships.tracks.data.length > 0 && data.relationships.tracks.data[0].attributes != null) ? ((data.relationships.tracks.data[0].attributes.artwork != null)? data.relationships.tracks.data[0].attributes.artwork.url : ''):'')"
|
||||
:video="(data.attributes != null && data.attributes.editorialVideo != null) ? (data.attributes.editorialVideo.motionDetailSquare ? data.attributes.editorialVideo.motionDetailSquare.video : (data.attributes.editorialVideo.motionSquareVideo1x1 ? data.attributes.editorialVideo.motionSquareVideo1x1.video : '')) : '' "
|
||||
size="260"
|
||||
></mediaitem-artwork>
|
||||
</div>
|
||||
<div class="playlist-name" v-show="nameEditing"><input type="text" spellcheck="false"
|
||||
class="nameEdit"
|
||||
v-model="data.attributes.name"
|
||||
@blur="editPlaylist"
|
||||
@change="editPlaylist"
|
||||
@keydown.enter="editPlaylist"/></div>
|
||||
<div class="playlist-artist item-navigate"
|
||||
v-if="getArtistName(data) != ''"
|
||||
@click="data.attributes && data.attributes.artistName ? app.searchAndNavigate(data,'artist') : ''">
|
||||
{{getArtistName(data)}}
|
||||
</div>
|
||||
<div class="playlist-desc" v-if="data.attributes.description && (data.attributes.description.standard || data.attributes.description.short)">
|
||||
<div v-if="data.attributes.description.short" class="content" v-html="data.attributes.description.short"></div>
|
||||
<div v-else-if="data.attributes.description.standard" class="content" v-html="data.attributes.description.standard"></div>
|
||||
<button v-if="data.attributes.description.short" class="more-btn"
|
||||
@click="editorialNotesExpanded = !editorialNotesExpanded">
|
||||
More
|
||||
</div>
|
||||
<div class="col playlist-info">
|
||||
<template v-if="!editorialNotesExpanded">
|
||||
<div>
|
||||
<div class="playlist-name" @click="editPlaylistName()" v-show="!nameEditing">
|
||||
{{data.attributes ? (data.attributes.name ??
|
||||
(data.attributes.title ?? '') ?? '') : ''}}
|
||||
</div>
|
||||
<div class="playlist-name" v-show="nameEditing"><input type="text" spellcheck="false"
|
||||
class="nameEdit"
|
||||
v-model="data.attributes.name"
|
||||
@blur="editPlaylist"
|
||||
@change="editPlaylist"
|
||||
@keydown.enter="editPlaylist"/></div>
|
||||
<div class="playlist-artist item-navigate"
|
||||
v-if="getArtistName(data) != ''"
|
||||
@click="data.attributes && data.attributes.artistName ? app.searchAndNavigate(data,'artist') : ''">
|
||||
{{getArtistName(data)}}
|
||||
</div>
|
||||
<div class="playlist-desc" v-if="data.attributes.description && (data.attributes.description.standard || data.attributes.description.short)">
|
||||
<div v-if="data.attributes.description.short" class="content" v-html="data.attributes.description.short"></div>
|
||||
<div v-else-if="data.attributes.description.standard" class="content" v-html="data.attributes.description.standard"></div>
|
||||
<button v-if="data.attributes.description.short" 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" v-observe-visibility="{callback: isHeaderVisible}">
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 0; play()">
|
||||
Play
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 1;play()">
|
||||
Shuffle
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="inLibrary!=null && confirm!=true"
|
||||
@click="confirmButton()">
|
||||
{{ (!inLibrary) ? "Add to Library" : "Remove from Library" }}
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="confirm==true"
|
||||
@click="(!inLibrary) ? addToLibrary(data.attributes.playParams.id.toString()) : removeFromLibrary(data.attributes.playParams.id.toString()) ">
|
||||
Confirm?
|
||||
</button>
|
||||
<button class="more-btn-round" style="float:right;" @click="menu">
|
||||
<div class="svg-icon"></div>
|
||||
</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
|
||||
</div>
|
||||
</div>
|
||||
<div class="artworkContainer" v-if="data.attributes.artwork != null">
|
||||
<artwork-material :url="data.attributes.artwork.url" size="260" images="1"></artwork-material>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="floating-header" :style="{opacity: (headerVisible ? 0 : 1),'pointer-events': (headerVisible ? 'none' : '')}">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{data.attributes ? (data.attributes.name ??
|
||||
(data.attributes.title ?? '') ?? '') : ''}}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<div>
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 0; play()">
|
||||
Play
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 1;play()">
|
||||
Shuffle
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="inLibrary!=null && confirm!=true"
|
||||
@click="confirmButton()">
|
||||
{{ (!inLibrary) ? "Add to Library" : "Remove from Library" }}
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="confirm==true"
|
||||
@click="(!inLibrary) ? addToLibrary(data.attributes.playParams.id.toString()) : removeFromLibrary(data.attributes.playParams.id.toString()) ">
|
||||
Confirm?
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="playlist-controls">
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 0; play()">
|
||||
Play
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;"
|
||||
@click="app.mk.shuffleMode = 1;play()">
|
||||
Shuffle
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="inLibrary!=null && confirm!=true"
|
||||
@click="confirmButton()">
|
||||
{{ (!inLibrary) ? "Add to Library" : "Remove from Library" }}
|
||||
</button>
|
||||
<button class="md-btn" style="min-width: 120px;" v-if="confirm==true"
|
||||
@click="(!inLibrary) ? addToLibrary(data.attributes.playParams.id.toString()) : removeFromLibrary(data.attributes.playParams.id.toString()) ">
|
||||
Confirm?
|
||||
</button>
|
||||
<button class="playlist-more" @click="menu">
|
||||
<div style=" margin-top: -1px;
|
||||
margin-left: -5px;
|
||||
width: 36px;
|
||||
height: 36px;">
|
||||
<%- include("../svg/more.svg") %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<button class="more-btn-round" style="float:right;" @click="menu">
|
||||
<div class="svg-icon"></div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -118,6 +155,20 @@
|
|||
style="width: 50%;">
|
||||
{{data.attributes.copyright}}
|
||||
</div>
|
||||
<hr>
|
||||
<template v-if="typeof data.meta != 'undefined'">
|
||||
<div v-for="view in data.meta.views.order" v-if="data.views[view].data.length != 0">
|
||||
<div class="row" >
|
||||
<div class="col">
|
||||
<h3>{{ data.views[view].attributes.title }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<mediaitem-scroller-horizontal :items="data.views[view].data"></mediaitem-scroller-horizontal>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
@ -138,7 +189,8 @@
|
|||
confirm: false,
|
||||
app: this.$root,
|
||||
itemBadges: [],
|
||||
badgesRequested: false
|
||||
badgesRequested: false,
|
||||
headerVisible: true
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
|
@ -153,6 +205,9 @@
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
isHeaderVisible(visible) {
|
||||
this.headerVisible = visible
|
||||
},
|
||||
getBadges() {
|
||||
return
|
||||
if (this.badgesRequested) {
|
||||
|
|
|
@ -14,13 +14,16 @@
|
|||
<mediaitem-square v-else :item="item" :type="getKind(item)"></mediaitem-square>
|
||||
</template>
|
||||
</template>
|
||||
<button v-if="triggerEnabled" style="opacity:0;height: 32px;" v-observe-visibility="{callback: visibilityChanged}">Show More</button>
|
||||
<button v-if="triggerEnabled" style="opacity:0;height: 32px;"
|
||||
v-observe-visibility="{callback: visibilityChanged}">Show More
|
||||
</button>
|
||||
</div>
|
||||
<transition name="fabfade">
|
||||
<button class="top-fab" v-show="showFab" @click="scrollToTop()">
|
||||
<%- include("../svg/arrow-up.svg") %>
|
||||
</button>
|
||||
</transition>
|
||||
<div class="well" v-show="loading"><div class="spinner"></div></div>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
|
@ -47,16 +50,17 @@
|
|||
canSeeTrigger: false,
|
||||
showFab: false,
|
||||
commonKind: "song",
|
||||
api: this.$root.mk.api
|
||||
api: this.$root.mk.api,
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getKind(item) {
|
||||
if(typeof item.kind != "undefined") {
|
||||
if (typeof item.kind != "undefined") {
|
||||
this.commonKind = item.kind;
|
||||
return item.kind
|
||||
}
|
||||
if(typeof item.attributes.playParams != "undefined") {
|
||||
if (typeof item.attributes.playParams != "undefined") {
|
||||
this.commonKind = item.attributes.playParams.kind
|
||||
return item.attributes.playParams.kind
|
||||
}
|
||||
|
@ -71,73 +75,48 @@
|
|||
})
|
||||
},
|
||||
getNext() {
|
||||
// if this.data.next is not null, then we can run this.data.next() and concat to this.data.data to get the next page
|
||||
switch(this.type) {
|
||||
default:
|
||||
case "artists":
|
||||
if (this.data.next && this.triggerEnabled) {
|
||||
this.triggerEnabled = false;
|
||||
|
||||
let nextFn = (data => {
|
||||
console.log(data);
|
||||
this.data.next = data.next;
|
||||
this.data.data = this.data.data.concat(data.data);
|
||||
this.triggerEnabled = true;
|
||||
});
|
||||
if(typeof this.data.next == "function") {
|
||||
this.data.next().then(data => nextFn(data));
|
||||
}else{
|
||||
this.api.v3.music(this.data.next).then(data => nextFn(data));
|
||||
}
|
||||
}else{
|
||||
console.log("No next page");
|
||||
this.triggerEnabled = false;
|
||||
}
|
||||
break;
|
||||
case "search":
|
||||
if (this.data.next && this.triggerEnabled) {
|
||||
this.triggerEnabled = false;
|
||||
this.data.next().then(data => {
|
||||
console.log(data);
|
||||
this.data.next = data[this.data.groups].next;
|
||||
this.data.data = this.data.data.concat(data[this.data.groups].data.data);
|
||||
this.triggerEnabled = true;
|
||||
});
|
||||
}else{
|
||||
console.log("No next page");
|
||||
this.triggerEnabled = false;
|
||||
}
|
||||
break;
|
||||
case "listen_now":
|
||||
case "curator":
|
||||
if (this.data.next && this.triggerEnabled) {
|
||||
this.triggerEnabled = false;
|
||||
app.mk.api.v3.music(this.data.next).then(data => {
|
||||
console.log(data);
|
||||
this.data.next = data.data.next;
|
||||
this.data.data = this.data.data.concat(data.data.data);
|
||||
this.triggerEnabled = true;
|
||||
});
|
||||
}else{
|
||||
console.log("No next page");
|
||||
this.triggerEnabled = false;
|
||||
}
|
||||
break;
|
||||
let self = this
|
||||
this.triggerEnabled = false;
|
||||
if (typeof this.data.next == "undefined") {
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
|
||||
this.api.v3.music(this.data.next, app.collectionList.requestBody).then((response) => {
|
||||
console.log(response)
|
||||
if (!app.collectionList.response.groups) {
|
||||
if (response.data.next) {
|
||||
this.data.data = this.data.data.concat(response.data.data);
|
||||
this.data.next = response.data.next;
|
||||
this.triggerEnabled = true;
|
||||
}
|
||||
this.loading = false
|
||||
}else{
|
||||
if(!response.data.results[app.collectionList.response.groups]) {
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
if (response.data.results[app.collectionList.response.groups].next) {
|
||||
this.data.data = this.data.data.concat(response.data.results[app.collectionList.response.groups].data);
|
||||
this.data.next = response.data.results[app.collectionList.response.groups].next;
|
||||
this.triggerEnabled = true;
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
headerVisibility: function (isVisible, entry) {
|
||||
if(isVisible) {
|
||||
if (isVisible) {
|
||||
this.showFab = false;
|
||||
}else{
|
||||
} else {
|
||||
this.showFab = true;
|
||||
}
|
||||
},
|
||||
visibilityChanged: function (isVisible, entry) {
|
||||
if(isVisible) {
|
||||
if (isVisible) {
|
||||
this.canSeeTrigger = true;
|
||||
this.getNext();
|
||||
}else{
|
||||
} else {
|
||||
this.canSeeTrigger = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
async getArtistFeed() {
|
||||
let artists = this.followedArtists
|
||||
let self = this
|
||||
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=featured-release,full-albums,appears-on-albums,featured-albums,featured-on-albums,singles,compilation-albums,live-albums,latest-release,top-music-videos,similar-artists,top-songs,playlists,more-to-hear,more-to-see&extend=artistBio,bornOrFormed,editorialArtwork,editorialVideo,isGroup,origin,hero&extend[playlists]=trackCount&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=20&art[url]=f`).then(artistData => {
|
||||
this.app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/artists?ids=${artists.toString()}&views=latest-release&include[songs]=albums&fields[albums]=artistName,artistUrl,artwork,contentRating,editorialArtwork,editorialVideo,name,playParams,releaseDate,url,trackCount&limit[artists:top-songs]=2&art[url]=f`).then(artistData => {
|
||||
artistData.data.data.forEach(item => {
|
||||
if (item.views["latest-release"].data.length != 0) {
|
||||
self.artistFeed.push(item.views["latest-release"].data[0])
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
<mediaitem-square :item="getTopResult()"></mediaitem-square>
|
||||
</template>
|
||||
</div>
|
||||
<div v-else style="text-align: center">
|
||||
<h3>No Results</h3>
|
||||
<p>Try a new search.</p>
|
||||
</div>
|
||||
<div class="col" v-if="search.results.song">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
@ -108,10 +112,10 @@
|
|||
},
|
||||
methods: {
|
||||
getTopResult() {
|
||||
if (this.search.results["meta"]) {
|
||||
try {
|
||||
return this.search.results[this.search.results.meta.results.order[0]]["data"][0]
|
||||
} else {
|
||||
return false;
|
||||
} catch( error ) {
|
||||
return false
|
||||
}
|
||||
},
|
||||
async getCategories() {
|
||||
|
|
|
@ -5,5 +5,8 @@
|
|||
{{ $store.state.test }}
|
||||
<div class="spinner"></div>
|
||||
<button class="md-btn">Cider Button</button>
|
||||
<div style="position: relative;width: 300px;height: 300px;">
|
||||
<artwork-material url="https://is3-ssl.mzstatic.com/image/thumb/Music126/v4/13/41/13/1341133b-560f-1aee-461f-c4b32ec049b4/cover.jpg/{w}x{h}bb.jpg"></artwork-material>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue