|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>PiFlash - Raspberry Pi Image Flasher</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<link rel="stylesheet" href="styles.css"> |
|
|
</head> |
|
|
<body class="bg-gray-50 dark:bg-gray-900 min-h-screen transition-colors duration-200"> |
|
|
<div class="container mx-auto px-4 py-8 text-gray-800 dark:text-gray-200"> |
|
|
|
|
|
<header class="mb-10 text-center"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<div class="flex items-center"> |
|
|
<i class="fas fa-raspberry-pi text-4xl text-red-600 mr-3"></i> |
|
|
<h1 class="text-4xl font-bold text-gray-800 dark:text-gray-100">PiFlash</h1> |
|
|
</div> |
|
|
<button id="themeToggle" class="p-2 rounded-full bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-200"> |
|
|
<i class="fas fa-moon dark:hidden"></i> |
|
|
<i class="fas fa-sun hidden dark:block"></i> |
|
|
</button> |
|
|
</div> |
|
|
<p class="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto"> |
|
|
A simple web-based tool to flash Raspberry Pi OS images to your SD cards. No additional software required! |
|
|
</p> |
|
|
</header> |
|
|
|
|
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8"> |
|
|
|
|
|
<div class="lg:col-span-1 space-y-6"> |
|
|
<div class="bg-white dark:bg-gray-800 rounded-xl shadow-md p-6 card-hover transition-colors duration-200"> |
|
|
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
|
<i class="fas fa-sd-card mr-2 text-blue-500"></i> Select Storage Device |
|
|
</h2> |
|
|
<div id="deviceList" class="space-y-3"> |
|
|
|
|
|
</div> |
|
|
<button id="refreshDevices" class="w-full mt-2 flex items-center justify-center text-blue-500 hover:text-blue-700"> |
|
|
<i class="fas fa-sync-alt mr-2"></i> Refresh Devices |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="bg-white rounded-xl shadow-md p-6 card-hover"> |
|
|
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
|
<i class="fas fa-cog mr-2 text-purple-500"></i> Flash Options |
|
|
</h2> |
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Validation</label> |
|
|
<select id="validationOption" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
|
|
<option value="verify">Verify after writing</option> |
|
|
<option value="skip">Skip verification</option> |
|
|
</select> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Compression</label> |
|
|
<select id="compressionOption" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
|
|
<option value="auto">Auto (recommended)</option> |
|
|
<option value="always">Always decompress</option> |
|
|
<option value="never">Never decompress</option> |
|
|
</select> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<input type="checkbox" id="unmount" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" checked> |
|
|
<label for="unmount" class="ml-2 block text-sm text-gray-700">Unmount before writing</label> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<input type="checkbox" id="eject" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" checked> |
|
|
<label for="eject" class="ml-2 block text-sm text-gray-700">Eject when complete</label> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="lg:col-span-1 space-y-6"> |
|
|
<div class="bg-white rounded-xl shadow-md p-6 card-hover h-full"> |
|
|
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
|
<i class="fas fa-download mr-2 text-green-500"></i> Select OS Image |
|
|
</h2> |
|
|
|
|
|
<div class="mb-4"> |
|
|
<div class="flex space-x-2 mb-3"> |
|
|
<button id="tabRecommended" class="tab-button px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-sm font-medium">Recommended</button> |
|
|
<button id="tabAll" class="tab-button px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm font-medium">All</button> |
|
|
<button id="tabOther" class="tab-button px-3 py-1 bg-gray-100 text-gray-700 rounded-full text-sm font-medium">Other</button> |
|
|
</div> |
|
|
<div class="relative"> |
|
|
<input type="text" id="searchOS" placeholder="Search OS images..." class="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:ring-blue-500 focus:border-blue-500 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100"> |
|
|
<i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="osImageList" class="space-y-3 overflow-y-auto max-h-96"> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="mt-4"> |
|
|
<input type="file" id="customImageFile" accept=".img,.zip,.gz,.xz" class="hidden"> |
|
|
<div id="customImageUpload" class="border-2 border-dashed border-gray-300 rounded-lg p-4 text-center hover:border-blue-400 cursor-pointer"> |
|
|
<i class="fas fa-file-upload text-3xl text-gray-400 mb-2"></i> |
|
|
<h3 class="font-medium text-gray-700">Use Custom Image</h3> |
|
|
<p class="text-sm text-gray-500">Upload your own .img or .zip file</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="lg:col-span-1 space-y-6"> |
|
|
<div class="bg-white rounded-xl shadow-md p-6 card-hover"> |
|
|
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
|
<i class="fas fa-bolt mr-2 text-yellow-500"></i> Flash Summary |
|
|
</h2> |
|
|
|
|
|
<div id="flashSummary" class="bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg p-4 mb-4"> |
|
|
<div class="flex items-center mb-2"> |
|
|
<i class="fas fa-info-circle text-gray-500 mr-2"></i> |
|
|
<h3 class="font-medium text-gray-700">Select Image and Device</h3> |
|
|
</div> |
|
|
<p class="text-sm text-gray-600"> |
|
|
Choose an OS image and storage device to get started. |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Wi-Fi Configuration (Optional)</label> |
|
|
<input type="text" id="wifiSSID" placeholder="SSID" class="w-full p-2 border border-gray-300 rounded-md mb-2 focus:ring-blue-500 focus:border-blue-500"> |
|
|
<input type="password" id="wifiPassword" placeholder="Password" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Hostname (Optional)</label> |
|
|
<input type="text" id="hostname" placeholder="raspberrypi" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Enable SSH</label> |
|
|
<select id="sshOption" class="w-full p-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"> |
|
|
<option value="disabled">Disabled</option> |
|
|
<option value="password">Enabled with password authentication</option> |
|
|
<option value="key">Enabled with public key only</option> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<button id="flashButton" class="w-full mt-6 py-3 px-4 bg-gray-400 text-white font-semibold rounded-lg shadow-md transition duration-300 flex items-center justify-center cursor-not-allowed" disabled> |
|
|
<i class="fas fa-bolt mr-2"></i> Select Image and Device |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="progressSection" class="bg-white rounded-xl shadow-md p-6 card-hover hidden"> |
|
|
<h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center"> |
|
|
<i class="fas fa-spinner fa-spin mr-2 text-blue-500"></i> Flashing in Progress |
|
|
</h2> |
|
|
|
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<div class="flex justify-between text-sm text-gray-600 mb-1"> |
|
|
<span id="progressStatus">Preparing...</span> |
|
|
<span id="progressPercent">0%</span> |
|
|
</div> |
|
|
<div class="w-full bg-gray-200 rounded-full h-2.5"> |
|
|
<div id="progressBar" class="progress-bar bg-blue-600 h-2.5 rounded-full" style="width: 0%"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-3"> |
|
|
<div class="flex items-center"> |
|
|
<i class="fas fa-exclamation-triangle text-yellow-500 mr-2"></i> |
|
|
<h3 class="font-medium text-yellow-800">Important</h3> |
|
|
</div> |
|
|
<p class="text-sm text-yellow-700 mt-1"> |
|
|
Do not remove the SD card or close this browser tab during the flashing process. |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
<div id="progressSteps" class="space-y-2 text-sm"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="pt-4 border-t border-gray-200"> |
|
|
<p class="text-sm text-gray-500"> |
|
|
<i class="fas fa-clock mr-1"></i> Estimated time remaining: <span id="timeRemaining">Calculating...</span> |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
<button id="cancelFlash" class="w-full py-2 px-4 bg-red-600 hover:bg-red-700 text-white font-semibold rounded-lg"> |
|
|
Cancel Flashing |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="completionSection" class="bg-white rounded-xl shadow-md p-6 card-hover hidden"> |
|
|
<div class="text-center"> |
|
|
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100 mb-4"> |
|
|
<i class="fas fa-check text-green-600 text-xl"></i> |
|
|
</div> |
|
|
<h3 class="text-lg font-medium text-gray-900 mb-2">Flash Complete!</h3> |
|
|
<p class="text-sm text-gray-500 mb-4" id="completionMessage"> |
|
|
Your SD card is ready to use. |
|
|
</p> |
|
|
<div class="bg-gray-50 p-3 rounded-lg text-left mb-4"> |
|
|
<p class="text-sm font-medium text-gray-700 mb-1">Next Steps:</p> |
|
|
<ul class="text-sm text-gray-600 list-disc list-inside space-y-1"> |
|
|
<li>Insert the SD card into your Raspberry Pi</li> |
|
|
<li>Connect power to boot the device</li> |
|
|
<li>Follow the setup instructions</li> |
|
|
</ul> |
|
|
</div> |
|
|
<button id="flashAnother" class="w-full py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none"> |
|
|
Flash Another Card |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<footer class="mt-16 text-center text-sm text-gray-500"> |
|
|
<p>PiFlash is an open-source tool. Use at your own risk.</p> |
|
|
<p class="mt-1">Not affiliated with the Raspberry Pi Foundation.</p> |
|
|
<div class="flex justify-center space-x-4 mt-3"> |
|
|
<a href="https://github.com/your-org/piflash" class="text-blue-500 hover:text-blue-700"><i class="fab fa-github"></i> GitHub</a> |
|
|
<a href="#" class="text-blue-500 hover:text-blue-700"><i class="fas fa-question-circle"></i> Help</a> |
|
|
<a href="#" class="text-blue-500 hover:text-blue-700"><i class="fas fa-bug"></i> Report Issue</a> |
|
|
</div> |
|
|
</footer> |
|
|
</div> |
|
|
|
|
|
<script src="js/app.js"></script> |
|
|
<script> |
|
|
|
|
|
const themeToggle = document.getElementById('themeToggle'); |
|
|
const html = document.documentElement; |
|
|
|
|
|
|
|
|
const savedTheme = localStorage.getItem('theme') || |
|
|
(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); |
|
|
html.classList.toggle('dark', savedTheme === 'dark'); |
|
|
|
|
|
themeToggle.addEventListener('click', () => { |
|
|
html.classList.toggle('dark'); |
|
|
localStorage.setItem('theme', html.classList.contains('dark') ? 'dark' : 'light'); |
|
|
}); |
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=S-Dreamer/piflash" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
|
</html> |
|
|
|