Better download button + community screenshots

This commit is contained in:
Santiago Fisela
2026-03-14 17:54:11 -03:00
parent 002f248f23
commit 84e81b1602
10 changed files with 269 additions and 8 deletions

View File

@@ -90,7 +90,7 @@
<div class="action-buttons">
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
class="main-btn get-launcher">
class="main-btn get-launcher" id="main-download-btn">
<span>Get Launcher</span>
<img src="/logo.png" class="btn-icon">
</a>
@@ -107,7 +107,7 @@
<div class="carousel-header">Community Screenshots</div>
<div class="carousel-view">
<button class="carousel-arrow left">&lt;</button>
<img src="/TU7_Panorama_Background_S.png" class="carousel-img">
<img src="/Community/image.png" class="carousel-img">
<button class="carousel-arrow right">&gt;</button>
</div>
<div class="carousel-footer">See more in Discord</div>
@@ -148,9 +148,18 @@
<section class="tab-content" id="media">
<div class="home-layout">
<div class="features-row" style="flex-wrap: wrap; gap: 10px;">
<img src="/TU7_Panorama_Background_S.png" style="width: 30%; border: 2px solid #fff;">
<img src="/TU7_Panorama_Background_S.png" style="width: 30%; border: 2px solid #fff;">
<img src="/TU7_Panorama_Background_S.png" style="width: 30%; border: 2px solid #fff;">
<img src="/Community/image.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
<img src="/Community/image2.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
<img src="/Community/image3.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
<img src="/Community/image4.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
<img src="/Community/image5.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
<img src="/Community/image6.png"
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
</div>
<div class="cta-section">
<h2>Community Gallery</h2>
@@ -166,13 +175,17 @@
</div>
<div class="action-buttons" style="margin-top: 20px;">
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
class="main-btn">
class="main-btn" id="download-win">
<span>Download for Windows</span>
</a>
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
class="main-btn">
class="main-btn" id="download-linux">
<span>Download for Linux</span>
</a>
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
class="main-btn" id="download-macos">
<span>Download for macOS</span>
</a>
</div>
</div>
</section>
@@ -191,6 +204,22 @@
</div>
</div>
</div>
<div id="download-modal" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<h2 id="modal-title">Select Downloader</h2>
<button id="close-modal" class="close-btn">X</button>
</div>
<div id="modal-options" class="modal-options-grid">
<!-- Dynamic download buttons will be inserted here -->
</div>
<div class="modal-footer">
<p>Choose the format that works best for your system.</p>
</div>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>

BIN
public/Community/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 KiB

BIN
public/Community/image2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
public/Community/image3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

BIN
public/Community/image4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
public/Community/image5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 KiB

BIN
public/Community/image6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
public/controller.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

View File

