Browse Source

Added logic for searching for playlists in manage station modal

Kristian Vos 3 years ago
parent
commit
b7eb16ee3f

+ 82 - 0
backend/logic/actions/playlists.js

@@ -219,6 +219,88 @@ export default {
 		);
 	}),
 
+	/**
+	 * Searches through all playlists that can be included in a community station
+	 *
+	 * @param {object} session - the session object automatically added by the websocket
+	 * @param {string} query - the query
+	 * @param {Function} cb - gets called with the result
+	 */
+	searchCommunity: isLoginRequired(async function searchCommunity(session, query, cb) {
+		async.waterfall(
+			[
+				next => {
+					if (!query || typeof query !== "string") next("Invalid query.");
+					else if (query.length < 3) next("Invalid query.");
+					else next();
+				},
+
+				next => {
+					PlaylistsModule.runJob("SEARCH", {
+						query,
+						includeUser: true,
+						includeGenre: true,
+						includeOwn: true,
+						userId: session.userId
+					})
+						.then(response => {
+							next(null, response.playlists);
+						})
+						.catch(err => {
+							next(err);
+						});
+				}
+			],
+			async (err, playlists) => {
+				if (err) {
+					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
+					this.log("ERROR", "PLAYLISTS_SEARCH_COMMUNITY", `Searching playlists failed. "${err}"`);
+					return cb({ status: "error", message: err });
+				}
+				this.log("SUCCESS", "PLAYLISTS_SEARCH_COMMUNITY", "Searching playlists successful.");
+				return cb({ status: "success", data: { playlists } });
+			}
+		);
+	}),
+
+	/**
+	 * Searches through all playlists that can be included in an official station
+	 *
+	 * @param {object} session - the session object automatically added by the websocket
+	 * @param {string} query - the query
+	 * @param {Function} cb - gets called with the result
+	 */
+	searchOfficial: isAdminRequired(async function searchOfficial(session, query, cb) {
+		async.waterfall(
+			[
+				next => {
+					if (!query || typeof query !== "string") next("Invalid query.");
+					else if (query.length < 3) next("Invalid query.");
+					else next();
+				},
+
+				next => {
+					PlaylistsModule.runJob("SEARCH", { query, includeGenre: true, includePrivate: true })
+						.then(response => {
+							next(null, response.playlists);
+						})
+						.catch(err => {
+							next(err);
+						});
+				}
+			],
+			async (err, playlists) => {
+				if (err) {
+					err = await UtilsModule.runJob("GET_ERROR", { error: err }, this);
+					this.log("ERROR", "PLAYLISTS_SEARCH_OFFICIAL", `Searching playlists failed. "${err}"`);
+					return cb({ status: "error", message: err });
+				}
+				this.log("SUCCESS", "PLAYLISTS_SEARCH_OFFICIAL", "Searching playlists successful.");
+				return cb({ status: "success", data: { playlists } });
+			}
+		);
+	}),
+
 	/**
 	 * Gets the first song from a private playlist
 	 *

+ 64 - 0
backend/logic/playlists.js

@@ -979,6 +979,70 @@ class _PlaylistsModule extends CoreClass {
 		);
 	}
 
+	/**
+	 * Searches through playlists
+	 *
+	 * @param {object} payload - object that contains the payload
+	 * @param {string} payload.query - the query
+	 * @param {string} payload.includePrivate - include private playlists
+	 * @param {string} payload.includeStation - include station playlists
+	 * @param {string} payload.includeUser - include user playlists
+	 * @param {string} payload.includeGenre - include genre playlists
+	 * @param {string} payload.includeOwn - include own user playlists
+	 * @param {string} payload.userId - the user id of the person requesting
+	 * @param {string} payload.includeSongs - include songs
+	 * @returns {Promise} - returns promise (reject, resolve)
+	 */
+	SEARCH(payload) {
+		return new Promise((resolve, reject) =>
+			async.waterfall(
+				[
+					next => {
+						const types = [];
+						if (payload.includeStation) types.push("station");
+						if (payload.includeUser) types.push("user");
+						if (payload.includeGenre) types.push("genre");
+						if (types.length === 0 && !payload.includeOwn) return next("No types have been included.");
+
+						const privacies = ["public"];
+						if (payload.includePrivate) privacies.push("private");
+
+						const includeObject = payload.includeSongs ? null : { songs: false };
+						const filterArray = [
+							{
+								displayName: new RegExp(`${payload.query}`, "i"),
+								privacy: { $in: privacies },
+								type: { $in: types }
+							}
+						];
+
+						if (payload.includeOwn && payload.userId)
+							filterArray.push({
+								displayName: new RegExp(`${payload.query}`, "i"),
+								type: "user",
+								createdBy: payload.userId
+							});
+
+						return next(null, filterArray, includeObject);
+					},
+
+					(filterArray, includeObject, next) => {
+						PlaylistsModule.playlistModel.find({ $or: filterArray }, includeObject, next);
+					},
+
+					(playlists, next) => {
+						if (playlists.length > 0) next(null, playlists);
+						else next("No playlists found");
+					}
+				],
+				(err, playlists) => {
+					if (err && err !== true) return reject(new Error(err));
+					return resolve({ playlists });
+				}
+			)
+		);
+	}
+
 	/**
 	 * Clears and refills a station playlist
 	 *

+ 18 - 1
frontend/src/components/modals/ManageStation/Tabs/Playlists.vue

@@ -80,6 +80,8 @@
 							class="input"
 							type="text"
 							placeholder="Enter your playlist query here..."
+							v-model="playlistQuery"
+							@keyup.enter="searchForPlaylists()"
 						/>
 					</p>
 					<p class="control">
@@ -204,7 +206,8 @@ export default {
 	mixins: [SortablePlaylists],
 	data() {
 		return {
-			tab: "current"
+			tab: "current",
+			playlistQuery: ""
 		};
 	},
 	computed: {
@@ -385,6 +388,20 @@ export default {
 			});
 			return selected;
 		},
+		searchForPlaylists() {
+			const query = this.playlistQuery;
+
+			const action =
+				this.station.type === "official"
+					? "playlists.searchOfficial"
+					: "playlists.searchCommunity";
+
+			this.socket.dispatch(action, query, res => {
+				if (res.status === "success") {
+					console.log(res);
+				} else if (res.status === "error") new Toast(res.message);
+			});
+		},
 		...mapActions("station", ["updatePrivatePlaylistQueueSelected"]),
 		...mapActions("modalVisibility", ["openModal"]),
 		...mapActions("user/playlists", ["editPlaylist", "setPlaylists"])