diff --git a/.gitignore b/.gitignore index 5972eec3..d469a498 100644 --- a/.gitignore +++ b/.gitignore @@ -308,4 +308,5 @@ GitHub.sublime-settings #Service Worker mappings src/renderer/sw.js.map -src/renderer/workbox-962786f2.js.map \ No newline at end of file +src/renderer/workbox-962786f2.js.map +/src/renderer/musickit-dev.js diff --git a/src/main/base/store.ts b/src/main/base/store.ts index 686cca4f..79df0198 100644 --- a/src/main/base/store.ts +++ b/src/main/base/store.ts @@ -57,7 +57,8 @@ export class ConfigStore { "animated_artwork": "limited", // 0 = always, 1 = limited, 2 = never "animated_artwork_qualityLevel": 1, "bg_artwork_rotation": false, - "hw_acceleration": "default" // default, webgpu, disabled + "hw_acceleration": "default", // default, webgpu, disabled + "showuserinfo": true }, "lyrics": { "enable_mxm": false, diff --git a/src/renderer/assets/feather/mic.svg b/src/renderer/assets/feather/mic.svg new file mode 100644 index 00000000..dc5f780c --- /dev/null +++ b/src/renderer/assets/feather/mic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/feather/plus-circle-white.svg b/src/renderer/assets/feather/plus-circle-white.svg new file mode 100644 index 00000000..bd6a25ec --- /dev/null +++ b/src/renderer/assets/feather/plus-circle-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/renderer/assets/feather/x-circlePng.png b/src/renderer/assets/feather/x-circlePng.png new file mode 100644 index 00000000..9b0f9ca2 Binary files /dev/null and b/src/renderer/assets/feather/x-circlePng.png differ diff --git a/src/renderer/assets/playPng.png b/src/renderer/assets/playPng.png new file mode 100644 index 00000000..8ece27c0 Binary files /dev/null and b/src/renderer/assets/playPng.png differ diff --git a/src/renderer/assets/shufflePng.png b/src/renderer/assets/shufflePng.png new file mode 100644 index 00000000..982547d6 Binary files /dev/null and b/src/renderer/assets/shufflePng.png differ diff --git a/src/renderer/index.js b/src/renderer/index.js index a478a3ca..45c3a65d 100644 --- a/src/renderer/index.js +++ b/src/renderer/index.js @@ -257,7 +257,7 @@ const app = new Vue({ tmpVar: [], notification: false, chrome: { - hideUserInfo: ipcRenderer.sendSync("is-dev"), + hideUserInfo: ipcRenderer.sendSync("is-dev") || false, artworkReady: false, userinfo: { "id": "", @@ -486,13 +486,21 @@ const app = new Vue({ let self = this clearTimeout(this.hangtimer) this.mk = MusicKit.getInstance() + let needsReload = (typeof localStorage["music.ampwebplay.media-user-token"] == "undefined") this.mk.authorize().then(() => { self.mkIsReady = true - //document.location.reload() + if(needsReload) { + document.location.reload() + } }) this.$forceUpdate() if (this.isDev) { this.mk.privateEnabled = true + // Hide UserInfo if Dev mode + this.chrome.hideUserInfo = true + } else { + // Get Hide User from Settings + this.chrome.hideUserInfo = !this.cfg.visual.showuserinfo } if (this.cfg.visual.hw_acceleration == "disabled") { document.body.classList.add("no-gpu") @@ -560,7 +568,8 @@ const app = new Vue({ app.mk.bitrate = app.cfg.audio.quality = 64 break; default: - app.mk.bitrate = app.cfg.audio.quality + // app.mk.bitrate = app.cfg.audio.quality + break; } @@ -717,6 +726,10 @@ const app = new Vue({ this.$forceUpdate() }, 500) }, + unauthorize() { + this.mk.unauthorize() + document.location.reload() + }, getAppClasses() { if (this.cfg.advanced.experiments.includes('compactui')) { return { compact: true } @@ -3254,6 +3267,15 @@ const app = new Vue({ return 0 !== s && (h = s > 0 ? "-" : "+"), `${h}${leadingZeros(n, 2)}:${leadingZeros(d, 2)}` }, + toggleHideUserInfo() { + if(this.chrome.hideUserInfo) { + this.cfg.visual.showuserinfo = true + this.chrome.hideUserInfo = false + } else { + this.cfg.visual.showuserinfo = false + this.chrome.hideUserInfo = true + } + } } }) @@ -3518,4 +3540,4 @@ async function webGPU() { webGPU().then() let screenWidth = screen.width; -let screenHeight = screen.height; \ No newline at end of file +let screenHeight = screen.height; diff --git a/src/renderer/style.less b/src/renderer/style.less index 7d886249..8b9ad700 100644 --- a/src/renderer/style.less +++ b/src/renderer/style.less @@ -1056,7 +1056,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track { height: 1.2em; line-height: 1.3em; overflow: hidden; - margin: 0 0 0.5em; + margin: 0 0 0 0.25em; } .app-chrome .app-chrome-item > .app-playback-controls .song-artist { @@ -2058,9 +2058,9 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { .md-btn { background: rgba(100, 100, 100, 0.5); - padding: 4px 12px; + padding: 6px 12px; border-radius: 4px; - font-size: 13px; + font-size: 16px; border: 1px solid rgb(100 100 100 / 35%); color: #eee; box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.3), 0px 1px 1px rgba(0, 0, 0, 0.4); @@ -2094,6 +2094,40 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } +.md-ico-play { + content:url("./assets/playPng.png"); + width: 10px; + height: 12px; + margin-right: 1px; + align-self: center; +} + +.md-ico-shuffle { + content:url("./assets/shufflePng.png"); + width: 15px; + height: 13px; + margin-right: 1px; + align-self: center; +} + +.md-ico-remove { + content:url("./assets/feather/x-circlePng.png"); + width: 16px; + height: 16px; + margin-right: 1px; + margin-bottom: -1.5px; + align-self: center; +} + +.md-ico-add { + content:url("./assets/feather/plus-circle-white.svg"); + width: 16px; + height: 16px; + margin-right: 1px; + margin-bottom: -1.5px; + align-self: center; +} + .md-select { width: 100%; padding: 6px; @@ -2519,6 +2553,107 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { } } +// Podcast Page +.content-inner.podcasts-page { + display: flex; + height: calc(100% - var(--navigationBarHeight)); + padding: 0px; + + .podcast-artwork { + width: 200px; + margin: 16px auto; + height: 200px; + } + + .podcasts-list { + height: 100%; + width: 280px; + background: rgb(200 200 200 / 10%); + overflow-y: overlay; + border-right: 1px solid var(--color2); + flex: none; + overflow-x: hidden; + } + + .episodes-list { + height: 100%; + width: 100%; + background: rgb(200 200 200 / 6%); + overflow-y: overlay; + overflow-x: hidden; + + .episodes-inline-info { + padding: 14px 14px 0px 14px; + + .podcast-show-info { + display: flex; + justify-content: center; + flex-direction: column; + } + + .podcast-show-description { + margin: 32px 6px; + font-size: 0.8rem; + white-space: pre-wrap; + display:block; + } + + .podcast-artwork { + width: 120px; + margin: 0px auto; + height: 120px; + } + } + } + + .podcasts-details { + height: 100%; + width: 400px; + flex: none; + background: rgba(200, 200, 200, 0.1); + overflow-y: overlay; + border-left: 1px solid var(--color2); + overflow-x: hidden; + + .podcast-genre { + text-align: center; + margin: 6px; + font-size: 0.8em; + font-weight: 500; + opacity: 0.8; + } + + .podcast-metainfo { + text-align: center; + font-size: 0.7em; + opacity: 0.8; + } + + .podcast-header { + text-align:center; + } + + .podcast-play-btn { + width: 50%; + display: block; + margin: 0 auto; + } + + .podcast-description { + margin: 12px; + font-size: 0.75em; + white-space: pre-wrap; + display:block; + } + + + } + +} + + + + /* Album / Playlist Page */ .playlist-page { --bgColor: transparent; @@ -4372,7 +4507,7 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb { height: 1.2em; line-height: 1.3em; overflow: hidden; - margin: 0 0 0.5em; + margin: 0 0 0 0.25em; } &:hover { diff --git a/src/renderer/views/components/libraryartist-item.ejs b/src/renderer/views/components/libraryartist-item.ejs index 686a62f1..50335f51 100644 --- a/src/renderer/views/components/libraryartist-item.ejs +++ b/src/renderer/views/components/libraryartist-item.ejs @@ -2,28 +2,20 @@
+ :class="{'mediaitem-selected': app.select_hasMediaItem(guid)}" + @contextmenu="contextMenu">
@@ -62,22 +54,19 @@ return minutes + ":" + (seconds < 10 ? '0' : '') + seconds; }, getDataType() { - if (this.item.attributes.playParams.isLibrary) { - return this.item.type - } else { - return this.item.attributes.playParams.kind - } + return this.item.type }, async select(e) { let u = this.item - let u1 = await app.mk.api.v3.music(`/v1/me/library/artists/${u.id}/albums`, - {platform: "web", - "include[library-albums]": "artists,tracks", - "include[library-artists]": "catalog", - "fields[artists]": "url", - "includeOnly": "catalog,artists"} - ) + let u1 = await app.mk.api.v3.music(`/v1/me/library/artists/${u.id}/albums`, { + "platform": "web", + "include[library-albums]": "artists,tracks", + "include[library-artists]": "catalog", + "fields[artists]": "url", + "includeOnly": "catalog,artists" + }) app.showCollection({data : Object.assign({},u1.data.data)}, u.attributes.name?? '', ''); + app.select_selectMediaItem(u.id, this.getDataType(), this.index, this.guid, true) }, getArtwork(){ let u = "" @@ -87,79 +76,37 @@ return u; }, contextMenu(event) { + let self = this let data_type = this.getDataType() - let item_id = this.item.attributes.playParams.id ?? this.item.id - let isLibrary = this.item.attributes.playParams.isLibrary ?? false + + let item = self.item + item.attributes.artistName = item.attributes.name; let useMenu = "normal" if (app.selectedMediaItems.length <= 1) { app.selectedMediaItems = [] - app.select_selectMediaItem(item_id, data_type, this.index, this.guid, isLibrary) + app.select_selectMediaItem(this.item.id, data_type, this.index, this.guid, true) } else { useMenu = "multiple" } + let menus = { multiple: { - items: [ - { - "name": "Add to Playlist...", - "action": function () { - app.promptAddToPlaylist() - } - }, - { - name: `Play ${app.selectedMediaItems.length} tracks next`, - action: () => { - let itemsToPlay = {} - app.selectedMediaItems.forEach(item => { - if (!itemsToPlay[item.kind]) { - itemsToPlay[item.kind] = [] - } - itemsToPlay[item.kind].push(item.id) - }) - // loop through itemsToPlay - for (let kind in itemsToPlay) { - let ids = itemsToPlay[kind] - if (ids.length > 0) { - app.mk.playNext({[kind + "s"]: itemsToPlay[kind]}) - } - } - console.log(itemsToPlay) - app.selectedMediaItems = [] - } - }, - { - name: `Play ${app.selectedMediaItems.length} tracks later`, - action: () => { - let itemsToPlay = {} - app.selectedMediaItems.forEach(item => { - if (!itemsToPlay[item.kind]) { - itemsToPlay[item.kind] = [] - } - itemsToPlay[item.kind].push(item.id) - }) - // loop through itemsToPlay - for (let kind in itemsToPlay) { - let ids = itemsToPlay[kind] - if (ids.length > 0) { - app.mk.playLater({[kind + "s"]: itemsToPlay[kind]}) - } - } - app.selectedMediaItems = [] - } - }, - ] + items: [] // }, normal: { items: [ { - "name": "Add to Playlist...", + "name": "Go to Artist", + "icon": "./assets/feather/user.svg", "action": function () { - app.promptAddToPlaylist() + app.searchAndNavigate(self.item, 'artist') + console.log(self.item) } }, { + "icon": "./assets/feather/radio.svg", "name": "Start Radio", "action": function () { app.mk.setStationQueue({song: self.item.attributes.playParams.id ?? self.item.id}).then(() => { @@ -169,31 +116,15 @@ } }, { - "name": "Play Next", + "icon": "./assets/feather/share.svg", + "name": "Share", "action": function () { - app.mk.playNext({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id}) - app.mk.queue._reindex() - app.selectedMediaItems = [] - } - }, - { - "name": "Play Later", - "action": function () { - app.mk.playLater({[self.item.attributes.playParams.kind ?? self.item.type]: self.item.attributes.playParams.id ?? self.item.id}) - app.mk.queue._reindex() - app.selectedMediaItems = [] - } - }, - { - "name": "Go to Artist", - "action": function () { - app.searchAndNavigate(self.item, 'artist') - } - }, - { - "name": "Go to Album", - "action": function () { - app.searchAndNavigate(self.item, 'album') + if (!self.item.attributes.url && self.item.relationships){ + if (self.item.relationships.catalog){ + app.mkapi(self.item.attributes.playParams.kind, false, self.item.relationships.catalog.data[0].id).then(u => {self.app.copyToClipboard((u.length && u.length > 0)? u[0].attributes.url : u.attributes.url)}) + } + } else { + self.app.copyToClipboard(self.item.attributes.url)} } }, ] @@ -208,7 +139,9 @@ menus.multiple.items = menus.multiple.items.concat(this.contextExt.multiple) } } - CiderContextMenu.Create(event, menus[useMenu]) + //CiderContextMenu.Create(event, menus[useMenu]); // Depreciated Context Menu + app.showMenuPanel(menus[useMenu], event); + }, visibilityChanged: function (isVisible, entry) { this.isVisible = isVisible diff --git a/src/renderer/views/main.ejs b/src/renderer/views/main.ejs index 7dac8db4..065d2b2b 100644 --- a/src/renderer/views/main.ejs +++ b/src/renderer/views/main.ejs @@ -83,9 +83,11 @@
+ :style="[mk.nowPlayingItem['attributes']['contentRating'] == 'explicit' ? {'margin-left' : '23px'} : {'margin-left' : '0px'} ]"> {{ mk.nowPlayingItem["attributes"]["name"] }} -
+
@@ -148,9 +150,9 @@
- + @click="invokeDrawer('lyrics')"> + +
@@ -198,6 +200,8 @@ page="browse"> +
Library
@@ -218,7 +222,7 @@
- -
@@ -312,7 +316,7 @@ @@ -339,6 +343,14 @@
+ + + + + +
- - - -
- - - -
@@ -482,4 +482,4 @@ } }) - \ No newline at end of file + diff --git a/src/renderer/views/pages/podcasts.ejs b/src/renderer/views/pages/podcasts.ejs new file mode 100644 index 00000000..c4084b08 --- /dev/null +++ b/src/renderer/views/pages/podcasts.ejs @@ -0,0 +1,173 @@ + + + + \ No newline at end of file diff --git a/src/renderer/views/pages/settings.ejs b/src/renderer/views/pages/settings.ejs index 7615759b..d68e7d31 100644 --- a/src/renderer/views/pages/settings.ejs +++ b/src/renderer/views/pages/settings.ejs @@ -10,7 +10,7 @@
+
+
+ Show Personal Info +
+
+ +
+
Lyrics
@@ -605,6 +613,9 @@ }, changeAudioQuality : function(){ app.mk.bitrate = app.cfg.audio.quality + }, + toggleUserInfo : function(){ + app.chrome.hideUserInfo = !app.cfg.visual.showuserinfo } } })