소스 검색

Further worked on community station queues.

KrisVos130 8 년 전
부모
커밋
caed8e28db

+ 9 - 49
backend/logic/actions/queueSongs.js

@@ -63,55 +63,15 @@ module.exports = {
 		async.waterfall([
 			// Get YouTube data from id
 			(next) => {
-				const youtubeParams = [
-					'part=snippet,contentDetails,statistics,status',
-					`id=${encodeURIComponent(id)}`,
-					`key=${config.get('apis.youtube.key')}`
-				].join('&');
-
-				request(`https://www.googleapis.com/youtube/v3/videos?${youtubeParams}`, (err, res, body) => {
-
-					if (err) {
-						console.error(err);
-						return next('Failed to find song from YouTube');
-					}
-
-					body = JSON.parse(body);
-
-					//TODO Clean up duration converter
-					let dur = body.items[0].contentDetails.duration;
-					dur = dur.replace('PT', '');
-					let duration = 0;
-					dur = dur.replace(/([\d]*)H/, (v, v2) => {
-						v2 = Number(v2);
-						duration = (v2 * 60 * 60);
-						return '';
-					});
-					dur = dur.replace(/([\d]*)M/, (v, v2) => {
-						v2 = Number(v2);
-						duration = (v2 * 60);
-						return '';
-					});
-					dur = dur.replace(/([\d]*)S/, (v, v2) => {
-						v2 = Number(v2);
-						duration += v2;
-						return '';
-					});
-
-					let newSong = {
-						_id: body.items[0].id,
-						title: body.items[0].snippet.title,
-						artists: [],
-						genres: [],
-						duration,
-						skipDuration: 0,
-						thumbnail: 'empty',
-						explicit: false,
-						requestedBy: userId,
-						requestedAt
-					};
-
-					next(null, newSong);
+				utils.getSongFromYouTube(id, (song) => {
+					song.artists = [];
+					song.genres = [];
+					song.skipDuration = 0;
+					song.thumbnail = 'empty';
+					song.explicit = false;
+					song.requestedBy = userId;
+					song.requestedAt = requestedAt;
+					next(null, song);
 				});
 			},
 			(newSong, next) => {

+ 37 - 11
backend/logic/actions/stations.js

@@ -404,17 +404,33 @@ module.exports = {
 					}
 				});
 				if (has) return cb({'status': 'failure', 'message': 'That song has already been added to the queue.'});
-				db.models.station.update({_id: stationId}, {$push: {queue: {_id: songId, title: "Title", duration: 100, requestedBy: userId}}}, (err) => {
-					console.log(err);
-					if (err) return cb({'status': 'failure', 'message': 'Something went wrong.'});
-					stations.updateStation(stationId, (err, station) => {
-						if (err) return cb(err);
-						if (station.currentSong === null || station.currentSong._id === undefined) {
-							notifications.schedule(`stations.nextSong?id=${stationId}`, 1);
-						}
-						cache.pub('station.queueUpdate', stationId);
-						cb({'status': 'success', 'message': 'Added that song to the queue.'});
-					});
+
+				songs.getSong(songId, (err, song) => {
+					if (err) {
+						utils.getSongFromYouTube(songId, (song) => {
+							song.artists = [];
+							song.skipDuration = 0;
+							song.likes = -1;
+							song.dislikes = -1;
+							song.thumbnail = "empty";
+							song.explicit = false;
+							cont(song);
+						});
+					} else cont(song);
+					function cont(song) {
+						db.models.station.update({_id: stationId}, {$push: {queue: song}}, (err) => {
+							console.log(err);
+							if (err) return cb({'status': 'failure', 'message': 'Something went wrong.'});
+							stations.updateStation(stationId, (err, station) => {
+								if (err) return cb(err);
+								if (station.currentSong === null || station.currentSong._id === undefined) {
+									notifications.schedule(`stations.nextSong?id=${stationId}`, 1);
+								}
+								cache.pub('station.queueUpdate', stationId);
+								cb({'status': 'success', 'message': 'Added that song to the queue.'});
+							});
+						});
+					}
 				});
 			} else cb({'status': 'failure', 'message': 'That station is not a community station.'});
 		});
@@ -442,4 +458,14 @@ module.exports = {
 		});
 	}),
 
+	getQueue: hooks.adminRequired((session, stationId, cb) => {
+		stations.getStation(stationId, (err, station) => {
+			if (err) return cb(err);
+			if (!station) return cb({'status': 'failure', 'message': 'Station not found.'});
+			if (station.type === 'community') {
+				cb({'status': 'success', queue: station.queue});
+			} else cb({'status': 'failure', 'message': 'That station is not a community station.'});
+		});
+	}),
+
 };

+ 5 - 0
backend/logic/db/schemas/station.js

@@ -25,7 +25,12 @@ module.exports = {
 	queue: [{
 		_id: { type: String, required: true },
 		title: { type: String },
+		artists: [{ type: String }],
 		duration: { type: Number },
+		skipDuration: { type: Number },
+		thumbnail: { type: String },
+		likes: { type: Number, default: -1 },
+		dislikes: { type: Number, default: -1 },
 		requestedBy: { type: String, required: true }
 	}]
 };

