Better download button + community screenshots
43
index.html
|
|
@ -90,7 +90,7 @@
|
||||||
|
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
|
<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>
|
<span>Get Launcher</span>
|
||||||
<img src="/logo.png" class="btn-icon">
|
<img src="/logo.png" class="btn-icon">
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -107,7 +107,7 @@
|
||||||
<div class="carousel-header">Community Screenshots</div>
|
<div class="carousel-header">Community Screenshots</div>
|
||||||
<div class="carousel-view">
|
<div class="carousel-view">
|
||||||
<button class="carousel-arrow left"><</button>
|
<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>
|
<button class="carousel-arrow right">></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="carousel-footer">See more in Discord</div>
|
<div class="carousel-footer">See more in Discord</div>
|
||||||
|
|
@ -148,9 +148,18 @@
|
||||||
<section class="tab-content" id="media">
|
<section class="tab-content" id="media">
|
||||||
<div class="home-layout">
|
<div class="home-layout">
|
||||||
<div class="features-row" style="flex-wrap: wrap; gap: 10px;">
|
<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="/Community/image.png"
|
||||||
<img src="/TU7_Panorama_Background_S.png" style="width: 30%; border: 2px solid #fff;">
|
style="width: 31%; border: 2px solid #fff; aspect-ratio: 16/9; object-fit: cover;">
|
||||||
<img src="/TU7_Panorama_Background_S.png" style="width: 30%; border: 2px solid #fff;">
|
<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>
|
||||||
<div class="cta-section">
|
<div class="cta-section">
|
||||||
<h2>Community Gallery</h2>
|
<h2>Community Gallery</h2>
|
||||||
|
|
@ -166,13 +175,17 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="action-buttons" style="margin-top: 20px;">
|
<div class="action-buttons" style="margin-top: 20px;">
|
||||||
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
|
<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>
|
<span>Download for Windows</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://github.com/Emerald-Legacy-Launcher/Emerald-Legacy-Launcher/releases/latest"
|
<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>
|
<span>Download for Linux</span>
|
||||||
</a>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -191,6 +204,22 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</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 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 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));
|
document.getElementById('next-tab')?.addEventListener('click', () => updateTabs(activeIndex + 1));
|
||||||
|
|
||||||
const carouselImg = document.querySelector('.carousel-img') as HTMLImageElement;
|
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;
|
let screenIndex = 0;
|
||||||
|
|
||||||
const rotateScreenshot = (dir: number) => {
|
const rotateScreenshot = (dir: number) => {
|
||||||
|
|
@ -51,5 +58,109 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
document.querySelector('.carousel-arrow.left')?.addEventListener('click', () => rotateScreenshot(-1));
|
document.querySelector('.carousel-arrow.left')?.addEventListener('click', () => rotateScreenshot(-1));
|
||||||
document.querySelector('.carousel-arrow.right')?.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);
|
setInterval(() => rotateScreenshot(1), 5000);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
121
src/style.css
|
|
@ -482,4 +482,125 @@ body {
|
||||||
grid-column: 1 / -1;
|
grid-column: 1 / -1;
|
||||||
justify-content: center;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||