diff --git a/index.html b/index.html index 5549a4e..d9e9b5e 100644 --- a/index.html +++ b/index.html @@ -93,33 +93,26 @@
-
Get Launcher
- +
GitHub Repo
- +
Join Discord
- -
- Join Fluxer -
- -
-
@@ -358,4 +348,4 @@ - + \ No newline at end of file diff --git a/public/Launcher/home.png b/public/Launcher/home.png index 29abf4f..437bafe 100644 Binary files a/public/Launcher/home.png and b/public/Launcher/home.png differ diff --git a/public/Launcher/settings.png b/public/Launcher/settings.png index 02a5a5c..0600b1b 100644 Binary files a/public/Launcher/settings.png and b/public/Launcher/settings.png differ diff --git a/public/Launcher/versions.png b/public/Launcher/versions.png index 2c714b5..69cc12c 100644 Binary files a/public/Launcher/versions.png and b/public/Launcher/versions.png differ diff --git a/src/main.ts b/src/main.ts index 21c2499..31f2e5e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -134,7 +134,7 @@ document.addEventListener('DOMContentLoaded', () => { document.querySelector('.carousel-arrow.left')?.addEventListener('click', () => rotateScreenshot(-1, true)); document.querySelector('.carousel-arrow.right')?.addEventListener('click', () => rotateScreenshot(1, true)); - const repo = 'Emerald-Legacy-Launcher/Emerald-Legacy-Launcher'; + const repo = 'LCE-Hub/LCE-Emerald-Launcher'; const modal = document.getElementById('download-modal'); const modalOptions = document.getElementById('modal-options'); const modalTitle = document.getElementById('modal-title'); @@ -143,6 +143,7 @@ document.addEventListener('DOMContentLoaded', () => { let latestAssets: any[] = []; let nightlyAssets: any[] = []; let currentOSType = 'Windows'; + let fetchStatus: 'loading' | 'success' | 'error' = 'loading'; const detectOS = () => { const ua = window.navigator.userAgent.toLowerCase(); @@ -185,6 +186,36 @@ document.addEventListener('DOMContentLoaded', () => { return null; }; + const getReadableAssetName = (name: string, osType: string) => { + const lowerName = name.toLowerCase(); + if (osType === 'Windows') { + if (lowerName.endsWith('.exe')) return 'Windows Setup (.exe)'; + if (lowerName.endsWith('.msi')) return 'Windows Installer (.msi)'; + } + if (osType === 'macOS') { + if (lowerName.includes('aarch64') || lowerName.includes('arm64')) { + return 'macOS Apple Silicon'; + } + return 'macOS Intel'; + } + if (osType === 'Linux') { + if (lowerName.endsWith('.flatpak')) return 'Flatpak'; + if (lowerName.endsWith('.deb')) return 'Debian/Ubuntu (.deb)'; + if (lowerName.endsWith('.rpm')) return 'RedHat/Fedora (.rpm)'; + if (lowerName.endsWith('.appimage')) return 'AppImage'; + } + return name; + }; + + const formatBytes = (bytes: number) => { + if (!bytes || bytes === 0) return 'Size Unknown'; + const k = 1024; + const dm = 1; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + }; + const openDownloadModal = (osType: string) => { if (!modal || !modalOptions || !modalTitle) return; currentOSType = osType; @@ -203,7 +234,7 @@ document.addEventListener('DOMContentLoaded', () => { filteredAssets = assets.filter(a => a.name.endsWith('.dmg')); title = `Emerald Legacy for macOS ${isNightly ? '(Nightly)' : ''}`; } else if (osType === 'Linux') { - filteredAssets = assets.filter(a => a.name.endsWith('.flatpak') || a.name.endsWith('.deb') || a.name.endsWith('.rpm')); + filteredAssets = assets.filter(a => a.name.endsWith('.flatpak') || a.name.endsWith('.deb') || a.name.endsWith('.rpm') || a.name.endsWith('.AppImage')); title = `Emerald Legacy for Linux ${isNightly ? '(Nightly)' : ''}`; } @@ -211,17 +242,46 @@ document.addEventListener('DOMContentLoaded', () => { const recommended = getRecommendedAsset(osType, arch, filteredAssets); modalTitle.innerText = title; - modalOptions.innerHTML = filteredAssets.length > 0 ? filteredAssets.map(asset => { - const isRecommended = asset.name === recommended?.name; - return ` - - `; - }).join('') : `
No builds found for this platform.
`; + + if (filteredAssets.length > 0) { + modalOptions.innerHTML = filteredAssets.map(asset => { + const isRecommended = asset.name === recommended?.name; + const readableName = getReadableAssetName(asset.name, osType); + const readableSize = formatBytes(asset.size); + return ` + + `; + }).join(''); + } else { + if (fetchStatus === 'loading') { + modalOptions.innerHTML = `
Loading download links...
`; + } else if (fetchStatus === 'error') { + modalOptions.innerHTML = ` +
+

Failed to retrieve download links automatically.

+ + VIEW RELEASES ON GITHUB + +
+ `; + } else { + if (isNightly) { + modalOptions.innerHTML = ` +
+

No nightly builds are currently available.

+

Please toggle Nightly off to download stable versions.

+
+ `; + } else { + modalOptions.innerHTML = `
No builds found for this platform.
`; + } + } + } modal.classList.add('active'); }; @@ -235,45 +295,52 @@ document.addEventListener('DOMContentLoaded', () => { (window as any).playAudioSFX = (file: string) => audio.playSFX(file); const updateDownloadButtons = async () => { + fetchStatus = 'loading'; try { - const [latestRes, nightlyRes] = await Promise.all([ + const [latestRes, nightlyRes] = await Promise.allSettled([ fetch(`https://api.github.com/repos/${repo}/releases/latest`), fetch(`https://api.github.com/repos/${repo}/releases/tags/nightly`) ]); - const [latestData, nightlyData] = await Promise.all([ - latestRes.json(), - nightlyRes.json() - ]); - - latestAssets = latestData.assets || []; - nightlyAssets = nightlyData.assets || []; - - const { os } = detectOS(); - - const mainBtn = document.getElementById('main-download-btn'); - if (mainBtn) { - mainBtn.addEventListener('click', (e) => { - e.preventDefault(); - openDownloadModal(os === 'Unknown' ? 'Windows' : os); - }); - const span = mainBtn.querySelector('span'); - if (span) span.innerText = `Download for ${os === 'Unknown' ? 'Your OS' : os}`; + if (latestRes.status === 'fulfilled' && latestRes.value.ok) { + const latestData = await latestRes.value.json(); + latestAssets = latestData.assets || []; + fetchStatus = 'success'; + } else { + fetchStatus = 'error'; } - const winBtn = document.getElementById('download-win'); - const linuxBtn = document.getElementById('download-linux'); - const macBtn = document.getElementById('download-macos'); - - winBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('Windows'); }); - linuxBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('Linux'); }); - macBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('macOS'); }); - + if (nightlyRes.status === 'fulfilled' && nightlyRes.value.ok) { + const nightlyData = await nightlyRes.value.json(); + nightlyAssets = nightlyData.assets || []; + } else { + nightlyAssets = []; + } } catch (error) { console.error('Error fetching releases:', error); + fetchStatus = 'error'; } }; + const winBtn = document.getElementById('download-win'); + const linuxBtn = document.getElementById('download-linux'); + const macBtn = document.getElementById('download-macos'); + + winBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('Windows'); }); + linuxBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('Linux'); }); + macBtn?.addEventListener('click', (e) => { e.preventDefault(); openDownloadModal('macOS'); }); + + const { os } = detectOS(); + const mainBtn = document.getElementById('main-download-btn'); + if (mainBtn) { + mainBtn.addEventListener('click', (e) => { + e.preventDefault(); + openDownloadModal(os === 'Unknown' ? 'Windows' : os); + }); + const span = mainBtn.querySelector('span'); + if (span) span.innerText = `Download for ${os === 'Unknown' ? 'Your OS' : os}`; + } + closeModal?.addEventListener('click', () => { audio.playSFX('back.ogg'); modal?.classList.remove('active');