소스 검색

Worked more on community stations.

KrisVos130 8 년 전
부모
커밋
92211928a6

+ 33 - 19
backend/logic/actions/stations.js

@@ -41,10 +41,8 @@ cache.sub('station.queueUpdate', stationId => {
 
 cache.sub('station.create', stationId => {
 	stations.initializeStation(stationId, (err, station) => {
-		//TODO Emit to homepage and admin station page
-		if (!err) {
-			io.io.to('home').emit("event:stations.created", station);
-		}
+		//TODO Emit to admin station page
+		io.io.to('home').emit("event:stations.created", station);
 	});
 });
 
@@ -115,18 +113,34 @@ module.exports = {
 				/*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(session.socketId, `station.${stationId}`);
-				utils.socketJoinSongRoom(session.socketId, `song.${station.currentSong._id}`);
-				//TODO Emit to cache, listen on cache
-				songs.getSong(station.currentSong._id, (err, song) => {
-					if (!err && song) {
-						station.currentSong.likes = song.likes;
-						station.currentSong.dislikes = song.dislikes;
-					} else {
-						station.currentSong.likes = -1;
-						station.currentSong.dislikes = -1;
-					}
-					cb({ status: 'success', currentSong: station.currentSong, startedAt: station.startedAt, paused: station.paused, timePaused: station.timePaused });
-				});
+				if (station.currentSong) {
+					utils.socketJoinSongRoom(session.socketId, `song.${station.currentSong._id}`);
+					//TODO Emit to cache, listen on cache
+					songs.getSong(station.currentSong._id, (err, song) => {
+						if (!err && song) {
+							station.currentSong.likes = song.likes;
+							station.currentSong.dislikes = song.dislikes;
+						} else {
+							station.currentSong.likes = -1;
+							station.currentSong.dislikes = -1;
+						}
+						cb({
+							status: 'success',
+							currentSong: station.currentSong,
+							startedAt: station.startedAt,
+							paused: station.paused,
+							timePaused: station.timePaused
+						});
+					});
+				} else {
+					cb({
+						status: 'success',
+						currentSong: null,
+						startedAt: station.startedAt,
+						paused: station.paused,
+						timePaused: station.timePaused
+					});
+				}
 				//});
 			}
 			else {
@@ -360,14 +374,14 @@ module.exports = {
 					description,
 					type: "community",
 					queue: [],
-					currentSong: stations.defaultSong
+					currentSong: null
 				}, next);
 			}
 
 		], (err, station) => {
-			if (err) throw err;
+			if (err) {console.log(err); throw err;}
 			cache.pub('station.create', data._id);
-			return cb(null, { 'status': 'success', 'message': 'Successfully created station.' });
+			return cb({ 'status': 'success', 'message': 'Successfully created station.' });
 		});
 	}),
 

+ 8 - 8
backend/logic/db/schemas/station.js

@@ -5,20 +5,20 @@ module.exports = {
 	description: { type: String, min: 2, max: 128, required: true },
 	paused: { type: Boolean, default: false, required: true },
 	currentSong: {
-		_id: { type: String, unique: true, required: true },
-		title: { type: String, required: true },
+		_id: { type: String },
+		title: { type: String },
 		artists: [{ type: String }],
-		duration: { type: Number, required: true },
-		skipDuration: { type: Number, required: true },
-		thumbnail: { type: String, required: true },
-		likes: { type: Number, default: -1, required: true },
-		dislikes: { type: Number, default: -1, required: true },
+		duration: { type: Number },
+		skipDuration: { type: Number },
+		thumbnail: { type: String },
+		likes: { type: Number, default: -1 },
+		dislikes: { type: Number, default: -1 },
 	},
 	currentSongIndex: { type: Number, default: 0, required: true },
 	timePaused: { type: Number, default: 0, required: true },
 	pausedAt: { type: Number, default: 0, required: true },
 	startedAt: { type: Number, default: 0, required: true },
-	playlist: { type: Array, required: true },
+	playlist: { type: Array },
 	genres: [{ type: String }],
 	privacy: { type: String, enum: ["public", "unlisted", "private"], default: "private" },
 	locked: { type: Boolean, default: false },

+ 154 - 113
backend/logic/stations.js

@@ -15,7 +15,15 @@ cache.sub('station.pause', (stationId) => {
 });
 
 cache.sub('station.resume', (stationId) => {
-	module.exports.getStation(stationId, (err, station) => {})
+	module.exports.initializeStation(stationId)
+});
+
+cache.sub('station.queueUpdate', (stationId) => {
+	module.exports.getStation(stationId, (err, station) => {
+		if (!station.currentSong) {
+			module.exports.initializeStation(stationId);
+		}
+	});
 });
 
 module.exports = {
@@ -27,7 +35,7 @@ module.exports = {
 			if (!err) {
 				stations.forEach((station) => {
 					console.info("Initializing Station: " + station._id);
-					_this.initializeStation(station);
+					_this.initializeStation(station._id);
 				});
 				cb();
 			}
@@ -35,6 +43,7 @@ module.exports = {
 	},
 
 	initializeStation: function(stationId, cb) {
+		console.log(112233, stationId);
 		if (typeof cb !== 'function') cb = ()=>{};
 		let _this = this;
 		_this.getStation(stationId, (err, station) => {
@@ -48,116 +57,137 @@ module.exports = {
 								async.waterfall([
 
 									(next) => {
-										if (station.playlist.length > 0) {
-											function func() {
-												if (station.currentSongIndex < station.playlist.length - 1) {
-													station.currentSongIndex++;
-													songs.getSong(station.playlist[station.currentSongIndex], (err, song) => {
-														if (!err) {
-															let $set = {};
+										if (station.type === "official") {
+											if (station.playlist.length > 0) {
+												function func() {
+													if (station.currentSongIndex < station.playlist.length - 1) {
+														station.currentSongIndex++;
+														songs.getSong(station.playlist[station.currentSongIndex], (err, song) => {
+															if (!err) {
+																let $set = {};
 
-															$set.currentSong = {
-																_id: song._id,
-																title: song.title,
-																artists: song.artists,
-																duration: song.duration,
-																likes: song.likes,
-																dislikes: song.dislikes,
-																skipDuration: song.skipDuration,
-																thumbnail: song.thumbnail
-															};
-															$set.startedAt = Date.now();
-															$set.timePaused = 0;
-															next(null, $set);
-														} else {
-															db.models.station.update({_id: station._id}, {$inc: {currentSongIndex: 1}}, (err) => {
-																_this.updateStation(station._id, () => {
-																	func();
+																$set.currentSong = {
+																	_id: song._id,
+																	title: song.title,
+																	artists: song.artists,
+																	duration: song.duration,
+																	likes: song.likes,
+																	dislikes: song.dislikes,
+																	skipDuration: song.skipDuration,
+																	thumbnail: song.thumbnail
+																};
+																$set.startedAt = Date.now();
+																$set.timePaused = 0;
+																next(null, $set);
+															} else {
+																db.models.station.update({_id: station._id}, {$inc: {currentSongIndex: 1}}, (err) => {
+																	_this.updateStation(station._id, () => {
+																		func();
+																	});
 																});
-															});
-														}
-													});
-												} else {
-													db.models.station.update({_id: station._id}, {$set: {currentSongIndex: 0}}, (err) => {
-														_this.updateStation(station._id, (err, station) => {
-															console.log(12345678, err, station);
-															_this.calculateSongForStation(station, (err, newPlaylist) => {
-																console.log('New playlist: ', newPlaylist);
-																if (!err) {
-																	songs.getSong(newPlaylist[0], (err, song) => {
+															}
+														});
+													} else {
+														db.models.station.update({_id: station._id}, {$set: {currentSongIndex: 0}}, (err) => {
+															_this.updateStation(station._id, (err, station) => {
+																console.log(12345678, err, station);
+																_this.calculateSongForStation(station, (err, newPlaylist) => {
+																	console.log('New playlist: ', newPlaylist);
+																	if (!err) {
+																		songs.getSong(newPlaylist[0], (err, song) => {
+																			let $set = {};
+																			if (song) {
+																				$set.currentSong = {
+																					_id: song._id,
+																					title: song.title,
+																					artists: song.artists,
+																					duration: song.duration,
+																					likes: song.likes,
+																					dislikes: song.dislikes,
+																					skipDuration: song.skipDuration,
+																					thumbnail: song.thumbnail
+																				};
+																				station.playlist = newPlaylist;
+																			} else {
+																				$set.currentSong = _this.defaultSong;
+																			}
+																			$set.startedAt = Date.now();
+																			$set.timePaused = 0;
+																			next(null, $set);
+																		});
+																	} else {
 																		let $set = {};
-																		if (song) {
-																			$set.currentSong = {
-																				_id: song._id,
-																				title: song.title,
-																				artists: song.artists,
-																				duration: song.duration,
-																				likes: song.likes,
-																				dislikes: song.dislikes,
-																				skipDuration: song.skipDuration,
-																				thumbnail: song.thumbnail
-																			};
-																			station.playlist = newPlaylist;
-																		} else {
-																			$set.currentSong = _this.defaultSong;
-																		}
+																		$set.currentSong = _this.defaultSong;
 																		$set.startedAt = Date.now();
 																		$set.timePaused = 0;
 																		next(null, $set);
-																	});
-																} else {
-																	let $set = {};
-																	$set.currentSong = _this.defaultSong;
-																	$set.startedAt = Date.now();
-																	$set.timePaused = 0;
-																	next(null, $set);
-																}
-															})
+																	}
+																})
+															});
 														});
-													});
+													}
 												}
+
+												func();
+											} else {
+												_this.calculateSongForStation(station, (err, playlist) => {
+													if (!err && playlist.length === 0) {
+														let $set = {};
+														$set.currentSongIndex = 0;
+														$set.currentSong = _this.defaultSong;
+														$set.startedAt = Date.now();
+														$set.timePaused = 0;
+														next(null, $set);
+													} else {
+														songs.getSong(playlist[0], (err, song) => {
+															let $set = {};
+															if (!err) {
+																$set.currentSong = {
+																	_id: song._id,
+																	title: song.title,
+																	artists: song.artists,
+																	duration: song.duration,
+																	likes: song.likes,
+																	dislikes: song.dislikes,
+																	skipDuration: song.skipDuration,
+																	thumbnail: song.thumbnail
+																};
+															} else {
+																$set.currentSong = _this.defaultSong;
+															}
+															$set.currentSongIndex = 0;
+															$set.startedAt = Date.now();
+															$set.timePaused = 0;
+															next(null, $set);
+														});
+													}
+												});
 											}
-											func();
 										} else {
-											_this.calculateSongForStation(station, (err, playlist) => {
-												if (!err && playlist.length === 0) {
+											if (station.queue.length > 0) {
+												db.models.station.update({_id: stationId}, {$pull: {_id: station.queue[0]._id}}, (err) => {
+													if (err) return next(err);
 													let $set = {};
-													$set.currentSongIndex = 0;
-													$set.currentSong = _this.defaultSong;
+													$set.currentSong = {
+														_id: station.queue[0]._id,
+														title: station.queue[0].title,
+														duration: station.queue[0].duration
+													};
 													$set.startedAt = Date.now();
 													$set.timePaused = 0;
 													next(null, $set);
-												} else {
-													songs.getSong(playlist[0], (err, song) => {
-														let $set = {};
-														if (!err) {
-															$set.currentSong = {
-																_id: song._id,
-																title: song.title,
-																artists: song.artists,
-																duration: song.duration,
-																likes: song.likes,
-																dislikes: song.dislikes,
-																skipDuration: song.skipDuration,
-																thumbnail: song.thumbnail
-															};
-														} else {
-															$set.currentSong = _this.defaultSong;
-														}
-														$set.currentSongIndex = 0;
-														$set.startedAt = Date.now();
-														$set.timePaused = 0;
-														next(null, $set);
-													});
-												}
-											});
+												});
+
+												func();
+											} else {
+												next(null, {currentSong: null});
+											}
 										}
 									},
 
 									($set, next) => {
 										db.models.station.update({_id: station._id}, {$set}, (err) => {
 											_this.updateStation(station._id, (err, station) => {
-												console.log(err, station);
 												next(null, station);
 											});
 										});
@@ -165,41 +195,51 @@ module.exports = {
 
 
 								], (err, station) => {
-									console.log(err, station);
-									io.io.to(`station.${station._id}`).emit("event:songs.next", {
-										currentSong: station.currentSong,
-										startedAt: station.startedAt,
-										paused: station.paused,
-										timePaused: 0
-									});
-									utils.socketsJoinSongRoom(io.io.to(`station.${station._id}`).sockets, `song.${station.currentSong._id}`);
-									// schedule a notification to be dispatched when the next song ends
-									console.log("NEXT SONG!!!");
-									if (!station.paused) {
-										notifications.schedule(`stations.nextSong?id=${station._id}`, station.currentSong.duration * 1000);
+									console.log(err);
+									if (!err) {
+										io.io.to(`station.${station._id}`).emit("event:songs.next", {
+											currentSong: station.currentSong,
+											startedAt: station.startedAt,
+											paused: station.paused,
+											timePaused: 0
+										});
+										if (station.currentSong !== null && station.currentSong._id !== undefined) {
+											utils.socketsJoinSongRoom(io.io.to(`station.${station._id}`).sockets, `song.${station.currentSong._id}`);
+											console.log("NEXT SONG!!!", station.currentSong);
+											if (!station.paused) {
+												notifications.schedule(`stations.nextSong?id=${station._id}`, station.currentSong.duration * 1000);
+											}
+										} else {
+											console.log("22", !!(station.currentSong));
+											utils.socketsLeaveSongRooms(io.io.to(`station.${station._id}`).sockets, `song.${station.currentSong._id}`);
+										}
 									}
-									cb(err, station);
 								});
 							}
 							// the station doesn't exist anymore, unsubscribe from it
 							else {
+								console.log(112233445566, "REMOVE NOTIFICATION");
 								notifications.remove(notification);
 							}
 						});
 					}, true);
-					if (!station.paused) {
+					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));
-						if (isNaN(timeLeft)) timeLeft = -1;
-						if (station.currentSong.duration * 1000 < timeLeft || timeLeft < 0) {
-							console.log("Test");
-							notifications.schedule(`stations.nextSong?id=${station._id}`, 1);
+						if (station.currentSong) {
+							let timeLeft = ((station.currentSong.duration * 1000) - (Date.now() - station.startedAt - station.timePaused));
+							if (isNaN(timeLeft)) timeLeft = -1;
+							if (station.currentSong.duration * 1000 < timeLeft || timeLeft < 0) {
+								console.log("Test");
+								notifications.schedule(`stations.nextSong?id=${station._id}`, 1);
+							} else {
+								notifications.schedule(`stations.nextSong?id=${station._id}`, timeLeft);
+							}
 						} else {
-							notifications.schedule(`stations.nextSong?id=${station._id}`, timeLeft);
+							notifications.schedule(`stations.nextSong?id=${station._id}`, 1);
 						}
 					} else {
 						notifications.unschedule(`stations.nextSong?id${station._id}`);
@@ -268,6 +308,7 @@ module.exports = {
 			(station, next) => {
 				if (station) {
 					station = cache.schemas.station(station);
+					console.log(1234321, stationId);
 					cache.hset('stations', stationId, station);
 					next(true, station);
 				} else next('Station not found.');
@@ -289,7 +330,7 @@ module.exports = {
 
 			(station, next) => {
 				if (!station) return next('Station not found.');
-
+				console.log(123444321, stationId);
 				cache.hset('stations', stationId, station, (err) => {
 					if (err) return next(err);
 					next(null, station);

+ 12 - 0
backend/logic/utils.js

@@ -195,5 +195,17 @@ module.exports = {
 			}
 			socket.join(room);
 		}
+	},
+	socketsLeaveSongRooms: function(sockets) {
+		for (let id in sockets) {
+			let socket = sockets[id];
+			let rooms = socket.rooms;
+			for (let roomId in rooms) {
+				console.log(roomId);
+				if (roomId.indexOf('song.') !== -1) {
+					socket.leave(roomId);
+				}
+			}
+		}
 	}
 };

+ 1 - 1
frontend/App.vue

@@ -106,7 +106,7 @@
 			},
 			'ccs': function () {
 				let _this = this;
-				this.socket.emit('stations.create', _this.ccs.name, _this.ccs.displayName, _this.ccs.description, result => {
+				this.socket.emit('stations.createCommunity', {_id: _this.ccs.name, displayName: _this.ccs.displayName, description: _this.ccs.description}, result => {
 					if (result.status === 'success') {
 						Toast.methods.addToast(`You have added the station successfully`, 4000);
 					} else {

+ 6 - 4
frontend/components/MainHeader.vue

@@ -59,11 +59,13 @@
 	@import 'theme.scss';
 
 	.nav {
-		background-color: $grey-darker;
-		height: 50px;
+		background-color: #03a9f4;
+		height: 64px;
 
 		.is-brand {
-			font-size: 26px !important;
+			font-size: 2.1rem !important;
+			line-height: 64px !important;
+			padding: 0 20px;
 		}
 
 		.nav-item {
@@ -75,7 +77,7 @@
 			}
 		}
 		.admin {
-			color: $blue;
+			color: $red;
 		}
 	}
 	.grouped {

+ 68 - 37
frontend/components/Station/Station.vue

@@ -6,17 +6,18 @@
 	<users-sidebar v-if='sidebars.users'></users-sidebar>
 	
 	<div class="station">
-		<div class="columns is-mobile">
+		<h1 v-if="noSong" class="noSong">No song is currently playing.</h1>
+		<div class="columns is-mobile" v-if="!noSong">
 			<div class="column is-8-desktop is-offset-2-desktop is-12-mobile">
 				<div class="video-container">
 					<div id="player"></div>
 					<div class="seeker-bar-container white" id="preview-progress">
-						<div class="seeker-bar light-blue" style="width: 60.9869%;"></div>
+						<div class="seeker-bar light-blue" style="width: 0%;"></div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div class="columns is-mobile">
+		<div class="columns is-mobile" v-if="!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">
@@ -117,7 +118,8 @@
 					queue: false,
 					users: false,
 					playlist: false
-				}
+				},
+				noSong: false
 			}
 		},
 		methods: {
@@ -207,14 +209,18 @@
 			},
 			resumeLocalStation: function() {
 				this.paused = false;
-				if (this.playerReady) {
-					this.player.seekTo(this.getTimeElapsed() / 1000);
-					this.player.playVideo();
+				if (!this.noSong) {
+					if (this.playerReady) {
+						this.player.seekTo(this.getTimeElapsed() / 1000);
+						this.player.playVideo();
+					}
 				}
 			},
 			pauseLocalStation: function() {
 				this.paused = true;
-				if (this.playerReady) this.player.pauseVideo();
+				if (!this.noSong) {
+					if (this.playerReady) this.player.pauseVideo();
+				}
 			},
 			skipStation: function () {
 				let _this = this;
@@ -307,36 +313,47 @@
 			_this.socket = _this.$parent.socket;
 			_this.socket.emit('stations.join', _this.stationId, data => {
 				if (data.status === "success") {
-					_this.currentSong = data.currentSong;
+					_this.currentSong = (data.currentSong) ? data.currentSong : {};
 					_this.startedAt = data.startedAt;
 					_this.paused = data.paused;
 					_this.timePaused = data.timePaused;
-					_this.youtubeReady();
-					_this.playVideo();
-					_this.socket.emit('songs.getOwnSongRatings', data.currentSong._id, data => {
-						if (_this.currentSong._id === data.songId) {
-							_this.liked = data.liked;
-							_this.disliked = data.disliked;
-						}
-					});
+					if (data.currentSong) {
+						_this.youtubeReady();
+						_this.playVideo();
+						_this.socket.emit('songs.getOwnSongRatings', data.currentSong._id, data => {
+							if (_this.currentSong._id === data.songId) {
+								_this.liked = data.liked;
+								_this.disliked = data.disliked;
+							}
+						});
+					} else {
+						_this.noSong = true;
+					}
 				} else {
 					//TODO Handle error
 				}
 			});
 
 			_this.socket.on('event:songs.next', data => {
-				_this.currentSong = data.currentSong;
+				_this.currentSong = (data.currentSong) ? data.currentSong : {};
 				_this.startedAt = data.startedAt;
 				_this.paused = data.paused;
 				_this.timePaused = data.timePaused;
-				_this.playVideo();
-				_this.socket.emit('songs.getOwnSongRatings', data.currentSong._id, (data) => {
-					console.log(data);
-					if (_this.currentSong._id === data.songId) {
-						_this.liked = data.liked;
-						_this.disliked = data.disliked;
+				if (data.currentSong) {
+					if (!_this.playerReady) {
+						_this.youtubeReady();
 					}
-				});
+					_this.playVideo();
+					_this.socket.emit('songs.getOwnSongRatings', data.currentSong._id, (data) => {
+						console.log(data);
+						if (_this.currentSong._id === data.songId) {
+							_this.liked = data.liked;
+							_this.disliked = data.disliked;
+						}
+					});
+				} else {
+					_this.noSong = true;
+				}
 			});
 
 			_this.socket.on('event:stations.pause', data => {
@@ -349,32 +366,41 @@
 			});
 
 			_this.socket.on('event:song.like', data => {
-				if (data.songId === _this.currentSong._id) {
-					_this.currentSong.likes++;
-					if (data.undisliked) _this.currentSong.dislikes--;
+				if (!this.noSong) {
+					if (data.songId === _this.currentSong._id) {
+						_this.currentSong.likes++;
+						if (data.undisliked) _this.currentSong.dislikes--;
+					}
 				}
 			});
 
 			_this.socket.on('event:song.dislike', data => {
-				if (data.songId === _this.currentSong._id) {
-					_this.currentSong.dislikes++;
-					if (data.unliked) _this.currentSong.likes--;
+				if (!this.noSong) {
+					if (data.songId === _this.currentSong._id) {
+						_this.currentSong.dislikes++;
+						if (data.unliked) _this.currentSong.likes--;
+					}
 				}
 			});
 
 			_this.socket.on('event:song.unlike', data => {
-				if (data.songId === _this.currentSong._id) _this.currentSong.likes--;
+				if (!this.noSong) {
+					if (data.songId === _this.currentSong._id) _this.currentSong.likes--;
+				}
 			});
 
 			_this.socket.on('event:song.undislike', data => {
-				if (data.songId === _this.currentSong._id) _this.currentSong.dislikes--;
+				if (!this.noSong) {
+					if (data.songId === _this.currentSong._id) _this.currentSong.dislikes--;
+				}
 			});
 
 			_this.socket.on('event:song.newRatings', data => {
-				console.log(data, 1234);
-				if (data.songId === _this.currentSong._id) {
-					_this.liked = data.liked;
-					_this.disliked = data.disliked;
+				if (!this.noSong) {
+					if (data.songId === _this.currentSong._id) {
+						_this.liked = data.liked;
+						_this.disliked = data.disliked;
+					}
 				}
 			});
 
@@ -387,6 +413,11 @@
 </script>
 
 <style lang="scss">
+	.noSong {
+		color: #03A9F4;
+		text-align: center;
+	}
+
 	.slideout {
 		top: 50px;
 		height: 100%;

+ 27 - 11
frontend/components/Station/StationHeader.vue

@@ -1,10 +1,8 @@
 <template>
 	<nav class="nav">
 		<div class="nav-left">
-			<a class="nav-item" href="#" v-link="{ path: '/' }" @click="this.$dispatch('leaveStation', title)">
-				<span class="icon">
-					<i class="material-icons">home</i>
-				</span>
+			<a class="nav-item logo" href="#" v-link="{ path: '/' }" @click="this.$dispatch('leaveStation', title)">
+				Musare
 			</a>
 			<a class="nav-item" href="#" @click="$parent.toggleModal()">
 				<span class="icon">
@@ -18,32 +16,32 @@
 			</a>
 			<a v-if="$parent.$parent.role === 'admin'" class="nav-item" href="#" @click="$parent.skipStation()">
 				<span class="icon">
-					<i class="material-icons left">skip_next</i>
+					<i class="material-icons">skip_next</i>
 				</span>
 			</a>
 			<a v-if="$parent.$parent.role !== 'admin' && $parent.$parent.loggedIn" class="nav-item" href="#" @click="$parent.voteSkipStation()">
 				<span class="icon">
-					<i class="material-icons left">skip_next</i>
+					<i class="material-icons">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>
+					<i class="material-icons">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>
+					<i class="material-icons">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>
+					<i class="material-icons">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>
+					<i class="material-icons">pause</i>
 				</span>
 			</a>
 		</div>
@@ -97,7 +95,7 @@
 <style lang="scss" scoped>
 	@import 'theme.scss';
 	.nav {
-		background-color: $grey-darker;
+		background-color: #03a9f4;
 	}
 
 	a.nav-item {
@@ -106,6 +104,24 @@
 		&:hover {
 			color: $white;
 		}
+
+		padding: 0 18px;
+		.icon {
+			height: 64px;
+			i {
+				font-size: 2rem;
+				line-height: 64px;
+				height: 64px;
+				width: 34px;
+			}
+		}
+	}
+
+	.logo {
+		font-size: 2.1rem;
+		line-height: 64px;
+		padding-left: 20px !important;
+		padding-right: 20px !important;
 	}
 
 	.nav-center {

+ 8 - 2
frontend/components/pages/Home.vue

@@ -5,7 +5,7 @@
 			<div class="group-title">Official Stations</div>
 			<div class="group-stations">
 				<div class="stations-station" v-for="station in stations.official" v-link="{ path: '/official/' + station._id }" @click="this.$dispatch('joinStation', station._id)">
-					<img class="station-image" :src="station.currentSong.thumbnail" />
+					<img class="station-image" :src="station.currentSong.thumbnail" onerror="this.src='/assets/notes.png'" />
 					<div class="station-info">
 						<div class="station-grid-left">
 							<h3>{{ station.displayName }}</h3>
@@ -23,7 +23,7 @@
 			<div class="group-title">Community Stations</div>
 			<div class="group-stations">
 				<div class="stations-station" v-for="station in stations.community" v-link="{ path: '/community/' + station._id }" @click="this.$dispatch('joinStation', station._id)">
-					<img class="station-image" :src="station.currentSong.thumbnail" />
+					<img class="station-image" :src="station.currentSong.thumbnail" onerror="this.src='/assets/notes.png'" />
 					<div class="station-info">
 						<div class="station-grid-left">
 							<h3>{{ station.displayName }}</h3>
@@ -66,12 +66,18 @@
 					_this.socket = _this.$parent.socket;
 					_this.socket.emit("stations.index", data => {
 						if (data.status === "success")  data.stations.forEach(station => {
+							if (!station.currentSong) {
+								station.currentSong = {thumbnail: '/assets/notes.png'};
+							}
 							if (station.type == 'official') _this.stations.official.push(station);
 							else _this.stations.community.push(station);
 						});
 					});
 					_this.socket.emit("apis.joinRoom", 'home', () => {});
 					_this.socket.on('event:stations.created', (station) => {
+						if (!station.currentSong) {
+							station.currentSong = {};
+						}
 						_this.stations[station.type].push(station);
 					});
 					clearInterval(socketInterval);