Selaa lähdekoodia

Worked on station editing and station privacy.

KrisVos130 8 vuotta sitten
vanhempi
commit
f384141a67

+ 106 - 54
backend/logic/actions/stations.js

@@ -68,11 +68,46 @@ module.exports = {
 			}
 
 			let arr = [];
+			let done = 0;
 			for (let prop in stations) {
-				arr.push(stations[prop]);
+				// TODO If community, check if on whitelist
+				let station = stations[prop];
+				if (station.privacy === 'public') {
+					add(true, station);
+				} else if (!session.sessionId) {
+					add(false);
+				} else {
+					cache.hget('sessions', session.sessionId, (err, session) => {
+						if (err || !session) {
+							add(false);
+						} else {
+							db.models.user.findOne({_id: session.userId}, (err, user) => {
+								if (err || !user) {
+									add(false);
+								} else if (user.role === 'admin') {
+									add(true, station);
+								} else if (station.type === 'official') {
+									add(false);
+								} else if (station.owner === session.userId) {
+									add(true, station);
+								} else add(false);
+							});
+						}
+					});
+				}
 			}
 
-			cb({ status: 'success', stations: arr });
+			function add(add, station) {
+				console.log("ADD!", add, station);
+				if (add) {
+					arr.push(station);
+				}
+				done++;
+				if (done === Object.keys(stations).length) {
+					console.log("DONE!", done);
+					cb({ status: 'success', stations: arr });
+				}
+			}
 		});
 	},
 
@@ -108,48 +143,61 @@ module.exports = {
 
 			if (station) {
 
-				//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(session.socketId, `station.${stationId}`);
-				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;
-						}
+				if (station.privacy !== 'private') {
+					func();
+				} else {
+					// TODO If community, check if on whitelist
+					if (!session.userId) return cb({ status: 'error', message: 'An error occurred while joining the station1' });
+					db.models.user.findOne({_id: session.userId}, (err, user) => {
+						if (err || !user) return cb({ status: 'error', message: 'An error occurred while joining the station2' });
+						if (user.role === 'admin') return func();
+						if (station.type === 'official') return cb({ status: 'error', message: 'An error occurred while joining the station3' });
+						if (station.owner === session.userId) return func();
+						return cb({ status: 'error', message: 'An error occurred while joining the station4' });
+					});
+				}
+
+				function func() {
+					utils.socketJoinRoom(session.socketId, `station.${stationId}`);
+					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',
+								data: {
+									type: station.type,
+									currentSong: station.currentSong,
+									startedAt: station.startedAt,
+									paused: station.paused,
+									timePaused: station.timePaused,
+									description: station.description,
+									displayName: station.displayName,
+									privacy: station.privacy
+								}
+							});
+						});
+					} else {
 						cb({
 							status: 'success',
 							data: {
 								type: station.type,
-								currentSong: station.currentSong,
+								currentSong: null,
 								startedAt: station.startedAt,
 								paused: station.paused,
 								timePaused: station.timePaused
 							}
 						});
-					});
-				} else {
-					cb({
-						status: 'success',
-						data: {
-							type: station.type,
-							currentSong: null,
-							startedAt: station.startedAt,
-							paused: station.paused,
-							timePaused: station.timePaused
-						}
-					});
+					}
 				}
-				//});
-			}
-			else {
+			} else {
 				cb({ status: 'failure', message: `That station doesn't exist` });
 			}
 		});
@@ -237,29 +285,33 @@ module.exports = {
 		});
 	},
 
-	lock: hooks.adminRequired((session, stationId, cb) => {
-		stations.getStation(stationId, (err, station) => {
-			if (err && err !== true) {
-				return cb({ status: 'error', message: 'An error occurred while locking the station' });
-			} else if (station) {
-				// Add code to update Mongo and Redis
-				cb({ status: 'success' });
-			} else {
-				cb({ status: 'failure', message: `That station doesn't exist, it may have been deleted` });
-			}
+	updateDisplayName: hooks.adminRequired((session, stationId, newDisplayName, cb) => {
+		db.models.station.update({_id: stationId}, {$set: {displayName: newDisplayName}}, (err) => {
+			if (err) return cb({ status: 'failure', message: 'Something went wrong when saving the station.' });
+			stations.updateStation(stationId, () => {
+				//TODO Pub/sub for displayName change
+				cb({ status: 'success', message: 'Successfully updated the display name.' });
+			})
 		});
 	}),
 
-	unlock: hooks.adminRequired((session, stationId, cb) => {
-		stations.getStation(stationId, (err, station) => {
-			if (err && err !== true) {
-				return cb({ status: 'error', message: 'An error occurred while unlocking the station' });
-			} else if (station) {
-				// Add code to update Mongo and Redis
-				cb({ status: 'success' });
-			} else {
-				cb({ status: 'failure', message: `That station doesn't exist, it may have been deleted` });
-			}
+	updateDescription: hooks.adminRequired((session, stationId, newDescription, cb) => {
+		db.models.station.update({_id: stationId}, {$set: {description: newDescription}}, (err) => {
+			if (err) return cb({ status: 'failure', message: 'Something went wrong when saving the station.' });
+			stations.updateStation(stationId, () => {
+				//TODO Pub/sub for description change
+				cb({ status: 'success', message: 'Successfully updated the description.' });
+			})
+		});
+	}),
+
+	updatePrivacy: hooks.adminRequired((session, stationId, newPrivacy, cb) => {
+		db.models.station.update({_id: stationId}, {$set: {privacy: newPrivacy}}, (err) => {
+			if (err) return cb({ status: 'failure', message: 'Something went wrong when saving the station.' });
+			stations.updateStation(stationId, () => {
+				//TODO Pub/sub for privacy change
+				cb({ status: 'success', message: 'Successfully updated the privacy.' });
+			})
 		});
 	}),
 

+ 2 - 1
backend/logic/db/schemas/station.js

@@ -32,5 +32,6 @@ module.exports = {
 		likes: { type: Number, default: -1 },
 		dislikes: { type: Number, default: -1 },
 		requestedBy: { type: String, required: true }
-	}]
+	}],
+	owner: { type: String }
 };

+ 106 - 0
frontend/components/Modals/EditStation.vue

@@ -0,0 +1,106 @@
+<template>
+	<div class='modal is-active'>
+		<div class='modal-background'></div>
+		<div class='modal-card'>
+			<header class='modal-card-head'>
+				<p class='modal-card-title'>Edit station</p>
+				<button class='delete' @click='$parent.toggleModal("editStation")'></button>
+			</header>
+			<section class='modal-card-body'>
+				<label class='label'>Display name</label>
+				<div class='control is-grouped'>
+					<p class='control is-expanded'>
+						<input class='input' type='text' placeholder='Station Display Name' v-model='$parent.station.displayName'>
+					</p>
+					<p class='control'>
+						<a class='button is-info' @click='updateDisplayName()'>Update</a>
+					</p>
+				</div>
+				<label class='label'>Description</label>
+				<div class='control is-grouped'>
+					<p class='control is-expanded'>
+						<input class='input' type='text' placeholder='Station Display Name' v-model='$parent.station.description'>
+					</p>
+					<p class='control'>
+						<a class='button is-info' @click='updateDescription()'>Update</a>
+					</p>
+				</div>
+				<label class="label">Privacy</label>
+				<div class='control is-grouped'>
+					<p class="control is-expanded">
+						<span class="select">
+							<select v-model="$parent.station.privacy">
+								<option v-bind:value="'public'">Public</option>
+								<option v-bind:value="'unlisted'">Unlisted</option>
+								<option v-bind:value="'private'">Private</option>
+							</select>
+						</span>
+					</p>
+					<p class='control'>
+						<a class='button is-info' @click='updatePrivacy()'>Update</a>
+					</p>
+				</div>
+			</section>
+		</div>
+	</div>
+</template>
+
+<script>
+	import { Toast } from 'vue-roaster';
+
+	export default {
+		data() {
+			return {
+
+			}
+		},
+		methods: {
+			updateDisplayName: function () {
+				this.socket.emit('stations.updateDisplayName', this.$parent.stationId, this.$parent.station.displayName, res => {
+					if (res.status == 'success') return Toast.methods.addToast(res.message, 4000);
+					Toast.methods.addToast(res.message, 8000);
+				});
+			},
+			updateDescription: function () {
+				this.socket.emit('stations.updateDescription', this.$parent.stationId, this.$parent.station.description, res => {
+					if (res.status == 'success') return Toast.methods.addToast(res.message, 4000);
+					Toast.methods.addToast(res.message, 8000);
+				});
+			},
+			updatePrivacy: function () {
+				this.socket.emit('stations.updatePrivacy', this.$parent.stationId, this.$parent.station.privacy, res => {
+					if (res.status == 'success') return Toast.methods.addToast(res.message, 4000);
+					Toast.methods.addToast(res.message, 8000);
+				});
+			}
+		},
+		ready: function () {
+			let _this = this;
+			let socketInterval = setInterval(() => {
+				if (!!_this.$parent.$parent.socket) {
+					_this.socket = _this.$parent.$parent.socket;
+					clearInterval(socketInterval);
+				}
+			}, 100);
+		}
+	}
+</script>
+
+<style type='scss' scoped>
+
+
+	.controls {
+		display: flex;
+
+		a {
+			display: flex;
+    		align-items: center;
+		}
+	}
+
+	.table {
+		margin-bottom: 0;
+	}
+
+	h5 { padding: 20px 0; }
+</style>

+ 5 - 0
frontend/components/Station/CommunityHeader.vue

@@ -4,6 +4,11 @@
 			<a class="nav-item logo" href="#" v-link="{ path: '/' }" @click="this.$dispatch('leaveStation', title)">
 				Musare
 			</a>
+			<a class="nav-item" href="#" @click="$parent.toggleModal('editStation')">
+				<span class="icon">
+					<i class="material-icons">flag</i>
+				</span>
+			</a>
 			<a v-if="$parent.$parent.role === 'admin'" class="nav-item" href="#" @click="$parent.skipStation()">
 				<span class="icon">
 					<i class="material-icons">skip_next</i>

+ 5 - 0
frontend/components/Station/OfficialHeader.vue

@@ -9,6 +9,11 @@
 					<i class="material-icons">playlist_add</i>
 				</span>
 			</a>
+			<a class="nav-item" href="#" @click="$parent.toggleModal('editStation')">
+				<span class="icon">
+					<i class="material-icons">flag</i>
+				</span>
+			</a>
 			<a class="nav-item" href="#">
 				<span class="icon">
 					<i class="material-icons">flag</i>

+ 10 - 3
frontend/components/Station/Station.vue

@@ -5,6 +5,7 @@
 	<song-queue v-if='modals.addSongToQueue'></song-queue>
 	<edit-playlist v-if='modals.editPlaylist'></edit-playlist>
 	<create-playlist v-if='modals.createPlaylist'></create-playlist>
+	<edit-station v-if='modals.editStation'></edit-station>
 
 	<queue-sidebar v-if='sidebars.queue'></queue-sidebar>
 	<playlist-sidebar v-if='sidebars.playlist'></playlist-sidebar>
@@ -64,6 +65,7 @@
 	import SongQueue from '../Modals/AddSongToQueue.vue';
 	import EditPlaylist from '../Modals/Playlists/Edit.vue';
 	import CreatePlaylist from '../Modals/Playlists/Create.vue';
+	import EditStation from '../Modals/EditStation.vue';
 
 	import QueueSidebar from '../Sidebars/Queue.vue';
 	import PlaylistSidebar from '../Sidebars/Playlist.vue';
@@ -87,7 +89,8 @@
 				modals: {
 					addSongToQueue: false,
 					editPlaylist: false,
-					createPlaylist: false
+					createPlaylist: false,
+					editStation: false
 				},
 				sidebars: {
 					queue: false,
@@ -97,7 +100,8 @@
 				noSong: false,
 				simpleSong: false,
 				queue: [],
-				timeBeforePause: 0
+				timeBeforePause: 0,
+				station: {}
 			}
 		},
 		methods: {
@@ -106,9 +110,11 @@
 				this.toggleModal('editPlaylist');
 			},
 			toggleModal: function (type) {
+				console.log(type);
 				if (type == 'addSongToQueue') this.modals.addSongToQueue = !this.modals.addSongToQueue;
 				else if (type == 'editPlaylist') this.modals.editPlaylist = !this.modals.editPlaylist;
 				else if (type == 'createPlaylist') this.modals.createPlaylist = !this.modals.createPlaylist;
+				else if (type == 'editStation') this.modals.editStation = !this.modals.editStation;
 			},
 			youtubeReady: function() {
 				let local = this;
@@ -293,6 +299,7 @@
 					_this.socket.removeAllListeners();
 					_this.socket.emit('stations.join', _this.stationId, res => {
 						if (res.status === "success") {
+							_this.station = {displayName: res.data.displayName, description: res.data.description, privacy: res.data.privacy};
 							_this.currentSong = (res.data.currentSong) ? res.data.currentSong : {};
 							_this.type = res.data.type;
 							_this.startedAt = res.data.startedAt;
@@ -413,7 +420,7 @@
 			volume = (typeof volume === "number") ? volume : 20;
 			$("#volumeSlider").val(volume);
 		},
-		components: { OfficialHeader, CommunityHeader, SongQueue, EditPlaylist, CreatePlaylist, QueueSidebar, PlaylistSidebar, UsersSidebar }
+		components: { OfficialHeader, CommunityHeader, SongQueue, EditPlaylist, CreatePlaylist, EditStation, QueueSidebar, PlaylistSidebar, UsersSidebar }
 	}
 </script>