Merge branch 'innolab' of https://github.com/ciderapp/Cider into innolab
This commit is contained in:
commit
ecfdeece64
22 changed files with 566 additions and 128 deletions
|
@ -49,9 +49,21 @@
|
|||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<div class="row" v-if="!seenReplay">
|
||||
<div class="col">
|
||||
<button class="md-btn md-btn-block md-btn-replay--hero" @click="$root.appRoute('replay')">Replay {{ year }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h3>{{app.getLz('home.madeForYou')}}</h3>
|
||||
<div class="row">
|
||||
<div class="col nopadding">
|
||||
<h3>{{app.getLz('home.madeForYou')}}</h3>
|
||||
</div>
|
||||
<div class="col-auto nopadding flex-center">
|
||||
<button class="md-btn md-btn-replay" v-if="seenReplay" @click="$root.appRoute('replay')">Replay {{ year }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="well">
|
||||
<mediaitem-scroller-horizontal :items="madeForYou" v-if="isSectionReady('madeForYou')">
|
||||
</mediaitem-scroller-horizontal>
|
||||
|
@ -98,7 +110,9 @@
|
|||
artistFeed: [],
|
||||
showingArtistFeed: false,
|
||||
page: "main",
|
||||
sectionsReady: []
|
||||
sectionsReady: [],
|
||||
year: new Date().getFullYear(),
|
||||
seenReplay: localStorage.getItem('seenReplay')
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
|
@ -106,6 +120,10 @@
|
|||
this.getListenNowData()
|
||||
await this.getArtistFeed()
|
||||
await this.getFavorites()
|
||||
if (new Date().getMonth() == 11) {
|
||||
this.seenReplay = false
|
||||
localStorage.setItem('seenReplay', false)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async seeAllHistory() {
|
||||
|
|
|
@ -15,8 +15,16 @@
|
|||
v-model="library.songs.search" class="search-input">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto flex-center">
|
||||
<div class="col-auto flex-center">
|
||||
<div class="row">
|
||||
<button class="col md-btn md-btn-primary md-btn-icon" style="min-width: 100px;margin-right: 3px;"
|
||||
@click="app.mk.shuffleMode = 0; play()"> <img class="md-ico-play">
|
||||
{{app.getLz('term.play')}}
|
||||
</button>
|
||||
<button class="col md-btn md-btn-primary md-btn-icon" style="min-width: 100px;margin-right: 3px;"
|
||||
@click="app.mk.shuffleMode = 1;play()"> <img class="md-ico-shuffle">
|
||||
{{app.getLz('term.shuffle')}}
|
||||
</button>
|
||||
<div class="col">
|
||||
<select class="md-select" v-model="prefs.sort" @change="$root.searchLibrarySongs()">
|
||||
<optgroup :label="app.getLz('term.sortBy')">
|
||||
|
@ -75,6 +83,28 @@
|
|||
methods: {
|
||||
sayHello: function () {
|
||||
alert('Hello world!');
|
||||
},
|
||||
play: function () {
|
||||
|
||||
function shuffleArray(array) {
|
||||
for (var i = array.length - 1; i > 0; i--) {
|
||||
var j = Math.floor(Math.random() * (i + 1));
|
||||
var temp = array[i];
|
||||
array[i] = array[j];
|
||||
array[j] = temp;
|
||||
}
|
||||
}
|
||||
|
||||
let query = this.app.library.songs.displayListing.map(item => new MusicKit.MediaItem(item));
|
||||
if (!app.mk.queue.isEmpty)
|
||||
app.mk.queue.splice(0, app.mk.queue._itemIDs.length);
|
||||
app.mk.stop().then(() => {
|
||||
if (app.mk.shuffleMode == 1) {
|
||||
shuffleArray(query)
|
||||
}
|
||||
app.mk.queue.append(query)
|
||||
app.mk.changeToMediaAtIndex(0)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
144
src/renderer/views/pages/replay.ejs
Normal file
144
src/renderer/views/pages/replay.ejs
Normal file
|
@ -0,0 +1,144 @@
|
|||
<script type="text/x-template" id="replay-page">
|
||||
<div class="content-inner replay-page">
|
||||
<vue-horizontal style="height: 300px;">
|
||||
<div class="replay-period" v-for="year in years" @click="getReplayYear(year.attributes.year)">
|
||||
<div class="artwork-container">
|
||||
<mediaitem-artwork :size="200" :url="year.relationships.playlist.data[0].attributes.artwork.url"></mediaitem-artwork>
|
||||
</div>
|
||||
{{ year.attributes.year }}
|
||||
</div>
|
||||
</vue-horizontal>
|
||||
<hr>
|
||||
<transition name="replaycard">
|
||||
<div class="replay-viewport" v-if="loaded.id != -1">
|
||||
<!-- Stats -->
|
||||
<h1 class="replay-header">{{ loaded.attributes.year }} Replay</h1>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<h4>{{ loaded.attributes.listenTimeInMinutes }} minutes</h4>
|
||||
<h4>{{ loaded.attributes.uniqueAlbumCount }} Unique Albums</h4>
|
||||
<h4>{{ loaded.attributes.uniqueArtistCount }} Unique Artists</h4>
|
||||
<h4>{{ loaded.attributes.uniqueSongCount }} Unique Songs</h4>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<mediaitem-square kind="card" :item="loaded.relationships.playlist.data[0]"></mediaitem-square>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Top Artists-->
|
||||
<h3>Top Artists</h3>
|
||||
<div class="well">
|
||||
<mediaitem-scroller-horizontal>
|
||||
<div class="card replay-card" v-for="artistData in loaded.views['top-artists'].data">
|
||||
<div class="card-body">
|
||||
<mediaitem-square :item="artistData.relationships.artist.data[0]"></mediaitem-square>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
{{ artistData.attributes.listenTimeInMinutes }} minutes<br>
|
||||
Listened to: {{ artistData.attributes.playCount }} times
|
||||
</div>
|
||||
</div>
|
||||
</mediaitem-scroller-horizontal>
|
||||
</div>
|
||||
<!-- Top Albums-->
|
||||
<h3>Top Albums</h3>
|
||||
<div class="well">
|
||||
<mediaitem-scroller-horizontal>
|
||||
<div class="card replay-card" v-for="albumData in loaded.views['top-albums'].data">
|
||||
<div class="card-body">
|
||||
<mediaitem-square :item="albumData.relationships.album.data[0]"></mediaitem-square>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
{{ albumData.attributes.listenTimeInMinutes }} minutes<br>
|
||||
{{ albumData.attributes.playCount }} plays
|
||||
</div>
|
||||
</div>
|
||||
</mediaitem-scroller-horizontal>
|
||||
</div>
|
||||
<!-- Top Songs-->
|
||||
<h3>Top Songs</h3>
|
||||
<div class="well">
|
||||
<listitem-horizontal :show-library-status="false" :items="songsToArray(loaded.views['top-songs'].data)"></listitem-horizontal>
|
||||
</div>
|
||||
<h3>Top Genres</h3>
|
||||
<div class="top-genres-container">
|
||||
<div v-for="genre in loaded.topGenres" class="replay-genre-display">
|
||||
<div class="genre-name">
|
||||
{{ genre.genre }}
|
||||
</div>
|
||||
<div class="genre-count">
|
||||
<div class="genre-count-bar" :style="{'width': genre.count + '%'}">
|
||||
{{ genre.count }}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
Vue.component('replay-page', {
|
||||
template: '#replay-page',
|
||||
data: function () {
|
||||
return {
|
||||
years: [],
|
||||
loaded: {
|
||||
id: -1
|
||||
}
|
||||
}
|
||||
},
|
||||
async mounted() {
|
||||
// Get available years
|
||||
let year = await app.mk.api.v3.music("/v1/me/music-summaries/search?extend=inLibrary&period=year&fields[music-summaries]=period%2Cyear&include[music-summaries]=playlist")
|
||||
this.years = year.data.data
|
||||
this.years.reverse()
|
||||
localStorage.setItem("seenReplay", true)
|
||||
this.getReplayYear();
|
||||
},
|
||||
methods: {
|
||||
songsToArray(songsData) {
|
||||
let songs = []
|
||||
let topGenres = {}
|
||||
let genrePlayCount = 0;
|
||||
songsData.forEach(function (songData) {
|
||||
let song = songData.relationships.song.data[0]
|
||||
song.attributes.playCount = songData.attributes.playCount
|
||||
songs.push(song)
|
||||
genrePlayCount += song.attributes.playCount
|
||||
song.attributes.genreNames.forEach(function (genre) {
|
||||
if (genre != "Music") {
|
||||
if (topGenres[genre] == undefined) {
|
||||
topGenres[genre] = song.attributes.playCount
|
||||
} else {
|
||||
topGenres[genre] += song.attributes.playCount
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
let topGenresArray = []
|
||||
for (let genre in topGenres) {
|
||||
topGenresArray.push({
|
||||
genre: genre,
|
||||
count: topGenres[genre]
|
||||
})
|
||||
}
|
||||
topGenresArray.sort(function (a, b) {
|
||||
return b.count - a.count
|
||||
})
|
||||
topGenresArray.forEach(function (genre) {
|
||||
genre.count = Math.round(genre.count / genrePlayCount * 100)
|
||||
})
|
||||
this.loaded.topGenres = topGenresArray
|
||||
|
||||
return songs
|
||||
},
|
||||
async getReplayYear(year = new Date().getFullYear()) {
|
||||
this.loaded.id = -1
|
||||
let response = await app.mk.api.v3.music(`/v1/me/music-summaries/year-${year}?extend=inLibrary&views=top-artists%2Ctop-albums%2Ctop-songs&include[music-summaries]=playlist&include[playlists]=tracks&includeOnly=playlist%2Ctracks%2Csong%2Cartist%2Calbum`)
|
||||
console.warn(response.data.data[0])
|
||||
this.loaded = response.data.data[0]
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
|
@ -645,6 +645,36 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.debug')}}</span>
|
||||
</div>
|
||||
<div class="settings-option-body">
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.debug.copy_log')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" @click="copyLogs">
|
||||
{{$root.getLz('action.copy')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.debug.openAppData')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" @click="openAppData">
|
||||
{{$root.getLz('action.open')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="md-option-header">
|
||||
<span>{{$root.getLz('settings.header.experimental')}}</span>
|
||||
</div>
|
||||
|
@ -691,16 +721,32 @@
|
|||
<input type="checkbox" v-model="app.cfg.general.close_button_hide" switch/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line">
|
||||
<div class="md-option-line update-check">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.experimental.copy_log')}}
|
||||
{{$root.getLz('settings.option.general.updateCider')}}
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<button class="md-btn" @click="copyLogs">
|
||||
{{$root.getLz('action.copy')}}
|
||||
<button class="md-btn" @click="app.checkForUpdate()">
|
||||
{{$root.getLz('term.check')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md-option-line update-check">
|
||||
<div class="md-option-segment">
|
||||
{{$root.getLz('settings.option.general.updateCider.branch')}}<br>
|
||||
<small>({{$root.getLz('settings.option.general.updateCider.branch.description')}})</small>
|
||||
</div>
|
||||
<div class="md-option-segment md-option-segment_auto">
|
||||
<select class="md-select" style="width:180px;" v-model="app.cfg.general.update_branch">
|
||||
<option value="main">
|
||||
{{$root.getLz('settings.option.general.updateCider.branch.main')}}
|
||||
</option>
|
||||
<option value="develop">
|
||||
{{$root.getLz('settings.option.general.updateCider.branch.develop')}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="opacity: 0.5; pointer-events: none">
|
||||
<div class="md-option-header">
|
||||
|
@ -790,6 +836,9 @@
|
|||
ipcRenderer.send('fetch-log')
|
||||
notyf.success(app.getLz('term.share.success'));
|
||||
},
|
||||
openAppData() {
|
||||
ipcRenderer.send('open-appdata')
|
||||
},
|
||||
getLanguages: function () {
|
||||
let langs = this.$root.lzListing
|
||||
let categories = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue