Browse Source

fix(Profile): public playlists now shown to logged-out users viewing a profile

Signed-off-by: Jonathan <theflametrooper@gmail.com>
Jonathan 4 years ago
parent
commit
bd9d22362e

+ 2 - 2
backend/logic/actions/apis.js

@@ -118,12 +118,12 @@ export default {
 	 * @param {Function} cb - callback
 	 */
 	joinRoom(session, page, cb) {
-		if (page === "home") {
+		if (page === "home" || page.startsWith("profile-")) {
 			IOModule.runJob("SOCKET_JOIN_ROOM", {
 				socketId: session.socketId,
 				room: page
 			})
-				.then()
+				.then(() => {})
 				.catch(err => {
 					this.log("ERROR", `Joining room failed: ${err.message}`);
 				});

+ 131 - 15
backend/logic/actions/playlists.js

@@ -21,6 +21,12 @@ CacheModule.runJob("SUB", {
 				socket.emit("event:playlist.create", playlist);
 			});
 		});
+
+		if (playlist.privacy === "public")
+			IOModule.runJob("EMIT_TO_ROOM", {
+				room: `profile-${playlist.createdBy}`,
+				args: ["event:playlist.create", playlist]
+			});
 	}
 });
 
@@ -32,6 +38,11 @@ CacheModule.runJob("SUB", {
 				socket.emit("event:playlist.delete", res.playlistId);
 			});
 		});
+
+		IOModule.runJob("EMIT_TO_ROOM", {
+			room: `profile-${res.userId}`,
+			args: ["event:playlist.delete", res.playlistId]
+		});
 	}
 });
 
@@ -74,6 +85,18 @@ CacheModule.runJob("SUB", {
 				});
 			});
 		});
+
+		if (res.privacy === "public")
+			IOModule.runJob("EMIT_TO_ROOM", {
+				room: `profile-${res.userId}`,
+				args: [
+					"event:playlist.addSong",
+					{
+						playlistId: res.playlistId,
+						song: res.song
+					}
+				]
+			});
 	}
 });
 
@@ -88,6 +111,18 @@ CacheModule.runJob("SUB", {
 				});
 			});
 		});
+
+		if (res.privacy === "public")
+			IOModule.runJob("EMIT_TO_ROOM", {
+				room: `profile-${res.userId}`,
+				args: [
+					"event:playlist.removeSong",
+					{
+						playlistId: res.playlistId,
+						songId: res.songId
+					}
+				]
+			});
 	}
 });
 
@@ -102,6 +137,18 @@ CacheModule.runJob("SUB", {
 				});
 			});
 		});
+
+		if (res.privacy === "public")
+			IOModule.runJob("EMIT_TO_ROOM", {
+				room: `profile-${res.userId}`,
+				args: [
+					"event:playlist.updateDisplayName",
+					{
+						playlistId: res.playlistId,
+						displayName: res.displayName
+					}
+				]
+			});
 	}
 });
 
@@ -110,12 +157,20 @@ CacheModule.runJob("SUB", {
 	cb: res => {
 		IOModule.runJob("SOCKETS_FROM_USER", { userId: res.userId }, this).then(response => {
 			response.sockets.forEach(socket => {
-				socket.emit("event:playlist.updatePrivacy", {
-					playlistId: res.playlistId,
-					privacy: res.privacy
-				});
+				socket.emit("event:playlist.updatePrivacy");
 			});
 		});
+
+		if (res.playlist.privacy === "public")
+			return IOModule.runJob("EMIT_TO_ROOM", {
+				room: `profile-${res.userId}`,
+				args: ["event:playlist.create", res.playlist]
+			});
+
+		return IOModule.runJob("EMIT_TO_ROOM", {
+			room: `profile-${res.userId}`,
+			args: ["event:playlist.delete", res.playlist._id]
+		});
 	}
 });
 
@@ -166,6 +221,64 @@ export default {
 		);
 	}),
 
+	/**
+	 * Gets a list of all the playlists for a specific user
+	 *
+	 * @param {object} session - the session object automatically added by socket.io
+	 * @param {string} userId - the user id in question
+	 * @param {Function} cb - gets called with the result
+	 */
+	indexForUser: async function indexForUser(session, userId, cb) {
+		const playlistModel = await DBModule.runJob(
+			"GET_MODEL",
+			{
+				modelName: "playlist"
+			},
+			this
+		);
+
+		async.waterfall(
+			[
+				next => {
+					playlistModel.find({ createdBy: userId }, next);
+				},
+
+				(playlists, next) => {
+					if (session.userId === userId) return next(null, playlists); // user requesting playlists is the owner of the playlists
+
+					const filteredPlaylists = [];
+
+					return async.each(
+						playlists,
+						(playlist, nextPlaylist) => {
+							if (playlist.privacy === "public") filteredPlaylists.push(playlist);
+							return nextPlaylist();
+						},
+						() => next(null, filteredPlaylists)
+					);
+				}
+			],
+			async (err, playlists) => {
+				if (err) {
+					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
+					this.log(
+						"ERROR",
+						"PLAYLIST_INDEX_FOR_USER",
+						`Indexing playlists for user "${userId}" failed. "${err}"`
+					);
+					return cb({ status: "failure", message: err });
+				}
+
+				this.log("SUCCESS", "PLAYLIST_INDEX_FOR_USER", `Successfully indexed playlists for user "${userId}".`);
+
+				return cb({
+					status: "success",
+					data: playlists
+				});
+			}
+		);
+	},
+
 	/**
 	 * Gets all playlists for the user requesting it
 	 *
@@ -173,7 +286,7 @@ export default {
 	 * @param {boolean} showNonModifiablePlaylists - whether or not to show non modifiable playlists e.g. liked songs
 	 * @param {Function} cb - gets called with the result
 	 */
