Browse Source

feat: allowed anyone to view public playlists on a user's profile

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

+ 10 - 16
backend/logic/actions/playlists.js

@@ -168,13 +168,8 @@ export default {
 	 * @param {Function} cb - gets called with the result
 	 */
 	index: isAdminRequired(async function index(session, cb) {
-		const playlistModel = await DBModule.runJob(
-			"GET_MODEL",
-			{
-				modelName: "playlist"
-			},
-			this
-		);
+		const playlistModel = await DBModule.runJob("GET_MODEL", { modelName: "playlist" }, this);
+
 		async.waterfall(
 			[
 				next => {
@@ -205,9 +200,7 @@ export default {
 			[
 				next => {
 					PlaylistsModule.runJob("GET_PLAYLIST", { playlistId }, this)
-						.then(playlist => {
-							next(null, playlist);
-						})
+						.then(playlist => next(null, playlist))
 						.catch(next);
 				},
 
@@ -469,19 +462,20 @@ export default {
 	 * @param {string} playlistId - the id of the playlist we are getting
 	 * @param {Function} cb - gets called with the result
 	 */
-	getPlaylist: isLoginRequired(function getPlaylist(session, playlistId, cb) {
+	getPlaylist: function getPlaylist(session, playlistId, cb) {
 		async.waterfall(
 			[
 				next => {
 					PlaylistsModule.runJob("GET_PLAYLIST", { playlistId }, this)
-						.then(playlist => {
-							next(null, playlist);
-						})
+						.then(playlist => next(null, playlist))
 						.catch(next);
 				},
 
 				(playlist, next) => {
-					if (!playlist || playlist.createdBy !== session.userId) return next("Playlist not found");
+					if (!playlist) return next("Playlist not found");
+					if (playlist.privacy !== "public" && playlist.createdBy !== session.userId)
+						return next("User unauthorised to view playlist.");
+
 					return next(null, playlist);
 				}
 			],
@@ -508,7 +502,7 @@ export default {
 				});
 			}
 		);
-	}),
+	},
 
 	/**
 	 * Obtains basic metadata of a playlist in order to format an activity

+ 1 - 3
backend/logic/playlists.js

@@ -387,9 +387,7 @@ class _PlaylistsModule extends CoreClass {
 				[
 					next => {
 						CacheModule.runJob("HGETALL", { table: "playlists" }, this)
-							.then(playlists => {
-								next(null, playlists);
-							})
+							.then(playlists => next(null, playlists))
 							.catch(next);
 					},
 

+ 2 - 1
frontend/src/App.vue

@@ -635,7 +635,8 @@ h4.section-title {
 			color: $green;
 		}
 
-		.edit-icon {
+		.edit-icon,
+		.view-icon {
 			color: $primary-color;
 		}
 

+ 64 - 30
frontend/src/components/modals/EditPlaylist/index.vue

@@ -1,9 +1,14 @@
 <template>
-	<modal title="Edit Playlist" class="edit-playlist-modal">
+	<modal
+		:title="
+			userId === playlist.createdBy ? 'Edit Playlist' : 'View Playlist'
+		"
+		class="edit-playlist-modal"
+	>
 		<div slot="body">
 			<div
 				:class="{
-					'view-only': !playlist.isUserModifiable,
+					'view-only': !isEditable(),
 					'edit-playlist-modal-inner-container': true
 				}"
 			>
@@ -13,10 +18,17 @@
 						<h5>Duration: {{ totalLength() }}</h5>
 					</div>
 
-					<div class="section-margin-bottom" />
+					<div
+						class="section-margin-bottom"
+						v-if="
+							(!playlist.isUserModifiable &&
+								userId === playlist.createdBy) ||
+								isEditable()
+						"
+					/>
 
 					<div id="playlist-settings-section" class="section">
-						<div v-if="playlist.isUserModifiable">
+						<div v-if="isEditable()">
 							<h4 class="section-title">Edit Details</h4>
 
 							<p class="section-description">
@@ -51,33 +63,35 @@
 							</div>
 						</div>
 
-						<label class="label">
-							Change privacy
-						</label>
-						<div class="control is-grouped input-with-button">
-							<div class="control is-expanded select">
-								<select v-model="playlist.privacy">
-									<option value="private">Private</option>
-									<option value="public">Public</option>
-								</select>
+						<div v-if="userId === playlist.createdBy">
+							<label class="label">
+								Change privacy
+							</label>
+							<div class="control is-grouped input-with-button">
+								<div class="control is-expanded select">
+									<select v-model="playlist.privacy">
+										<option value="private">Private</option>
+										<option value="public">Public</option>
+									</select>
+								</div>
+								<p class="control">
+									<a
+										class="button is-info"
+										@click="updatePrivacy()"
+										href="#"
+										>Update Privacy</a
+									>
+								</p>
 							</div>
-							<p class="control">
-								<a
-									class="button is-info"
-									@click="updatePrivacy()"
-									href="#"
-									>Update Privacy</a
-								>
-							</p>
 						</div>
-					</div>
 
-					<div class="section-margin-bottom" />
+						<div class="section-margin-bottom" />
+					</div>
 
 					<div
 						id="import-from-youtube-section"
 						class="section"
-						v-if="playlist.isUserModifiable"
+						v-if="isEditable()"
 					>
 						<h4 class="section-title">Import from YouTube</h4>
 
@@ -203,7 +217,7 @@
 
 				<div id="second-column">
 					<div id="rearrange-songs-section" class="section">
-						<div v-if="playlist.isUserModifiable">
+						<div v-if="isEditable()">
 							<h4 class="section-title">Rearrange Songs</h4>
 
 							<p class="section-description">
@@ -295,8 +309,13 @@
 									</li>
 								</transition-group>
 							</draggable>
+							<p v-else class="nothing-here-text">
+								This playlist doesn't have any songs.
+							</p>
 						</aside>
 					</div>
+
+					<div class="section-margin-bottom" />
 				</div>
 
 				<!--
@@ -318,7 +337,7 @@
 				class="button is-danger"
 				@click="removePlaylist()"
 				href="#"
-				v-if="playlist.isUserModifiable"
+				v-if="isEditable()"
 			>
 				Remove Playlist
 			</a>
@@ -368,6 +387,7 @@ export default {
 		...mapState("user/playlists", {
 			editing: state => state.editing
 		}),
+		...mapState({ userId: state => state.user.auth.userId }),
 		dragOptions() {
 			return {
 				animation: 200,
@@ -382,10 +402,13 @@ export default {
 			this.socket = socket;
 
 			this.socket.emit("playlists.getPlaylist", this.editing, res => {
+				console.log(res);
+
 				if (res.status === "success") {
 					this.playlist = res.data;
 					this.playlist.songs.sort((a, b) => a.position - b.position);
 				}
+
 				this.playlist.oldId = res.data._id;
 			});
 
@@ -434,6 +457,12 @@ export default {
 		});
 	},
 	methods: {
+		isEditable() {
+			return (
+				this.playlist.isUserModifiable &&
+				this.userId === this.playlist.createdBy
+			);
+		},
 		updateSongPositioning({ moved }) {
 			if (!moved) return; // we only need to update when song is moved
 
@@ -694,10 +723,14 @@ export default {
 		max-width: 100% !important;
 	}
 
+	#first-column {
+		width: 100%;
+	}
+
 	#second-column {
 		width: 100%;
 
-		.section-margin-bottom {
+		.section-margin-bottom:first-child {
 			display: block !important;
 		}
 	}
@@ -720,7 +753,8 @@ export default {
 	}
 
 	.section {
-		padding: 5px !important;
+		// padding: 5px !important;
+		padding: 0 !important;
 		margin: 0 20px;
 		max-width: 600px;
 		display: flex;
@@ -738,7 +772,6 @@ export default {
 	}
 
 	#first-column {
-		flex-grow: 1;
 		max-width: 100%;
 
 		.section {
@@ -788,8 +821,9 @@ export default {
 
 	#second-column {
 		max-width: 100%;
+		flex-grow: 1;
 
-		.section-margin-bottom {
+		.section-margin-bottom:first-child {
 			display: none;
 		}
 	}

+ 14 - 10
frontend/src/pages/Profile.vue

@@ -141,7 +141,8 @@
 				<div class="content playlists-tab" v-if="tab === 'playlists'">
 					<div v-if="playlists.length > 0">
 						<h4 class="section-title">
-							{{ isUser ? "My" : null }} Playlists
+							{{ user._id === userId ? "My" : null }}
+							Playlists
 						</h4>
 
 						<p class="section-description">
@@ -186,19 +187,23 @@
 										"
 										:playlist="playlist"
 									>
-										<div
-											v-if="user._id === userId"
-											slot="actions"
-										>
+										<div slot="actions">
 											<i
+												v-if="user._id === userId"
 												@click="
-													editPlaylistClick(
-														playlist._id
-													)
+													showPlaylist(playlist._id)
 												"
 												class="material-icons edit-icon"
 												>edit</i
 											>
+											<i
+												v-else
+												@click="
+													showPlaylist(playlist._id)
+												"
+												class="material-icons view-icon"
+												>visibility</i
+											>
 										</div>
 									</playlist-item>
 								</div>
@@ -442,8 +447,7 @@ export default {
 	methods: {
 		formatDistance,
 		parseISO,
-		editPlaylistClick(playlistId) {
-			console.log(playlistId);
+		showPlaylist(playlistId) {
 			this.editPlaylist(playlistId);
 			this.openModal({ sector: "station", modal: "editPlaylist" });
 		},