@@ -34,7 +34,14 @@ document.addEventListener('DOMContentLoaded', () => {
document.getElementById('next-tab')?.addEventListener('click', () => updateTabs(activeIndex + 1));
const carouselImg = document.querySelector('.carousel-img') as HTMLImageElement;
const screenshots = ['/TU7_Panorama_Background_S.png', '/logo.png'];
const screenshots = [
'/Community/image.png',
'/Community/image2.png',
'/Community/image3.png',
'/Community/image4.png',
'/Community/image5.png',
'/Community/image6.png'
];
let screenIndex = 0;
const rotateScreenshot = (dir: number) => {
@@ -51,5 +58,109 @@ document.addEventListener('DOMContentLoaded', () => {
document.querySelector('.carousel-arrow.left')?.addEventListener('click', () => rotateScreenshot(-1));
document.querySelector('.carousel-arrow.right')?.addEventListener('click', () => rotateScreenshot(1));
// --- Download Logic ---
const repo = 'Emerald-Legacy-Launcher/Emerald-Legacy-Launcher';
const modal = document.getElementById('download-modal');
const modalOptions = document.getElementById('modal-options');
const modalTitle = document.getElementById('modal-title');
const closeModal = document.getElementById('close-modal');
let latestAssets: any[] = [];
const detectOS = () => {
const ua = window.navigator.userAgent;
let os = 'Unknown';
let arch = 'x64';
if (ua.indexOf('Win') !== -1) os = 'Windows';
if (ua.indexOf('Mac') !== -1) os = 'macOS';
if (ua.indexOf('Linux') !== -1) os = 'Linux';
if (ua.indexOf('arm64') !== -1 || ua.indexOf('aarch64') !== -1) {
arch = 'arm64';
}
return { os, arch };
};
const getRecommendedAsset = (os: string, arch: string, assets: any[]) => {
if (os === 'Windows') return assets.find(a => a.name.endsWith('.exe'));
if (os === 'macOS') return assets.find(a => a.name.endsWith(arch === 'arm64' ? 'aarch64.dmg' : 'x64.dmg'));
if (os === 'Linux') return assets.find(a => a.name.endsWith('.AppImage'));
return null;
};
const openDownloadModal = (osType: string) => {
if (!modal || !modalOptions || !modalTitle) return;
const { arch } = detectOS();
let filteredAssets = [];
let title = 'Select Downloader';
if (osType === 'Windows') {
filteredAssets = latestAssets.filter(a => a.name.endsWith('.exe') || a.name.endsWith('.msi'));
title = 'Emerald Legacy for Windows';
} else if (osType === 'macOS') {
filteredAssets = latestAssets.filter(a => a.name.endsWith('.dmg'));
title = 'Emerald Legacy for macOS';
} else if (osType === 'Linux') {
filteredAssets = latestAssets.filter(a => a.name.endsWith('.AppImage') || a.name.endsWith('.deb') || a.name.endsWith('.rpm'));
title = 'Emerald Legacy for Linux';
}
const recommended = getRecommendedAsset(osType, arch, filteredAssets);
modalTitle.innerText = title;
modalOptions.innerHTML = filteredAssets.map(asset => {
const isRecommended = asset.name === recommended?.name;
return `
<div class="modal-btn-container">
<a href="${asset.browser_download_url}" class="main-btn">
<span>${asset.name.split('_').pop()?.split('-').pop() || asset.name}</span>
</a>
${isRecommended ? '<span class="splash-text">Recommended!</span>' : ''}
</div>
`;
}).join('');
modal.classList.add('active');
};
const updateDownloadButtons = async () => {
try {
const response = await fetch(`https://api.github.com/repos/${repo}/releases/latest`);
const data = await response.json();
latestAssets = data.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}`;
}
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'); });
} catch (error) {
console.error('Error fetching latest release:', error);
}
};
closeModal?.addEventListener('click', () => modal?.classList.remove('active'));
modal?.addEventListener('click', (e) => { if (e.target === modal) modal.classList.remove('active'); });
window.addEventListener('keydown', (e) => { if (e.key === 'Escape') modal?.classList.remove('active'); });
updateDownloadButtons();
setInterval(() => rotateScreenshot(1), 5000);
});

View File

@@ -482,4 +482,125 @@ body {
grid-column: 1 / -1;
justify-content: center;
}
}
/* --- Download Modal --- */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
display: none;
justify-content: center;
align-items: center;
z-index: 2000;
backdrop-filter: blur(4px);
}
.modal-overlay.active {
display: flex;
}
.modal-content {
background: #cecece;
border: 6px solid #f0f0f0;
border-right-color: #7b7b7b;
border-bottom-color: #7b7b7b;
width: 90%;
max-width: 600px;
padding: 8px;
position: relative;
box-shadow: 0 30px 60px rgba(0, 0, 0, 1);
}
.modal-content::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border: 4px solid #1a1a1a;
pointer-events: none;
}
.modal-header {
background: #3c3c3c;
padding: 15px 20px;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.modal-header h2 {
font-size: 2rem;
color: #fff;
text-shadow: 3px 3px 0 #000;
}
.close-btn {
background: #5c5c5c;
border: 3px solid #fff;
border-right-color: #2a2a2a;
border-bottom-color: #2a2a2a;
color: #fff;
font-family: var(--font-pixel);
font-size: 1.4rem;
padding: 4px 12px;
cursor: pointer;
}
.close-btn:hover {
outline: 4px solid var(--highlight-yellow);
}
.modal-options-grid {
background: #3c3c3c;
padding: 30px 20px;
display: flex;
flex-direction: column;
gap: 20px;
align-items: center;
min-height: 200px;
}
.modal-footer {
background: #7b7b7b;
padding: 10px;
text-align: center;
font-size: 1.1rem;
border-top: 4px solid #1a1a1a;
}
.modal-btn-container {
position: relative;
width: 100%;
max-width: 400px;
}
.splash-text {
position: absolute;
top: -15px;
right: -25px;
color: #ffff3f;
font-family: var(--font-silk);
font-size: 1.2rem;
text-shadow: 2px 2px 0 #3f3f00;
transform: rotate(-20deg);
pointer-events: none;
z-index: 10;
animation: splashPulse 0.5s ease-in-out infinite alternate;
white-space: nowrap;
}
@keyframes splashPulse {
from {
transform: rotate(-20deg) scale(1);
}
to {
transform: rotate(-20deg) scale(1.1);
}
}