diff --git a/web/src/plugins/soundboard/SoundboardTab.tsx b/web/src/plugins/soundboard/SoundboardTab.tsx index 3a961d2..ec94668 100644 --- a/web/src/plugins/soundboard/SoundboardTab.tsx +++ b/web/src/plugins/soundboard/SoundboardTab.tsx @@ -414,29 +414,34 @@ export default function SoundboardTab({ data }: SoundboardTabProps) { }, []); const soundKey = useCallback((s: Sound) => s.relativePath ?? s.fileName, []); const YTDLP_HOSTS = ['youtube.com', 'www.youtube.com', 'm.youtube.com', 'youtu.be', 'music.youtube.com', 'instagram.com', 'www.instagram.com']; + /** Auto-prepend https:// if missing */ + const normalizeUrl = useCallback((value: string): string => { + const v = value.trim(); + if (!v) return v; + if (/^https?:\/\//i.test(v)) return v; + return 'https://' + v; + }, []); const isSupportedUrl = useCallback((value: string) => { try { - const parsed = new URL(value.trim()); + const parsed = new URL(normalizeUrl(value)); const host = parsed.hostname.toLowerCase(); - // Direct MP3 link if (parsed.pathname.toLowerCase().endsWith('.mp3')) return true; - // YouTube / Instagram if (YTDLP_HOSTS.some(h => host === h || host.endsWith('.' + h))) return true; return false; } catch { return false; } - }, []); + }, [normalizeUrl]); const getUrlType = useCallback((value: string): 'youtube' | 'instagram' | 'mp3' | null => { try { - const parsed = new URL(value.trim()); + const parsed = new URL(normalizeUrl(value)); const host = parsed.hostname.toLowerCase(); if (host.includes('youtube') || host === 'youtu.be') return 'youtube'; if (host.includes('instagram')) return 'instagram'; if (parsed.pathname.toLowerCase().endsWith('.mp3')) return 'mp3'; return null; } catch { return null; } - }, []); + }, [normalizeUrl]); const guildId = selected ? selected.split(':')[0] : ''; const channelId = selected ? selected.split(':')[1] : ''; @@ -632,7 +637,7 @@ export default function SoundboardTab({ data }: SoundboardTabProps) { } async function handleUrlImport() { - const trimmed = importUrl.trim(); + const trimmed = normalizeUrl(importUrl); if (!trimmed) return notify('Bitte einen Link eingeben', 'error'); if (!isSupportedUrl(trimmed)) return notify('Nur YouTube, Instagram oder direkte MP3-Links', 'error'); setImportBusy(true); @@ -1017,7 +1022,7 @@ export default function SoundboardTab({ data }: SoundboardTabProps) { setImportUrl(e.target.value)}