Merge branch 'develop' of https://github.com/Apple-Music-Electron/Cider into develop
This commit is contained in:
commit
5331d8dd57
5 changed files with 150 additions and 8 deletions
|
@ -215,6 +215,8 @@
|
||||||
// Settings - Audio
|
// Settings - Audio
|
||||||
"settings.header.audio": "オーディオ",
|
"settings.header.audio": "オーディオ",
|
||||||
"settings.header.audio.description": "Ciderのオーディオ設定",
|
"settings.header.audio.description": "Ciderのオーディオ設定",
|
||||||
|
"settings.option.audio.volumeStep": "音量調整のステップ",
|
||||||
|
"settings.option.audio.maxVolume": "最大音量",
|
||||||
"settings.option.audio.quality": "音質", // Dropdown
|
"settings.option.audio.quality": "音質", // Dropdown
|
||||||
"settings.header.audio.quality.hireslossless": "ハイレゾロスレス",
|
"settings.header.audio.quality.hireslossless": "ハイレゾロスレス",
|
||||||
"settings.header.audio.quality.hireslossless.description": "(最大解像度 24 ビット/192 kHz)",
|
"settings.header.audio.quality.hireslossless.description": "(最大解像度 24 ビット/192 kHz)",
|
||||||
|
|
|
@ -108,6 +108,7 @@
|
||||||
"term.fullscreenView": "全螢幕顯示",
|
"term.fullscreenView": "全螢幕顯示",
|
||||||
"term.defaultView": "預設顯示",
|
"term.defaultView": "預設顯示",
|
||||||
"term.audioSettings": "音訊設定",
|
"term.audioSettings": "音訊設定",
|
||||||
|
"term.audioControls": "音訊控制",
|
||||||
"term.spacializedAudioSetting": "空間音訊設定",
|
"term.spacializedAudioSetting": "空間音訊設定",
|
||||||
"term.clearAll": "清空",
|
"term.clearAll": "清空",
|
||||||
"term.recentStations": "最近收聽的廣播",
|
"term.recentStations": "最近收聽的廣播",
|
||||||
|
@ -209,6 +210,7 @@
|
||||||
"action.copy": "複製",
|
"action.copy": "複製",
|
||||||
"action.newpreset": "新增預設", // Equalizer Preset
|
"action.newpreset": "新增預設", // Equalizer Preset
|
||||||
"action.deletepreset": "刪除預設", // Equalizer Preset
|
"action.deletepreset": "刪除預設", // Equalizer Preset
|
||||||
|
"action.open": "開啟",
|
||||||
|
|
||||||
// Settings - General
|
// Settings - General
|
||||||
"settings.header.general": "一般",
|
"settings.header.general": "一般",
|
||||||
|
@ -229,6 +231,8 @@
|
||||||
// Settings - Audio
|
// Settings - Audio
|
||||||
"settings.header.audio": "音訊",
|
"settings.header.audio": "音訊",
|
||||||
"settings.header.audio.description": "調整 Cider 的音訊設定",
|
"settings.header.audio.description": "調整 Cider 的音訊設定",
|
||||||
|
"settings.option.audio.volumeStep": "音量改變量",
|
||||||
|
"settings.option.audio.maxVolume": "最大音量",
|
||||||
"settings.option.audio.quality": "音訊品質", // Dropdown
|
"settings.option.audio.quality": "音訊品質", // Dropdown
|
||||||
"settings.header.audio.quality.hireslossless": "高品質無損壓縮",
|
"settings.header.audio.quality.hireslossless": "高品質無損壓縮",
|
||||||
"settings.header.audio.quality.hireslossless.description": "(高達 24-bit/192 kHz)",
|
"settings.header.audio.quality.hireslossless.description": "(高達 24-bit/192 kHz)",
|
||||||
|
@ -312,13 +316,17 @@
|
||||||
"settings.option.connectivity.lastfmScrobble.filterLoop": "不記錄單曲循環 (LastFM)",
|
"settings.option.connectivity.lastfmScrobble.filterLoop": "不記錄單曲循環 (LastFM)",
|
||||||
// Refer to term.connect for the connect button
|
// Refer to term.connect for the connect button
|
||||||
|
|
||||||
|
// Settings - Debug
|
||||||
|
"settings.header.debug": "除錯",
|
||||||
|
"settings.option.debug.copy_log": "複製執行紀錄檔至剪貼簿",
|
||||||
|
"settings.option.debug.openAppData": "打開 Cider 資料夾",
|
||||||
|
|
||||||
// Settings - Experimental
|
// Settings - Experimental
|
||||||
"settings.header.experimental": "實驗性功能",
|
"settings.header.experimental": "實驗性功能",
|
||||||
"settings.header.experimental.description": "調整 Cider 的實驗性功能",
|
"settings.header.experimental.description": "調整 Cider 的實驗性功能",
|
||||||
"settings.option.experimental.compactUI": "使用緊密的介面設計", // Toggle
|
"settings.option.experimental.compactUI": "使用緊密的介面設計", // Toggle
|
||||||
"settings.option.experimental.closeButtonBehaviour": "關閉按鈕操作", // Dropdown
|
"settings.option.experimental.closeButtonBehaviour": "關閉按鈕操作", // Dropdown
|
||||||
"settings.option.experimental.close_button_hide": "關閉按鈕將 Cider 隱藏至系統列",
|
"settings.option.experimental.close_button_hide": "關閉按鈕將 Cider 隱藏至系統列",
|
||||||
"settings.option.experimental.copy_log": "複製執行紀錄檔至剪貼簿",
|
|
||||||
"settings.option.experimental.inline_playlists": "將播放列表做為行内元素顯示",
|
"settings.option.experimental.inline_playlists": "將播放列表做為行内元素顯示",
|
||||||
|
|
||||||
// Refer to term.disabled & term.enabled
|
// Refer to term.disabled & term.enabled
|
||||||
|
|
|
@ -904,6 +904,78 @@
|
||||||
.replay-page {
|
.replay-page {
|
||||||
--replayTextShadow: 0px 3px 2px #6f3f52;
|
--replayTextShadow: 0px 3px 2px #6f3f52;
|
||||||
|
|
||||||
|
.replay-period {
|
||||||
|
height: 200px;
|
||||||
|
width: 200px;
|
||||||
|
margin: 6px;
|
||||||
|
border-radius: var(--mediaItemRadius);
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform .2s var(--appleEase);
|
||||||
|
transition-delay: .1s;
|
||||||
|
align-self: center;
|
||||||
|
&:hover {
|
||||||
|
transform: translateY(-6px);
|
||||||
|
transition-delay: 0s;
|
||||||
|
}
|
||||||
|
.artwork-container {
|
||||||
|
height:200px;
|
||||||
|
width:200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.replay-playlist-container {
|
||||||
|
.cd-mediaitem-square {
|
||||||
|
height: 230px;
|
||||||
|
width: 230px;
|
||||||
|
.info-rect {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.replay-video {
|
||||||
|
max-height: 300px;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.mediaitem-artwork {
|
||||||
|
max-height: 300px;
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mediaitem-artwork .animatedartwork-view-box .animated video {
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-genres-container {
|
||||||
|
|
||||||
|
.genre-name {
|
||||||
|
font-size: 0.9em;
|
||||||
|
margin: 6px 0px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.genre-count {
|
||||||
|
width: 100%;
|
||||||
|
height: 32px;
|
||||||
|
background: #ffffff14;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.genre-count-bar {
|
||||||
|
height: 100%;
|
||||||
|
width: 0%;
|
||||||
|
background: var(--keyColor);
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 32px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.cd-mediaitem-square {
|
.cd-mediaitem-square {
|
||||||
.mediaitem-artwork {
|
.mediaitem-artwork {
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
:size="size"
|
:size="size"
|
||||||
shadow="subtle"
|
shadow="subtle"
|
||||||
:bgcolor="getBgColor()"
|
:bgcolor="getBgColor()"
|
||||||
|
:video-priority="forceVideo"
|
||||||
:type="item.type"></mediaitem-artwork>
|
:type="item.type"></mediaitem-artwork>
|
||||||
</div>
|
</div>
|
||||||
<button class="menu-btn" v-if="!nomenu.includes(item.type)"
|
<button class="menu-btn" v-if="!nomenu.includes(item.type)"
|
||||||
|
@ -57,6 +58,10 @@
|
||||||
type: String,
|
type: String,
|
||||||
default: '190'
|
default: '190'
|
||||||
},
|
},
|
||||||
|
forceVideo: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
'contextExt': {type: Object, required: false},
|
'contextExt': {type: Object, required: false},
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
|
|
|
@ -1,12 +1,23 @@
|
||||||
<script type="text/x-template" id="replay-page">
|
<script type="text/x-template" id="replay-page">
|
||||||
<div class="content-inner replay-page">
|
<div class="content-inner replay-page">
|
||||||
<h1 class="header-text">Replay</h1>
|
<vue-horizontal style="height: 300px;">
|
||||||
<button v-for="year in years" class="md-btn md-btn-primary" @click="getReplayYear(year.attributes.year)">{{ year.attributes.year }}</button>
|
<div class="replay-period" v-for="year in years" @click="getReplayYear(year.attributes.year)">
|
||||||
<button class="md-btn md-btn-primary" @click="getReplayYear()">This Year</button>
|
<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>
|
<hr>
|
||||||
<transition name="replaycard">
|
<transition name="replaycard">
|
||||||
<div class="replay-viewport" v-if="loaded.id != -1">
|
<div class="replay-viewport" v-if="loaded.id != -1">
|
||||||
<!-- Stats -->
|
<!-- Stats -->
|
||||||
|
<div class="replay-video" v-if="false">
|
||||||
|
<mediaitem-artwork
|
||||||
|
:url="loaded.playlist.attributes.editorialVideo.motionWideVideo21x9.previewFrame.url"
|
||||||
|
:video="loaded.playlist.attributes.editorialVideo.motionWideVideo21x9.video"
|
||||||
|
:video-priority="true"></mediaitem-artwork>
|
||||||
|
</div>
|
||||||
<h1 class="replay-header">{{ loaded.attributes.year }} Replay</h1>
|
<h1 class="replay-header">{{ loaded.attributes.year }} Replay</h1>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@ -16,8 +27,8 @@
|
||||||
<h4>{{ loaded.attributes.uniqueArtistCount }} Unique Artists</h4>
|
<h4>{{ loaded.attributes.uniqueArtistCount }} Unique Artists</h4>
|
||||||
<h4>{{ loaded.attributes.uniqueSongCount }} Unique Songs</h4>
|
<h4>{{ loaded.attributes.uniqueSongCount }} Unique Songs</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto replay-playlist-container">
|
||||||
<mediaitem-square kind="card" :item="loaded.relationships.playlist.data[0]"></mediaitem-square>
|
<mediaitem-square kind="card" :force-video="true" :item="loaded.playlist"></mediaitem-square>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Top Artists-->
|
<!-- Top Artists-->
|
||||||
|
@ -55,6 +66,19 @@
|
||||||
<div class="well">
|
<div class="well">
|
||||||
<listitem-horizontal :show-library-status="false" :items="songsToArray(loaded.views['top-songs'].data)"></listitem-horizontal>
|
<listitem-horizontal :show-library-status="false" :items="songsToArray(loaded.views['top-songs'].data)"></listitem-horizontal>
|
||||||
</div>
|
</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>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -74,24 +98,55 @@
|
||||||
// Get available years
|
// 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")
|
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 = year.data.data
|
||||||
|
this.years.reverse()
|
||||||
localStorage.setItem("seenReplay", true)
|
localStorage.setItem("seenReplay", true)
|
||||||
this.getReplayYear();
|
this.getReplayYear();
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
songsToArray(songsData) {
|
songsToArray(songsData) {
|
||||||
let songs = []
|
let songs = []
|
||||||
|
let topGenres = {}
|
||||||
|
let genrePlayCount = 0;
|
||||||
songsData.forEach(function (songData) {
|
songsData.forEach(function (songData) {
|
||||||
let song = songData.relationships.song.data[0]
|
let song = songData.relationships.song.data[0]
|
||||||
song.attributes.playCount = songData.attributes.playCount
|
song.attributes.playCount = songData.attributes.playCount
|
||||||
songs.push(song)
|
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
|
return songs
|
||||||
},
|
},
|
||||||
async getReplayYear(year = new Date().getFullYear()) {
|
async getReplayYear(year = new Date().getFullYear()) {
|
||||||
this.loaded.id = -1
|
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`)
|
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])
|
let replayData = response.data.data[0]
|
||||||
this.loaded = response.data.data[0]
|
// extended playlist
|
||||||
|
let playlist = await app.mk.api.v3.music(replayData.relationships.playlist.data[0].href, {extend: "editorialArtwork,editorialVideo"})
|
||||||
|
replayData.playlist = playlist.data.data[0]
|
||||||
|
this.loaded = replayData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue