added add to playlist for list item songs

This commit is contained in:
booploops 2021-12-22 02:44:53 -08:00
parent 2c3535fcdc
commit 00e032a0ec
6 changed files with 173 additions and 19 deletions

View file

@ -239,23 +239,60 @@ const app = new Vue({
hangtimer: null,
selectedMediaItems: [],
routes: ["browse", "listen_now", "radio"],
musicBaseUrl: "https://api.music.apple.com/"
musicBaseUrl: "https://api.music.apple.com/",
modals: {
addToPlaylist: false
},
},
watch: {
page: () => {
document.getElementById("app-content").scrollTo(0, 0);
app.selectedMediaItems = [];
app.resetState()
},
showingPlaylist: () => {
document.getElementById("app-content").scrollTo(0, 0);
app.selectedMediaItems = [];
app.resetState()
},
artistPage: () => {
document.getElementById("app-content").scrollTo(0, 0);
app.selectedMediaItems = [];
app.resetState()
},
},
methods: {
resetState() {
app.selectedMediaItems = [];
for (let key in app.modals) {
app.modals[key] = false;
}
},
promptAddToPlaylist() {
app.modals.addToPlaylist = true;
},
addSelectedToPlaylist(playlist_id) {
let self = this
let pl_items = []
for (let i = 0; i < self.selectedMediaItems.length; i++) {
if(self.selectedMediaItems[i].kind == "song") {
self.selectedMediaItems[i].kind = "songs"
}else if(self.selectedMediaItems[i].kind == "album") {
self.selectedMediaItems[i].kind = "albums"
} else if(self.selectedMediaItems[i].kind == "library-song") {
self.selectedMediaItems[i].kind = "library-songs"
} else if(self.selectedMediaItems[i].kind == "library-album") {
self.selectedMediaItems[i].kind = "library-albums"
}
pl_items.push({
id: self.selectedMediaItems[i].id,
type: self.selectedMediaItems[i].kind
})
}
this.modals.addToPlaylist = false
this.mk.api.library.appendTracksToPlaylist(playlist_id, pl_items).then(()=>{
if(this.page == 'playlist_' + this.showingPlaylist.id) {
this.getPlaylistFromID(this.showingPlaylist.id)
}
})
},
async init() {
let self = this
clearTimeout(this.hangtimer)
@ -326,7 +363,7 @@ const app = new Vue({
let type = (self.mk.nowPlayingItem != null) ? self.mk.nowPlayingItem["type"] ?? '' : '';
if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie")) {
if (type.includes("musicVideo") || type.includes("uploadedVideo") || type.includes("music-movie")) {
document.getElementById("apple-music-video-container").style.display = "block";
// app.chrome.topChromeVisible = false
} else {
@ -366,7 +403,6 @@ const app = new Vue({
this.appRoute(window.location.hash)
}
setTimeout(() =>{
this.getBrowsePage();
this.$forceUpdate()}, 500)
@ -401,13 +437,14 @@ const app = new Vue({
return false
}
},
select_selectMediaItem(id, kind, index, guid) {
select_selectMediaItem(id, kind, index, guid, library) {
if (!this.select_hasMediaItem(guid)) {
this.selectedMediaItems.push({
id: id,
kind: kind,
index: index,
guid: guid
guid: guid,
isLibrary: library
})
}
},
@ -466,10 +503,11 @@ const app = new Vue({
let playlistId = response.id
this.playlists.loadingState = 0
this.showingPlaylist = response
if(!response.relationships.tracks.next) {
if (!response.relationships.tracks.next) {
this.playlists.loadingState = 1
return
}
function getPlaylistTracks(next) {
app.apiCall(app.musicBaseUrl + next, res => {
if (self.showingPlaylist.id != playlistId) {
@ -669,7 +707,6 @@ const app = new Vue({
window.location.hash = `${kind}/${id}`
document.querySelector("#app-content").scrollTop = 0
} else if (!kind.toString().includes("radioStation") && !kind.toString().includes("song") && !kind.toString().includes("musicVideo") && !kind.toString().includes("uploadedVideo") && !kind.toString().includes("music-movie")) {
if (kind.toString().includes("music-movie")){kind = "musicMovie"}
app.page = (kind) + "_" + (id);
app.getTypeFromID((kind), (id), (isLibrary), {extend: "editorialVideo"});
window.location.hash = `${kind}/${id}`

View file

@ -1520,6 +1520,49 @@ input[type="range"].web-slider.display--small::-webkit-slider-thumb {
/* Cider */
.modal-fullscreen {
display:flex;
justify-content: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
.modal-window {
background: #333;
border-radius: var(--mediaItemRadius);
box-shadow: var(--mediaItemShadow-Shadow);
display:flex;
flex-flow: column;
.modal-header {
width:100%;
padding: 6px;
}
.modal-content {
width:100%;
height:100%;
overflow: hidden;
overflow-y: scroll;
}
.modal-footer {
}
}
}
.addtoplaylist-panel {
.modal-header {
padding: 16px;
}
.modal-window {
max-height: 500px;
max-width: 300px;
}
}
#navigation-bar {
width: 100%;
background: rgba(0, 0, 0, 0.25);

View file

@ -0,0 +1,36 @@
<script type="text/x-template" id="add-to-playlist">
<template>
<div class="modal-fullscreen addtoplaylist-panel" @click.self="app.resetState()">
<div class="modal-window">
<div class="modal-header">
<div class="row">
<div class="col flex-center">
Add To Playlist
</div>
<div class="col-auto">
<button class="md-btn" @click="app.resetState()">Close</button>
</div>
</div>
</div>
<div class="modal-content">
<button class="md-btn" @click="app.addSelectedToPlaylist(playlist.id)" style="width:100%;" v-for="playlist in playlists" v-if="playlist.attributes.canEdit && playlist.type != 'library-playlist-folders'">{{ playlist.attributes.name }}</button>
</div>
</div>
</div>
</template>
</script>
<script>
Vue.component('add-to-playlist', {
template: '#add-to-playlist',
props: {
playlists: {
type: Array,
required: true
}
},
methods: {
}
});
</script>

View file

@ -4,9 +4,10 @@
@contextmenu="contextMenu"
@click="select"
:data-id="item.attributes.playParams.id ?? item.id"
:data-type="item.type ?? item.attributes.playParams.kind"
:data-type="getDataType()"
:data-index="index"
:data-guid="guid"
:data-islibrary="this.item.attributes.playParams.isLibrary ?? false"
class="cd-mediaitem-list-item"
:class="{'mediaitem-selected': app.select_hasMediaItem(guid)}">
<template v-if="isVisible">
@ -84,11 +85,23 @@
'contextExt': {type: Object, required: false},
},
methods: {
getDataType() {
if(this.item.attributes.playParams.isLibrary) {
return this.item.type
}else{
return this.item.attributes.playParams.kind
}
},
select(e) {
let data_type = this.getDataType()
let item_id = this.item.attributes.playParams.id ?? this.item.id
let isLibrary = this.item.attributes.playParams.isLibrary ?? false
if (e.shiftKey) {
if (this.index != -1) {
if(app.selectedMediaItems.length == 0) {
app.select_selectMediaItem(this.item.attributes.playParams.id ?? this.item.id, this.item.attributes.playParams.kind ?? this.item.type, this.index, this.guid)
app.select_selectMediaItem(item_id, this.getDataType(), this.index, this.guid, isLibrary)
}
let allMediaItems = document.querySelectorAll(".cd-mediaitem-list-item[data-index]")
let startIndex = Math.min(...app.selectedMediaItems.map(item => item.index))
@ -100,7 +113,8 @@
app.select_selectMediaItem(item.getAttribute("data-id"),
item.getAttribute("data-type"),
item.getAttribute("data-index"),
item.getAttribute("data-guid"))
item.getAttribute("data-guid")),
item.getAttribute("data-islibrary")
}
}
} else if (this.index > endIndex) {
@ -110,7 +124,8 @@
app.select_selectMediaItem(item.getAttribute("data-id"),
item.getAttribute("data-type"),
item.getAttribute("data-index"),
item.getAttribute("data-guid"))
item.getAttribute("data-guid")),
item.getAttribute("data-islibrary")
}
}
} else {
@ -120,7 +135,8 @@
app.select_selectMediaItem(item.getAttribute("data-id"),
item.getAttribute("data-type"),
item.getAttribute("data-index"),
item.getAttribute("data-guid"))
item.getAttribute("data-guid")),
item.getAttribute("data-islibrary")
}
}
}
@ -129,29 +145,39 @@
if (app.select_hasMediaItem(this.guid)) {
app.select_removeMediaItem(this.guid)
} else {
app.select_selectMediaItem(this.item.attributes.playParams.id ?? this.item.id, this.item.attributes.playParams.kind ?? this.item.type, this.index, this.guid)
app.select_selectMediaItem(item_id, this.getDataType(), this.index, this.guid, isLibrary)
}
} else {
if (app.select_hasMediaItem(this.guid)) {
app.selectedMediaItems = []
} else {
app.selectedMediaItems = []
app.select_selectMediaItem(this.item.attributes.playParams.id ?? this.item.id, this.item.attributes.playParams.kind ?? this.item.type, this.index, this.guid)
app.select_selectMediaItem(item_id, this.getDataType(), this.index, this.guid, isLibrary)
}
}
},
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 useMenu = "normal"
if (app.selectedMediaItems.length <= 1) {
app.selectedMediaItems = []
app.select_selectMediaItem(this.item.attributes.playParams.id ?? this.item.id, this.item.attributes.playParams.kind ?? this.item.type, this.index, this.guid)
app.select_selectMediaItem(item_id, data_type, this.index, this.guid, isLibrary)
} else {
useMenu = "multiple"
}
let menus = {
multiple: {
items: [
{
"name": "Add to Playlist...",
"action": function () {
app.promptAddToPlaylist()
}
},
{
name: `Play ${app.selectedMediaItems.length} tracks next`,
action: () => {
@ -197,6 +223,12 @@
},
normal: {
items: [
{
"name": "Add to Playlist...",
"action": function () {
app.promptAddToPlaylist()
}
},
{
"name": "Start Radio",
"action": function () {

View file

@ -173,6 +173,7 @@
Playlists
</div>
<button class="app-sidebar-item" v-for="item in playlists.listing" :key="item.id"
@dragover="()=>{}"
:href="item.href"
@click='appRoute(`playlist_` + item.id); showingPlaylist = [];getPlaylistFromID(app.page.substring(9))'>
{{ item.attributes.name }}
@ -408,6 +409,9 @@
<transition name="wpfade">
<div class="bg-artwork--placeholder" v-else></div>
</transition>
<transition name="wpfade">
<add-to-playlist :playlists="playlists.listing" v-if="modals.addToPlaylist"></add-to-playlist>
</transition>
<div id="apple-music-video-container">
<div id="apple-music-video-player-controls">
<div id="player-exit" title="Close" onclick="app.exitMV()">
@ -485,6 +489,8 @@
</button>
</script>
<!-- Add to playlist -->
<%- include('components/add-to-playlist') %>
<!-- Queue -->
<%- include('components/queue') %>
<!-- Queue Item -->

View file

@ -60,7 +60,7 @@
<div class="playlist-body">
<div class="well">
<div style="width:100%">
<draggable :sort="data.attributes.canEdit" v-model="data.relationships.tracks.data" @start="drag=true" @end="drag=false;put()">
<draggable :sort="data.attributes.canEdit && data.type == 'library-playlists'" v-model="data.relationships.tracks.data" @start="drag=true" @end="drag=false;put()">
<mediaitem-list-item :item="item" :parent="getItemParent(data)" :index="index" :context-ext="buildContextMenu()"
v-for="(item,index) in data.relationships.tracks.data"></mediaitem-list-item>
</draggable>