Merge branch 'develop' of https://github.com/Apple-Music-Electron/Cider into develop

This commit is contained in:
cryptofyre 2022-02-17 23:16:29 -06:00
commit 5331d8dd57
5 changed files with 150 additions and 8 deletions

View file

@ -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)",

View file

@ -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

View file

@ -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 {

View file

@ -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 () {

View file

@ -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
} }
} }
}); });