diff --git a/web/src/app/_components/downloadButton.tsx b/web/src/app/_components/downloadButton.tsx deleted file mode 100644 index f144aaf..0000000 --- a/web/src/app/_components/downloadButton.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { useState } from 'react'; -import { Button } from '@mui/material'; -import Download from '@mui/icons-material/Download'; - -interface DownloadButtonProps { - assetId: number; - assetName: string; -} - -const DownloadButton: React.FC = ({ assetId, assetName }) => { - const [downloading, setDownloading] = useState(false); - - const handleDownload = async () => { - setDownloading(true); - try { - // Fetch the download URL - const res = await fetch(`/api/maps/${assetId}/location`); - if (!res.ok) throw new Error('Failed to fetch download location'); - - const location = await res.text(); - - // Method 1: Try direct download with proper cleanup - try { - const link = document.createElement('a'); - link.href = location.trim(); // Remove any whitespace - link.download = `${assetName}.rbxm`; - link.target = '_blank'; // Open in new tab as fallback - link.rel = 'noopener noreferrer'; // Security best practice - - // Ensure the link is properly attached before clicking - document.body.appendChild(link); - link.click(); - - // Clean up after a short delay to ensure download starts - setTimeout(() => { - document.body.removeChild(link); - }, 100); - - } catch (domError) { - console.warn('Direct download failed, trying fallback:', domError); - // Method 2: Fallback - open in new window - window.open(location.trim(), '_blank'); - } - - } catch (err) { - console.error('Download error:', err); - // Optional: Show user-friendly error message - alert('Download failed. Please try again.'); - } finally { - setDownloading(false); - } - }; - - return ( - - ); -}; - -export default DownloadButton; diff --git a/web/src/app/maps/[mapId]/page.tsx b/web/src/app/maps/[mapId]/page.tsx index cd8da52..c1d9b75 100644 --- a/web/src/app/maps/[mapId]/page.tsx +++ b/web/src/app/maps/[mapId]/page.tsx @@ -30,7 +30,8 @@ import PersonIcon from "@mui/icons-material/Person"; import FlagIcon from "@mui/icons-material/Flag"; import BugReportIcon from "@mui/icons-material/BugReport"; import ContentCopyIcon from "@mui/icons-material/ContentCopy"; -import DownloadButton from "@/app/_components/downloadButton"; +import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile"; +import DownloadIcon from '@mui/icons-material/Download'; import { hasRole, RolesConstants } from "@/app/ts/Roles"; export default function MapDetails() { @@ -41,6 +42,7 @@ export default function MapDetails() { const [error, setError] = useState(null); const [copySuccess, setCopySuccess] = useState(false); const [roles, setRoles] = useState(RolesConstants.Empty); + const [downloading, setDownloading] = useState(false); useEffect(() => { async function getMap() { @@ -124,6 +126,48 @@ export default function MapDetails() { setCopySuccess(true); }; + + const handleDownload = async () => { + setDownloading(true); + try { + // Fetch the download URL + const res = await fetch(`/api/maps/${mapId}/location`); + if (!res.ok) throw new Error('Failed to fetch download location'); + + const location = await res.text(); + + // Method 1: Try direct download with proper cleanup + try { + const link = document.createElement('a'); + link.href = location.trim(); // Remove any whitespace + link.download = `${map?.DisplayName}.rbxm`; + link.target = '_blank'; // Open in new tab as fallback + link.rel = 'noopener noreferrer'; // Security best practice + + // Ensure the link is properly attached before clicking + document.body.appendChild(link); + link.click(); + + // Clean up after a short delay to ensure download starts + setTimeout(() => { + document.body.removeChild(link); + }, 100); + + } catch (domError) { + console.warn('Direct download failed, trying fallback:', domError); + // Method 2: Fallback - open in new window + window.open(location.trim(), '_blank'); + } + + } catch (err) { + console.error('Download error:', err); + // Optional: Show user-friendly error message + alert('Download failed. Please try again.'); + } finally { + setDownloading(false); + } + }; + const handleCloseSnackbar = () => { setCopySuccess(false); }; @@ -255,6 +299,24 @@ export default function MapDetails() { + {!loading && hasRole(roles,RolesConstants.MapDownload) && ( + + + + Download + + + + + + + + )} @@ -337,9 +399,6 @@ export default function MapDetails() { > Submit a Mapfix - {hasRole(roles,RolesConstants.MapDownload) && ( - - )}