Merge branch 'main' of https://github.com/ciderapp/Cider
This commit is contained in:
commit
a04cbccc05
9 changed files with 319 additions and 50 deletions
|
@ -114,6 +114,7 @@ const app = new Vue({
|
|||
hints: [],
|
||||
showHints: false,
|
||||
results: {},
|
||||
resultsSocial: {},
|
||||
limit: 10
|
||||
},
|
||||
playerLCD: {
|
||||
|
@ -2167,6 +2168,15 @@ const app = new Vue({
|
|||
}).then(function (results) {
|
||||
self.search.results = results
|
||||
})
|
||||
await this.mk.api.socialSearch(this.search.term, {
|
||||
types: ["playlists", "social-profiles"],
|
||||
limit: 25,
|
||||
with: ["serverBubbles", "lyricSnippet"],
|
||||
"art[url]": "f",
|
||||
"art[social-profiles:url]": "c"
|
||||
}, { includeResponseMeta: !0 }).then(function (results) {
|
||||
self.search.resultsSocial = results
|
||||
})
|
||||
},
|
||||
isInLibrary(playParams) {
|
||||
let self = this
|
||||
|
|
|
@ -1539,6 +1539,26 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.home-page {
|
||||
background: linear-gradient(0deg, black, #4c2c31);
|
||||
top: 0;
|
||||
padding-top: var(--navbarHeight);
|
||||
|
||||
.user-icon {
|
||||
border-radius: 100%;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
overflow: hidden;
|
||||
box-shadow: var(--mediaItemShadow-Shadow);
|
||||
}
|
||||
|
||||
.well.profile-well {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cider */
|
||||
|
||||
.modal-fullscreen {
|
||||
|
@ -1552,6 +1572,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
z-index: 9999;
|
||||
|
||||
.modal-window {
|
||||
background: #333;
|
||||
border-radius: 10px;
|
||||
|
@ -1581,15 +1602,15 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
width: 100%;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow-y: overlay;
|
||||
}
|
||||
.modal-footer {
|
||||
|
||||
}
|
||||
.modal-footer {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1608,6 +1629,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
.modal-title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
|
@ -1659,9 +1681,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.name {
|
||||
|
||||
}
|
||||
.name {}
|
||||
|
||||
&:hover {
|
||||
background: var(--selected);
|
||||
|
@ -2180,6 +2200,20 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
height: 100%;
|
||||
object-fit: cover;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.no-shadow {
|
||||
box-shadow: none;
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.subtle-shadow {
|
||||
box-shadow: var(--mediaItemShadow-ShadowSubtle);
|
||||
}
|
||||
&.shadow {
|
||||
box-shadow: var(--mediaItemShadow-Shadow);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2272,6 +2306,11 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
&:hover::-webkit-scrollbar-thumb {
|
||||
box-shadow: inset 0px 0px 10px 10px rgb(200 200 200 / 50%);
|
||||
}
|
||||
|
||||
&.small {
|
||||
overflow-x: overlay;
|
||||
height: 210px;
|
||||
}
|
||||
}
|
||||
|
||||
/* mediaitem-list-item */
|
||||
|
@ -2755,6 +2794,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
>.play-btn,
|
||||
>.menu-btn {
|
||||
opacity: 1;
|
||||
|
@ -2777,6 +2817,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
&.mediaitem-video {
|
||||
height: 200px;
|
||||
width: 240px;
|
||||
|
||||
.artwork {
|
||||
height: 120px;
|
||||
width: 212px;
|
||||
|
@ -2786,11 +2827,22 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
&.mediaitem-brick {
|
||||
height: 200px;
|
||||
width: 240px;
|
||||
|
||||
.artwork {
|
||||
height: 123px;
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
&.mediaitem-small {
|
||||
width: 140px;
|
||||
height: 180px;
|
||||
|
||||
.artwork {
|
||||
height: 128px;
|
||||
width: 128px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* mediaitem-square */
|
||||
|
@ -2855,6 +2907,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
}
|
||||
|
||||
&:hover {
|
||||
|
||||
>.play-btn,
|
||||
>.menu-btn {
|
||||
opacity: 1;
|
||||
|
@ -2877,6 +2930,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
&.mediaitem-video {
|
||||
height: calc(var(--frame) / 220 * 200);
|
||||
width: calc(var(--frame) / 220 * 240);
|
||||
|
||||
.artwork {
|
||||
height: calc(var(--frame) / 220 * 120);
|
||||
width: calc(var(--frame) / 220 * 212);
|
||||
|
@ -2886,6 +2940,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
&.mediaitem-brick {
|
||||
height: calc(var(--frame) / 220 * 200);
|
||||
width: calc(var(--frame) / 220 * 240);
|
||||
|
||||
.artwork {
|
||||
height: calc(var(--frame) / 220 * 123);
|
||||
width: calc(var(--frame));
|
||||
|
@ -2959,6 +3014,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
border-radius: 0px;
|
||||
box-shadow: unset;
|
||||
background: black;
|
||||
|
||||
.lyric-body {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -2982,6 +3038,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modular
|
||||
|
||||
/* Transitions */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script type="text/x-template" id="mediaitem-artwork">
|
||||
<div class="mediaitem-artwork" :class="{'rounded': (type == 'artists')}" :key="url" :style="getStyle()"
|
||||
<div class="mediaitem-artwork" :class="[{'rounded': (type == 'artists')}, classes]"
|
||||
v-observe-visibility="{callback: visibilityChanged}">
|
||||
<img :src="app.getMediaItemArtwork(url, size, width)"
|
||||
decoding="async" loading="lazy"
|
||||
|
@ -40,7 +40,7 @@
|
|||
},
|
||||
shadow: {
|
||||
type: String,
|
||||
default: 'none'
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -49,8 +49,12 @@
|
|||
isVisible: false,
|
||||
style: {
|
||||
"box-shadow": ""
|
||||
},
|
||||
classes: []
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getClasses()
|
||||
},
|
||||
methods: {
|
||||
getVideoPriority() {
|
||||
|
@ -63,18 +67,21 @@
|
|||
}
|
||||
return this.videoPriority
|
||||
},
|
||||
getStyle() {
|
||||
getClasses() {
|
||||
switch (this.shadow) {
|
||||
case "none":
|
||||
this.classes.push("no-shadow")
|
||||
break;
|
||||
case "large":
|
||||
this.style["box-shadow"] = "var(--mediaItemShadow-Shadow)"
|
||||
this.classes.push("shadow")
|
||||
break;
|
||||
case "subtle":
|
||||
this.style["box-shadow"] = "var(--mediaItemShadow-ShadowSubtle)"
|
||||
this.classes.push("subtle-shadow")
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return this.style;
|
||||
return this.classes;
|
||||
},
|
||||
getArtworkStyle() {
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script type="text/x-template" id="mediaitem-scroller-horizontal">
|
||||
<template>
|
||||
<div class="cd-hmedia-scroller">
|
||||
<mediaitem-square :item="item"
|
||||
<div class="cd-hmedia-scroller" :class="kind">
|
||||
<mediaitem-square :kind="kind" :item="item"
|
||||
v-for="item in items"></mediaitem-square>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -10,7 +10,17 @@
|
|||
<script>
|
||||
Vue.component('mediaitem-scroller-horizontal', {
|
||||
template: '#mediaitem-scroller-horizontal',
|
||||
props: ['items'],
|
||||
props: {
|
||||
'items': {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
'kind': {
|
||||
type: String,
|
||||
required: false,
|
||||
defualt: ""
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
|
|
|
@ -107,6 +107,9 @@
|
|||
case "385": // editorial
|
||||
return ["mediaitem-brick"]
|
||||
break;
|
||||
case "small":
|
||||
return ["mediaitem-small"]
|
||||
break;
|
||||
case "music-videos":
|
||||
case "uploadedVideo":
|
||||
case "uploaded-videos":
|
||||
|
|
|
@ -168,6 +168,7 @@
|
|||
<div class="app-sidebar-header-text">
|
||||
Apple Music
|
||||
</div>
|
||||
<sidebar-library-item v-if="isDev" name="Home" page="home"></sidebar-library-item>
|
||||
<sidebar-library-item name="Listen Now" page="listen_now"></sidebar-library-item>
|
||||
<sidebar-library-item name="Browse" page="browse"></sidebar-library-item>
|
||||
<sidebar-library-item name="Radio" page="radio"></sidebar-library-item>
|
||||
|
@ -295,6 +296,12 @@
|
|||
:title="collectionList.title"></cider-collection-list>
|
||||
</template>
|
||||
</transition>
|
||||
<!-- Home -->
|
||||
<transition name="wpfade">
|
||||
<template v-if="page == 'home'">
|
||||
<cider-home></cider-home>
|
||||
</template>
|
||||
</transition>
|
||||
<!-- Playlist / Album page-->
|
||||
<transition name="wpfade">
|
||||
<template v-if="page.includes('playlist_')">
|
||||
|
@ -502,6 +509,9 @@
|
|||
<!-- Listen Now -->
|
||||
<%- include('pages/listen_now') %>
|
||||
|
||||
<!-- Home -->
|
||||
<%- include('pages/home') %>
|
||||
|
||||
<!-- Playlists / Albums -->
|
||||
<%- include('pages/cider-playlist') %>
|
||||
|
||||
|
|
|
@ -46,7 +46,8 @@
|
|||
triggerEnabled: true,
|
||||
canSeeTrigger: false,
|
||||
showFab: false,
|
||||
commonKind: "song"
|
||||
commonKind: "song",
|
||||
api: this.$root.mk.api
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -72,12 +73,18 @@
|
|||
case "artists":
|
||||
if (this.data.next && this.triggerEnabled) {
|
||||
this.triggerEnabled = false;
|
||||
this.data.next().then(data => {
|
||||
|
||||
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 => next);
|
||||
}else{
|
||||
this.api.v3.music(this.data.next).then(data => nextFn);
|
||||
}
|
||||
}else{
|
||||
console.log("No next page");
|
||||
this.triggerEnabled = false;
|
||||
|
|
132
src/renderer/views/pages/home.ejs
Normal file
132
src/renderer/views/pages/home.ejs
Normal file
|
@ -0,0 +1,132 @@
|
|||
<script type="text/x-template" id="cider-home">
|
||||
<div class="content-inner home-page">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Home</h3>
|
||||
<div class="well profile-well">
|
||||
<div class="user-icon">
|
||||
<mediaitem-artwork shadow="none" :url="profile.attributes.artwork.url" size="300"></mediaitem-artwork>
|
||||
</div>
|
||||
<h3>{{ profile.attributes.name }}</h3>
|
||||
<h4>@{{ profile.attributes.handle }}</h4>
|
||||
<button class="md-btn">Share</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Recently Played</h3>
|
||||
<div class="well">
|
||||
<mediaitem-list-item v-for="item in recentlyPlayed.limit(6)" :item="item"></mediaitem-list-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Your Favorites</h3>
|
||||
<div class="well">
|
||||
<mediaitem-scroller-horizontal kind="small" :items="friendsListeningTo" :item="item"></mediaitem-scroller-horizontal>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Made For You</h3>
|
||||
<div class="well">
|
||||
<mediaitem-square kind="small" v-for="item in madeForYou" :item="item"></mediaitem-square>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h3>Your Artist Feed</h3>
|
||||
<div class="well">
|
||||
<mediaitem-list-item v-for="item in recentlyPlayed.limit(6)" :item="item"></mediaitem-list-item>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Friends Listening To</h3>
|
||||
<div class="well">
|
||||
<mediaitem-square kind="small" v-for="item in friendsListeningTo" :item="item"></mediaitem-square>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script>
|
||||
Vue.component('cider-home', {
|
||||
template: '#cider-home',
|
||||
data: function () {
|
||||
return {
|
||||
app: this.$root,
|
||||
madeForYou: [],
|
||||
recentlyPlayed: [],
|
||||
friendsListeningTo: [],
|
||||
profile: {},
|
||||
modify: 0
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
let self = this
|
||||
this.getListenNowData()
|
||||
},
|
||||
methods: {
|
||||
getRecentlyPlayed() {
|
||||
|
||||
},
|
||||
async getListenNowData() {
|
||||
let self = this
|
||||
this.app.mk.api.personalRecommendations("",
|
||||
{
|
||||
name: "listen-now",
|
||||
with: "friendsMix,library,social",
|
||||
"art[social-profiles:url]": "c",
|
||||
"art[url]": "c,f",
|
||||
"omit[resource]": "autos",
|
||||
"relate[editorial-items]": "contents",
|
||||
extend: ["editorialCard", "editorialVideo"],
|
||||
"extend[albums]": ["artistUrl"],
|
||||
"extend[library-albums]": ["artistUrl", "editorialVideo"],
|
||||
"extend[playlists]": ["artistNames", "editorialArtwork", "editorialVideo"],
|
||||
"extend[library-playlists]": ["artistNames", "editorialArtwork", "editorialVideo"],
|
||||
"extend[social-profiles]": "topGenreNames",
|
||||
"include[albums]": "artists",
|
||||
"include[songs]": "artists",
|
||||
"include[music-videos]": "artists",
|
||||
"fields[albums]": ["artistName", "artistUrl", "artwork", "contentRating", "editorialArtwork", "editorialVideo", "name", "playParams", "releaseDate", "url"],
|
||||
"fields[artists]": ["name", "url"],
|
||||
"extend[stations]": ["airDate", "supportsAirTimeUpdates"],
|
||||
"meta[stations]": "inflectionPoints",
|
||||
types: "artists,albums,editorial-items,library-albums,library-playlists,music-movies,music-videos,playlists,stations,uploaded-audios,uploaded-videos,activities,apple-curators,curators,tv-shows,social-profiles,social-upsells",
|
||||
platform: "web"
|
||||
},
|
||||
{
|
||||
includeResponseMeta: !0,
|
||||
reload: !0
|
||||
}
|
||||
).then((data) => {
|
||||
console.log(data.data[1])
|
||||
self.recentlyPlayed = data.data[1].relationships.contents.data
|
||||
self.friendsListeningTo = data.data.filter(section => {
|
||||
if (section.meta.metrics.moduleType == "11") {
|
||||
return section
|
||||
}
|
||||
;
|
||||
})[0].relationships.contents.data
|
||||
self.madeForYou = data.data.filter(section => {
|
||||
if (section.meta.metrics.moduleType == "6") {
|
||||
return section
|
||||
}
|
||||
;
|
||||
})[0].relationships.contents.data
|
||||
});
|
||||
|
||||
app.mk.api.v3.music("/v1/me/social/profile/").then((response) => {
|
||||
self.profile = response.data.data[0]
|
||||
console.log("!!!")
|
||||
console.log(response.data.data[0])
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -12,7 +12,9 @@
|
|||
<div class="col">
|
||||
<h3>Songs</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" @click="app.showSearchView(app.search.term, 'song', app.friendlyTypes('song'))" v-if="search.results.song.data.length >= 6">
|
||||
<div class="col-auto flex-center"
|
||||
@click="app.showSearchView(app.search.term, 'song', app.friendlyTypes('song'))"
|
||||
v-if="search.results.song.data.length >= 6">
|
||||
<button class="cd-btn-seeall">See All</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -31,7 +33,10 @@
|
|||
<h3>{{ app.friendlyTypes(section) }}</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.results[section].data.length >= 10">
|
||||
<button class="cd-btn-seeall" @click="app.showSearchView(app.search.term, section, app.friendlyTypes(section))">See All</button>
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showSearchView(app.search.term, section, app.friendlyTypes(section))">See
|
||||
All
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="!app.friendlyTypes(section).includes('Video')">
|
||||
|
@ -44,6 +49,34 @@
|
|||
</template>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.playlist">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>Shared Playlists</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.playlist.data.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showCollection(search.resultsSocial.playlist.data, 'Shared Playlists', 'default')">See All
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.playlist.data.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
<template v-if="search.resultsSocial.profile">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>People</h3>
|
||||
</div>
|
||||
<div class="col-auto flex-center" v-if="search.resultsSocial.profile.data.data.length >= 10">
|
||||
<button class="cd-btn-seeall"
|
||||
@click="app.showCollection(search.resultsSocial.profile.data, 'People', 'default')">See All
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<mediaitem-scroller-horizontal-large
|
||||
:items="search.resultsSocial.profile.data.data.limit(10)"></mediaitem-scroller-horizontal-large>
|
||||
</template>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue