mirror of
https://github.com/Retropex/custom-ocean.xyz-dashboard.git
synced 2025-05-12 19:20:45 +02:00
Update boot.html
This commit is contained in:
parent
bfb9840d24
commit
2ce3a40a65
@ -6,6 +6,168 @@
|
||||
<title>Ocean.xyz Pool Miner - Initializing...</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=VT323&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/static/css/boot.css">
|
||||
<style>
|
||||
/* Added styles for configuration form */
|
||||
#config-form {
|
||||
display: none;
|
||||
margin-top: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
border: 1px solid #f7931a;
|
||||
padding: 15px;
|
||||
max-width: 600px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
box-shadow: 0 0 10px rgba(247, 147, 26, 0.5);
|
||||
}
|
||||
|
||||
.config-title {
|
||||
color: #f7931a;
|
||||
font-size: 22px;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
text-shadow: 0 0 8px rgba(247, 147, 26, 0.8);
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 5px;
|
||||
color: #f7931a;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
background-color: #111;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 8px;
|
||||
color: white;
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 5px #f7931a;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
background-color: #f7931a;
|
||||
border: none;
|
||||
color: black;
|
||||
padding: 8px 15px;
|
||||
font-family: 'VT323', monospace;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
min-width: 120px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-color: #ffa642;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background-color: #333;
|
||||
color: #f7931a;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
/* Make skip button more mobile-friendly */
|
||||
#skip-button {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 1000;
|
||||
padding: 12px 20px;
|
||||
font-size: 18px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#skip-button {
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
padding: 15px 25px;
|
||||
font-size: 20px; /* Larger font size for better tap targets */
|
||||
border-radius: 10px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tooltip styles */
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border: 1px solid #f7931a;
|
||||
padding: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 125%;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tooltip:hover .tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Form success/error message */
|
||||
#form-message {
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.message-success {
|
||||
background-color: rgba(50, 205, 50, 0.2);
|
||||
border: 1px solid #32CD32;
|
||||
color: #32CD32;
|
||||
}
|
||||
|
||||
.message-error {
|
||||
background-color: rgba(255, 0, 0, 0.2);
|
||||
border: 1px solid #ff0000;
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button id="skip-button">SKIP</button>
|
||||
@ -24,7 +186,8 @@
|
||||
<div id="terminal-content">
|
||||
<span id="output"></span><span class="cursor"></span>
|
||||
<span id="prompt-container">
|
||||
<span id="prompt-text">Initialize mining dashboard? [Y/N]:
|
||||
<span id="prompt-text">
|
||||
Initialize mining dashboard? [Y/N]:
|
||||
<span class="prompt-cursor"></span>
|
||||
<input type="text" id="user-input" maxlength="1" autocomplete="off" spellcheck="false" autofocus style="font-size: 16px; font-weight: bold;">
|
||||
</span>
|
||||
@ -32,6 +195,46 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Configuration Form -->
|
||||
<div id="config-form">
|
||||
<div class="config-title">MINING CONFIGURATION</div>
|
||||
<div class="form-group">
|
||||
<label for="wallet-address">
|
||||
Bitcoin Wallet Address
|
||||
<span class="tooltip">
|
||||
?
|
||||
<span class="tooltip-text">Your Ocean.xyz pool mining address</span>
|
||||
</span>
|
||||
</label>
|
||||
<input type="text" id="wallet-address" placeholder="bc1..." value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="power-cost">
|
||||
Power Cost ($/kWh)
|
||||
<span class="tooltip">
|
||||
?
|
||||
<span class="tooltip-text">Your electricity cost per kilowatt-hour</span>
|
||||
</span>
|
||||
</label>
|
||||
<input type="number" id="power-cost" step="0.01" min="0" placeholder="0.12" value="">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="power-usage">
|
||||
Power Usage (Watts)
|
||||
<span class="tooltip">
|
||||
?
|
||||
<span class="tooltip-text">Total power consumption of your mining equipment</span>
|
||||
</span>
|
||||
</label>
|
||||
<input type="number" id="power-usage" step="1" min="0" placeholder="3450" value="">
|
||||
</div>
|
||||
<div id="form-message"></div>
|
||||
<div class="form-actions">
|
||||
<button class="btn btn-secondary" id="use-defaults">Use Defaults</button>
|
||||
<button class="btn" id="save-config">Save & Continue</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Debug logging
|
||||
function updateDebug(message) {
|
||||
@ -54,14 +257,107 @@
|
||||
const loadingMessage = document.getElementById('loading-message');
|
||||
const promptContainer = document.getElementById('prompt-container');
|
||||
const userInput = document.getElementById('user-input');
|
||||
const configForm = document.getElementById('config-form');
|
||||
let messageIndex = 0;
|
||||
let timeoutId = null;
|
||||
let waitingForUserInput = false;
|
||||
let bootComplete = false;
|
||||
let configLoaded = false;
|
||||
let currentConfig = {
|
||||
wallet: "bc1py5zmrtssheq3shd8cptpl5l5m3txxr5afynyg2gyvam6w78s4dlqqnt4v9",
|
||||
power_cost: 0.0,
|
||||
power_usage: 0.0
|
||||
};
|
||||
|
||||
// Replace the current loadConfig function with this improved version
|
||||
function loadConfig() {
|
||||
// Always make a fresh request to get the latest config
|
||||
fetch('/api/config?nocache=' + new Date().getTime()) // Add cache-busting parameter
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load configuration: ' + response.statusText);
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log("Loaded configuration:", data);
|
||||
currentConfig = data;
|
||||
|
||||
// After loading, always update the form fields with the latest values
|
||||
document.getElementById('wallet-address').value = currentConfig.wallet || "";
|
||||
document.getElementById('power-cost').value = currentConfig.power_cost || "";
|
||||
document.getElementById('power-usage').value = currentConfig.power_usage || "";
|
||||
configLoaded = true;
|
||||
})
|
||||
.catch(err => {
|
||||
console.error("Error loading config:", err);
|
||||
// Use default values if loading fails
|
||||
currentConfig = {
|
||||
wallet: "bc1py5zmrtssheq3shd8cptpl5l5m3txxr5afynyg2gyvam6w78s4dlqqnt4v9",
|
||||
power_cost: 0.0,
|
||||
power_usage: 0.0
|
||||
};
|
||||
|
||||
// Still update the form with default values
|
||||
document.getElementById('wallet-address').value = currentConfig.wallet || "";
|
||||
document.getElementById('power-cost').value = currentConfig.power_cost || "";
|
||||
document.getElementById('power-usage').value = currentConfig.power_usage || "";
|
||||
});
|
||||
}
|
||||
|
||||
// Also update the save button event handler to reload the config after saving
|
||||
document.getElementById('save-config').addEventListener('click', function () {
|
||||
const messageElement = document.getElementById('form-message');
|
||||
messageElement.style.display = 'block';
|
||||
|
||||
saveConfig()
|
||||
.then(data => {
|
||||
console.log("Configuration saved:", data);
|
||||
messageElement.textContent = "Configuration saved successfully!";
|
||||
messageElement.className = "message-success";
|
||||
|
||||
// Update currentConfig with the saved values
|
||||
currentConfig = data.config || data;
|
||||
|
||||
setTimeout(redirectToDashboard, 1000);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error saving configuration:", error);
|
||||
messageElement.textContent = "Error saving configuration. Please try again.";
|
||||
messageElement.className = "message-error";
|
||||
});
|
||||
});
|
||||
|
||||
// Save configuration
|
||||
function saveConfig() {
|
||||
const wallet = document.getElementById('wallet-address').value.trim();
|
||||
const powerCost = parseFloat(document.getElementById('power-cost').value) || 0;
|
||||
const powerUsage = parseFloat(document.getElementById('power-usage').value) || 0;
|
||||
|
||||
const updatedConfig = {
|
||||
wallet: wallet || currentConfig.wallet,
|
||||
power_cost: powerCost,
|
||||
power_usage: powerUsage
|
||||
};
|
||||
|
||||
return fetch('/api/config', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(updatedConfig)
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to save configuration');
|
||||
}
|
||||
return response.json();
|
||||
});
|
||||
}
|
||||
|
||||
// Safety timeout: redirect after 60 seconds if boot not complete
|
||||
window.addEventListener('load', function() {
|
||||
setTimeout(function() {
|
||||
window.addEventListener('load', function () {
|
||||
setTimeout(function () {
|
||||
if (!bootComplete && !waitingForUserInput) {
|
||||
console.warn("Safety timeout reached - redirecting to dashboard");
|
||||
redirectToDashboard();
|
||||
@ -69,6 +365,54 @@
|
||||
}, 60000);
|
||||
});
|
||||
|
||||
// Configuration form event listeners
|
||||
document.getElementById('save-config').addEventListener('click', function () {
|
||||
const messageElement = document.getElementById('form-message');
|
||||
messageElement.style.display = 'block';
|
||||
|
||||
saveConfig()
|
||||
.then(data => {
|
||||
console.log("Configuration saved:", data);
|
||||
messageElement.textContent = "Configuration saved successfully!";
|
||||
messageElement.className = "message-success";
|
||||
setTimeout(redirectToDashboard, 1000);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("Error saving configuration:", error);
|
||||
messageElement.textContent = "Error saving configuration. Please try again.";
|
||||
messageElement.className = "message-error";
|
||||
});
|
||||
});
|
||||
|
||||
// Replace the current Use Defaults button event listener with this fixed version
|
||||
document.getElementById('use-defaults').addEventListener('click', function () {
|
||||
console.log("Use Defaults button clicked");
|
||||
|
||||
// Always use the hardcoded default values, not the currentConfig
|
||||
const defaultWallet = "bc1py5zmrtssheq3shd8cptpl5l5m3txxr5afynyg2gyvam6w78s4dlqqnt4v9";
|
||||
const defaultPowerCost = 0.0;
|
||||
const defaultPowerUsage = 0.0;
|
||||
|
||||
console.log("Setting to default values");
|
||||
|
||||
// Apply the hardcoded default values to the form fields
|
||||
document.getElementById('wallet-address').value = defaultWallet;
|
||||
document.getElementById('power-cost').value = defaultPowerCost;
|
||||
document.getElementById('power-usage').value = defaultPowerUsage;
|
||||
|
||||
// Show visual feedback that the button was clicked
|
||||
const btn = document.getElementById('use-defaults');
|
||||
const originalText = btn.textContent;
|
||||
btn.textContent = "Defaults Applied";
|
||||
btn.style.backgroundColor = "#32CD32";
|
||||
|
||||
// Reset the button after a short delay
|
||||
setTimeout(function () {
|
||||
btn.textContent = originalText;
|
||||
btn.style.backgroundColor = "";
|
||||
}, 1500);
|
||||
});
|
||||
|
||||
// Redirect to dashboard
|
||||
function redirectToDashboard() {
|
||||
updateDebug("Boot sequence complete, redirecting...");
|
||||
@ -77,13 +421,16 @@
|
||||
}
|
||||
|
||||
// Fade in Bitcoin logo
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
setTimeout(function() {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
setTimeout(function () {
|
||||
bitcoinLogo.style.visibility = 'visible';
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
bitcoinLogo.style.opacity = '1';
|
||||
}, 100);
|
||||
}, 500);
|
||||
|
||||
// Load configuration
|
||||
loadConfig();
|
||||
});
|
||||
|
||||
// Post-confirmation messages with retro typing effect
|
||||
@ -94,6 +441,9 @@
|
||||
setTimeout(redirectToDashboard, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Configuration form will be shown after boot sequence
|
||||
if (response.toUpperCase() === 'Y') {
|
||||
const yesMessages = [
|
||||
{ text: "INITIALIZING DASHBOARD...\n", html: true, delay: 400 },
|
||||
{ text: "Connecting to real-time data feeds...", speed: 20, delay: 300 },
|
||||
@ -106,51 +456,27 @@
|
||||
{ text: "<span class='green'>CURRENT RATE CONFIRMED</span>\n", html: true, delay: 300 },
|
||||
{ text: "Calibrating hashrate telemetry...", speed: 15, delay: 200 },
|
||||
{ text: "<span class='green'>CALIBRATED</span>\n", html: true, delay: 200 },
|
||||
{ text: "Loading historical mining data: [", speed: 15, delay: 100 },
|
||||
{ text: "<span class='green'>████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='green'>████████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='green'>███████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='green'>████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='green'>██</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='green'>█</span>", html: true, delay: 100 },
|
||||
{ text: "] <span class='green'>COMPLETE</span>\n", html: true, delay: 400 },
|
||||
{ text: "Block reward calculation initialized...", speed: 15, delay: 300 },
|
||||
{ text: "<span class='yellow'>HALVING SCHEDULE VERIFIED</span>\n", html: true, delay: 400 },
|
||||
{ text: "Satoshi per kWh optimizer: <span class='green'>ENGAGED</span>\n", html: true, delay: 500 },
|
||||
{ text: "Launching mining dashboard in 3...", speed: 80, delay: 1000 },
|
||||
{ text: " 2...", speed: 80, delay: 1000 },
|
||||
{ text: " 1...\n", speed: 80, delay: 1000 },
|
||||
{ text: "<span class='green'>STACK SATS MODE: ACTIVATED</span>\n", html: true, delay: 500 }
|
||||
{ text: "Loading mining configuration...", speed: 15, delay: 200 },
|
||||
{ text: "<span class='green'>LOADED</span>\n", html: true, delay: 300 },
|
||||
{ text: "Preparing configuration interface...", speed: 15, delay: 800 },
|
||||
{ text: "<span class='green'>READY</span>\n", html: true, delay: 500 },
|
||||
{ text: "\nPlease configure your mining setup or use the default values:\n", html: true, delay: 800, showConfigForm: true }
|
||||
];
|
||||
const noMessages = [
|
||||
{ text: "DASHBOARD INITIALIZATION ABORTED.\n", html: true, delay: 400 },
|
||||
{ text: "Mining processes will continue in background.\n", speed: 30, delay: 500 },
|
||||
{ text: "Attempting emergency recovery...\n", speed: 30, delay: 1000 },
|
||||
{ text: "Bypassing authentication checks...", speed: 20, delay: 300 },
|
||||
{ text: "<span class='green'>SUCCESS</span>\n", html: true, delay: 500 },
|
||||
{ text: "Initializing fallback ASIC control interface...", speed: 20, delay: 300 },
|
||||
{ text: "<span class='green'>ACTIVE</span>\n", html: true, delay: 400 },
|
||||
{ text: "<span class='green'>RECOVERY SUCCESSFUL!</span>\n", html: true, delay: 400 },
|
||||
{ text: "Loading minimal dashboard in safe mode: [", speed: 15, delay: 100 },
|
||||
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
||||
{ text: "<span class='yellow'>████████</span>", html: true, delay: 100 },
|
||||
{ text: "] <span class='white'>READY</span>\n", html: true, delay: 400 },
|
||||
{ text: "\nNOTE: REDUCED FUNCTIONALITY IN SAFE MODE\n", html: true, delay: 500 },
|
||||
{ text: "Launching minimal dashboard in 3...", speed: 80, delay: 1000 },
|
||||
{ text: " 2...", speed: 80, delay: 1000 },
|
||||
{ text: " 1...\n", speed: 80, delay: 1000 },
|
||||
{ text: "<span class='green'>BITCOIN MINING CONTINUES REGARDLESS! ;)</span>\n", html: true, delay: 500 }
|
||||
];
|
||||
const messages = response === 'Y' ? yesMessages : noMessages;
|
||||
|
||||
let msgIndex = 0;
|
||||
function processNextMessage() {
|
||||
if (msgIndex >= messages.length) {
|
||||
bootComplete = true;
|
||||
setTimeout(redirectToDashboard, 500);
|
||||
if (msgIndex >= yesMessages.length) {
|
||||
return;
|
||||
}
|
||||
const currentMessage = messages[msgIndex];
|
||||
const currentMessage = yesMessages[msgIndex];
|
||||
|
||||
if (currentMessage.showConfigForm) {
|
||||
msgIndex++;
|
||||
// Show configuration form
|
||||
document.getElementById('config-form').style.display = 'block';
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMessage.html) {
|
||||
outputElement.innerHTML += currentMessage.text;
|
||||
msgIndex++;
|
||||
@ -171,22 +497,31 @@
|
||||
}
|
||||
}
|
||||
setTimeout(processNextMessage, 500);
|
||||
} catch(err) {
|
||||
} else {
|
||||
// If user selects 'N', just redirect to dashboard
|
||||
outputElement.innerHTML += "N\n\nDASHBOARD INITIALIZATION ABORTED.\n";
|
||||
outputElement.innerHTML += "\nUsing default configuration values.\n";
|
||||
setTimeout(redirectToDashboard, 2000);
|
||||
}
|
||||
} catch (err) {
|
||||
setTimeout(redirectToDashboard, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Y/N prompt input
|
||||
userInput.addEventListener('keydown', function(e) {
|
||||
userInput.addEventListener('keydown', function (e) {
|
||||
if (waitingForUserInput && e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
const response = userInput.value.toUpperCase();
|
||||
|
||||
if (response === 'Y' || response === 'N') {
|
||||
promptContainer.style.display = 'none';
|
||||
waitingForUserInput = false;
|
||||
outputElement.innerHTML += response + "\n";
|
||||
userInput.value = '';
|
||||
showPostConfirmationMessages(response);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Show the prompt
|
||||
@ -197,7 +532,7 @@
|
||||
userInput.focus();
|
||||
}
|
||||
|
||||
// We disable truncation so all text is visible.
|
||||
// Disable truncation so all text is visible
|
||||
function manageTerminalContent() { }
|
||||
|
||||
// Retro typing effect for boot messages
|
||||
@ -210,20 +545,23 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log("Processing boot message index:", messageIndex);
|
||||
|
||||
if (messageIndex >= bootMessages.length) { return; }
|
||||
const currentMessage = bootMessages[messageIndex];
|
||||
|
||||
if (currentMessage.showPrompt) {
|
||||
messageIndex++;
|
||||
showUserPrompt();
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentMessage.html) {
|
||||
outputElement.innerHTML += currentMessage.text;
|
||||
messageIndex++;
|
||||
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!currentMessage.typingIndex) { currentMessage.typingIndex = 0; }
|
||||
if (currentMessage.typingIndex < currentMessage.text.length) {
|
||||
outputElement.innerHTML += currentMessage.text.charAt(currentMessage.typingIndex);
|
||||
@ -233,14 +571,14 @@
|
||||
messageIndex++;
|
||||
timeoutId = setTimeout(typeBootMessages, currentMessage.delay || 300);
|
||||
}
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
messageIndex++;
|
||||
timeoutId = setTimeout(typeBootMessages, 500);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip button: immediately redirect
|
||||
skipButton.addEventListener('click', function() {
|
||||
skipButton.addEventListener('click', function () {
|
||||
clearTimeout(timeoutId);
|
||||
redirectToDashboard();
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user