Skip to content

Commit

Permalink
Add ability to add songs to a playlist
Browse files Browse the repository at this point in the history
  • Loading branch information
zachomedia committed Jun 12, 2019
1 parent 5262970 commit 10d7a0a
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 13 deletions.
101 changes: 88 additions & 13 deletions src/components/controls/SongActions.vue
Original file line number Diff line number Diff line change
@@ -1,35 +1,66 @@
<template>
<b-dropdown variant="link" size="sm" no-caret right boundary="window" v-if="(isAuthorized && !isLibrary) || showQueue || (song.assets && song.assets[0] && song.assets[0].metadata)">
<template slot="button-content">
<i class="fa fa-ellipsis-h" /><span class="sr-only">Song actions</span>
</template>
<div>
<b-dropdown variant="link" size="sm" no-caret right boundary="window" v-if="(isAuthorized && !isLibrary) || showQueue || (song.assets && song.assets[0] && song.assets[0].metadata)">
<template slot="button-content">
<i class="fa fa-ellipsis-h" /><span class="sr-only">Song actions</span>
</template>

<b-dropdown-item-button @click.stop="addToLibrary()" v-if="isAuthorized && !isLibrary">Add to library</b-dropdown-item-button>
<b-dropdown-item-button @click.stop="goToAlbum()" v-if="song.assets && song.assets[0] && song.assets[0].metadata">Go to album</b-dropdown-item-button>
<b-dropdown-divider v-if="(isAuthorized && !isLibrary) || (song.assets && song.assets[0] && song.assets[0].metadata)" />
<b-dropdown-item-button v-if="showQueue" @click.stop="playNext()">Play next</b-dropdown-item-button>
<b-dropdown-item-button v-if="showQueue" @click.stop="playLater()">Play later</b-dropdown-item-button>
<b-dropdown-divider v-if="showQueue && isAuthorized" />
<b-dropdown-item-button @click.stop="love()" v-if="isAuthorized">Love</b-dropdown-item-button>
<b-dropdown-item-button @click.stop="dislike()" v-if="isAuthorized">Dislike</b-dropdown-item-button>
</b-dropdown>
<b-dropdown-item-button @click.stop="addToLibrary()" v-if="isAuthorized && !isLibrary">Add to library</b-dropdown-item-button>
<b-dropdown-item-button @click.stop="showAddToPlaylistPopup()" v-if="isAuthorized">Add to playlist</b-dropdown-item-button>
<b-dropdown-divider v-if="isAuthorized || (song.assets && song.assets[0] && song.assets[0].metadata)" />
<b-dropdown-item-button @click.stop="goToAlbum()" v-if="song.assets && song.assets[0] && song.assets[0].metadata">Go to album</b-dropdown-item-button>
<b-dropdown-divider v-if="(isAuthorized && !isLibrary) || (song.assets && song.assets[0] && song.assets[0].metadata)" />
<b-dropdown-item-button v-if="showQueue" @click.stop="playNext()">Play next</b-dropdown-item-button>
<b-dropdown-item-button v-if="showQueue" @click.stop="playLater()">Play later</b-dropdown-item-button>
<b-dropdown-divider v-if="showQueue && isAuthorized" />
<b-dropdown-item-button @click.stop="love()" v-if="isAuthorized">Love</b-dropdown-item-button>
<b-dropdown-item-button @click.stop="dislike()" v-if="isAuthorized">Dislike</b-dropdown-item-button>
</b-dropdown>

<b-modal v-model="showAddToPlaylist" title="Add to playlist" centered hide-footer>
<error-message :error="playlistsError" v-if="playlistsError" />
<loader v-else-if="loadingPlaylists" />
<b-list-group v-else>
<b-list-group-item href="#" v-for="playlist in writablePlaylists" :key="playlist.id" @click.stop="addToPlaylist(playlist)">{{ playlist.attributes.name }}</b-list-group-item>
</b-list-group>
</b-modal>
</div>
</template>

<script>
import { mapState } from 'vuex';
import { errorMessage, trackToMediaItem, EventBus } from '../../utils';
import Raven from 'raven-js';
import mergeWith from 'lodash.mergewith';
import Loader from '../utils/Loader';
import ErrorMessage from '../utils/ErrorMessage';
export default {
name: 'SongActions',
props: {
song: Object,
showQueue: Boolean
},
components: {
Loader,
ErrorMessage
},
data () {
return {
showAddToPlaylist: false,
loadingPlaylists: false,
playlists: [],
playlistsError: null
};
},
computed: {
...mapState('musicKit', ['isAuthorized']),
isLibrary () {
return this.song.type.indexOf('library-') === 0;
},
writablePlaylists () {
return this.playlists.filter(p => p.attributes.canEdit);
}
},
methods: {
Expand All @@ -48,6 +79,50 @@ export default {
this.$store.dispatch('alerts/add', errorMessage(err));
}
},
async showAddToPlaylistPopup () {
this.loadingPlaylists = true;
this.showAddToPlaylist = true;
this.playlists = [];
try {
let options = { limit: 100 };
for (var offset = 0, res = null; res === null || res.length !== 0; offset += options.limit) {
res = await this.$store.getters['musicKit/get'](true, 'playlists', undefined, mergeWith(options, { offset: offset }));
this.playlists = this.playlists.concat(res);
}
} catch (err) {
console.error(err);
Raven.captureException(err);
this.playlistsError = err;
}
this.loadingPlaylists = false;
},
async addToPlaylist (playlist) {
try {
this.showAddToPlaylist = false;
await this.$store.dispatch('musicKit/addToPlaylist', {
playlistId: playlist.id,
items: [
{
id: this.song.id,
type: this.song.type
}
]
});
this.$store.dispatch('alerts/add', {
variant: 'success',
title: 'Added to playlist',
message: `Successfully added "${this.song.attributes.name}" to "${playlist.attributes.name}".`
});
} catch (err) {
console.error(err);
Raven.captureException(err);
this.$store.dispatch('alerts/add', errorMessage(err));
}
},
goToAlbum () {
if (this.song.assets && this.song.assets[0].metadata) {
this.$router.push({
Expand Down
22 changes: 22 additions & 0 deletions src/store/modules/musicKit.js
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,28 @@ const actions = {
addToLibrary (_, items) {
let api = getApi(false);
return api.addToLibrary(items);
},

addToPlaylist (_, { playlistId, items }) {
return new Promise(async (resolve, reject) => {
try {
let res = await fetch(`https://api.music.apple.com/v1/me/library/playlists/${playlistId}/tracks`, {
method: 'POST',
headers: apiHeaders(),
body: JSON.stringify({
data: items
})
});

if (res.status === 200 || res.status === 204) {
resolve(true);
} else {
reject(MusicKit.MKError(MusicKit.MKError.SERVER_ERROR));
}
} catch (err) {
reject(err);
}
});
}
};

Expand Down

0 comments on commit 10d7a0a

Please sign in to comment.