koel/resources/assets/js/components/shared/add-to-menu.vue

175 lines
4.9 KiB
Vue
Raw Normal View History

2016-01-06 07:45:02 +00:00
<template>
2016-03-05 09:01:12 +00:00
<div class="add-to-playlist" v-show="showing" v-on-clickaway="close">
2016-01-16 18:11:24 +00:00
<p>Add {{ songs.length }} {{ songs.length | pluralize 'song' }} to</p>
2016-01-06 07:45:02 +00:00
<ul>
2016-04-07 10:49:08 +00:00
<li v-if="mergedSettings.canQueue" @click="queueSongsAfterCurrent">After Current Song</li>
2016-01-06 07:45:02 +00:00
<li v-if="mergedSettings.canQueue" @click="queueSongsToBottom">Bottom of Queue</li>
<li v-if="mergedSettings.canQueue" @click="queueSongsToTop">Top of Queue</li>
<li v-if="mergedSettings.canLike" @click="addSongsToFavorite">Favorites</li>
<li v-for="playlist in playlistState.playlists" @click="addSongsToExistingPlaylist(playlist)">{{ playlist.name }}</li>
2016-01-06 07:45:02 +00:00
</ul>
2016-01-16 18:11:24 +00:00
2016-01-06 07:45:02 +00:00
<p>or create a new playlist</p>
2016-02-19 07:20:34 +00:00
2016-01-06 07:45:02 +00:00
<form class="form-save form-simple" @submit.prevent="createNewPlaylistFromSongs">
2016-02-19 07:20:34 +00:00
<input type="text"
2016-03-05 09:01:12 +00:00
@keyup.esc.prevent="close"
2016-02-19 07:20:34 +00:00
v-model="newPlaylistName"
2016-01-06 07:45:02 +00:00
placeholder="Playlist name"
required>
2016-01-16 18:11:24 +00:00
<button type="submit">
<i class="fa fa-save"></i>
</button>
2016-01-06 07:45:02 +00:00
</form>
</div>
</template>
<script>
import { assign, last } from 'lodash';
2016-02-19 07:20:34 +00:00
import VueClickaway from 'vue-clickaway';
2016-01-06 07:45:02 +00:00
2016-03-05 09:01:12 +00:00
import songMenuMethods from '../../mixins/song-menu-methods';
2016-01-06 07:45:02 +00:00
import playlistStore from '../../stores/playlist';
export default {
props: ['songs', 'showing', 'settings'],
2016-03-05 09:01:12 +00:00
mixins: [VueClickaway.mixin, songMenuMethods],
2016-01-06 07:45:02 +00:00
data() {
return {
newPlaylistName: '',
playlistState: playlistStore.state,
mergedSettings: assign({
2016-01-06 07:45:02 +00:00
canQueue: true,
canLike: true,
}, this.settings),
};
},
watch: {
songs() {
if (!this.songs.length) {
2016-03-05 09:01:12 +00:00
this.close();
2016-01-06 07:45:02 +00:00
}
},
},
methods: {
/**
* Save the selected songs as a playlist.
* As of current we don't have selective save.
*/
createNewPlaylistFromSongs() {
this.newPlaylistName = this.newPlaylistName.trim();
2016-02-19 07:20:34 +00:00
2016-01-06 07:45:02 +00:00
if (!this.newPlaylistName) {
return;
}
playlistStore.store(this.newPlaylistName, this.songs, () => {
this.newPlaylistName = '';
2016-02-19 07:20:34 +00:00
this.$nextTick(() => {
// Activate the new playlist right away
this.$root.loadPlaylist(last(this.playlistState.playlists));
});
2016-01-06 07:45:02 +00:00
});
2016-01-07 01:11:16 +00:00
2016-03-05 09:01:12 +00:00
this.close();
2016-01-06 07:45:02 +00:00
},
2016-03-05 09:01:12 +00:00
/**
* Override the method from "songMenuMethods" mixin for this own logic.
*/
close() {
2016-01-07 01:11:16 +00:00
this.$dispatch('add-to-menu:close');
},
2016-01-06 07:45:02 +00:00
},
};
</script>
<style lang="sass" scoped>
2016-03-13 17:00:32 +00:00
@import "../../../sass/partials/_vars.scss";
@import "../../../sass/partials/_mixins.scss";
2016-01-06 07:45:02 +00:00
.add-to-playlist {
@include context-menu();
position: absolute;
2016-03-05 09:01:12 +00:00
padding: 8px;
2016-01-06 07:45:02 +00:00
top: 36px;
left: 0;
width: 100%;
2016-02-19 07:20:34 +00:00
2016-01-06 07:45:02 +00:00
p {
margin: 4px 0;
font-size: 90%;
&::first-of-type {
margin-top: 0;
}
}
$itemHeight: 28px;
$itemMargin: 2px;
ul {
max-height: 5 * ($itemHeight + $itemMargin);
2016-02-19 07:20:34 +00:00
overflow-y: scroll;
2016-01-06 07:45:02 +00:00
-webkit-overflow-scrolling: touch;
}
li {
background: rgba(255, 255, 255, .2);
height: $itemHeight;
line-height: $itemHeight;
padding: 0 8px;
margin: $itemMargin 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-radius: 3px;
background: #fff;
&:hover {
background: $colorHighlight;
color: #fff;
}
}
&::before {
display: block;
content: " ";
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
border-bottom: 10px solid rgb(232, 232, 232);
position: absolute;
top: -7px;
left: calc(50% - 10px);
}
form {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
input[type="text"] {
width: 100%;
border-radius: 5px 0 0 5px;
height: 28px;
}
button[type="submit"] {
margin-top: 0;
border-radius: 0 5px 5px 0 !important;
height: 28px;
margin-left: -2px !important;
}
}
}
</style>