Quellcode durchsuchen

Fixed station pausing/resuming.

KrisVos130 vor 8 Jahren
Ursprung
Commit
49863bfccd

+ 68 - 8
backend/logic/actions/stations.js

@@ -22,20 +22,22 @@ const defaultSong = {
 	thumbnail: 'https://i.scdn.co/image/2ddde58427f632037093857ebb71a67ddbdec34b'
 };
 
-cache.sub('station.locked', stationName => {
-	io.to(`station.${stationName}`).emit("event:station.locked");
+cache.sub('station.locked', stationId => {
+	io.io.to(`station.${stationId}`).emit("event:stations.locked");
 });
 
-cache.sub('station.unlocked', stationName => {
-	io.to(`station.${stationName}`).emit("event:station.unlocked");
+cache.sub('station.unlocked', stationId => {
+	io.io.to(`station.${stationId}`).emit("event:stations.unlocked");
 });
 
-cache.sub('station.pause', stationName => {
-	io.to(`station.${stationName}`).emit("event:station.pause");
+cache.sub('station.pause', stationId => {
+	io.io.to(`station.${stationId}`).emit("event:stations.pause");
 });
 
-cache.sub('station.resume', stationName => {
-	io.to(`station.${stationName}`).emit("event:station.resume");
+cache.sub('station.resume', stationId => {
+	stations.initializeAndReturnStation(stationId, (err, station) => {
+		io.io.to(`station.${stationId}`).emit("event:stations.resume", {timePaused: station.timePaused});
+	});
 });
 
 cache.sub('station.create', stationId => {
@@ -202,6 +204,64 @@ module.exports = {
 		});
 	},
 
+	pause: (sessionId, stationId, cb) => {
+		//TODO Require admin
+		stations.initializeAndReturnStation(stationId, (err, station) => {
+			if (err && err !== true) {
+				return cb({ status: 'error', message: 'An error occurred while pausing the station' });
+			} else if (station) {
+				if (!station.paused) {
+					station.paused = true;
+					station.pausedAt = Date.now();
+					cache.hset('stations', stationId, station, (err) => {
+						if (!err) {
+							db.models.station.update({_id: stationId}, {$set: {paused: true}}, () => {
+								cache.pub('station.pause', stationId);
+								cb({ status: 'success' });
+							});
+						} else {
+							cb({ status: 'failure', message: 'An error occurred while pausing the station.' });
+						}
+					});
+				} else {
+					cb({ status: 'failure', message: 'That station was already paused.' });
+				}
+				cb({ status: 'success' });
+			} else {
+				cb({ status: 'failure', message: `That station doesn't exist, it may have been deleted` });
+			}
+		});
+	},
+
+	resume: (sessionId, stationId, cb) => {
+		//TODO Require admin
+		stations.initializeAndReturnStation(stationId, (err, station) => {
+			if (err && err !== true) {
+				return cb({ status: 'error', message: 'An error occurred while resuming the station' });
+			} else if (station) {
+				if (station.paused) {
+					station.paused = false;
+					station.timePaused += (Date.now() - station.pausedAt);
+					cache.hset('stations', stationId, station, (err) => {
+						if (!err) {
+							db.models.station.update({_id: stationId}, {$set: {paused: false, timePaused: station.timePaused}}, () => {
+								cache.pub('station.resume', stationId);
+								cb({ status: 'success' });
+							});
+						} else {
+							cb({ status: 'failure', message: 'An error occurred while resuming the station.' });
+						}
+					});
+				} else {
+					cb({ status: 'failure', message: 'That station is not paused.' });
+				}
+				cb({ status: 'success' });
+			} else {
+				cb({ status: 'failure', message: `That station doesn't exist, it may have been deleted` });
+			}
+		});
+	},
+
 	remove: (sessionId, stationId, cb) => {
 		cache.hdel('stations', stationId, () => {
 			// TODO: Update Mongo

+ 23 - 5
backend/logic/stations.js

@@ -1,7 +1,5 @@
 'use strict';
 
-// This file contains all the logic for Socket.IO
-
 const cache = require('./cache');
 const db = require('./db');
 const io = require('./io');
@@ -10,6 +8,16 @@ const notifications = require('./notifications');
 const async = require('async');
 let skipTimeout = null;
 
+//TEMP
+cache.sub('station.pause', (stationId) => {
+	clearTimeout(skipTimeout);
+	skipTimeout = null;
+});
+
+cache.sub('station.resume', (stationId) => {
+	module.exports.initializeAndReturnStation(stationId, (err, station) => {})
+});
+
 module.exports = {
 
 	init: function(cb) {
@@ -115,13 +123,14 @@ module.exports = {
 												thumbnail: song.thumbnail
 											};
 											station.startedAt = Date.now();
+											station.timePaused = 0;
 											next(null, station);
 										}
 									});
 								} else {
 									station.currentSongIndex = 0;
 									_this.calculateSongForStation(station, (err, newPlaylist) => {
-										console.log('New playlist: ', newPlaylist)
+										console.log('New playlist: ', newPlaylist);
 										if (!err) {
 											db.models.song.findOne({ _id: newPlaylist[0] }, (err, song) => {
 												if (song) {
@@ -136,6 +145,7 @@ module.exports = {
 														thumbnail: song.thumbnail
 													};
 													station.startedAt = Date.now();
+													station.timePaused = 0;
 													station.playlist = newPlaylist;
 													next(null, station);
 												}
@@ -173,13 +183,21 @@ module.exports = {
 			if (!station.paused) {
 				if (!station.startedAt) {
 					station.startedAt = Date.now();
+					station.timePaused = 0;
 					cache.hset('stations', stationId, station);
 				}
+				let timeLeft = ((station.currentSong.duration * 1000) - (Date.now() - station.startedAt - station.timePaused));
+				console.log(timeLeft, 1234);
+				console.log((station.currentSong.duration * 1000), Date.now(), station.startedAt, station.timePaused);
 				//setTimeout(skipSongTemp, station.currentSong.duration * 1000);
 				if (skipTimeout === null) {
-					skipTimeout = setTimeout(skipSongTemp, 1000);
+					skipTimeout = setTimeout(skipSongTemp, timeLeft);
+				}
+				if (station.currentSong.duration * 1000 < timeLeft) {
+					clearTimeout(skipTimeout);
+					skipSongTemp();
 				}
-				notifications.schedule(`stations.nextSong?id=${station.id}`, station.currentSong.duration * 1000);
+				notifications.schedule(`stations.nextSong?id=${station.id}`, ((station.currentSong.duration * 1000) - (Date.now() - station.startedAt - station.timePaused)));
 			}
 
 			return cb(null, station);

+ 23 - 2
frontend/components/Station/Station.vue

@@ -203,7 +203,7 @@
 					}
 				}
 			},
-			unpauseStation: function() {
+			resumeLocalStation: function() {
 				let local = this;
 				local.paused = false;
 				if (local.playerReady) {
@@ -211,13 +211,25 @@
 					local.player.playVideo();
 				}
 			},
-			pauseStation: function() {
+			pauseLocalStation: function() {
 				let local = this;
 				local.paused = true;
 				if (local.playerReady) {
 					local.player.pauseVideo();
 				}
 			},
+			resumeStation: function () {
+				let _this = this;
+				_this.socket.emit('stations.resume', _this.stationId, (result) => {
+					//TODO Toasts
+				});
+			},
+			pauseStation: function () {
+				let _this = this;
+				_this.socket.emit('stations.pause', _this.stationId, (result) => {
+					//TODO Toasts
+				});
+			},
 			addSongToQueue: function(songId) {
 				let local = this;
 				local.socket.emit('queueSongs.add', songId, res => {
@@ -269,6 +281,15 @@
 				_this.playVideo();
 			});
 
+			_this.socket.on('event:stations.pause', data => {
+				_this.pauseLocalStation();
+			});
+
+			_this.socket.on('event:stations.resume', data => {
+				_this.timePaused = data.timePaused;
+				_this.resumeLocalStation();
+			});
+
 			let volume = parseInt(localStorage.getItem("volume"));
 			volume = (typeof volume === "number") ? volume : 20;
 			$("#volumeSlider").val(volume);

+ 20 - 0
frontend/components/Station/StationHeader.vue

@@ -21,6 +21,26 @@
 					<i class="material-icons left">skip_next</i>
 				</span>
 			</a>
+			<a class="nav-item" href="#" v-if="$parent.$parent.role === 'admin' && $parent.locked" @click="$parent.unlockStation()">
+				<span class="icon">
+					<i class="material-icons left">lock_outline</i>
+				</span>
+			</a>
+			<a class="nav-item" href="#" v-if="$parent.$parent.role === 'admin' && !$parent.locked" @click="$parent.lockStation()">
+				<span class="icon">
+					<i class="material-icons left">lock_open</i>
+				</span>
+			</a>
+			<a class="nav-item" href="#" v-if="$parent.$parent.role === 'admin' && $parent.paused" @click="$parent.resumeStation()">
+				<span class="icon">
+					<i class="material-icons left">play_arrow</i>
+				</span>
+			</a>
+			<a class="nav-item" href="#" v-if="$parent.$parent.role === 'admin' && !$parent.paused" @click="$parent.pauseStation()">
+				<span class="icon">
+					<i class="material-icons left">pause</i>
+				</span>
+			</a>
 		</div>
 
 		<div class="nav-center">