Browse Source

Worked more on stations. (WIP)

KrisVos130 8 years ago
parent
commit
055bf0fed2

+ 18 - 3
backend/index.js

@@ -8,6 +8,7 @@ const db = require('./logic/db');
 const app = require('./logic/app');
 const io = require('./logic/io');
 const cache = require('./logic/cache');
+const notifications = require('./logic/notifications');
 const config = require('config');
 
 async.waterfall([
@@ -17,7 +18,7 @@ async.waterfall([
 		cache.init(config.get('redis').url, () => {
 			// load some test stations into the cache
 			async.waterfall([
-				(next) => cache.hset('stations', '7dbf25fd-b10d-6863-2f48-637f6014b162', cache.schemas.station({
+				(next) => cache.hset('stations', 'edm', cache.schemas.station({
 					name: 'edm',
 					genres: ['edm'],
 					type: 'official',
@@ -25,9 +26,20 @@ async.waterfall([
 					description: 'EDM Music',
 					playlist: [
 						'gCYcHz2k5x0'
-					]
+					],
+					currentSong: {
+						id: 'gCYcHz2k5x0',
+						title: 'Title',
+						artists: ['Artist1'],
+						genres: ['edm', 'pop'],
+						thumbnail: 'test',
+						duration: 100,
+						skipDuration: 10,
+						likes: 0,
+						dislikes: 0
+					}
 				}), next),
-				(next) => cache.hset('stations', '79cedff1-5341-7f0e-6542-50491c4797b4', cache.schemas.station({
+				(next) => cache.hset('stations', 'chill', cache.schemas.station({
 					name: 'chill',
 					genres: ['chill'],
 					type: 'official',
@@ -50,6 +62,9 @@ async.waterfall([
 	// setup the socket.io server (all client / server communication is done over this)
 	(next) => io.init(next),
 
+	// setup the notifications
+	(next) => notifications.init(config.get('redis').url, next),
+
 	// setup the frontend for local setups
 	(next) => {
 		if (!config.get("isDocker")) {

+ 39 - 28
backend/logic/actions/stations.js

@@ -10,6 +10,8 @@ const cache = require('../cache');
 const notifications = require('../notifications');
 const utils = require('../utils');
 
+let stationsLoaded = {};
+
 /**
  * Loads a station into the cache, and sets up all the related logic
  *
@@ -17,7 +19,6 @@ const utils = require('../utils');
  * @param {Function} cb - gets called when this function completes
  */
 function initializeAndReturnStation (stationId, cb) {
-
 	async.waterfall([
 
 		// first check the cache for the station
@@ -37,30 +38,42 @@ function initializeAndReturnStation (stationId, cb) {
 		}
 
 	], (err, station) => {
-
 		if (err && err !== true) return cb(err);
 
 		// get notified when the next song for this station should play, so that we can notify our sockets
-		let notification = notifications.subscribe(`stations.nextSong?id=${station.id}`, () => {
-			// get the station from the cache
-			cache.hget('stations', station.id, (err, station) => {
-				if (station) {
-					// notify all the sockets on this station to go to the next song
-					io.to(`station.${stationId}`).emit("event:songs.next", {
-						currentSong: station.currentSong,
-						startedAt: station.startedAt,
-						paused: station.paused,
-						timePaused: 0
-					});
-					// schedule a notification to be dispatched when the next song ends
-					notifications.schedule(`stations.nextSong?id=${station.id}`, station.currentSong.duration * 1000);
-				}
-				// the station doesn't exist anymore, unsubscribe from it
-				else {
-					notifications.remove(notification);
-				}
-			});
-		}, true);
+		if (stationsLoaded[stationId] === undefined) {
+			stationsLoaded[stationId] = 1;
+			let notification = notifications.subscribe(`stations.nextSong?id=${station.id}`, () => {
+				// get the station from the cache
+				cache.hget('stations', station.name, (err, station) => {
+					if (station) {
+						console.log(777);
+						// notify all the sockets on this station to go to the next song
+						io.to(`station.${stationId}`).emit("event:songs.next", {
+							currentSong: station.currentSong,
+							startedAt: station.startedAt,
+							paused: station.paused,
+							timePaused: 0
+						});
+						// schedule a notification to be dispatched when the next song ends
+						notifications.schedule(`stations.nextSong?id=${station.id}`, station.currentSong.duration * 1000);
+					}
+					// the station doesn't exist anymore, unsubscribe from it
+					else {
+						console.log(888);
+						notifications.remove(notification);
+						delete stationsLoaded[stationId];
+					}
+				});
+			}, true);
+
+			if (!station.paused) {
+				console.log(station);
+				notifications.schedule(`stations.nextSong?id=${station.id}`, station.currentSong.duration * 1000);
+			}
+		}
+
+		return cb(null, station);
 
 		// will need to be added once station namespace thing is decided
 		// function generatePlaylist(arr) {
@@ -120,8 +133,6 @@ module.exports = {
 	 * @return {{ status: String, userCount: Integer }}
 	 */
 	join: (session, stationId, cb) => {
-		io.io.to("SomeRoom").emit("SomeRoomMessage");
-		io.io.emit("SomeRoomMessage");
 		initializeAndReturnStation(stationId, (err, station) => {
 
 			if (err && err !== true) {
@@ -132,13 +143,13 @@ module.exports = {
 
 				if (session) session.stationId = stationId;
 
-				//TODO Loop through all sockets, see if socket with same sessionid exists, and if so leave all other station rooms and join this stationRoom
+				//TODO Loop through all sockets, see if socket with same session exists, and if so leave all other station rooms and join this stationRoom
 
 				cache.client.hincrby('station.userCounts', stationId, 1, (err, userCount) => {
 					if (err) return cb({ status: 'error', message: 'An error occurred while joining the station' });
-					utils.socketJoinRoom(sessionId);
+					utils.socketJoinRoom(session);
 					//TODO Emit to cache, listen on cache
-					cb({ status: 'success', userCount });
+					cb({ status: 'success', currentSong: station.currentSong, startedAt: station.startedAt, paused: station.paused, timePaused: station.timePaused });
 				});
 			}
 			else {
@@ -202,7 +213,7 @@ module.exports = {
 			else if (station) {
 				cache.client.hincrby('station.userCounts', stationId, -1, (err, userCount) => {
 					if (err) return cb({ status: 'error', message: 'An error occurred while leaving the station' });
-					utils.socketLeaveRooms(sessionId);
+					utils.socketLeaveRooms(session);
 					cb({ status: 'success', userCount });
 				});
 			} else {

+ 1 - 0
backend/logic/io.js

@@ -19,6 +19,7 @@ module.exports = {
 		this.io.use((socket, next) => {
 			let cookies = socket.request.headers.cookie;
 			// set the sessionId for the socket (this will have to be checked every request, this allows us to have a logout all devices option)
+			console.log(utils.cookies.parseCookies(cookies).SID);
 			if (cookies) socket.sessionId = utils.cookies.parseCookies(cookies).SID;
 			return next();
 		});

+ 1 - 0
backend/logic/notifications.js

@@ -25,6 +25,7 @@ const lib = {
 			});
 		});
 		client.psubscribe('__keyevent@0__:expired');
+		cb();
 	},
 
 	/**

+ 6 - 4
backend/logic/utils.js

@@ -128,7 +128,7 @@ module.exports = {
 			return this.toString(cookies);
 		}
 	},
-	socketFromSession: sessionId => {
+	socketFromSession: function(sessionId) {
 		let sockets = io.io.sockets;
 		for (let i = 0; i < sockets.length; i++) {
 			let socket = sockets[i];
@@ -137,16 +137,18 @@ module.exports = {
 			}
 		}
 	},
-	socketLeaveRooms: (sessionId, room) => {
+	socketLeaveRooms: function(sessionId, room) {
 		let socket = this.socketFromSession(sessionId);
 		let rooms = io.sockets.manager.roomClients[socket.id];
 		for (let j = 0; j < rooms.length; j++) {
 			socket.leave(rooms[j]);
 		}
 	},
-	socketJoinRoom: (sessionId, room) => {
+	socketJoinRoom: function(sessionId, room) {
 		let socket = this.socketFromSession(sessionId);
-		let rooms = io.sockets.manager.roomClients[socket.id];
+		console.log(socket);
+		//console.log(io.io.sockets[socket.id]);
+		let rooms = io.io.sockets.manager.roomClients[socket.id];
 		for (let j = 0; j < rooms.length; j++) {
 			socket.leave(rooms[j]);
 		}

+ 0 - 3
frontend/App.vue

@@ -36,9 +36,6 @@
 			lofig.get('socket.url', function(res) {
 				let socket = _this.socket = io(window.location.protocol + '//' + res);
 				socket.on("ready", status => _this.loggedIn = status);
-				socket.on("SomeRoomMessage", function() {
-				    console.log("SOME ROOM MESSAGE!");
-				});
 			});
 		},
 		events: {

+ 15 - 6
frontend/components/Station/Station.vue

@@ -242,12 +242,21 @@
 			_this.socket = _this.$parent.socket;
 
 			_this.socket.emit('stations.join', _this.stationId, data => {
-				_this.currentSong = data.currentSong;
-				_this.startedAt = data.startedAt;
-				_this.paused = data.paused;
-				_this.timePaused = data.timePaused;
-				_this.youtubeReady();
-				_this.playVideo();
+				console.log(data);
+				if (data.status === "success") {
+					_this.currentSong = data.currentSong;
+					_this.startedAt = data.startedAt;
+					_this.paused = data.paused;
+					_this.timePaused = data.timePaused;
+					_this.youtubeReady();
+					_this.playVideo();
+				} else {
+					//TODO Handle error
+				}
+			});
+
+			_this.socket.on("SomeRoomMessage", function() {
+				console.log("SOME ROOM MESSAGE!!");
 			});
 
 			_this.socket.on('event:songs.next', data => {

+ 19 - 11
frontend/components/pages/Home.vue

@@ -55,7 +55,7 @@
 		<div class="group">
 			<div class="group-title">Official Stations</div>
 			<div class="group-stations">
-				<div class="stations-station" v-for="station in $parent.stations.official" v-link="{ path: '/' + station.name }" @click="this.$dispatch('joinStation', station.id)">
+				<div class="stations-station" v-for="station in stations.official" v-link="{ path: '/' + station.name }" @click="this.$dispatch('joinStation', station.id)">
 					<img class="station-image" :src="station.playlist[station.currentSongIndex].thumbnail" />
 					<div class="station-info">
 						<div class="station-grid-left">
@@ -69,10 +69,10 @@
 				</div>
 			</div>
 		</div>
-		<div class="group" v-if="$parent.stations.community.length">
+		<div class="group" v-if="stations.community.length">
 			<div class="group-title">Community Stations</div>
 			<div class="group-stations">
-				<div class="stations-station" v-for="station in $parent.stations.community" v-link="{ path: '/community/' + station.name }" @click="this.$dispatch('joinStation', station.id)">
+				<div class="stations-station" v-for="station in stations.community" v-link="{ path: '/community/' + station.name }" @click="this.$dispatch('joinStation', station.id)">
 					<img class="station-image" :src="station.playlist[station.currentSongIndex].thumbnail" />
 					<div class="station-info">
 						<div class="station-grid-left">
@@ -113,14 +113,22 @@
 			lofig.get('recaptcha.key', function(key) {
 				_this.recaptcha.key = key;
 			});
-			socket.emit("stations.index", data => {
-				if (data.status === "success")  data.stations.forEach(station => {
-					if (station.type == 'official') _this.stations.official.push(station);
-					else _this.stations.community.push(station);
-				});
-			});
-			socket.emit("");
-			socket.on("");
+
+
+			let socketInterval = setInterval(() => {
+				if (!!_this.$parent.socket) {
+					_this.socket = _this.$parent.socket;
+					_this.socket.emit("stations.index", data => {
+						if (data.status === "success")  data.stations.forEach(station => {
+							if (station.type == 'official') _this.stations.official.push(station);
+							else _this.stations.community.push(station);
+						});
+					});
+					_this.socket.emit("");
+					_this.socket.on("");
+					clearInterval(socketInterval);
+				}
+			}, 100);
 		},
 		methods: {
 			toggleModal: function(type) {