+ 5 - 6
backend/logic/stations.js

@@ -20,7 +20,7 @@ cache.sub('station.resume', (stationId) => {
 
 cache.sub('station.queueUpdate', (stationId) => {
 	module.exports.getStation(stationId, (err, station) => {
-		if (!station.currentSong) {
+		if (!station.currentSong && station.queue.length > 0) {
 			module.exports.initializeStation(stationId);
 		}
 	});
@@ -300,11 +300,7 @@ module.exports = {
 										console.log("##1", err);
 										if (err) return next(err);
 										let $set = {};
-										$set.currentSong = {
-											_id: station.queue[0]._id,
-											title: station.queue[0].title,
-											duration: station.queue[0].duration
-										};
+										$set.currentSong = station.queue[0];
 										$set.startedAt = Date.now();
 										$set.timePaused = 0;
 										if (station.paused) {
@@ -325,6 +321,9 @@ module.exports = {
 								console.log("##2.5", err);
 								_this.updateStation(station._id, (err, station) => {
 									console.log("##2.6", err);
+									if (station.type === 'community') {
+										cache.pub('station.queueUpdate', stationId);
+									}
 									next(null, station);
 								});
 							});

+ 46 - 0
backend/logic/utils.js

@@ -2,6 +2,8 @@
 
 const 	moment = require('moment'),
 		io = require('./io'),
+		config = require('config'),
+		request = require('request'),
 		cache = require('./cache');
 
 class Timer {
@@ -207,5 +209,49 @@ module.exports = {
 				}
 			}
 		}
+	},
+	getSongFromYouTube: (songId, cb) => {
+		const youtubeParams = [
+			'part=snippet,contentDetails,statistics,status',
+			`id=${encodeURIComponent(songId)}`,
+			`key=${config.get('apis.youtube.key')}`
+		].join('&');
+
+		request(`https://www.googleapis.com/youtube/v3/videos?${youtubeParams}`, (err, res, body) => {
+
+			if (err) {
+				console.error(err);
+				return next('Failed to find song from YouTube');
+			}
+
+			body = JSON.parse(body);
+
+			//TODO Clean up duration converter
+			let dur = body.items[0].contentDetails.duration;
+			dur = dur.replace('PT', '');
+			let duration = 0;
+			dur = dur.replace(/([\d]*)H/, (v, v2) => {
+				v2 = Number(v2);
+				duration = (v2 * 60 * 60);
+				return '';
+			});
+			dur = dur.replace(/([\d]*)M/, (v, v2) => {
+				v2 = Number(v2);
+				duration = (v2 * 60);
+				return '';
+			});
+			dur = dur.replace(/([\d]*)S/, (v, v2) => {
+				v2 = Number(v2);
+				duration += v2;
+				return '';
+			});
+
+			let song = {
+				_id: body.items[0].id,
+				title: body.items[0].snippet.title,
+				duration
+			};
+			cb(song);
+		});
 	}
 };

+ 1 - 1
frontend/components/Sidebars/Queue.vue

@@ -20,7 +20,7 @@
 				</div>
 			</article>
 
-			<article class="media" v-for='song in playlist'>
+			<article class="media" v-for='song in $parent.queue'>
 				<div class="media-content">
 					<div class="content">
 						<p>

+ 55 - 43
frontend/components/Station/Station.vue

@@ -25,7 +25,7 @@
 		<div class="columns is-mobile" v-show="!noSong">
 			<div class="column is-8-desktop is-offset-2-desktop is-12-mobile">
 				<div class="columns is-mobile">
-					<div class="column is-8-desktop is-12-mobile">
+					<div class="column is-12-mobile" v-bind:class="{'is-8-desktop': !simpleSong}">
 						<h4 id="time-display">{{timeElapsed}} / {{formatTime(currentSong.duration)}}</h4>
 						<h3>{{currentSong.title}}</h3>
 						<h4 class="thin" style="margin-left: 0">{{currentSong.artists}}</h4>
@@ -49,7 +49,7 @@
 							</div>
 						</div>
 					</div>
-					<div class="column is-4-desktop is-12-mobile">
+					<div class="column is-4-desktop is-12-mobile" v-if="!simpleSong">
 						<img class="image" id="song-thumbnail" style="margin-top: 10px !important" :src="currentSong.thumbnail" alt="Song Thumbnail" />
 					</div>
 				</div>
@@ -96,7 +96,9 @@
 					playlist: false
 				},
 				noSong: false,
-				simpleSong: false
+				simpleSong: false,
+				queue: [],
+				timeBeforePause: 0
 			}
 		},
 		methods: {
@@ -112,34 +114,40 @@
 			youtubeReady: function() {
 				let local = this;
 				console.log("@@5", local.currentSong._id);
-				local.player = new YT.Player("player", {
-					height: 270,
-					width: 480,
-					videoId: local.currentSong._id,
-					playerVars: { controls: 0, iv_load_policy: 3, rel: 0, showinfo: 0 },
-					events: {
-						'onReady': function(event) {
-							console.log("@@6");
-							local.playerReady = true;
-							let volume = parseInt(localStorage.getItem("volume"));
-							volume = (typeof volume === "number") ? volume : 20;
-							local.player.setVolume(volume);
-							if (volume > 0) local.player.unMute();
-							console.log("@@7");
-							local.playVideo();
-						},
-						'onStateChange': function(event) {
-							if (event.data === 1 && local.videoLoading === true) {
-								local.videoLoading = false;
-								local.player.seekTo(local.getTimeElapsed() / 1000, true);
-								if (local.paused) local.player.pauseVideo();
+				if (!local.player) {
+					local.player = new YT.Player("player", {
+						height: 270,
+						width: 480,
+						videoId: local.currentSong._id,
+						playerVars: {controls: 0, iv_load_policy: 3, rel: 0, showinfo: 0},
+						events: {
+							'onReady': function (event) {
+								console.log("@@6");
+								local.playerReady = true;
+								let volume = parseInt(localStorage.getItem("volume"));
+								volume = (typeof volume === "number") ? volume : 20;
+								local.player.setVolume(volume);
+								if (volume > 0) local.player.unMute();
+								console.log("@@7");
+								local.playVideo();
+							},
+							'onStateChange': function (event) {
+								if (event.data === 1 && local.videoLoading === true) {
+									local.videoLoading = false;
+									local.player.seekTo(local.getTimeElapsed() / 1000, true);
+									if (local.paused) local.player.pauseVideo();
+								} else if (event.data === 1 && local.paused) {
+									local.player.seekTo(local.timeBeforePause / 1000, true);
+									local.player.pauseVideo();
+								}
+								if (event.data === 2 && !local.paused) {
+									local.player.seekTo(local.getTimeElapsed() / 1000, true);
+									local.player.playVideo();
+								}
 							}
-						},
-						'onError': function(err) {
-							console.log("@@@@", err, local.currentSong._id);
 						}
-					}
-				});
+					});
+				}
 			},
 			getTimeElapsed: function() {
 				let local = this;
@@ -212,6 +220,7 @@
 			pauseLocalStation: function() {
 				this.paused = true;
 				if (!this.noSong) {
+					this.timeBeforePause = this.getTimeElapsed();
 					if (this.playerReady) this.player.pauseVideo();
 				}
 			},
@@ -281,17 +290,6 @@
 			let socketInterval = setInterval(() => {
 				if (!!_this.$parent.socket) {
 					_this.socket = _this.$parent.socket;
-<<<<<<< 10e2c9a208c1e4d81b218d7782ef618b4f49990c
-					_this.socket.emit('stations.join', _this.stationId, data => {
-						if (data.status === "success") {
-							_this.currentSong = (data.currentSong) ? data.currentSong : {};
-							_this.startedAt = data.startedAt;
-							_this.paused = data.paused;
-							_this.timePaused = data.timePaused;
-							if (data.currentSong) {
-								_this.noSong = false;
-								_this.simpleSong = (data.currentSong.likes === -1 && data.currentSong.dislikes === -1);
-=======
 					_this.socket.emit('stations.join', _this.stationId, res => {
 						if (res.status === "success") {
 							_this.currentSong = (res.data.currentSong) ? res.data.currentSong : {};
@@ -300,7 +298,8 @@
 							_this.paused = res.data.paused;
 							_this.timePaused = res.data.timePaused;
 							if (res.data.currentSong) {
->>>>>>> Seperated Community and Official Station Headers
+								_this.noSong = false;
+								_this.simpleSong = (res.data.currentSong.likes === -1 && res.data.currentSong.dislikes === -1);
 								_this.youtubeReady();
 								_this.playVideo();
 								_this.socket.emit('songs.getOwnSongRatings', res.data.currentSong._id, data => {
@@ -311,9 +310,17 @@
 								});
 							} else {
 								if (_this.playerReady) _this.player.pauseVideo();
-								console.log("NO SONG TRUE1", data);
+								console.log("NO SONG TRUE1", res);
 								_this.noSong = true;
 							}
+							if (_this.type === 'community') {
+								_this.socket.emit('stations.getQueue', _this.stationId, data => {
+									console.log(data);
+									if (data.status === 'success') {
+										_this.queue = data.queue;
+									}
+								});
+							}
 						} else {
 							//TODO Handle error
 						}
@@ -388,6 +395,12 @@
 							}
 						}
 					});
+
+					_this.socket.on('event:queue.update', queue => {
+						if (this.type === 'community') {
+							this.queue = queue;
+						}
+					});
 					clearInterval(socketInterval);
 				}
 			}, 100);
@@ -549,7 +562,6 @@
 				left: 0;
 				width: 100%;
 				height: 100%;
-				pointer-events: none;
 			}
 		}
 		.video-col {