diff --git a/src/i18n/README.md b/src/i18n/README.md index 6552894c..72e15e8b 100644 --- a/src/i18n/README.md +++ b/src/i18n/README.md @@ -121,4 +121,10 @@ Update 16/02/2022 21:45 UTC * `term.audioControls`: Added for `en_US`. * `settings.option.audio.volumeStep`: Added for `en_US`. -* `settings.option.audio.maxVolume`: Added for `en_US`.` \ No newline at end of file +* `settings.option.audio.maxVolume`: Added for `en_US`.` + +Update 17/02/2022 10:00 UTC ++ `settings.header.debug`: Added for `en_US`. ++ `settings.option.debug.copy_log`: Replaces `settings.option.experimental.copy_log`. ++ `settings.option.debug.openAppData`: Added for `en_US` ++ `action.open`: Added for `en_US` \ No newline at end of file diff --git a/src/i18n/en_US.jsonc b/src/i18n/en_US.jsonc index 037cbe9c..a14377d8 100644 --- a/src/i18n/en_US.jsonc +++ b/src/i18n/en_US.jsonc @@ -231,7 +231,7 @@ "action.copy": "Copy", "action.newpreset": "New Preset...", // Equalizer Preset "action.deletepreset": "Delete Preset", - + "action.open": "Open", // Settings - General "settings.header.general": "General", "settings.header.general.description": "Adjust the general settings for Cider.", @@ -339,13 +339,19 @@ "settings.option.connectivity.lastfmScrobble.removeFeatured": "Remove featuring artists from song title (Last.fm)", "settings.option.connectivity.lastfmScrobble.filterLoop": "Filter looped track (Last.fm)", // Refer to term.connect for the connect button - + + // Settings - Debug + "settings.header.debug": "Debug", + "settings.option.debug.copy_log": "Copy logs to clipboard", + "settings.option.debug.openAppData": "Open Cider Folder", + + // Settings - Experimental "settings.header.experimental": "Experimental", "settings.header.experimental.description": "Adjust the experimental settings for Cider.", "settings.option.experimental.compactUI": "Compact UI", // Toggle "settings.option.experimental.close_button_hide": "Close Button Should Hide the Application", - "settings.option.experimental.copy_log": "Copy logs to clipboard", + "settings.option.experimental.inline_playlists": "Inline Playlists and Albums", // Refer to term.disabled & term.enabled diff --git a/src/main/base/browserwindow.ts b/src/main/base/browserwindow.ts index a586b662..8e079151 100644 --- a/src/main/base/browserwindow.ts +++ b/src/main/base/browserwindow.ts @@ -47,6 +47,7 @@ export class BrowserWindow { "pages/library-videos", "pages/remote-pair", "pages/themes-github", + "pages/replay", "components/mediaitem-artwork", "components/artwork-material", "components/menu-panel", @@ -125,6 +126,16 @@ export class BrowserWindow { this.options.width = windowState.width; this.options.height = windowState.height; + switch(process.platform) { + default: + + break; + case "linux": + this.options.autoHideMenuBar = true + this.options.frame = true + break; + } + // Start the webserver for the browser window to load this.startWebServer(); @@ -699,7 +710,9 @@ export class BrowserWindow { ipcMain.on('get-version', (_event) => { _event.returnValue = app.getVersion() }); - + ipcMain.on('open-appdata', (_event) => { + shell.openPath(app.getPath('userData')); + }); /* ********************************************************************************************* * Window Events * **********************************************************************************************/ diff --git a/src/main/base/store.ts b/src/main/base/store.ts index da89a70a..0e9267f0 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -27,7 +27,7 @@ export class Store { }, "audio": { "volume": 1, - "volumeStep": 0.1, + "volumeStep": 0.02, "maxVolume": 1, "lastVolume": 1, "muted": false, diff --git a/src/main/plugins/lastfm.ts b/src/main/plugins/lastfm.ts index c5222203..a7433b8b 100644 --- a/src/main/plugins/lastfm.ts +++ b/src/main/plugins/lastfm.ts @@ -266,7 +266,7 @@ export default class LastFMPlugin { * Runs on song change * @param attributes Music Attributes */ - lfmItemChange(attributes: any): void { + nowPlayingItemDidChangeLastFM(attributes: any): void { attributes.status = true if (!this._store.lastfm.filterLoop) { this._lastfm.cachedNowPlayingAttributes = false; diff --git a/src/preload/cider-preload.js b/src/preload/cider-preload.js index 50e4d1ee..243b7951 100644 --- a/src/preload/cider-preload.js +++ b/src/preload/cider-preload.js @@ -32,7 +32,7 @@ const MusicKitInterop = { } // LastFM's Custom Call - // await MusicKitInterop.modifyNamesOnLocale(); + await MusicKitInterop.modifyNamesOnLocale(); if (trackFilter || !app.cfg.lastfm.filterLoop) { global.ipcRenderer.send('nowPlayingItemDidChangeLastFM', attributes); } diff --git a/src/renderer/assets/feather/external-link.svg b/src/renderer/assets/feather/external-link.svg new file mode 100644 index 00000000..6236df3e --- /dev/null +++ b/src/renderer/assets/feather/external-link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/index.js b/src/renderer/index.js index 7daf7bb8..c0b0442d 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -1354,8 +1354,15 @@ const app = new Vue({ } }, async getNowPlayingItemDetailed(target) { - let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, (app.mk.nowPlayingItem.songId == -1), (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], {"include[songs]": "albums,artists", l : app.mklang}); - app.searchAndNavigate(u.data.data[0], target) + try { + let u = await app.mkapi(app.mk.nowPlayingItem.playParams.kind, + (app.mk.nowPlayingItem.songId == -1), + (app.mk.nowPlayingItem.songId != -1) ? app.mk.nowPlayingItem.songId : app.mk.nowPlayingItem["id"], + { "include[songs]": "albums,artists", l: app.mklang }); + app.searchAndNavigate(u.data.data[0], target) + } catch (e) { + app.searchAndNavigate(app.mk.nowPlayingItem, target) + } }, async searchAndNavigate(item, target) { let self = this @@ -3037,7 +3044,7 @@ const app = new Vue({ type += "s" } type = type.replace("library-", "") - let id = item.attributes.playParams.catalogId ?? item.id + let id = item.attributes.playParams.catalogId ?? item.attributes.playParams.id ?? item.id let index = types.findIndex(function (type) { return type.type == this diff --git a/src/renderer/less/linux.less b/src/renderer/less/linux.less new file mode 100644 index 00000000..6b26d1ee --- /dev/null +++ b/src/renderer/less/linux.less @@ -0,0 +1,6 @@ +// Linux +body[platform="linux"] { + #window-controls-container { + display: none; + } +} \ No newline at end of file diff --git a/src/renderer/less/pages.less b/src/renderer/less/pages.less index f95f07e4..ee7ba294 100644 --- a/src/renderer/less/pages.less +++ b/src/renderer/less/pages.less @@ -819,3 +819,180 @@ margin: 16px; } } + +//Home +.home-page { + top: 0; + padding-top: var(--navbarHeight); + + .md-btn-replay { + background: var(--replayGradient); + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgba(200, 200, 200, 0.2); + text-transform: uppercase; + font-weight: bold; + } + .md-btn-replay--hero { + font-size: 1em; + padding: 16px; + background: var(--replayGradient); + border: 0px; + box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 20%); + margin-top: 1em; + font-size: 0.9em; + text-transform: uppercase; + font-weight: bold; + } + + .artist-feed-card { + position: absolute; + bottom: 0; + left: 10%; + z-index: 1; + background: black; + width: 80%; + height: 96%; + overflow: scroll; + border-radius: 10px; + } + + .col.madeforyou-col { + width: 420px; + min-width: 0px; + max-width: 420px; + } + + .well.artistfeed-well { + margin-top: 0px; + height: 392px; + align-content: flex-start; + } + + .hint-text { + font-size: 0.9rem; + color: rgb(200 200 200 / 70%); + } + + .user-icon { + border-radius: 100%; + width: 128px; + height: 128px; + overflow: hidden; + box-shadow: var(--mediaItemShadow-Shadow); + margin: 16px; + } + + .well.profile-well { + flex-direction: column; + justify-content: center; + align-items: center; + + .name { + margin: 4px; + font-weight: 500; + } + + .handle { + margin: 4px; + opacity: 0.7; + font-weight: 500; + } + } +} + +// Replay +.replay-page { + --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; + } + } + + .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 { + .mediaitem-artwork { + animation: replayFadeIn .5s var(--appleEase); + } + transition: transform .2s var(--appleEase); + transition-delay: .1s; + &:hover { + transform: scale(1.1); + transition-delay: 0s; + } + } + + @keyframes replayFadeIn { + 0% { + //border-radius: 100%; + transform: translateY(10px) scale(0.9); + opacity: 0; + } + + 100% { + //border-radius: var(--mediaItemRadius); + transform: scale(1); + opacity: 1; + } + } + + .replay-viewport { + background: var(--replayGradient); + padding: 16px 40px; + border-radius: 10px; + box-shadow: var(--mediaItemShadow), var(--mediaItemShadow-Shadow); + color: rgb(238 238 238 / 86%); + + .replay-header { + text-align: center; + font-size: 3em; + text-shadow: var(--replayTextShadow); + } + } + .replay-card { + background: transparent; + border:0px; + } +} \ No newline at end of file diff --git a/src/renderer/style.less b/src/renderer/style.less index 4b4d957c..08813883 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -38,6 +38,7 @@ --songProgressColor: var(--keyColor); --songProgressBackground: #333; --textColor: #eee; + --replayGradient: linear-gradient(45deg, hsl(248deg 58% 29%), hsl(13deg 41% 42%)); } html, @@ -1085,6 +1086,7 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.cl max-width: 500px; border-left: 1px solid rgb(200 200 200 / 8%); border-right: 1px solid rgb(200 200 200 / 8%); + -webkit-app-region: drag; } .app-chrome .app-chrome-item > .app-playback-controls { @@ -1092,6 +1094,7 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.cl justify-content: center; align-content: center; width: 100%; + -webkit-app-region: no-drag; } .app-chrome .app-chrome-item > .app-playback-controls { @@ -1220,6 +1223,7 @@ body[platform="darwin"] .app-chrome .app-chrome-item > .window-controls > div.cl height: 4px; background-color: rgb(200 200 200 / 10%); border-radius: 2px; + margin: 0; &::-webkit-slider-thumb { opacity: 0; @@ -1645,66 +1649,6 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 100%; } -.home-page { - top: 0; - padding-top: var(--navbarHeight); - - .artist-feed-card { - position: absolute; - bottom: 0; - left: 10%; - z-index: 1; - background: black; - width: 80%; - height: 96%; - overflow: scroll; - border-radius: 10px; - } - - .col.madeforyou-col { - width: 420px; - min-width: 0px; - max-width: 420px; - } - - .well.artistfeed-well { - margin-top: 0px; - height: 392px; - align-content: flex-start; - } - - .hint-text { - font-size: 0.9rem; - color: rgb(200 200 200 / 70%); - } - - .user-icon { - border-radius: 100%; - width: 128px; - height: 128px; - overflow: hidden; - box-shadow: var(--mediaItemShadow-Shadow); - margin: 16px; - } - - .well.profile-well { - flex-direction: column; - justify-content: center; - align-items: center; - - .name { - margin: 4px; - font-weight: 500; - } - - .handle { - margin: 4px; - opacity: 0.7; - font-weight: 500; - } - } -} - /* Cider */ .more-btn-round { @@ -2756,6 +2700,17 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { /* Transitions */ +.replaycard-enter-active, +.replaycard-leave-active { + transition: opacity .5s var(--appleEase), transform .5s var(--appleEase); +} + +.replaycard-enter, +.replaycard-leave-to { + opacity: 0; + transform: translateY(20px); +} + .modal-enter-active, .modal-leave-active { transition: opacity .1s var(--appleEase), transform .1s var(--appleEase); @@ -3155,4 +3110,5 @@ body[platform='darwin'] { } +@import url("less/linux.less"); @import url("less/compact.less"); diff --git a/src/renderer/views/app/app-content.ejs b/src/renderer/views/app/app-content.ejs index 1ebbd22e..b64e3f7d 100644 --- a/src/renderer/views/app/app-content.ejs +++ b/src/renderer/views/app/app-content.ejs @@ -172,4 +172,11 @@ + + + + + + + \ No newline at end of file diff --git a/src/renderer/views/components/listitem-horizontal.ejs b/src/renderer/views/components/listitem-horizontal.ejs index a8df81f4..ba00fe6f 100644 --- a/src/renderer/views/components/listitem-horizontal.ejs +++ b/src/renderer/views/components/listitem-horizontal.ejs @@ -3,7 +3,7 @@ @@ -19,6 +19,10 @@ items: { type: Array, required: true + }, + showLibraryStatus: { + type: Boolean, + default: true } }, data: function () { diff --git a/src/renderer/views/components/mediaitem-list-item.ejs b/src/renderer/views/components/mediaitem-list-item.ejs index fc671c53..44288389 100644 --- a/src/renderer/views/components/mediaitem-list-item.ejs +++ b/src/renderer/views/components/mediaitem-list-item.ejs @@ -74,6 +74,9 @@ {{ msToMinSec(item.attributes.durationInMillis ?? 0) }} + + {{ item.attributes.playCount }} + diff --git a/src/renderer/views/pages/home.ejs b/src/renderer/views/pages/home.ejs index 226dc360..45fe4b57 100644 --- a/src/renderer/views/pages/home.ejs +++ b/src/renderer/views/pages/home.ejs @@ -49,9 +49,21 @@ + + + Replay {{ year }} + + - {{app.getLz('home.madeForYou')}} + + + {{app.getLz('home.madeForYou')}} + + + Replay {{ year }} + + @@ -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() { diff --git a/src/renderer/views/pages/library-songs.ejs b/src/renderer/views/pages/library-songs.ejs index 567d2884..b2e27ab5 100644 --- a/src/renderer/views/pages/library-songs.ejs +++ b/src/renderer/views/pages/library-songs.ejs @@ -15,8 +15,16 @@ v-model="library.songs.search" class="search-input"> - + + + {{app.getLz('term.play')}} + + + {{app.getLz('term.shuffle')}} + @@ -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) + }); } } }); diff --git a/src/renderer/views/pages/replay.ejs b/src/renderer/views/pages/replay.ejs new file mode 100644 index 00000000..ecf92a6d --- /dev/null +++ b/src/renderer/views/pages/replay.ejs @@ -0,0 +1,144 @@ + + \ No newline at end of file diff --git a/src/renderer/views/pages/settings.ejs b/src/renderer/views/pages/settings.ejs index 32a50e46..5c51f5ab 100644 --- a/src/renderer/views/pages/settings.ejs +++ b/src/renderer/views/pages/settings.ejs @@ -620,6 +620,36 @@ + + + + + {{$root.getLz('settings.header.debug')}} + + + + + {{$root.getLz('settings.option.debug.copy_log')}} + + + + {{$root.getLz('action.copy')}} + + + + + + {{$root.getLz('settings.option.debug.openAppData')}} + + + + {{$root.getLz('action.open')}} + + + + + + {{$root.getLz('settings.header.experimental')}} @@ -692,16 +722,6 @@ - - - {{$root.getLz('settings.option.experimental.copy_log')}} - - - - {{$root.getLz('action.copy')}} - - - @@ -791,6 +811,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 = {