add ratings, library change to web remote (#1285)

This commit is contained in:
Kendall Garner 2022-07-26 15:55:38 +00:00 committed by GitHub
parent 3ab6d3e56c
commit 8cf2ddf8dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 246 additions and 13 deletions

View file

@ -64,6 +64,15 @@ export class wsapi {
electron.ipcMain.on('wsapi-returnvolumeMax', (_event: any, arg: any) => {
this.returnmaxVolume(JSON.parse(arg));
});
electron.ipcMain.on('wsapi-libraryStatus', (_event: any, inLibrary: boolean, rating: number) => {
this.returnLibraryStatus(inLibrary, rating);
});
electron.ipcMain.on('wsapi-rate', (_event: any, kind: string, id: string, rating: number) => {
this.returnRatingStatus(kind, id, rating);
});
electron.ipcMain.on('wsapi-change-library', (_event: any, kind: string, id: string, shouldAdd: boolean) => {
this.returnLibraryChange(kind, id, shouldAdd);
});
this.wss = new WebSocketServer({
port: this.port,
perMessageDeflate: {
@ -242,6 +251,15 @@ export class wsapi {
case "get-currentmediaitem":
this._win.webContents.executeJavaScript(`wsapi.getPlaybackState()`);
break;
case "library-status":
this._win.webContents.executeJavaScript(`wsapi.getLibraryStatus("${data.type}", "${data.id}")`);
break;
case "rating":
this._win.webContents.executeJavaScript(`wsapi.rate("${data.type}", "${data.id}", ${data.rating})`);
break;
case "change-library":
this._win.webContents.executeJavaScript(`wsapi.changeLibrary("${data.type}", "${data.id}", ${data.add})`);
break;
case "quit":
electron.app.quit();
break;
@ -317,4 +335,35 @@ export class wsapi {
client.send(JSON.stringify(response));
});
}
returnLibraryStatus(inLibrary: boolean, rating: number) {
const response: standardResponse = {
status: 0, data: {
inLibrary, rating
}, message: "OK", type: "libraryStatus"
}
this.clients.forEach(function each(client: any) {
client.send(JSON.stringify(response));
});
}
returnRatingStatus(kind: string, id: string, rating: number) {
const response: standardResponse = {
status: 0, data: { kind, id, rating },
message: "OK", type: "rate"
};
this.clients.forEach(function each(client: any) {
client.send(JSON.stringify(response));
});
}
returnLibraryChange(kind: string, id: string, shouldAdd: boolean) {
const response: standardResponse = {
status: 0, data: { kind, id, add: shouldAdd },
message: "OK", type: "change-library"
};
this.clients.forEach(function each(client: any) {
client.send(JSON.stringify(response));
});
}
}

View file

@ -118,6 +118,76 @@ const wsapi = {
},
getmaxVolume() {
ipcRenderer.send('wsapi-returnvolumeMax',JSON.stringify(app.cfg.audio.maxVolume));
},
getLibraryStatus(kind, id) {
if (kind === undefined || id === "no-id-found") return;
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/?ids[${truekind}]=${id}`, {
relate: "library",
fields: "inLibrary"
}).then(data => {
const res = data.data.data[0];
const inLibrary = res && res.attributes && res.attributes.inLibrary;
app.getRating({ type: truekind, id: id }).then(rating => {
ipcRenderer.send('wsapi-libraryStatus', inLibrary, rating);
})
})
},
rate(kind, id, rating) {
if (kind === undefined || id === "no-id-found") return;
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
if (rating === 0) {
app.mk.api.v3.music(`/v1/me/ratings/${truekind}/${id}`, {}, {
fetchOptions: {
method: "DELETE",
}
}).then(function () {
ipcRenderer.send('wsapi-rate', kind, id, rating);
})
} else {
app.mk.api.v3.music(`/v1/me/ratings/${truekind}/${id}`, {}, {
fetchOptions: {
method: "PUT",
body: JSON.stringify({
"type": "rating",
"attributes": {
"value": rating
}
})
}
}).then(function () {
ipcRenderer.send('wsapi-rate', kind, id, rating);
})
}
},
changeLibrary(kind, id, shouldAdd) {
if (shouldAdd) {
app.addToLibrary(id);
ipcRenderer.send('wsapi-change-library', kind, id, shouldAdd);
} else {
let truekind = (!kind.endsWith("s")) ? (kind + "s") : kind;
app.mk.api.v3.music(`/v1/catalog/${app.mk.storefrontId}/?ids[${truekind}]=${id}`, {
relate: "library",
fields: "inLibrary"
})
.then(res => {
res = res.data.data[0]
if (res && res.relationships && res.relationships.library && res.relationships.library.data) {
const item = res.relationships.library.data[0];
if (item) {
app.removeFromLibrary(kind, item.id)
}
ipcRenderer.send('wsapi-change-library', kind, id, shouldAdd);
}
});
}
}
}

View file

@ -24,7 +24,11 @@ var app = new Vue({
lyricsScrollingBlocked: false,
queue: {},
lowerPanelState: "controls",
userInteraction: false
userInteraction: false,
status: {
inLibrary: false,
rating: 0
}
},
queue: {
temp: []
@ -246,6 +250,17 @@ var app = new Vue({
id: id
}))
},
getLibraryStatus(type, id) {
if (type !== undefined && id !== "no-id-found") {
socket.send(JSON.stringify({
action: "library-status",
type: type,
id: id
}))
} else {
this.player.status = {};
}
},
searchQuery() {
if (this.search.query.length == 0) {
this.search.state = 0;
@ -412,8 +427,8 @@ var app = new Vue({
this.getQueue()
},
queueMove(evt) {
console.log(evt)
console.log(`new: ${evt.moved.newIndex} old: ${evt.moved.oldIndex}`)
// console.log(evt)
// console.log(`new: ${evt.moved.newIndex} old: ${evt.moved.oldIndex}`)
this.queue.temp.splice(evt.moved.newIndex, 0, this.queue.temp.splice(evt.moved.oldIndex, 1)[0])
socket.send(JSON.stringify({
action: "queue-move",
@ -557,11 +572,9 @@ var app = new Vue({
}
socket.onmessage = (e) => {
console.log(e.data)
const response = JSON.parse(e.data);
switch (response.type) {
default: console.log(response);
break;
default: break;
case "musickitapi.search":
self.showArtist(response.data["artists"][0]["id"]);
break;
@ -577,7 +590,8 @@ var app = new Vue({
}
break;
case "queue":
self.player.queue = response.data;
// console.log(response.data);
self.player.queue = response.data;
self.queue.temp = response.data["_queueItems"];
self.$forceUpdate()
break;
@ -601,6 +615,27 @@ var app = new Vue({
case "maxVolume":
this.player.maxVolume = response.data;
break;
case "libraryStatus":
this.player.status = response.data;
break;
case "rate":
var params = this.player.currentMediaItem.playParams;
if (params && params.id === response.data.id && params.kind === response.data.kind) {
this.player.status = {
rating: response.data.rating,
inLibrary: this.player.status.inLibrary
}
}
break;
case "change-library":
var params = this.player.currentMediaItem.playParams;
if (params && params.id === response.data.id && params.kind === response.data.kind) {
this.player.status = {
rating: this.player.status.rating,
inLibrary: response.data.add
}
}
break;
}
// console.log(e.data);
}
@ -608,6 +643,8 @@ var app = new Vue({
updatePlaybackState(mediaitem) {
var lyricsDisplayed = this.screen == "lyrics" || this.player.lowerPanelState == "lyrics"
if (this.player.currentMediaItem["isrc"] != mediaitem["isrc"]) {
this.getLibraryStatus(mediaitem.playParams.kind, mediaitem.playParams.id)
if (lyricsDisplayed) {
this.getLyrics()
}
@ -617,6 +654,39 @@ var app = new Vue({
}
this.player.currentMediaItem = mediaitem
},
openSongMenu() {
const params = this.player.currentMediaItem.playParams;
if (params) {
this.getLibraryStatus(params.kind, params.id);
}
this.player.songActions = true;
},
rate(rating) {
const params = this.player.currentMediaItem.playParams;
if (params && params.kind !== undefined && params.id !== "no-id-found") {
socket.send(JSON.stringify({
action: "rating",
type: params.kind,
id: params.id,
rating: rating
}))
}
},
toLibrary(shouldAdd) {
const params = this.player.currentMediaItem.playParams;
if (params && params.kind !== undefined && params.id !== "no-id-found") {
socket.send(JSON.stringify({
action: "change-library",
type: params.kind,
id: params.id,
add: shouldAdd
}))
}
},
quit() {
socket.send(JSON.stringify({
action: "quit"

View file

@ -838,6 +838,15 @@ input[type=range].web-slider::-webkit-slider-runnable-track {
cursor: pointer;
}
.context-menu .context-menu-item:disabled {
cursor: default;
filter: brightness(125%);
}
.context-menu .context-menu-item:active:disabled {
filter: brightness(125%);
}
.context-menu .context-menu-item:active {
filter: brightness(75%);
}

View file

@ -130,8 +130,8 @@
{{ player.currentMediaItem.artistName }}
</div>
</div>
<div class="col-auto nopadding player-more-container" v-if="false" style="">
<button @click="player.songActions = true;" class="player-more-button">...</button>
<div class="col-auto nopadding player-more-container" style="">
<button @click="openSongMenu()" class="player-more-button">...</button>
</div>
</div>
</div>
@ -525,7 +525,8 @@
</div>
<div class="md-body context-menu-body">
<button class="context-menu-item context-menu-item--left" v-if="false">
<button class="context-menu-item context-menu-item--left" v-if="!player.status.inLibrary"
@click="toLibrary(true)">
<div class="row">
<div class="col">
Add To Library
@ -535,7 +536,19 @@
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left" v-if="false">
<button class="context-menu-item context-menu-item--left" v-if="player.status.inLibrary"
@click="toLibrary(false)">
<div class="row">
<div class="col">
Remove From Library
</div>
<div class="col-auto">
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left" :disabled="player.status.rating === 1"
@click="rate(1)">
<div class="row">
<div class="col">
Love
@ -545,7 +558,29 @@
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left">
<button class="context-menu-item context-menu-item--left" :disabled="player.status.rating === 0"
@click="rate(0)">
<div class="row">
<div class="col">
Remove Rating
</div>
<div class="col-auto">
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left"
:disabled="player.status.rating === -1" @click="rate(-1)">
<div class="row">
<div class="col">
Dislike
</div>
<div class="col-auto">
👎
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left" v-if="false">
<div class="row">
<div class="col">
Share
@ -555,7 +590,7 @@
</div>
</div>
</button>
<button class="context-menu-item context-menu-item--left">
<button class="context-menu-item context-menu-item--left" v-if="false">
<div class="row">
<div class="col">
Open in {{ musicAppVariant() }}