Imported changes to web-remote from AME
This commit is contained in:
parent
45623f257b
commit
ab6c24f9be
11 changed files with 1265 additions and 595 deletions
1
index.js
1
index.js
|
@ -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")){
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
22
resources/web-remote/assets/Grabber.svg
Normal file
22
resources/web-remote/assets/Grabber.svg
Normal 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 |
1
resources/web-remote/assets/infinity.svg
Normal file
1
resources/web-remote/assets/infinity.svg
Normal 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
|
@ -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
|
||||||
|
|
|
@ -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"
|
|
||||||
}
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue