Pārlūkot izejas kodu

refactor: Remove request song modal and create import youtube playlist modal

Owen Diffey 3 gadi atpakaļ
vecāks
revīzija
48f2d420ab

+ 0 - 10
frontend/src/components/Queue.vue

@@ -88,16 +88,6 @@
 			<i class="material-icons icon-with-button">queue</i>
 			<span> Add Song To Queue </span>
 		</button>
-		<button
-			class="button is-primary tab-actionable-button"
-			v-if="
-				sector === 'station' && loggedIn && station.type === 'official'
-			"
-			@click="openModal('requestSong')"
-		>
-			<i class="material-icons icon-with-button">queue</i>
-			<span> Request Song </span>
-		</button>
 		<button
 			class="button is-primary tab-actionable-button disabled"
 			v-if="

+ 110 - 0
frontend/src/components/modals/ImportPlaylist.vue

@@ -0,0 +1,110 @@
+<template>
+	<modal title="Import Playlist">
+		<template #body>
+			<div class="vertical-padding">
+				<p class="section-description">
+					Import a playlist by using a link from YouTube
+				</p>
+
+				<div class="control is-grouped">
+					<p class="control is-expanded">
+						<input
+							class="input"
+							type="text"
+							placeholder="YouTube Playlist URL"
+							v-model="youtubeSearch.playlist.query"
+							@keyup.enter="importPlaylist()"
+						/>
+					</p>
+					<p id="playlist-import-type" class="control select">
+						<select
+							v-model="
+								youtubeSearch.playlist.isImportingOnlyMusic
+							"
+						>
+							<option :value="false">Import all</option>
+							<option :value="true">Import only music</option>
+						</select>
+					</p>
+					<p class="control">
+						<button
+							class="button is-info"
+							@click.prevent="importPlaylist()"
+						>
+							<i class="material-icons icon-with-button"
+								>publish</i
+							>Import
+						</button>
+					</p>
+				</div>
+			</div>
+		</template>
+	</modal>
+</template>
+
+<script>
+import { mapState, mapGetters } from "vuex";
+
+import Toast from "toasters";
+
+import SearchYoutube from "@/mixins/SearchYoutube.vue";
+
+import Modal from "../Modal.vue";
+
+export default {
+	components: { Modal },
+	mixins: [SearchYoutube],
+	computed: {
+		...mapState({
+			loggedIn: state => state.user.auth.loggedIn,
+			station: state => state.station.station
+		}),
+		...mapGetters({
+			socket: "websockets/getSocket"
+		})
+	},
+	methods: {
+		importPlaylist() {
+			let isImportingPlaylist = true;
+
+			// import query is blank
+			if (!this.youtubeSearch.playlist.query)
+				return new Toast("Please enter a YouTube playlist URL.");
+
+			const regex = /[\\?&]list=([^&#]*)/;
+			const splitQuery = regex.exec(this.youtubeSearch.playlist.query);
+
+			if (!splitQuery) {
+				return new Toast({
+					content: "Please enter a valid YouTube playlist URL.",
+					timeout: 4000
+				});
+			}
+
+			// don't give starting import message instantly in case of instant error
+			setTimeout(() => {
+				if (isImportingPlaylist) {
+					new Toast(
+						"Starting to import your playlist. This can take some time to do."
+					);
+				}
+			}, 750);
+
+			return this.socket.dispatch(
+				"songs.requestSet",
+				this.youtubeSearch.playlist.query,
+				this.youtubeSearch.playlist.isImportingOnlyMusic,
+				true,
+				res => {
+					isImportingPlaylist = false;
+
+					return new Toast({
+						content: res.message,
+						timeout: 20000
+					});
+				}
+			);
+		}
+	}
+};
+</script>

+ 0 - 8
frontend/src/components/modals/ManageStation/index.vue

@@ -162,14 +162,6 @@
 			</div>
 		</template>
 		<template #footer>
-			<button
-				class="button is-primary tab-actionable-button"
-				v-if="loggedIn && station.type === 'official'"
-				@click="openModal('requestSong')"
-			>
-				<i class="material-icons icon-with-button">queue</i>
-				<span> Request Song </span>
-			</button>
 			<div v-if="isOwnerOrAdmin()" class="right">
 				<quick-confirm @confirm="clearAndRefillStationQueue()">
 					<a class="button is-danger">

+ 0 - 286
frontend/src/components/modals/RequestSong.vue

@@ -1,286 +0,0 @@
-<template>
-	<modal title="Request Song">
-		<template #body>
-			<div class="vertical-padding">
-				<!-- Choosing a song from youtube -->
-
-				<h4 class="section-title">Choose a song</h4>
-				<p class="section-description">
-					Choose a song by searching or using a link from YouTube
-				</p>
-
-				<br />
-
-				<div class="control is-grouped input-with-button">
-					<p class="control is-expanded">
-						<input
-							class="input"
-							type="text"
-							placeholder="Enter your YouTube query here..."
-							v-model="youtubeSearch.songs.query"
-							autofocus
-							@keyup.enter="searchForSongs()"
-						/>
-					</p>
-					<p class="control">
-						<button
-							class="button is-info"
-							@click.prevent="searchForSongs()"
-						>
-							<i class="material-icons icon-with-button">search</i
-							>Search
-						</button>
-					</p>
-				</div>
-
-				<!-- Choosing a song from youtube - query results -->
-
-				<div
-					id="song-query-results"
-					v-if="youtubeSearch.songs.results.length > 0"
-				>
-					<search-query-item
-						v-for="(result, index) in youtubeSearch.songs.results"
-						:key="result.id"
-						:result="result"
-					>
-						<template #actions>
-							<transition
-								name="search-query-actions"
-								mode="out-in"
-							>
-								<i
-									v-if="result.isRequested"
-									key="added-to-playlist"
-									class="material-icons icon-requested"
-									content="Requested song"
-									v-tippy
-									>done</i
-								>
-								<i
-									v-else
-									@click.prevent="
-										addSongToQueue(result.id, index)
-									"
-									key="add-to-queue"
-									class="material-icons icon-request"
-									content="Request song"
-									v-tippy
-									>add</i
-								>
-							</transition>
-						</template>
-					</search-query-item>
-
-					<button
-						class="button is-default load-more-button"
-						@click.prevent="loadMoreSongs()"
-					>
-						Load more...
-					</button>
-				</div>
-
-				<!-- Import a playlist from youtube -->
-
-				<div v-if="station.type !== 'community'">
-					<hr class="section-horizontal-rule" />
-
-					<h4 class="section-title">Import a playlist</h4>
-					<p class="section-description">
-						Import a playlist by using a link from YouTube
-					</p>
-
-					<br />
-
-					<div class="control is-grouped">
-						<p class="control is-expanded">
-							<input
-								class="input"
-								type="text"
-								placeholder="YouTube Playlist URL"
-								v-model="youtubeSearch.playlist.query"
-								@keyup.enter="importPlaylist()"
-							/>
-						</p>
-						<p id="playlist-import-type" class="control select">
-							<select
-								v-model="
-									youtubeSearch.playlist.isImportingOnlyMusic
-								"
-							>
-								<option :value="false">Import all</option>
-								<option :value="true">Import only music</option>
-							</select>
-						</p>
-						<p class="control">
-							<button
-								class="button is-info"
-								@click.prevent="importPlaylist()"
-							>
-								<i class="material-icons icon-with-button"
-									>publish</i
-								>Import
-							</button>
-						</p>
-					</div>
-				</div>
-			</div>
-		</template>
-	</modal>
-</template>
-
-<script>
-import { mapState, mapGetters } from "vuex";
-
-import Toast from "toasters";
-
-import SearchYoutube from "@/mixins/SearchYoutube.vue";
-
-import SearchQueryItem from "../SearchQueryItem.vue";
-import Modal from "../Modal.vue";
-
-export default {
-	components: { Modal, SearchQueryItem },
-	mixins: [SearchYoutube],
-	computed: {
-		...mapState({
-			loggedIn: state => state.user.auth.loggedIn,
-			station: state => state.station.station
-		}),
-		...mapGetters({
-			socket: "websockets/getSocket"
-		})
-	},
-	methods: {
-		addSongToQueue(youtubeId, index) {
-			if (this.station.type === "community") {
-				this.socket.dispatch(
-					"stations.addToQueue",
-					this.station._id,
-					youtubeId,
-					res => {
-						if (res.status !== "success")
-							new Toast(`Error: ${res.message}`);
-						else {
-							this.youtubeSearch.songs.results[
-								index
-							].isRequested = true;
-
-							new Toast(res.message);
-						}
-					}
-				);
-			} else {
-				this.socket.dispatch("songs.request", youtubeId, false, res => {
-					if (res.status !== "success")
-						new Toast(`Error: ${res.message}`);
-					else {
-						this.youtubeSearch.songs.results[
-							index
-						].isRequested = true;
-
-						new Toast(res.message);
-					}
-				});
-			}
-		},
-		importPlaylist() {
-			let isImportingPlaylist = true;
-
-			// import query is blank
-			if (!this.youtubeSearch.playlist.query)
-				return new Toast("Please enter a YouTube playlist URL.");
-
-			const regex = /[\\?&]list=([^&#]*)/;
-			const splitQuery = regex.exec(this.youtubeSearch.playlist.query);
-
-			if (!splitQuery) {
-				return new Toast({
-					content: "Please enter a valid YouTube playlist URL.",
-					timeout: 4000
-				});
-			}
-
-			// don't give starting import message instantly in case of instant error
-			setTimeout(() => {
-				if (isImportingPlaylist) {
-					new Toast(
-						"Starting to import your playlist. This can take some time to do."
-					);
-				}
-			}, 750);
-
-			return this.socket.dispatch(
-				"songs.requestSet",
-				this.youtubeSearch.playlist.query,
-				this.youtubeSearch.playlist.isImportingOnlyMusic,
-				false,
-				res => {
-					isImportingPlaylist = false;
-					return new Toast({ content: res.message, timeout: 20000 });
-				}
-			);
-		}
-	}
-};
-</script>
-
-<style lang="less" scoped>
-.night-mode {
-	div {
-		color: var(--dark-grey);
-	}
-
-	.icon-request {
-		color: var(--white);
-	}
-}
-
-.song-actions {
-	.button {
-		height: 36px;
-		width: 140px;
-	}
-}
-
-.song-thumbnail div {
-	width: 96px;
-	height: 54px;
-	background-position: center;
-	background-repeat: no-repeat;
-}
-
-.table {
-	margin-bottom: 0;
-	margin-top: 20px;
-}
-
-.vertical-padding {
-	padding: 20px;
-}
-
-.icon-requested {
-	color: var(--green);
-}
-
-.icon-request {
-	color: var(--dark-gray-3);
-}
-
-#song-query-results {
-	padding: 10px;
-	max-height: 500px;
-	overflow: auto;
-	border: 1px solid var(--light-grey-3);
-	border-radius: @border-radius;
-
-	.search-query-item:not(:last-of-type) {
-		margin-bottom: 10px;
-	}
-
-	.load-more-button {
-		width: 100%;
-		margin-top: 10px;
-	}
-}
-</style>

+ 5 - 5
frontend/src/pages/Admin/Songs/index.vue

@@ -8,9 +8,9 @@
 				</button>
 				<button
 					class="button is-primary"
-					@click="openModal('requestSong')"
+					@click="openModal('importPlaylist')"
 				>
-					Request song
+					Import playlist
 				</button>
 				<button
 					class="button is-primary"
@@ -260,7 +260,7 @@
 		<edit-song v-if="modals.editSong" song-type="songs" />
 		<edit-songs v-if="modals.editSongs" />
 		<report v-if="modals.report" />
-		<request-song v-if="modals.requestSong" />
+		<import-playlist v-if="modals.importPlaylist" />
 		<bulk-actions v-if="modals.bulkActions" :type="bulkActionsType" />
 		<confirm v-if="modals.confirm" @confirmed="handleConfirmed()" />
 	</div>
@@ -291,8 +291,8 @@ export default {
 		ImportAlbum: defineAsyncComponent(() =>
 			import("@/components/modals/ImportAlbum.vue")
 		),
-		RequestSong: defineAsyncComponent(() =>
-			import("@/components/modals/RequestSong.vue")
+		ImportPlaylist: defineAsyncComponent(() =>
+			import("@/components/modals/ImportPlaylist.vue")
 		),
 		BulkActions: defineAsyncComponent(() =>
 			import("@/components/modals/BulkActions.vue")

+ 0 - 4
frontend/src/pages/Admin/Stations.vue

@@ -107,7 +107,6 @@
 			</advanced-table>
 		</div>
 
-		<request-song v-if="modals.requestSong" />
 		<create-playlist v-if="modals.createPlaylist" />
 		<manage-station
 			v-if="modals.manageStation"
@@ -134,9 +133,6 @@ import RunJobDropdown from "@/components/RunJobDropdown.vue";
 
 export default {
 	components: {
-		RequestSong: defineAsyncComponent(() =>
-			import("@/components/modals/RequestSong.vue")
-		),
 		EditPlaylist: defineAsyncComponent(() =>
 			import("@/components/modals/EditPlaylist")
 		),

+ 0 - 4
frontend/src/pages/Home.vue

@@ -489,7 +489,6 @@
 			:station-id="editingStationId"
 			sector="home"
 		/>
-		<request-song v-if="modals.requestSong" />
 		<create-playlist v-if="modals.createPlaylist" />
 		<edit-playlist v-if="modals.editPlaylist" />
 		<edit-song v-if="modals.editSong" song-type="songs" sector="home" />
@@ -521,9 +520,6 @@ export default {
 		ManageStation: defineAsyncComponent(() =>
 			import("@/components/modals/ManageStation/index.vue")
 		),
-		RequestSong: defineAsyncComponent(() =>
-			import("@/components/modals/RequestSong.vue")
-		),
 		EditPlaylist: defineAsyncComponent(() =>
 			import("@/components/modals/EditPlaylist")
 		),

+ 0 - 4
frontend/src/pages/Station/index.vue

@@ -650,7 +650,6 @@
 					</div>
 				</div>
 
-				<request-song v-if="modals.requestSong" />
 				<create-playlist v-if="modals.createPlaylist" />
 				<manage-station
 					v-if="modals.manageStation"
@@ -809,9 +808,6 @@ export default {
 		ContentLoader,
 		MainHeader,
 		MainFooter,
-		RequestSong: defineAsyncComponent(() =>
-			import("@/components/modals/RequestSong.vue")
-		),
 		EditPlaylist: defineAsyncComponent(() =>
 			import("@/components/modals/EditPlaylist")
 		),

+ 1 - 1
frontend/src/store/modules/modalVisibility.js

@@ -8,7 +8,7 @@ const state = {
 		login: false,
 		register: false,
 		createStation: false,
-		requestSong: false,
+		importPlaylist: false,
 		editPlaylist: false,
 		createPlaylist: false,
 		report: false,