Bladeren bron

Finished most of QueueSongs.vue

theflametrooper 8 jaren geleden
bovenliggende
commit
ddd3afa22d
3 gewijzigde bestanden met toevoegingen van 129 en 46 verwijderingen
  1. 17 16
      backend/logic/actions/queueSongs.js
  2. 10 4
      backend/logic/actions/songs.js
  3. 102 26
      frontend/components/Admin/QueueSongs.vue

+ 17 - 16
backend/logic/actions/queueSongs.js

@@ -8,17 +8,17 @@ const async = require('async');
 const config = require('config');
 const request = require('request');
 
-notifications.subscribe("queue.newSong", function(songId) {
-	io.to('admin.queue').emit("event:song.new", { songId });
+notifications.subscribe('queue.newSong', songId => {
+	io.to('admin.queue').emit('event:song.new', { songId });
 });
 
-notifications.subscribe("queue.removedSong", function(songId) {
-	io.to('admin.queue').emit("event:song.removed", { songId });
+notifications.subscribe('queue.removedSong', songId => {
+	io.to('admin.queue').emit('event:song.removed', { songId });
 });
 
-notifications.subscribe("queue.updatedSong", function(songId) {
+notifications.subscribe('queue.updatedSong', songId => {
 	//TODO Retrieve new Song object
-	io.to('admin.queue').emit("event:song.updated", { songId });
+	io.to('admin.queue').emit('event:song.updated', { songId });
 });
 
 module.exports = {
@@ -36,12 +36,12 @@ module.exports = {
 		//TODO Check if id and updatedSong is valid
 		db.models.queueSong.findOne({ id }, function(err, queueSong) {
 			if (err) throw err;
-			//List of properties that are allowed to be changed
-			const updatableProperties = ["id", "title", "artists", "genres", "thumbnail", "explicit", "duration", "skipDuration"];
+			// List of properties that are allowed to be changed
+			const updatableProperties = ['id', 'title', 'artists', 'genres', 'thumbnail', 'explicit', 'duration', 'skipDuration'];
 			//TODO Check if new id, if any, is already in use in queue or on rotation
 			let updated = false;
 			for (let prop in queueSong) {
-				if (updatableProperties.indexOf(prop) !== -1 && updatedSong.hasOwnProperty("prop") && updatedSong[prop] !== queueSong[prop]) {
+				if (updatableProperties.indexOf(prop) !== -1 && updatedSong.hasOwnProperty('prop') && updatedSong[prop] !== queueSong[prop]) {
 					queueSong[prop] = updatedSong[prop];
 					updated = true;
 				}
@@ -57,9 +57,10 @@ module.exports = {
 		});
 	},
 
-	remove: (session, id, cb) => {
-		//TODO Require admin/login
-		db.models.queueSong.find({ id }).remove().exec();
+	remove: (session, _id, cb) => {
+		// TODO Require admin/login
+		db.models.queueSong.find({ _id }).remove().exec();
+		cb({ status: 'success', message: 'Song was removed successfully' });
 	},
 
 	add: (session, id, cb) => {
@@ -90,22 +91,22 @@ module.exports = {
 
 					//TODO Clean up duration converter
 					let dur = body.items[0].contentDetails.duration;
-					dur = dur.replace("PT", "");
+					dur = dur.replace('PT', '');
 					let durInSec = 0;
 					dur = dur.replace(/([\d]*)H/, function(v, v2) {
 						v2 = Number(v2);
 						durInSec = (v2 * 60 * 60)
-						return "";
+						return '';
 					});
 					dur = dur.replace(/([\d]*)M/, function(v, v2) {
 						v2 = Number(v2);
 						durInSec = (v2 * 60)
-						return "";
+						return '';
 					});
 					dur = dur.replace(/([\d]*)S/, function(v, v2) {
 						v2 = Number(v2);
 						durInSec += v2;
-						return "";
+						return '';
 					});
 
 					let newSong = {

+ 10 - 4
backend/logic/actions/songs.js

@@ -19,17 +19,23 @@ module.exports = {
 		});
 	},
 
-	remove: (session, id, cb) => {
+	remove: (session, _id, cb) => {
 		//TODO Require admin/login
-		db.models.song.find({ id }).remove().exec();
+		db.models.song.find({ _id }).remove().exec();
 	},
 
-	add: (session, id, cb) => {
+	add: (session, song, cb) => {
 		//TODO Require admin/login
+		console.log(session.logged_in);
 		// if (!session.logged_in) return cb({ status: 'failure', message: 'You must be logged in to add a song' });
+		const newSong = new db.models.song(song);
+		newSong.save(err => {
+			if (err) throw err;
+			else cb({ status: 'success', message: 'Song has been moved from Queue' })
+		});
 		//TODO Check if video already in songs list
 		//TODO Check if video is in queue
-		//TODO Move video over, if it has the proper properties, and add the song to the appropriate stations
+		//TODO Add the song to the appropriate stations
 	}
 
 };

+ 102 - 26
frontend/components/Admin/QueueSongs.vue

@@ -1,69 +1,131 @@
 <template>
-	<div class="columns is-mobile">
-		<div class="column is-8-desktop is-offset-2-desktop is-12-mobile">
-			<table class="table is-striped">
+	<div class='columns is-mobile'>
+		<div class='column is-8-desktop is-offset-2-desktop is-12-mobile'>
+			<table class='table is-striped'>
 				<thead>
 					<tr>
-						<td>YouTube ID</td>
 						<td>Title</td>
-						<td>Thumbnail</td>
+						<td>YouTube ID</td>
 						<td>Artists</td>
+						<td>Genres</td>
 						<td>Options</td>
 					</tr>
 				</thead>
 				<tbody>
-					<tr v-for="(index, song) in songs" track-by="$index">
+					<tr v-for='(index, song) in songs' track-by='$index'>
 						<td>
-							<p class="control">
-								<input class="input" type="text" :value="song._id" v-model="song._id">
+							<p class='control'>
+								<input class='input' type='text' v-model='song.title'>
 							</p>
 						</td>
 						<td>
-							<p class="control">
-								<input class="input" type="text" :value="song.title" v-model="song.title">
+							<p class='control'>
+								<input class='input' type='text' v-model='song._id'>
 							</p>
 						</td>
 						<td>
-							<p class="control">
-								<input class="input" type="text" :value="song.thumbnail" v-model="song.thumbnail">
-							</p>
+							<div class='control'>
+								<input v-for='artist in song.artists' track-by='$index' class='input' type='text' v-model='artist'>
+							</div>
 						</td>
 						<td>
-							<div class="control">
-								<input v-for="artist in song.artists" track-by="$index" class="input" type="text" :value="artist" v-model="artist">
+							<div class='control'>
+								<input v-for='genre in song.genres' track-by='$index' class='input' type='text' v-model='genre'>
 							</div>
 						</td>
 						<td>
-							<a class="button is-danger" @click="remove(song, index)">Remove</a>
-							<a class="button is-success" @click="update(song)">Save Changes</a>
+							<a class='button is-primary' @click='edit(song, index)'>Edit</a>
+							<a class='button is-success' @click='add(song)'>Add</a>
+							<a class='button is-danger' @click='remove(song._id, index)'>Remove</a>
 						</td>
 					</tr>
 				</tbody>
 			</table>
 		</div>
 	</div>
+	<div class='modal' :class="{ 'is-active': isEditActive }">
+		<div class='modal-background'></div>
+		<div class='modal-card'>
+			<section class='modal-card-body'>
+				<h5 class='has-text-centered'><strong>Thumbnail Preview</strong></h5>
+				<img class='thumbnail-preview' :src='beingEdited.song.thumbnail'>
+				<label class='label'>Thumbnail URL</label>
+				<p class='control'>
+					<input class='input' type='text' v-model='beingEdited.song.thumbnail'>
+				</p>
+				<h5 class='has-text-centered'><strong>Edit Info</strong></h5>
+				<!--<label class='label'>Email</label>
+				<p class='control'>
+					<input class='input' type='text' placeholder='Email...' v-model='$parent.register.email'>
+				</p>-->
+				<label class='label'>Song ID</label>
+				<p class='control'>
+					<input class='input' type='text' v-model='beingEdited.song._id'>
+				</p>
+				<label class='label'>Song Title</label>
+				<p class='control'>
+					<input class='input' type='text' v-model='beingEdited.song.title'>
+				</p>
+				<label class='label'>Artists</label>
+				<div class='control'>
+					<input v-for='artist in beingEdited.song.artists' track-by='$index' class='input' type='text' v-model='artist'>
+				</div>
+				<label class='label'>Genres</label>
+				<div class='control'>
+					<input v-for='genre in beingEdited.song.genres' track-by='$index' class='input' type='text' v-model='genre'>
+				</div>
+				<label class='label'>Song Duration</label>
+				<p class='control'>
+					<input class='input' type='text' v-model='beingEdited.song.duration'>
+				</p>
+				<label class='label'>Skip Duration</label>
+				<p class='control'>
+					<input class='input' type='text' v-model='beingEdited.song.skipDuration'>
+				</p>
+			</section>
+			<footer class='modal-card-foot'>
+				<button class='delete' @click='toggleModal()'></button>
+			</footer>
+		</div>
+	</div>
 </template>
 
 <script>
+	import { Toast } from 'vue-roaster';
+
 	export default {
 		data() {
 			return {
-				songs: []
+				songs: [],
+				isEditActive: false,
+				beingEdited: {
+					index: 0,
+					song: {}
+				}
 			}
 		},
 		methods: {
-			update (song) {
-				this.socket.emit('queueSongs.update', song, res => {
-					console.log(res);
+			toggleModal: function () {
+				this.isEditActive = !this.isEditActive;
+			},
+			edit: function (song, index) {
+				this.beingEdited = { index, song };
+				this.isEditActive = true;
+			},
+			add: function (song) {
+				this.socket.emit('queueSongs.remove', song._id);
+				this.socket.emit('songs.add', song, res => {
+					if (res.status == 'success') Toast.methods.addToast(res.message, 2000);
 				});
 			},
-			remove (songId) {
-				this.socket.emit('queueSongs.remove', songId, res => {
-					console.log(res);
+			remove: function (id, index) {
+				this.songs.splice(index, 1);
+				this.socket.emit('queueSongs.remove', id, res => {
+					if (res.status == 'success') Toast.methods.addToast(res.message, 2000);
 				});
 			}
 		},
-		ready: function() {
+		ready: function () {
 			let _this = this;
 			let socketInterval = setInterval(() => {
 				if (!!_this.$parent.$parent.socket) {
@@ -78,5 +140,19 @@
 	}
 </script>
 
-<style lang="scss" scoped>
+<style lang='scss' scoped>
+	.thumbnail-preview {
+		display: flex;
+		margin: 0 auto;
+		padding: 10px 0 20px 0;
+	}
+
+	.modal-card-body, .modal-card-foot {
+		border-top: 0;
+		background-color: rgb(66, 165, 245);
+	}
+
+	.label, strong {
+		color: #fff;
+	}
 </style>