-	indexForUser: isLoginRequired(async function indexForUser(session, showNonModifiablePlaylists, cb) {
+	indexMyPlaylists: isLoginRequired(async function indexMyPlaylists(session, showNonModifiablePlaylists, cb) {
 		const playlistModel = await DBModule.runJob(
 			"GET_MODEL",
 			{
@@ -193,14 +306,14 @@ export default {
 					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
 					this.log(
 						"ERROR",
-						"PLAYLIST_INDEX_FOR_USER",
+						"PLAYLIST_INDEX_FOR_ME",
 						`Indexing playlists for user "${session.userId}" failed. "${err}"`
 					);
 					return cb({ status: "failure", message: err });
 				}
 				this.log(
 					"SUCCESS",
-					"PLAYLIST_INDEX_FOR_USER",
+					"PLAYLIST_INDEX_FOR_ME",
 					`Successfully indexed playlists for user "${session.userId}".`
 				);
 				return cb({
@@ -598,7 +711,8 @@ export default {
 					value: {
 						playlistId: playlist._id,
 						song: newSong,
-						userId: session.userId
+						userId: session.userId,
+						privacy: playlist.privacy
 					}
 				});
 				return cb({
@@ -801,7 +915,8 @@ export default {
 					value: {
 						playlistId: playlist._id,
 						songId,
-						userId: session.userId
+						userId: session.userId,
+						privacy: playlist.privacy
 					}
 				});
 				return cb({
@@ -858,7 +973,7 @@ export default {
 						.catch(next);
 				}
 			],
-			async err => {
+			async (err, playlist) => {
 				if (err) {
 					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
 					this.log(
@@ -878,7 +993,8 @@ export default {
 					value: {
 						playlistId,
 						displayName,
-						userId: session.userId
+						userId: session.userId,
+						privacy: playlist.privacy
 					}
 				});
 				return cb({
@@ -1232,6 +1348,7 @@ export default {
 	 *
 	 * @param {object} session - the session object automatically added by socket.io
 	 * @param {string} playlistId - the id of the playlist we are updating the privacy for
+	 * @param {string} privacy - what the new privacy of the playlist should be e.g. public
 	 * @param {Function} cb - gets called with the result
 	 */
 	updatePrivacy: isLoginRequired(async function updatePrivacy(session, playlistId, privacy, cb) {
@@ -1261,7 +1378,7 @@ export default {
 						.catch(next);
 				}
 			],
-			async err => {
+			async (err, playlist) => {
 				if (err) {
 					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
 					this.log(
@@ -1279,9 +1396,8 @@ export default {
 				CacheModule.runJob("PUB", {
 					channel: "playlist.updatePrivacy",
 					value: {
-						playlistId,
-						privacy,
-						userId: session.userId
+						userId: session.userId,
+						playlist
 					}
 				});
 				return cb({

+ 1 - 2
backend/logic/actions/stations.js

@@ -1529,8 +1529,7 @@ export default {
 
 				(station, next) => {
 					if (!station) return next("Station not found.");
-					if (station.theme === newTheme)
-						return next("No change in theme.");
+					if (station.theme === newTheme) return next("No change in theme.");
 					return stationModel.updateOne(
 						{ _id: stationId },
 						{ $set: { theme: newTheme } },

+ 1 - 1
frontend/src/components/modals/EditStation.vue

@@ -561,7 +561,7 @@ export default {
 		io.getSocket(socket => {
 			this.socket = socket;
 
-			this.socket.emit("playlists.indexForUser", true, res => {
+			this.socket.emit("playlists.indexMyPlaylists", true, res => {
 				if (res.status === "success") this.playlists = res.data;
 			});
 

+ 73 - 102
frontend/src/pages/Profile.vue

@@ -232,6 +232,7 @@ export default {
 
 		io.getSocket(socket => {
 			this.socket = socket;
+
 			this.socket.emit(
 				"users.findByUsername",
 				this.$route.params.username,
@@ -245,16 +246,81 @@ export default {
 						);
 						this.isUser = true;
 
-						if (this.user._id === this.userId) {
+						if (this.user._id !== this.userId) {
 							this.socket.emit(
-								"playlists.indexForUser",
-								true,
-								res => {
-									if (res.status === "success")
-										this.playlists = res.data;
-								}
+								"apis.joinRoom",
+								`profile-${res.data._id}`,
+								() => {}
 							);
+						}
+
+						this.socket.emit(
+							"playlists.indexForUser",
+							this.user._id,
+							res => {
+								if (res.status === "success")
+									this.playlists = res.data;
+							}
+						);
+
+						this.socket.on("event:playlist.create", playlist => {
+							this.playlists.push(playlist);
+						});
+
+						this.socket.on("event:playlist.delete", playlistId => {
+							this.playlists.forEach((playlist, index) => {
+								if (playlist._id === playlistId) {
+									this.playlists.splice(index, 1);
+								}
+							});
+						});
+
+						this.socket.on("event:playlist.addSong", data => {
+							this.playlists.forEach((playlist, index) => {
+								if (playlist._id === data.playlistId) {
+									this.playlists[index].songs.push(data.song);
+								}
+							});
+						});
+
+						this.socket.on("event:playlist.removeSong", data => {
+							this.playlists.forEach((playlist, index) => {
+								if (playlist._id === data.playlistId) {
+									this.playlists[index].songs.forEach(
+										(song, index2) => {
+											if (song.songId === data.songId) {
+												this.playlists[
+													index
+												].songs.splice(index2, 1);
+											}
+										}
+									);
+								}
+							});
+						});
 
+						this.socket.on(
+							"event:playlist.updateDisplayName",
+							data => {
+								this.playlists.forEach((playlist, index) => {
+									if (playlist._id === data.playlistId) {
+										this.playlists[index].displayName =
+											data.displayName;
+									}
+								});
+							}
+						);
+
+						this.socket.on("event:playlist.updatePrivacy", data => {
+							this.playlists.forEach((playlist, index) => {
+								if (playlist._id === data.playlistId) {
+									this.playlists[index].privacy =
+										data.privacy;
+								}
+							});
+						});
+
+						if (this.user._id === this.userId) {
 							this.socket.emit(
 								"activities.getSet",
 								this.userId,
@@ -288,101 +354,6 @@ export default {
 									});
 								}
 							);
-
-							this.socket.on(
-								"event:playlist.create",
-								playlist => {
-									this.playlists.push(playlist);
-								}
-							);
-
-							this.socket.on(
-								"event:playlist.delete",
-								playlistId => {
-									this.playlists.forEach(
-										(playlist, index) => {
-											if (playlist._id === playlistId) {
-												this.playlists.splice(index, 1);
-											}
-										}
-									);
-								}
-							);
-
-							this.socket.on("event:playlist.addSong", data => {
-								this.playlists.forEach((playlist, index) => {
-									if (playlist._id === data.playlistId) {
-										this.playlists[index].songs.push(
-											data.song
-										);
-									}
-								});
-							});
-
-							this.socket.on(
-								"event:playlist.removeSong",
-								data => {
-									this.playlists.forEach(
-										(playlist, index) => {
-											if (
-												playlist._id === data.playlistId
-											) {
-												this.playlists[
-													index
-												].songs.forEach(
-													(song, index2) => {
-														if (
-															song.songId ===
-															data.songId
-														) {
-															this.playlists[
-																index
-															].songs.splice(
-																index2,
-																1
-															);
-														}
-													}
-												);
-											}
-										}
-									);
-								}
-							);
-
-							this.socket.on(
-								"event:playlist.updateDisplayName",
-								data => {
-									this.playlists.forEach(
-										(playlist, index) => {
-											if (
-												playlist._id === data.playlistId
-											) {
-												this.playlists[
-													index
-												].displayName =
-													data.displayName;
-											}
-										}
-									);
-								}
-							);
-
-							this.socket.on(
-								"event:playlist.updatePrivacy",
-								data => {
-									this.playlists.forEach(
-										(playlist, index) => {
-											if (
-												playlist._id === data.playlistId
-											) {
-												this.playlists[index].privacy =
-													data.privacy;
-											}
-										}
-									);
-								}
-							);
 						}
 					}
 				}

+ 1 - 1
frontend/src/pages/Station/AddSongToQueue.vue

@@ -239,7 +239,7 @@ export default {
 	mounted() {
 		io.getSocket(socket => {
 			this.socket = socket;
-			this.socket.emit("playlists.indexForUser", true, res => {
+			this.socket.emit("playlists.indexMyPlaylists", true, res => {
 				if (res.status === "success") this.playlists = res.data;
 			});
 		});

+ 1 - 1
frontend/src/pages/Station/components/AddToPlaylistDropdown.vue

@@ -61,7 +61,7 @@ export default {
 		this.song = this.currentSong;
 		io.getSocket(socket => {
 			this.socket = socket;
-			this.socket.emit("playlists.indexForUser", false, res => {
+			this.socket.emit("playlists.indexMyPlaylists", false, res => {
 				if (res.status === "success") {
 					res.data.forEach(playlist => {
 						this.playlists[playlist._id] = playlist;

+ 2 - 1
frontend/src/pages/Station/components/Sidebar/MyPlaylists.vue

@@ -74,11 +74,12 @@ export default {
 			this.socket = socket;
 
 			/** Get playlists for user */
-			this.socket.emit("playlists.indexForUser", true, res => {
+			this.socket.emit("playlists.indexMyPlaylists", true, res => {
 				if (res.status === "success") this.playlists = res.data;
 			});
 
 			this.socket.on("event:playlist.create", playlist => {
+				console.log("create");
 				this.playlists.push(playlist);
 			});