Better download button + community screenshots
43
index.html
@@ -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"><</button>
|
||||
<img src="/TU7_Panorama_Background_S.png" class="carousel-img">
|
||||
<img src="/Community/image.png" class="carousel-img">
|
||||
<button class="carousel-arrow right">></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
|
After Width: | Height: | Size: 676 KiB |
BIN
public/Community/image2.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/Community/image3.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/Community/image4.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
public/Community/image5.png
Normal file
|
After Width: | Height: | Size: 686 KiB |
BIN
public/Community/image6.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
public/controller.png
Normal file
|
After Width: | Height: | Size: 300 B |
113
src/main.ts
@@ -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);
|
||||
});
|
||||
|
||||
121
src/style.css
@@ -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);
|
||||
}
|
||||
}
|
||||