Emulators page and json database

This commit is contained in:
2025-03-13 15:15:38 -03:00
parent 1a3d77f3fd
commit f5641989ab
4 changed files with 656 additions and 0 deletions

306
views/pages/emulators.ejs Normal file
View File

@@ -0,0 +1,306 @@
<script src='https://code.jquery.com/jquery-3.7.1.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.2/js/bootstrap.min.js'></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
<div class="emulators-container">
<pre style="font: 20px / 19px monospace; color: white; text-align: center; overflow: hidden;">
<%= generateAsciiArt() %>
Emulators
</pre>
<div class="container mt-4">
<div class="row" id="consoleCards">
<% if (typeof emulators !== 'undefined' && emulators) { %>
<% Object.entries(emulators).forEach(([consoleName, consoleData]) => { %>
<div class="col-md-4 col-sm-6 mb-4">
<div class="card console-card h-100" data-console="<%= consoleName %>">
<div class="text-center pt-3">
<img src="<%= consoleData.icon %>" alt="<%= consoleName %>" class="console-icon mb-2">
<div class="console-card-title"><%= consoleName %></div>
</div>
</div>
</div>
<% }); %>
<% } else { %>
<div class="col-12 text-center">
<div class="alert alert-warning">
No emulator data available. Please check your configuration.
</div>
</div>
<% } %>
</div>
</div>
</div>
<!-- Modal for displaying emulator details -->
<div class="modal fade" id="emulatorModal" tabindex="-1" role="dialog" aria-labelledby="emulatorModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content bg-dark text-white">
<div class="modal-header border-bottom border-secondary">
<h5 class="modal-title" id="emulatorModalLabel">
<i class="fas fa-gamepad mr-2 text-warning"></i>Recommended Emulators
</h5>
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body" id="emulatorList">
<!-- Emulator content will be dynamically inserted here -->
</div>
</div>
</div>
</div>
<style>
.emulators-container {
padding-bottom: 80px;
}
.console-card {
transition: all 0.3s ease;
cursor: pointer;
overflow: hidden;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.console-card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0.3);
border-color: rgb(255, 189, 51);
}
.console-icon {
max-height: 100px;
max-width: 90%;
object-fit: contain;
margin: 5px auto;
display: block;
transition: transform 0.2s;
}
.console-card:hover .console-icon {
transform: scale(1.05);
}
.console-card-title {
font-weight: bold;
margin-top: 10px;
padding: 12px;
background-color: rgba(0,0,0,0.2);
border-radius: 0 0 4px 4px;
transition: background-color 0.3s;
}
.console-card:hover .console-card-title {
background-color: rgba(255, 189, 51, 0.2);
}
/* Modal styles */
.modal-content {
border-radius: 8px;
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 189, 51, 0.2);
}
.modal-header {
background-color: #1a1d21;
padding: 15px 20px;
}
.modal-title {
font-weight: 600;
color: rgb(255, 189, 51);
}
.modal-body {
padding: 25px;
max-height: 80vh;
overflow-y: auto;
background-color: #232629;
}
/* Emulator card styles */
.emulator-card {
background-color: #2a3030;
border: 1px solid rgba(255,255,255,.1);
margin-bottom: 20px;
border-radius: 8px;
transition: all 0.3s;
overflow: hidden;
}
.emulator-card:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
border-color: rgba(255, 189, 51, 0.4);
}
.emulator-header {
background-color: rgba(0, 0, 0, 0.2);
padding: 15px 20px;
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.emulator-header h5 {
margin: 0;
color: rgb(255, 189, 51);
font-weight: 600;
}
.emulator-body {
padding: 20px;
}
.emulator-logo-container {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 15px;
padding: 15px;
background-color: rgba(0, 0, 0, 0.1);
border-radius: 6px;
min-height: 120px;
}
.emulator-logo {
max-height: 100px;
max-width: 100%;
object-fit: contain;
transition: transform 0.3s;
}
.emulator-logo:hover {
transform: scale(1.05);
}
.emulator-description {
margin-bottom: 20px;
line-height: 1.6;
color: #e0e0e0;
}
.platform-badges {
display: flex;
flex-wrap: wrap;
margin-bottom: 20px;
}
.platform-badge {
background-color: #3d4451;
border-radius: 20px;
padding: 5px 15px;
margin-right: 8px;
margin-bottom: 8px;
display: inline-block;
font-size: 0.85rem;
transition: all 0.2s;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.platform-badge:hover {
background-color: #4a5366;
transform: translateY(-2px);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.download-btn {
background-color: rgb(255, 189, 51);
color: #000;
border: none;
padding: 8px 20px;
border-radius: 5px;
font-weight: 600;
transition: all 0.3s;
}
.download-btn:hover {
background-color: rgb(255, 210, 115);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
color: #000;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Add click handlers to all console cards
const consoleCards = document.querySelectorAll('.console-card');
consoleCards.forEach(card => {
card.addEventListener('click', function() {
const consoleName = this.getAttribute('data-console');
showEmulators(consoleName);
});
});
});
function showEmulators(consoleName) {
<% if (typeof emulators !== 'undefined' && emulators) { %>
const consoleData = <%- JSON.stringify(emulators) %>[consoleName];
const modalTitle = document.getElementById('emulatorModalLabel');
const emulatorList = document.getElementById('emulatorList');
modalTitle.innerHTML = `<i class="fas fa-gamepad mr-2 text-warning"></i>Recommended Emulators | ${consoleName}`;
emulatorList.innerHTML = '';
// Create console icon at the top of the modal
const consoleIconContainer = document.createElement('div');
consoleIconContainer.className = 'text-center mb-4';
consoleIconContainer.innerHTML = `
<img src="${consoleData.icon}" alt="${consoleName}" style="max-height: 80px;">
<h4 class="mt-3 text-warning">${consoleName}</h4>
<div class="separator my-3"><span></span></div>
`;
emulatorList.appendChild(consoleIconContainer);
Object.entries(consoleData.emulators).forEach(([emulatorName, emulatorData]) => {
const emulatorCard = document.createElement('div');
emulatorCard.className = 'emulator-card';
let platformsHtml = '';
emulatorData.platforms.forEach(platform => {
let iconClass = '';
switch(platform.toLowerCase()) {
case 'windows': iconClass = 'fab fa-windows'; break;
case 'linux': iconClass = 'fab fa-linux'; break;
case 'macos': iconClass = 'fab fa-apple'; break;
case 'android': iconClass = 'fab fa-android'; break;
case 'ios': iconClass = 'fab fa-app-store-ios'; break;
default: iconClass = 'fas fa-desktop';
}
platformsHtml += `<span class="platform-badge"><i class="${iconClass} mr-2"></i>${platform}</span>`;
});
emulatorCard.innerHTML = `
<div class="emulator-header">
<h5>${emulatorName}</h5>
</div>
<div class="emulator-body">
<div class="row">
<div class="col-md-4">
<div class="emulator-logo-container">
<img src="${emulatorData.logo}" alt="${emulatorName}" class="emulator-logo">
</div>
</div>
<div class="col-md-8">
<div class="emulator-description">${emulatorData.description}</div>
<div class="platform-badges">
${platformsHtml}
</div>
<a href="${emulatorData.url}" target="_blank" class="btn download-btn">
<i class="fas fa-download mr-2"></i>Download
</a>
</div>
</div>
</div>
`;
emulatorList.appendChild(emulatorCard);
});
// Show the modal
$('#emulatorModal').modal('show');
<% } %>
}
</script>

View File

@@ -5,6 +5,9 @@
<li class="nav-item">
<a class="nav-link text-white" href="/settings">Settings</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/emulators">Emulators</a>
</li>
<li class="nav-item">
<a class="nav-link text-white" href="/about">About</a>
</li>