Imported changes to web-remote from AME

This commit is contained in:
booploops 2021-12-02 20:21:03 -08:00
parent 45623f257b
commit ab6c24f9be
11 changed files with 1265 additions and 595 deletions

View file

@ -48,7 +48,6 @@ function CreateWindow() {
app.on('ready', () => { app.on('ready', () => {
if (app.isQuiting) { app.quit(); return; } if (app.isQuiting) { app.quit(); return; }
require('vue-devtools').install()
// Apple Header tomfoolery. // Apple Header tomfoolery.
session.defaultSession.webRequest.onHeadersReceived((details, callback) => { session.defaultSession.webRequest.onHeadersReceived((details, callback) => {
if(details.url.match(/^https:\/\/store-\d{3}\.blobstore\.apple\.com/) || details.url.startsWith("https://store-037.blobstore.apple.com")){ if(details.url.match(/^https:\/\/store-\d{3}\.blobstore\.apple\.com/) || details.url.startsWith("https://store-037.blobstore.apple.com")){

View file

@ -180,7 +180,7 @@
</div> </div>
<div class="bg-artwork"></div> <div class="bg-artwork"></div>
</div> </div>
<script src="https://js-cdn.music.apple.com/musickit/v3/amp/musickit.js"></script> <script src="https://js-cdn.music.apple.com/musickit/v2/amp/musickit.js"></script>
<script src="index.js?v=1"></script> <script src="index.js?v=1"></script>
</body> </body>

View file

@ -1,4 +1,4 @@
const {app, BrowserWindow} = require("electron") const {app, BrowserWindow, ipcMain} = require("electron")
const {join, resolve} = require("path") const {join, resolve} = require("path")
const CiderWin = { const CiderWin = {
@ -34,6 +34,8 @@ const CiderWin = {
win.on("closed", () => { win.on("closed", () => {
win = null win = null
}) })
},
SetupHandlers() {
} }
} }

View file

@ -8,6 +8,7 @@ const path = require('path');
const port = process.argv[2] || 9000; const port = process.argv[2] || 9000;
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const getPort = require('get-port');
const { const {
ipcMain, ipcMain,
app, app,
@ -32,7 +33,7 @@ const wsapi = {
return v.toString(16); return v.toString(16);
}); });
}, },
InitWebSockets() { async InitWebSockets () {
ipcMain.on('wsapi-updatePlaybackState', (event, arg) => { ipcMain.on('wsapi-updatePlaybackState', (event, arg) => {
wsapi.updatePlaybackState(arg); wsapi.updatePlaybackState(arg);
}) })
@ -49,12 +50,20 @@ const wsapi = {
wsapi.returnSearchLibrary(JSON.parse(arg)); wsapi.returnSearchLibrary(JSON.parse(arg));
}); });
ipcMain.on('wsapi-returnDynamic', (event, arg, type) => {
wsapi.returnDynamic(JSON.parse(arg), type);
});
ipcMain.on('wsapi-returnMusicKitApi', (event, arg, method) => {
wsapi.returnMusicKitApi(JSON.parse(arg), method);
});
ipcMain.on('wsapi-returnLyrics', (event, arg) => { ipcMain.on('wsapi-returnLyrics', (event, arg) => {
wsapi.returnLyrics(JSON.parse(arg)); wsapi.returnLyrics(JSON.parse(arg));
}); });
var safeport = await getPort({port : 26369});
wss = new WebSocketServer({ wss = new WebSocketServer({
port: 26369, port: safeport,
perMessageDeflate: { perMessageDeflate: {
zlibDeflateOptions: { zlibDeflateOptions: {
// See zlib defaults. // See zlib defaults.
@ -75,10 +84,11 @@ const wsapi = {
// should not be compressed if context takeover is disabled. // should not be compressed if context takeover is disabled.
} }
}) })
console.log(`WebSocketServer started on port: ${safeport}`);
const defaultResponse = new wsapi.standardResponse(0, {}, "OK"); const defaultResponse = new wsapi.standardResponse(0, {}, "OK");
console.log(`WebSocketServer started on port: ${this.port}`);
wss.on('connection', function connection(ws) { wss.on('connection', function connection(ws) {
ws.id = wsapi.createId(); ws.id = wsapi.createId();
console.log(`Client ${ws.id} connected`) console.log(`Client ${ws.id} connected`)
@ -127,6 +137,13 @@ const wsapi = {
case "shuffle": case "shuffle":
app.win.webContents.executeJavaScript(`wsapi.toggleShuffle()`); app.win.webContents.executeJavaScript(`wsapi.toggleShuffle()`);
break; break;
case "set-shuffle":
if(data.shuffle == true) {
app.win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 1`);
}else{
app.win.webContents.executeJavaScript(`MusicKit.getInstance().shuffleMode = 0`);
}
break;
case "repeat": case "repeat":
app.win.webContents.executeJavaScript(`wsapi.toggleRepeat()`); app.win.webContents.executeJavaScript(`wsapi.toggleRepeat()`);
break; break;
@ -167,10 +184,9 @@ const wsapi = {
response.message = "Previous"; response.message = "Previous";
break; break;
case "musickit-api": case "musickit-api":
app.win.webContents.executeJavaScript(`wsapi.musickitApi(\`${data.method}\`, \`${data.id}\`, ${JSON.stringify(data.params)})`);
break; break;
case "musickit-library-api": case "musickit-library-api":
break; break;
case "set-autoplay": case "set-autoplay":
app.win.webContents.executeJavaScript(`wsapi.setAutoplay(${data.autoplay})`); app.win.webContents.executeJavaScript(`wsapi.setAutoplay(${data.autoplay})`);
@ -200,7 +216,7 @@ const wsapi = {
app.win.hide() app.win.hide()
break; break;
case "play-mediaitem": case "play-mediaitem":
app.win.webContents.executeJavaScript(`wsapi.playTrackById(${data.id})`); app.win.webContents.executeJavaScript(`wsapi.playTrackById(${data.id}, \`${data.kind}\`)`);
response.message = "Playing track"; response.message = "Playing track";
break; break;
case "get-status": case "get-status":
@ -249,6 +265,18 @@ const wsapi = {
client.send(JSON.stringify(response)); client.send(JSON.stringify(response));
}); });
}, },
returnMusicKitApi(results, method) {
const response = new wsapi.standardResponse(0, results, "OK", `musickitapi.${method}`);
wsapi.clients.forEach(function each(client) {
client.send(JSON.stringify(response));
});
},
returnDynamic(results, type) {
const response = new wsapi.standardResponse(0, results, "OK", type);
wsapi.clients.forEach(function each(client) {
client.send(JSON.stringify(response));
});
},
returnLyrics(results) { returnLyrics(results) {
const response = new wsapi.standardResponse(0, results, "OK", "lyrics"); const response = new wsapi.standardResponse(0, results, "OK", "lyrics");
wsapi.clients.forEach(function each(client) { wsapi.clients.forEach(function each(client) {
@ -272,9 +300,10 @@ const wsapi = {
wsapi.clients.forEach(function each(client) { wsapi.clients.forEach(function each(client) {
client.send(JSON.stringify(response)); client.send(JSON.stringify(response));
}); });
}, },
webRemotePort: 8090, webRemotePort: 8090,
InitWebServer() { async InitWebServer() {
const webRemotePort = await getPort({port : wsapi.webRemotePort});
// Web Remote // Web Remote
// express server that will serve static files in the "../web-remote" folder // express server that will serve static files in the "../web-remote" folder
const webapp = express(); const webapp = express();
@ -283,8 +312,8 @@ const wsapi = {
webapp.get('/', function (req, res) { webapp.get('/', function (req, res) {
res.sendFile(path.join(webRemotePath, 'index.html')); res.sendFile(path.join(webRemotePath, 'index.html'));
}); });
webapp.listen(wsapi.webRemotePort, function () { webapp.listen(webRemotePort, function () {
console.log(`Web Remote listening on port ${wsapi.webRemotePort}`); console.log(`Web Remote listening on port ${webRemotePort}`);
}); });
} }
} }

View file

@ -16,6 +16,14 @@ const wsapi = {
setAutoplay(value) { setAutoplay(value) {
MusicKit.getInstance().autoplayEnabled = value MusicKit.getInstance().autoplayEnabled = value
}, },
returnDynamic(data, type) {
ipcRenderer.send('wsapi-returnDynamic', JSON.stringify(data), type)
},
musickitApi(method, id, params) {
MusicKit.getInstance().api[method](id, params).then((results)=>{
ipcRenderer.send('wsapi-returnMusicKitApi', JSON.stringify(results), method)
})
},
getPlaybackState () { getPlaybackState () {
ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes()); ipcRenderer.send('wsapi-updatePlaybackState', MusicKitInterop.getAttributes());
}, },
@ -38,8 +46,8 @@ const wsapi = {
love() { love() {
}, },
playTrackById(id) { playTrackById(id, kind = "song") {
MusicKit.getInstance().setQueue({ song: id }).then(function (queue) { MusicKit.getInstance().setQueue({ [kind]: id }).then(function (queue) {
MusicKit.getInstance().play() MusicKit.getInstance().play()
}) })
}, },

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 28 64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g transform="matrix(1,0,0,1,-11,-10)">
<path d="M39,12.24C39,11.004 37.996,10 36.76,10L13.24,10C12.004,10 11,11.004 11,12.24L11,71.76C11,72.996 12.004,74 13.24,74L36.76,74C37.996,74 39,72.996 39,71.76L39,12.24Z" style="fill:rgb(108,108,108);fill-opacity:0.43;"/>
<g transform="matrix(0.714286,0,0,1,7.14286,0)">
<rect x="18" y="41" width="14" height="2" style="fill:rgb(231,231,231);fill-opacity:0.77;"/>
</g>
<g transform="matrix(0.714286,0,0,1,7.14286,-5)">
<rect x="18" y="41" width="14" height="2" style="fill:rgb(231,231,231);fill-opacity:0.77;"/>
</g>
<g transform="matrix(0.714286,0,0,1,7.14286,5)">
<rect x="18" y="41" width="14" height="2" style="fill:rgb(231,231,231);fill-opacity:0.77;"/>
</g>
<g transform="matrix(0.571429,0,0,0.6,10.7143,10.4)">
<path d="M25,26L32,36L18,36L25,26Z" style="fill:rgb(231,231,231);fill-opacity:0.77;"/>
</g>
<g transform="matrix(0.571429,0,0,-0.6,10.7143,73.6)">
<path d="M25,26L32,36L18,36L25,26Z" style="fill:rgb(231,231,231);fill-opacity:0.77;"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="white"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M471.1 96C405 96 353.3 137.3 320 174.6 286.7 137.3 235 96 168.9 96 75.8 96 0 167.8 0 256s75.8 160 168.9 160c66.1 0 117.8-41.3 151.1-78.6 33.3 37.3 85 78.6 151.1 78.6 93.1 0 168.9-71.8 168.9-160S564.2 96 471.1 96zM168.9 320c-40.2 0-72.9-28.7-72.9-64s32.7-64 72.9-64c38.2 0 73.4 36.1 94 64-20.4 27.6-55.9 64-94 64zm302.2 0c-38.2 0-73.4-36.1-94-64 20.4-27.6 55.9-64 94-64 40.2 0 72.9 28.7 72.9 64s-32.7 64-72.9 64z"/></svg>

After

Width:  |  Height:  |  Size: 684 B

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,9 @@
var socket; var socket;
Vue.component('footer-player', {
template: '#footer-player'
});
// vue instance // vue instance
var app = new Vue({ var app = new Vue({
el: '#app', el: '#app',
@ -22,6 +26,14 @@ var app = new Vue({
queue: { queue: {
temp: [] temp: []
}, },
artistPage: {
data: {},
editorsNotes: false
},
albumPage: {
data: {},
editorsNotes: false
},
search: { search: {
query: "", query: "",
results: [], results: [],
@ -31,12 +43,29 @@ var app = new Vue({
trackSelect: false, trackSelect: false,
selected: {}, selected: {},
queue: {}, queue: {},
lastPage: "search",
lastY: 0
}, },
lastPage: "player",
connectedState: 0, connectedState: 0,
url: window.location.hostname, url: window.location.hostname,
mode: "default",
// url: "localhost", // url: "localhost",
}, },
methods: { methods: {
searchScroll(e) {
this.search.lastY = e.target.scrollTop;
},
musicKitAPI(method, id, params) {
socket.send(
JSON.stringify({
action: "musickit-api",
method: method,
id: id,
params: params
})
)
},
resetPlayerUI() { resetPlayerUI() {
this.player.lowerPanelState = "controls"; this.player.lowerPanelState = "controls";
}, },
@ -111,7 +140,7 @@ var app = new Vue({
setTimeout(() => { setTimeout(() => {
this.getQueue() this.getQueue()
}, 1000) }, 1000)
}else{ } else {
this.getQueue() this.getQueue()
} }
}, },
@ -171,10 +200,11 @@ var app = new Vue({
getArtworkColor(hex) { getArtworkColor(hex) {
return `#${hex}` return `#${hex}`
}, },
playMediaItemById(id) { playMediaItemById(id, kind = "song") {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
action: "play-mediaitem", action: "play-mediaitem",
id: id id: id,
kind: kind
})) }))
this.screen = "player"; this.screen = "player";
}, },
@ -309,6 +339,38 @@ var app = new Vue({
return ["passed"] return ["passed"]
} }
}, },
showSearch(reset = false) {
if(reset) {
this.search.lastPage = "search"
}
switch(this.search.lastPage) {
case "search":
this.screen = "search"
break;
case "album":
this.screen = "album-page"
break;
case "artist":
this.screen = "artist-page"
break;
case "playlist":
this.screen = "playlist-page"
break;
}
},
showArtistByName(name) {
this.musicKitAPI("search", name, {types: "artists"})
},
showAlbum(id) {
this.search.lastPage = "album"
this.screen = "album-page"
this.musicKitAPI("album", id, {})
},
showArtist(id) {
this.search.lastPage = "artist"
this.screen = "artist-page"
this.musicKitAPI("artist", id, {include: "songs,playlists,albums"})
},
showQueue() { showQueue() {
this.queue.temp = this.player["queue"]["_queueItems"] this.queue.temp = this.player["queue"]["_queueItems"]
this.screen = "queue" this.screen = "queue"
@ -338,6 +400,31 @@ var app = new Vue({
})) }))
this.getCurrentMediaItem() this.getCurrentMediaItem()
}, },
setShuffle(val) {
socket.send(JSON.stringify({
action: "set-shuffle",
shuffle: val
}))
this.getCurrentMediaItem()
},
getMediaPalette(data) {
var palette = {
'--bgColor': `#${data['artwork']['bgColor']}`,
'--textColor1': `#${data['artwork']['textColor1']}`,
'--textColor2': `#${data['artwork']['textColor2']}`,
'--textColor3': `#${data['artwork']['textColor3']}`,
'--textColor4': `#${data['artwork']['textColor4']}`
}
return palette
},
playAlbum(id, shuffle = false) {
if(shuffle) {
this.setShuffle(true)
}else{
this.setShuffle(false)
}
this.playMediaItemById(id, 'album');
},
getLyrics() { getLyrics() {
socket.send(JSON.stringify({ socket.send(JSON.stringify({
action: "get-lyrics", action: "get-lyrics",
@ -373,6 +460,19 @@ var app = new Vue({
action: "get-currentmediaitem" action: "get-currentmediaitem"
})) }))
}, },
setStreamerOverlay() {
document.body.classList.add("streamer-overlay")
},
setMode(mode) {
switch(mode) {
default:
this.screen = "player"
break;
case "miniplayer":
this.screen = "miniplayer"
break;
}
},
connect() { connect() {
let self = this; let self = this;
this.connectedState = 0; this.connectedState = 0;
@ -384,7 +484,11 @@ var app = new Vue({
console.log(e); console.log(e);
console.log('connected'); console.log('connected');
app.connectedState = 1; app.connectedState = 1;
self.screen = "player" if(getParameterByName("mode")) {
self.setMode(getParameterByName("mode"))
}else{
self.setMode("default")
}
self.clearSelectedTrack() self.clearSelectedTrack()
} }
@ -404,20 +508,25 @@ var app = new Vue({
const response = JSON.parse(e.data); const response = JSON.parse(e.data);
switch (response.type) { switch (response.type) {
default: default:
console.log(response);
break;
case "musickitapi.search":
self.showArtist(response.data["artists"][0]["id"]);
break;
case "musickitapi.album":
if(self.screen == "album-page") {
self.albumPage.data = response.data
}
break;
case "musickitapi.artist":
if(self.screen == "artist-page") {
self.artistPage.data = response.data
}
break; break;
case "queue": case "queue":
self.player.queue = response.data; self.player.queue = response.data;
self.queue.temp = response.data["_queueItems"]; self.queue.temp = response.data["_queueItems"];
self.$forceUpdate() self.$forceUpdate()
if (self.screen == "queue") {
setTimeout(() => {
document.querySelector(".playing").scrollIntoView({
behavior: "smooth",
block: "start"
})
}, 200)
}
break; break;
case "lyrics": case "lyrics":
self.player.lyrics = response.data; self.player.lyrics = response.data;
@ -455,6 +564,16 @@ var app = new Vue({
}, },
}); });
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, '\\$&');
var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
function xmlToJson(xml) { function xmlToJson(xml) {
// Create the return object // Create the return object

View file

@ -1,20 +0,0 @@
{
"name": "AME",
"short_name": "AME",
"description": "AME",
"icons": [
{
"src": "images/icon.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "images/icon.png",
"sizes": "512x512",
"type": "image/png"
}
],
"display": "fullscreen",
"start_url": "/web-remote/index.html",
"orientation": "portrait"
}

View file

@ -2,6 +2,7 @@
:root { :root {
--appleEase: cubic-bezier(0.42, 0, 0.58, 1); --appleEase: cubic-bezier(0.42, 0, 0.58, 1);
--mediaItemShadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55);
--keyColor: #fa586a; --keyColor: #fa586a;
--keyColor-rgb: 250, 88, 106; --keyColor-rgb: 250, 88, 106;
--keyColor-rollover: #ff8a9c; --keyColor-rollover: #ff8a9c;
@ -85,6 +86,18 @@ body {
filter: blur(32px) saturate(180%); filter: blur(32px) saturate(180%);
} }
body.streamer-overlay {
background: transparent;
}
body.streamer-overlay #app {
background: transparent;
}
body.streamer-overlay #app:before {
display: none;
}
body { body {
background: #111; background: #111;
font-family: "Segoe UI Variable Display", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; font-family: "Segoe UI Variable Display", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
@ -124,6 +137,24 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
font-family: inherit; font-family: inherit;
} }
.wr-btn {
font-family: inherit;
appearance: none;
border:0px;
border-radius: 6px;
padding: 8px;
font-weight: 600;
background: rgb(80 80 80 / 70%);
color: white;
}
.footer-player {
padding: 6px;
display:flex;
border-top: 1px solid rgb(200 200 200 / 15%);
background: rgb(200 200 200 / 10%);
}
.player-duration-time { .player-duration-time {
opacity: 0.5; opacity: 0.5;
} }
@ -151,7 +182,7 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
border-radius: 8px; border-radius: 8px;
box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); box-shadow: var(--mediaItemShadow);
transition: transform .10s var(--appleEase); transition: transform .10s var(--appleEase);
} }
@ -160,6 +191,14 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
transform: scale(0.85); transform: scale(0.85);
} }
.lossless-badge {
background: rgb(150 150 150);
border-radius: 6px;
padding: 0px 6px;
color: rgb(30 30 30);
font-weight: 600;
}
.playback-slider { .playback-slider {
width: 90%; width: 90%;
} }
@ -218,6 +257,10 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
background-color: rgb(200 200 200 / 10%); background-color: rgb(200 200 200 / 10%);
} }
.playback-button--small.activeColor {
background-color: var(--keyColor);
}
.playback-button--small.search { .playback-button--small.search {
background-image: url("./assets/search.svg"); background-image: url("./assets/search.svg");
} }
@ -230,6 +273,10 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
background-image: url("./assets/quote-right.svg"); background-image: url("./assets/quote-right.svg");
} }
.playback-button--small.autoplay {
background-image: url("./assets/infinity.svg");
}
.playback-button--small.shuffle { .playback-button--small.shuffle {
background-image: url("./assets/shuffle.svg"); background-image: url("./assets/shuffle.svg");
} }
@ -392,8 +439,8 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
background-size: cover; background-size: cover;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
border-radius: 8px; border-radius: 4px;
box-shadow: inset 0px 0px 0px 1px rgb(200 200 200 / 16%), 0 8px 40px rgb(0 0 0 / 0.55); box-shadow: var(--mediaItemShadow);
} }
.list-entry-image.artist { .list-entry-image.artist {
@ -424,10 +471,48 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
.list-entry .handle { .list-entry .handle {
height: 100%; height: 100%;
width: 28px; width: 28px;
background:var(--keyColor);
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background-size: contain;
background-repeat: no-repeat;
background-image: url('./assets/Grabber.svg');
cursor: grab;
}
.list-entry .handle:active {
cursor: grabbing;
}
.song-scroller-horizontal {
display:flex;
overflow-y: scroll;
overflow-x:hidden;
overflow-y: overlay;
width: 100%;
height: 200px;
/*! flex-flow: row; */
flex-direction: row;
flex-wrap: wrap;
}
.song-placeholder {
height: 60px;
width: 50%;
flex: 0 0 auto;
}
.mediaitem-scroller-horizontal {
display:flex;
overflow-y: hidden;
overflow-x:scroll;
overflow-x: overlay;
width: 100%;
}
.album-placeholder {
height: 180px;
width: 180px;
flex: 0 0 auto;
} }
.md-container { .md-container {
@ -485,6 +570,8 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: scroll;
overflow-y: overlay;
} }
.queue-body { .queue-body {
@ -492,6 +579,130 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
height: 100%; height: 100%;
} }
.text-overflow-elipsis {
min-width: 0px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.album-body-container {
position: relative;
width: 100%;
height: 100%;
overflow-y: scroll;
overflow-y: overlay;
overflow-x: hidden;
}
.albumpage-artwork {
--artwork: url("");
width: 30vh;
height: 30vh;
margin: 0 auto;
border-radius: 6px;
background:black;
margin-bottom: 18px;
box-shadow: var(--mediaItemShadow);
background-image: var(--artwork);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.albumpage-misc-info {
text-align: center;
font-size: 13px;
font-weight: 600;
opacity: 0.50;
}
.albumpage-album-notes {
margin: 0 auto;
margin-top: 16px;
height: 60px;
overflow: hidden;
position: relative;
max-width: 300px;
}
.albumpage-album-notes>.notes-preview {
height: 60px;
overflow: hidden;
-webkit-mask-image: -webkit-gradient(linear, left 95%, left bottom, from(rgba(0, 0, 0, 1)), to(rgba(0, 0, 0, 0)));
}
.albumpage-album-notes>.notes-more {
position: absolute;
bottom:0px;
right:0px;
appearance: none;
background: transparent;
color: var(--keyColor);
font-weight: bold;
font-family: inherit;
text-transform: uppercase;
height: 100%;
width: 100%;
padding: 0px;
border:0px;
display:flex;
justify-content: flex-end;
align-items: flex-end;
}
.album-page-fullnotes-body {
padding: 22px;
font-size: 17px;
overflow-y: scroll;
overflow-y: overlay;
}
.albumpage-album-name {
margin: 0 auto;
font-size: 17px;
width: 100%;
text-align: center;
font-weight: 600;
}
.albumpage-artist-name {
margin: 0 auto;
width: 100%;
text-align: center;
font-size: 18px;
color: var(--keyColor);
}
.albumpage-artist-name:hover {
text-decoration: underline;
cursor: pointer;
}
.artist-header {
height: 400px;
width: 100%;
margin: 12px auto;
display: flex;
justify-content: center;
align-items: center;
padding: 12px;
flex-direction: column;
background: rgb(0 0 0 / 40%);
}
.artist-header .artist-header-portrait {
height: 200px;
width: 200px;
background: var(--artwork);
background-size: contain;
background-repeat: no-repeat;
border-radius: 100%;
box-shadow: var(--mediaItemShadow);
}
.search-body { .search-body {
position: absolute; position: absolute;
width: 100%; width: 100%;
@ -499,6 +710,12 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
padding-top: 220px; padding-top: 220px;
} }
.artist-body {
position: absolute;
width: 100%;
height: 100%;
}
.search-tab { .search-tab {
background: rgb(20 20 20 / 0.85); background: rgb(20 20 20 / 0.85);
border-radius: 50px; border-radius: 50px;
@ -691,6 +908,48 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
height: 100%; height: 100%;
} }
.miniplayer-main {
width: 100%;
height: 100%;
position: relative;
}
.miniplayer-main .miniplayer-controls {
position: absolute;
bottom: 0px;
left: 0px;
background:rgb(0 0 0 / 50%);
height: 80px;
z-index: 2;
width:100%;
display:flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(16px) saturate(180%);
}
.miniplayer-main .miniplayer-draggable {
position: absolute;
top: 0;
left: 0;
height: calc(100% - 80px);
width: 100%;
}
.miniplayer-main .miniplayer-controls .md-btn {
width: 40px;
background-size: 16px;
}
.media-artwork--miniplayer {
width: 100%;
height: 100%;
background: var(--artwork);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
/* Small Screen */ /* Small Screen */
@media only screen and (max-height: 668px) { @media only screen and (max-height: 668px) {
#app { #app {
@ -705,6 +964,23 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
#app { #app {
max-width: 100%; max-width: 100%;
} }
.album-body-container {
display: flex;
flex-wrap: wrap;
}
.album-body-container>.md-header {
min-width: 300px;
flex: 0 0 auto;
/*! max-width: 300px; */
margin: 0 auto;
}
.artist-body {
position: relative;
/*! flex: 0 0 auto; */
}
.player-panel { .player-panel {
display: flex; display: flex;