Browse Source

fix: certain YouTube video URLs could no longer be added to queues/playlists

Kristian Vos 2 months ago
parent
commit
858242bf1d

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

@@ -99,7 +99,7 @@ const replaceSongUrlMap = reactive({});
 const showReplacementInputs = ref(false);
 
 const youtubeVideoUrlRegex =
-	/^(https?:\/\/)?(www\.)?(m\.)?(music\.)?(youtube\.com|youtu\.be)\/(watch\?v=)?(?<youtubeId>[\w-]{11})((&([A-Za-z0-9]+)?)*)?$/;
+	/^(?:https?:\/\/)?(?:www\.)?(m\.)?(?:music\.)?(?:youtube\.com|youtu\.be)\/(?:watch\/?\?v=)?(?:.*&v=)?(?<youtubeId>[\w-]{11}).*$/;
 const youtubeVideoIdRegex = /^([\w-]{11})$/;
 
 const youtubePlaylistUrlRegex = /[\\?&]list=([^&#]*)/;

+ 30 - 9
frontend/src/composables/useYoutubeDirect.ts

@@ -3,7 +3,9 @@ import Toast from "toasters";
 import { AddSongToPlaylistResponse } from "@musare_types/actions/PlaylistsActions";
 import { useWebsocketsStore } from "@/stores/websockets";
 
-const youtubeVideoIdRegex = /^([\w-]{11})$/;
+const youtubeVideoUrlRegex =
+	/^(?:https?:\/\/)?(?:www\.)?(m\.)?(?:music\.)?(?:youtube\.com|youtu\.be)\/(?:watch\/?\?v=)?(?:.*&v=)?(?<youtubeId>[\w-]{11}).*$/;
+const youtubeVideoIdRegex = /^(?<youtubeId>[\w-]{11})$/;
 
 export const useYoutubeDirect = () => {
 	const youtubeDirect = ref("");
@@ -11,16 +13,35 @@ export const useYoutubeDirect = () => {
 	const { socket } = useWebsocketsStore();
 
 	const getYoutubeVideoId = () => {
+		const inputValue = youtubeDirect.value.trim();
+
+		// Check if the user simply used a YouTube ID in the input directly
+		const youtubeVideoIdMatch = youtubeVideoIdRegex.exec(inputValue);
+		if (youtubeVideoIdMatch && youtubeVideoIdMatch.groups.youtubeId) {
+			// eslint-disable-next-line prefer-destructuring
+			return youtubeVideoIdMatch.groups.youtubeId;
+		}
+
+		// Check if we can get the video ID from passing in the input value into the URL regex
+		const youtubeVideoUrlMatch = youtubeVideoUrlRegex.exec(inputValue);
+		if (youtubeVideoUrlMatch && youtubeVideoUrlMatch.groups.youtubeId) {
+			// eslint-disable-next-line prefer-destructuring
+			return youtubeVideoUrlMatch.groups.youtubeId;
+		}
+
+		// Check if the user provided a URL of some kind that has the query parameter v, which also passes the YouTube video ID regex
 		try {
-			const { searchParams } = new URL(youtubeDirect.value.trim());
-			if (searchParams.has("v")) return searchParams.get("v");
-		} catch (error) {
-			const youtubeVideoIdParts = youtubeVideoIdRegex.exec(
-				youtubeDirect.value.trim()
-			);
-			if (youtubeVideoIdParts) {
-				return youtubeVideoIdParts[1];
+			const { searchParams } = new URL(inputValue);
+			if (searchParams.has("v")) {
+				const vValue = searchParams.get("v");
+				const vValueMatch = youtubeVideoIdRegex.exec(vValue);
+				if (vValueMatch && vValueMatch.groups.youtubeId) {
+					// eslint-disable-next-line prefer-destructuring
+					return youtubeVideoIdMatch.groups.youtubeId;
+				}
 			}
+		} catch (error) {
+			return null;
 		}
 
 		return null;