Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 67 additions & 140 deletions public/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,23 @@ function updateLogoAndFavicon(isDarkMode) {
}
}

// Browser selection management
const browserIcons = {
midori: 'images/midori.webp',
waterfox: 'images/waterfox.png',
brave: 'images/brave.png'
};
// Browser selection management with grid
function setupBrowserGrid() {
const browserOptions = document.querySelectorAll('.browser-option');

browserOptions.forEach(option => {
option.addEventListener('click', () => {
// Remove selected class from all options
browserOptions.forEach(opt => opt.classList.remove('selected'));
// Add selected class to clicked option
option.classList.add('selected');
});
});
}

function updateBrowserPreview() {
const browserSelect = document.getElementById('browser-select');
const browserIcon = document.getElementById('browser-icon');
const selectedBrowser = browserSelect.value;

browserIcon.src = browserIcons[selectedBrowser];
browserIcon.alt = `${selectedBrowser.charAt(0).toUpperCase() + selectedBrowser.slice(1)} Browser`;
function getSelectedBrowser() {
const selectedOption = document.querySelector('.browser-option.selected');
return selectedOption ? selectedOption.dataset.browser : 'midori';
}

// Status message display
Expand All @@ -54,25 +57,28 @@ function showStatus(message, type = 'info') {
}
}

// Emulator management
let currentEmulatorId = null;

// Emulator management - open in new window
async function startEmulator() {
const browserSelect = document.getElementById('browser-select');
const ramSelect = document.getElementById('ram-select');
const vramSelect = document.getElementById('vram-select');
const startButton = document.getElementById('start-emulator');

const config = {
browser: browserSelect.value,
browser: getSelectedBrowser(),
ram: ramSelect.value,
vram: vramSelect.value
};

// Disable button and show loading
startButton.disabled = true;
startButton.classList.add('loading');
startButton.innerHTML = '<span class="button-icon">⏳</span>Starting...';
startButton.innerHTML = `
<svg class="button-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
<circle cx="12" cy="12" r="10" opacity="0.25"/>
<path d="M12 2 A 10 10 0 0 1 22 12" opacity="0.75"/>
</svg>
Starting...
`;

try {
const response = await fetch('/api/start-emulator', {
Expand All @@ -86,144 +92,65 @@ async function startEmulator() {
const data = await response.json();

if (response.ok) {
currentEmulatorId = data.emulatorId;
displayEmulatorInfo(config, data);
showStatus('Emulator started successfully!', 'success');
// Open emulator in new window with configuration
const params = new URLSearchParams({
browser: config.browser,
ram: config.ram,
vram: config.vram,
id: data.emulatorId
});

const emulatorWindow = window.open(
`emulator.html?${params.toString()}`,
'_blank',
'width=1000,height=800,resizable=yes,scrollbars=yes'
);

if (emulatorWindow) {
showStatus('Emulator started in new window!', 'success');
} else {
showStatus('Emulator started, but popup was blocked. Please allow popups for this site.', 'info');
}

// Reset button
startButton.disabled = false;
startButton.classList.remove('loading');
startButton.innerHTML = `
<svg class="button-icon" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5v14l11-7z"/>
</svg>
Start Emulator
`;
} else {
showStatus(`Error: ${data.error}`, 'error');
startButton.disabled = false;
startButton.classList.remove('loading');
startButton.innerHTML = '<span class="button-icon">▶️</span>Start Emulator';
startButton.innerHTML = `
<svg class="button-icon" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5v14l11-7z"/>
</svg>
Start Emulator
`;
}
} catch (error) {
console.error('Error starting emulator:', error);
showStatus('Failed to connect to server. Make sure the backend is running.', 'error');
startButton.disabled = false;
startButton.classList.remove('loading');
startButton.innerHTML = '<span class="button-icon">▶️</span>Start Emulator';
}
}

function displayEmulatorInfo(config, data) {
const emulatorDisplay = document.getElementById('emulator-display');
const emulatorInfo = document.getElementById('emulator-info');
const consoleOutput = document.getElementById('console-output');

// Show emulator display
emulatorDisplay.classList.remove('hidden');

// Display configuration
const ramText = config.ram === 'unlimited' ? 'Unlimited' : `${config.ram} GB`;
const vramText = config.vram === '1024' ? '1 GB' : `${config.vram} MB`;

emulatorInfo.innerHTML = `
<p><strong>Browser:</strong> ${config.browser.charAt(0).toUpperCase() + config.browser.slice(1)}</p>
<p><strong>RAM:</strong> ${ramText}</p>
<p><strong>VRAM:</strong> ${vramText}</p>
<p><strong>Emulator ID:</strong> ${data.emulatorId}</p>
<p><strong>Status:</strong> <span style="color: var(--accent-color);">Running</span></p>
`;

// Display console output
consoleOutput.textContent = data.output || 'Emulator starting...\n';

// Start polling for updates
pollEmulatorStatus();

// Scroll to emulator display
emulatorDisplay.scrollIntoView({ behavior: 'smooth' });
}

async function pollEmulatorStatus() {
if (!currentEmulatorId) return;

try {
const response = await fetch(`/api/emulator-status/${currentEmulatorId}`);
const data = await response.json();

if (response.ok) {
const consoleOutput = document.getElementById('console-output');
if (data.output) {
consoleOutput.textContent += data.output;
// Auto-scroll to bottom
consoleOutput.scrollTop = consoleOutput.scrollHeight;
}

// Continue polling if emulator is still running
if (data.running) {
setTimeout(pollEmulatorStatus, 2000);
} else {
showStatus('Emulator has stopped.', 'info');
resetUI();
}
}
} catch (error) {
console.error('Error polling emulator status:', error);
}
}

async function stopEmulator() {
if (!currentEmulatorId) return;

const stopButton = document.getElementById('stop-emulator');
stopButton.disabled = true;
stopButton.textContent = 'Stopping...';

try {
const response = await fetch(`/api/stop-emulator/${currentEmulatorId}`, {
method: 'POST'
});

const data = await response.json();

if (response.ok) {
showStatus('Emulator stopped successfully.', 'success');
resetUI();
} else {
showStatus(`Error: ${data.error}`, 'error');
stopButton.disabled = false;
stopButton.textContent = 'Stop';
}
} catch (error) {
console.error('Error stopping emulator:', error);
showStatus('Failed to stop emulator.', 'error');
stopButton.disabled = false;
stopButton.textContent = 'Stop';
startButton.innerHTML = `
<svg class="button-icon" viewBox="0 0 24 24" fill="currentColor">
<path d="M8 5v14l11-7z"/>
</svg>
Start Emulator
`;
}
}

function resetUI() {
const startButton = document.getElementById('start-emulator');
const emulatorDisplay = document.getElementById('emulator-display');
const stopButton = document.getElementById('stop-emulator');

// Reset start button
startButton.disabled = false;
startButton.classList.remove('loading');
startButton.innerHTML = '<span class="button-icon">▶️</span>Start Emulator';

// Hide emulator display
emulatorDisplay.classList.add('hidden');

// Reset stop button
stopButton.disabled = false;
stopButton.textContent = 'Stop';

// Clear emulator ID
currentEmulatorId = null;
}

// Event listeners
document.addEventListener('DOMContentLoaded', () => {
initTheme();
updateBrowserPreview();

// Browser selection change
document.getElementById('browser-select').addEventListener('change', updateBrowserPreview);
setupBrowserGrid();

// Start emulator button
document.getElementById('start-emulator').addEventListener('click', startEmulator);

// Stop emulator button
document.getElementById('stop-emulator').addEventListener('click', stopEmulator);
});
38 changes: 38 additions & 0 deletions public/emulator.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Browser IG - Emulator Running</title>
<link rel="icon" type="image/png" id="favicon">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="container">
<header>
<img id="logo" src="" alt="Browser IG Logo" class="logo">
<h1>Browser IG - Emulator</h1>
</header>

<main>
<div id="emulator-display" class="emulator-display">
<div class="emulator-header">
<h3>Emulator Running</h3>
<button id="stop-emulator" class="stop-button">Stop</button>
</div>
<div id="emulator-info" class="emulator-info"></div>
<div class="emulator-console">
<h4>Console Output:</h4>
<div id="console-output" class="console-output"></div>
</div>
</div>
</main>

<footer>
<p>&copy; 2024 Browser IG - QEMU Browser Emulator</p>
</footer>
</div>

<script src="emulator.js"></script>
</body>
</html>
Loading