mirror of
https://github.com/Retropex/custom-ocean.xyz-dashboard.git
synced 2025-05-12 11:10:44 +02:00
Cleaned up Earning Efficiency, Time To Block, and Block Odds in the Pool Hashrates card. Also fixed a display error on the Last Block line in the Payout Info card.
This commit is contained in:
parent
eab3e89a11
commit
ce3b186dc5
@ -290,32 +290,33 @@ h1 {
|
||||
/* Basic color classes for backward compatibility */
|
||||
.green {
|
||||
color: #39ff14 !important;
|
||||
text-shadow: 0 0 2px #39ff14, 0 0 2px #39ff14;
|
||||
text-shadow: 0 0 10px #39ff14, 0 0 2px #39ff14;
|
||||
}
|
||||
|
||||
.blue {
|
||||
color: #00dfff !important;
|
||||
text-shadow: 0 0 2px #00dfff, 0 0 2px #00dfff;
|
||||
text-shadow: 0 0 10px #00dfff, 0 0 2px #00dfff;
|
||||
}
|
||||
|
||||
.yellow {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: 0 0 2px #ffd700, 0 0 2px #ffd700 !important;
|
||||
text-shadow: 0 0 10px #ffd700, 0 0 2px #ffd700 !important;
|
||||
font-weight: normal !important;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: #ffffff !important;
|
||||
text-shadow: 0 0 2px #ffffff, 0 0 2px #ffffff;
|
||||
text-shadow: 0 0 10px #ffffff, 0 0 2px #ffffff;
|
||||
}
|
||||
|
||||
.red {
|
||||
color: #ff2d2d !important;
|
||||
text-shadow: 0 0 2px #ff2d2d, 0 0 2px #ff2d2d;
|
||||
text-shadow: 0 0 10px #ff2d2d, 0 0 2px #ff2d2d;
|
||||
}
|
||||
|
||||
.magenta {
|
||||
color: #ff2d95 !important;
|
||||
text-shadow: 0 0 2px #ff2d95, 0 0 2px #ff2d95;
|
||||
text-shadow: 0 0 10px #ff2d95, 0 0 2px #ff2d95;
|
||||
}
|
||||
|
||||
/* Bitcoin Progress Bar Styles */
|
||||
|
@ -113,7 +113,7 @@
|
||||
.metric-value {
|
||||
color: var(--text-color);
|
||||
font-weight: bold;
|
||||
text-shadow: 0 0 6px #32cd32;
|
||||
text-shadow: 0 0 10px #32cd32;
|
||||
}
|
||||
|
||||
/* Yellow color family (BTC price, sats metrics, time to payout) */
|
||||
@ -154,7 +154,7 @@
|
||||
#last_block_height,
|
||||
#pool_fees_percentage {
|
||||
color: #ffffff;
|
||||
text-shadow: 0 0 6px rgba(255, 255, 255, 0.6);
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
/* Blue metrics (time data) */
|
||||
@ -166,7 +166,7 @@
|
||||
.card-body strong {
|
||||
color: var(--primary-color);
|
||||
margin-right: 0.25rem;
|
||||
text-shadow: 0 0 2px var(--primary-color);
|
||||
text-shadow: 0 0 10px var(--primary-color);
|
||||
}
|
||||
|
||||
.card-body p {
|
||||
@ -236,3 +236,25 @@
|
||||
letter-spacing: 0.5px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Pool luck indicators */
|
||||
.very-lucky {
|
||||
color: #32CD32 !important;
|
||||
font-weight: bold !important;
|
||||
text-shadow: 0 0 6px rgba(50, 205, 50, 0.6) !important;
|
||||
}
|
||||
|
||||
.lucky {
|
||||
color: #90EE90 !important;
|
||||
text-shadow: 0 0 4px rgba(144, 238, 144, 0.5) !important;
|
||||
}
|
||||
|
||||
.normal-luck {
|
||||
color: #ffd700 !important;
|
||||
text-shadow: 0 0 4px rgba(255, 215, 0, 0.5) !important;
|
||||
}
|
||||
|
||||
.unlucky {
|
||||
color: #ff5555 !important;
|
||||
text-shadow: 0 0 4px rgba(255, 85, 85, 0.5) !important;
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ class ArrowIndicator {
|
||||
"difficulty", "daily_revenue", "daily_power_cost", "daily_profit_usd",
|
||||
"monthly_profit_usd", "daily_mined_sats", "monthly_mined_sats", "unpaid_earnings",
|
||||
"estimated_earnings_per_day_sats", "estimated_earnings_next_block_sats",
|
||||
"estimated_rewards_in_window_sats", "workers_hashing"
|
||||
"estimated_rewards_in_window_sats", "workers_hashing", "pool_luck"
|
||||
];
|
||||
|
||||
// Clear all arrows if requested
|
||||
@ -511,6 +511,30 @@ function formatTimeRemaining(seconds) {
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate pool luck as a percentage
|
||||
function calculatePoolLuck(actualSats, estimatedSats) {
|
||||
if (!actualSats || !estimatedSats || estimatedSats === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Calculate luck as a percentage (actual/estimated * 100)
|
||||
const luck = (actualSats / estimatedSats) * 100;
|
||||
return luck;
|
||||
}
|
||||
|
||||
// Format luck percentage for display with color coding
|
||||
function formatLuckPercentage(luckPercentage) {
|
||||
if (luckPercentage === null) {
|
||||
return "N/A";
|
||||
}
|
||||
|
||||
const formattedLuck = luckPercentage.toFixed(1) + "%";
|
||||
|
||||
// Don't add classes here, just return the formatted value
|
||||
// The styling will be applied separately based on the value
|
||||
return formattedLuck;
|
||||
}
|
||||
|
||||
// SSE Connection with Error Handling and Reconnection Logic
|
||||
function setupEventSource() {
|
||||
console.log("Setting up EventSource connection...");
|
||||
@ -1253,6 +1277,97 @@ function updateChartWithNormalizedData(chart, data) {
|
||||
|
||||
// Main UI update function with hashrate normalization
|
||||
function updateUI() {
|
||||
function ensureElementStyles() {
|
||||
// Create a style element if it doesn't exist
|
||||
if (!document.getElementById('customMetricStyles')) {
|
||||
const styleEl = document.createElement('style');
|
||||
styleEl.id = 'customMetricStyles';
|
||||
styleEl.textContent = `
|
||||
/* Ensure rows have consistent layout */
|
||||
.card-body p {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto 1fr;
|
||||
align-items: center;
|
||||
margin: 0.25rem 0;
|
||||
line-height: 1.2;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* Label style */
|
||||
.card-body strong {
|
||||
grid-column: 1;
|
||||
}
|
||||
|
||||
/* Main metric container */
|
||||
.main-metric {
|
||||
grid-column: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* All dividers */
|
||||
.metric-divider-container {
|
||||
grid-column: 3;
|
||||
justify-self: end;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.metric-divider {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-left: 1rem;
|
||||
padding-left: 0.75rem;
|
||||
height: 1.5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.metric-divider-value {
|
||||
font-size: 0.85em;
|
||||
font-weight: normal;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.metric-divider-note {
|
||||
font-size: 0.75em;
|
||||
opacity: 0.8;
|
||||
color: white;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
span[id^="indicator_"] {
|
||||
margin-left: 0.25rem;
|
||||
width: 1rem;
|
||||
display: inline-flex;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(styleEl);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to create dividers with consistent horizontal alignment
|
||||
function createDivider(valueId, valueText, labelText, valueClass = "yellow") {
|
||||
const dividerContainer = document.createElement("span");
|
||||
dividerContainer.className = "metric-divider";
|
||||
|
||||
// Value element
|
||||
const valueSpan = document.createElement("span");
|
||||
valueSpan.id = valueId;
|
||||
valueSpan.className = `metric-value metric-divider-value ${valueClass}`;
|
||||
valueSpan.textContent = valueText;
|
||||
dividerContainer.appendChild(valueSpan);
|
||||
|
||||
// Label element
|
||||
const labelSpan = document.createElement("span");
|
||||
labelSpan.className = "metric-divider-note";
|
||||
labelSpan.textContent = labelText;
|
||||
dividerContainer.appendChild(labelSpan);
|
||||
|
||||
return dividerContainer;
|
||||
}
|
||||
|
||||
if (!latestMetrics) {
|
||||
console.warn("No metrics data available");
|
||||
return;
|
||||
@ -1280,6 +1395,114 @@ function updateUI() {
|
||||
}
|
||||
updateElementText("pool_total_hashrate", formattedPoolHashrate);
|
||||
|
||||
// Add pool luck calculation right after pool_total_hashrate
|
||||
if (data.daily_mined_sats && data.estimated_earnings_per_day_sats) {
|
||||
const poolLuck = calculatePoolLuck(
|
||||
parseFloat(data.daily_mined_sats),
|
||||
parseFloat(data.estimated_earnings_per_day_sats)
|
||||
);
|
||||
|
||||
// Add pool_luck to the metrics data for arrow indicators
|
||||
if (poolLuck !== null) {
|
||||
data.pool_luck = poolLuck;
|
||||
}
|
||||
|
||||
const poolLuckValue = poolLuck !== null ? formatLuckPercentage(poolLuck) : "N/A";
|
||||
|
||||
// Get the pool_total_hashrate element's parent paragraph
|
||||
const poolHashratePara = document.getElementById("pool_total_hashrate").parentNode;
|
||||
|
||||
// Ensure grid layout and structure
|
||||
ensureElementStyles();
|
||||
|
||||
// Structure parent for proper grid layout (similar to the other metrics)
|
||||
if (!poolHashratePara.querySelector('.main-metric')) {
|
||||
const poolHashrate = document.getElementById("pool_total_hashrate");
|
||||
const indicatorPoolHashrate = document.getElementById("indicator_pool_total_hashrate");
|
||||
|
||||
// Create the main metric container
|
||||
const mainMetric = document.createElement("span");
|
||||
mainMetric.className = "main-metric";
|
||||
|
||||
// Move the metric and its indicator inside the container
|
||||
if (poolHashrate && indicatorPoolHashrate) {
|
||||
// Clear any existing text nodes between the elements
|
||||
let node = poolHashrate.nextSibling;
|
||||
while (node && node !== indicatorPoolHashrate) {
|
||||
const nextNode = node.nextSibling;
|
||||
if (node.nodeType === 3) { // Text node
|
||||
poolHashratePara.removeChild(node);
|
||||
}
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
poolHashrate.parentNode.insertBefore(mainMetric, poolHashrate);
|
||||
mainMetric.appendChild(poolHashrate);
|
||||
mainMetric.appendChild(indicatorPoolHashrate);
|
||||
}
|
||||
|
||||
// Create divider container for pool hashrate row
|
||||
const dividerContainer = document.createElement("span");
|
||||
dividerContainer.className = "metric-divider-container";
|
||||
poolHashratePara.appendChild(dividerContainer);
|
||||
}
|
||||
|
||||
// Get or create the divider container
|
||||
let poolDividerContainer = poolHashratePara.querySelector('.metric-divider-container');
|
||||
if (!poolDividerContainer) {
|
||||
poolDividerContainer = document.createElement("span");
|
||||
poolDividerContainer.className = "metric-divider-container";
|
||||
poolHashratePara.appendChild(poolDividerContainer);
|
||||
}
|
||||
|
||||
// Check if the "pool_luck" element already exists
|
||||
const existingLuck = document.getElementById("pool_luck");
|
||||
if (existingLuck) {
|
||||
// Update existing element
|
||||
existingLuck.textContent = poolLuckValue;
|
||||
|
||||
// Apply appropriate color class based on luck value
|
||||
existingLuck.className = "metric-value metric-divider-value";
|
||||
if (poolLuck !== null) {
|
||||
if (poolLuck > 110) {
|
||||
existingLuck.classList.add("very-lucky");
|
||||
} else if (poolLuck > 100) {
|
||||
existingLuck.classList.add("lucky");
|
||||
} else if (poolLuck >= 90) {
|
||||
existingLuck.classList.add("normal-luck");
|
||||
} else {
|
||||
existingLuck.classList.add("unlucky");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Create the divider if it doesn't exist
|
||||
const poolLuckDiv = createDivider("pool_luck", poolLuckValue, "Earnings Efficiency");
|
||||
|
||||
// Apply appropriate color class
|
||||
const valueSpan = poolLuckDiv.querySelector('#pool_luck');
|
||||
if (valueSpan && poolLuck !== null) {
|
||||
if (poolLuck > 110) {
|
||||
valueSpan.classList.add("very-lucky");
|
||||
} else if (poolLuck > 100) {
|
||||
valueSpan.classList.add("lucky");
|
||||
} else if (poolLuck >= 90) {
|
||||
valueSpan.classList.add("normal-luck");
|
||||
} else {
|
||||
valueSpan.classList.add("unlucky");
|
||||
}
|
||||
}
|
||||
|
||||
// Add the indicator after the value
|
||||
const indicatorSpan = document.createElement("span");
|
||||
indicatorSpan.id = "indicator_pool_luck";
|
||||
indicatorSpan.style.marginLeft = "5px";
|
||||
poolLuckDiv.appendChild(indicatorSpan);
|
||||
|
||||
// Add to divider container
|
||||
poolDividerContainer.appendChild(poolLuckDiv);
|
||||
}
|
||||
}
|
||||
|
||||
// 24hr Hashrate
|
||||
let formatted24hrHashrate = "N/A";
|
||||
if (data.hashrate_24hr != null) {
|
||||
@ -1290,48 +1513,77 @@ function updateUI() {
|
||||
}
|
||||
updateElementText("hashrate_24hr", formatted24hrHashrate);
|
||||
|
||||
// Calculate and display theoretical block finding time
|
||||
// Update the block time section with consistent addition logic
|
||||
let blockTime = "N/A"; // Default value
|
||||
if (data.hashrate_24hr != null && data.network_hashrate != null) {
|
||||
const blockTime = calculateBlockTime(
|
||||
blockTime = calculateBlockTime(
|
||||
data.hashrate_24hr,
|
||||
data.hashrate_24hr_unit || 'th/s',
|
||||
data.network_hashrate
|
||||
);
|
||||
}
|
||||
|
||||
// Update the time element if it exists, or create it
|
||||
const timeElement = document.getElementById("block_time");
|
||||
if (timeElement) {
|
||||
timeElement.textContent = blockTime;
|
||||
} else {
|
||||
// Find the hashrate_24hr element's parent paragraph
|
||||
const hashratePara = document.getElementById("hashrate_24hr").parentNode;
|
||||
// Find the hashrate_24hr element's parent paragraph
|
||||
const hashrate24hrPara = document.getElementById("hashrate_24hr").parentNode;
|
||||
|
||||
// Create the time element inline with spacing
|
||||
const timeSpan = document.createElement("span");
|
||||
timeSpan.id = "block_time";
|
||||
timeSpan.className = "metric-value yellow"; // Using yellow for time values
|
||||
timeSpan.style.marginLeft = "10px";
|
||||
timeSpan.style.fontSize = "0.75em"; // Slightly larger font size
|
||||
timeSpan.style.fontWeight = "Normal"; // Normal font
|
||||
timeSpan.textContent = blockTime;
|
||||
// Structure parent for proper grid layout
|
||||
if (!hashrate24hrPara.querySelector('.main-metric')) {
|
||||
const hashrate24hr = document.getElementById("hashrate_24hr");
|
||||
const indicator24hr = document.getElementById("indicator_hashrate_24hr");
|
||||
|
||||
// Create a small label for it
|
||||
const timeLabel = document.createElement("span");
|
||||
timeLabel.className = "metric-label";
|
||||
timeLabel.style.fontSize = "0.65em";
|
||||
timeLabel.style.opacity = "0.8";
|
||||
timeLabel.style.marginLeft = "5px";
|
||||
timeLabel.style.color = "white"; // White color for label"
|
||||
timeLabel.style.fontWeight = "Normal"; // Normal font
|
||||
timeLabel.textContent = "[Time to ₿]";
|
||||
// Create the main metric container
|
||||
const mainMetric = document.createElement("span");
|
||||
mainMetric.className = "main-metric";
|
||||
|
||||
// Add both elements after the arrow indicator
|
||||
const arrowIndicator = document.getElementById("indicator_hashrate_24hr");
|
||||
if (arrowIndicator && hashratePara) {
|
||||
arrowIndicator.parentNode.insertBefore(timeSpan, arrowIndicator.nextSibling);
|
||||
arrowIndicator.parentNode.insertBefore(timeLabel, timeSpan.nextSibling);
|
||||
// Move the metric and its indicator inside the container
|
||||
if (hashrate24hr && indicator24hr) {
|
||||
// Clear any existing text nodes between the elements
|
||||
let node = hashrate24hr.nextSibling;
|
||||
while (node && node !== indicator24hr) {
|
||||
const nextNode = node.nextSibling;
|
||||
if (node.nodeType === 3) { // Text node
|
||||
hashrate24hrPara.removeChild(node);
|
||||
}
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
hashrate24hr.parentNode.insertBefore(mainMetric, hashrate24hr);
|
||||
mainMetric.appendChild(hashrate24hr);
|
||||
mainMetric.appendChild(indicator24hr);
|
||||
}
|
||||
|
||||
// Create divider container
|
||||
const dividerContainer = document.createElement("span");
|
||||
dividerContainer.className = "metric-divider-container";
|
||||
hashrate24hrPara.appendChild(dividerContainer);
|
||||
}
|
||||
|
||||
// Get or create the divider container
|
||||
let dividerContainer = hashrate24hrPara.querySelector('.metric-divider-container');
|
||||
if (!dividerContainer) {
|
||||
dividerContainer = document.createElement("span");
|
||||
dividerContainer.className = "metric-divider-container";
|
||||
hashrate24hrPara.appendChild(dividerContainer);
|
||||
}
|
||||
|
||||
// Check if the "block_time" element already exists
|
||||
const existingBlockTime = document.getElementById("block_time");
|
||||
if (existingBlockTime) {
|
||||
// Find the containing metric-divider
|
||||
let dividerElement = existingBlockTime.closest('.metric-divider');
|
||||
if (dividerElement) {
|
||||
// Just update the text
|
||||
existingBlockTime.textContent = blockTime;
|
||||
} else {
|
||||
// If structure is broken, recreate it
|
||||
const blockTimeDiv = createDivider("block_time", blockTime, "[Time to ₿]");
|
||||
dividerContainer.innerHTML = ''; // Clear container
|
||||
dividerContainer.appendChild(blockTimeDiv);
|
||||
}
|
||||
} else {
|
||||
// Create the "Time to ₿" divider
|
||||
const blockTimeDiv = createDivider("block_time", blockTime, "[Time to ₿]");
|
||||
dividerContainer.appendChild(blockTimeDiv);
|
||||
}
|
||||
|
||||
// 3hr Hashrate
|
||||
@ -1344,7 +1596,50 @@ function updateUI() {
|
||||
}
|
||||
updateElementText("hashrate_3hr", formatted3hrHashrate);
|
||||
|
||||
// Calculate and display block finding probability for 24hr hashrate instead of 3hr hashrate
|
||||
// Same for 3hr data with blockOdds
|
||||
const hashrate3hrPara = document.getElementById("hashrate_3hr").parentNode;
|
||||
|
||||
// Structure parent for proper grid layout
|
||||
if (!hashrate3hrPara.querySelector('.main-metric')) {
|
||||
const hashrate3hr = document.getElementById("hashrate_3hr");
|
||||
const indicator3hr = document.getElementById("indicator_hashrate_3hr");
|
||||
|
||||
// Create the main metric container
|
||||
const mainMetric = document.createElement("span");
|
||||
mainMetric.className = "main-metric";
|
||||
|
||||
// Move the metric and its indicator inside the container
|
||||
if (hashrate3hr && indicator3hr) {
|
||||
// Clear any existing text nodes between the elements
|
||||
let node = hashrate3hr.nextSibling;
|
||||
while (node && node !== indicator3hr) {
|
||||
const nextNode = node.nextSibling;
|
||||
if (node.nodeType === 3) { // Text node
|
||||
hashrate3hrPara.removeChild(node);
|
||||
}
|
||||
node = nextNode;
|
||||
}
|
||||
|
||||
hashrate3hr.parentNode.insertBefore(mainMetric, hashrate3hr);
|
||||
mainMetric.appendChild(hashrate3hr);
|
||||
mainMetric.appendChild(indicator3hr);
|
||||
}
|
||||
|
||||
// Create divider container
|
||||
const dividerContainer = document.createElement("span");
|
||||
dividerContainer.className = "metric-divider-container";
|
||||
hashrate3hrPara.appendChild(dividerContainer);
|
||||
}
|
||||
|
||||
// Get or create the divider container
|
||||
let odds3hrContainer = hashrate3hrPara.querySelector('.metric-divider-container');
|
||||
if (!odds3hrContainer) {
|
||||
odds3hrContainer = document.createElement("span");
|
||||
odds3hrContainer.className = "metric-divider-container";
|
||||
hashrate3hrPara.appendChild(odds3hrContainer);
|
||||
}
|
||||
|
||||
// Apply the same consistent approach for the block odds section
|
||||
if (data.hashrate_24hr != null && data.network_hashrate != null) {
|
||||
const blockProbability = calculateBlockProbability(
|
||||
data.hashrate_24hr,
|
||||
@ -1352,39 +1647,14 @@ function updateUI() {
|
||||
data.network_hashrate
|
||||
);
|
||||
|
||||
// Update the block odds element
|
||||
const probabilityElement = document.getElementById("block_odds_3hr");
|
||||
if (probabilityElement) {
|
||||
probabilityElement.textContent = blockProbability;
|
||||
// Update the element if it already exists
|
||||
const existingProbability = document.getElementById("block_odds_3hr");
|
||||
if (existingProbability) {
|
||||
existingProbability.textContent = blockProbability;
|
||||
} else {
|
||||
// Find the hashrate_3hr element's parent paragraph
|
||||
const hashratePara = document.getElementById("hashrate_3hr").parentNode;
|
||||
|
||||
// Create the probability element inline with spacing
|
||||
const probSpan = document.createElement("span");
|
||||
probSpan.id = "block_odds_3hr";
|
||||
probSpan.className = "metric-value yellow";
|
||||
probSpan.style.marginLeft = "17px";
|
||||
probSpan.style.fontSize = "0.75em"; // Slightly larger font size
|
||||
probSpan.style.fontWeight = "Normal"; // Normal font
|
||||
probSpan.textContent = blockProbability;
|
||||
|
||||
// Create a small label for it
|
||||
const probLabel = document.createElement("span");
|
||||
probLabel.className = "metric-label";
|
||||
probLabel.style.fontSize = "0.65em";
|
||||
probLabel.style.opacity = "0.8";
|
||||
probLabel.style.marginLeft = "5px";
|
||||
probLabel.style.color = "white";
|
||||
probLabel.style.fontWeight = "Normal"; // Normal font
|
||||
probLabel.textContent = "[₿ Odds]";
|
||||
|
||||
// Add both elements after the arrow indicator
|
||||
const arrowIndicator = document.getElementById("indicator_hashrate_3hr");
|
||||
if (arrowIndicator && hashratePara) {
|
||||
arrowIndicator.parentNode.insertBefore(probSpan, arrowIndicator.nextSibling);
|
||||
arrowIndicator.parentNode.insertBefore(probLabel, probSpan.nextSibling);
|
||||
}
|
||||
// For block odds after 3hr hashrate
|
||||
const blockOddsDiv = createDivider("block_odds_3hr", blockProbability, "[₿ Odds]");
|
||||
odds3hrContainer.appendChild(blockOddsDiv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1476,7 +1746,7 @@ function updateUI() {
|
||||
|
||||
// Check for "next block" in any case format
|
||||
if (payoutText && /next\s+block/i.test(payoutText)) {
|
||||
$("#est_time_to_payout").attr("style", "color: #32CD32 !important; text-shadow: 0 0 6px rgba(50, 205, 50, 0.6) !important; animation: pulse 1s infinite !important; text-transform: uppercase !important;");
|
||||
$("#est_time_to_payout").attr("style", "color: #32CD32 !important; text-shadow: 0 0 10px rgba(50, 205, 50, 0.6) !important; animation: pulse 1s infinite !important; text-transform: uppercase !important;");
|
||||
} else {
|
||||
// Trim any extra whitespace
|
||||
const cleanText = payoutText ? payoutText.trim() : "";
|
||||
@ -1667,6 +1937,45 @@ $(document).ready(function () {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// Add this to your $(document).ready() function in main.js
|
||||
function fixLastBlockLine() {
|
||||
// Add the style to fix the Last Block line
|
||||
$("<style>")
|
||||
.prop("type", "text/css")
|
||||
.html(`
|
||||
/* Fix for Last Block line to keep all elements on one line */
|
||||
.card-body p.last-block-line {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.card-body p.last-block-line > strong {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-body p.last-block-line > span,
|
||||
.card-body p.last-block-line > #indicator_last_block {
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
}
|
||||
`)
|
||||
.appendTo("head");
|
||||
|
||||
// Apply the class to the Last Block line
|
||||
$("#payoutMiscCard .card-body p").each(function () {
|
||||
const strongElem = $(this).find("strong");
|
||||
if (strongElem.length && strongElem.text().includes("Last Block")) {
|
||||
$(this).addClass("last-block-line");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Call this function
|
||||
fixLastBlockLine();
|
||||
|
||||
// Load timezone setting early
|
||||
(function loadTimezoneEarly() {
|
||||
// First try to get from localStorage for instant access
|
||||
|
@ -117,7 +117,7 @@
|
||||
<div class="card-header">Pool Hashrates</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong>Pool Total Hashrate:</strong>
|
||||
<strong>Pool Hashrate:</strong>
|
||||
<span id="pool_total_hashrate" class="metric-value white">
|
||||
{% if metrics and metrics.pool_total_hashrate and metrics.pool_total_hashrate_unit %}
|
||||
{{ metrics.pool_total_hashrate }} {{ metrics.pool_total_hashrate_unit[:-2]|upper ~ metrics.pool_total_hashrate_unit[-2:] }}
|
||||
@ -256,7 +256,7 @@
|
||||
<div class="card-header">SATOSHI EARNINGS</div>
|
||||
<div class="card-body">
|
||||
<p>
|
||||
<strong>Daily Mined (Net):</strong>
|
||||
<strong>Projected Daily (Net):</strong>
|
||||
<span id="daily_mined_sats" class="metric-value yellow">
|
||||
{% if metrics and metrics.daily_mined_sats %}
|
||||
{{ metrics.daily_mined_sats|commafy }} SATS
|
||||
@ -267,7 +267,7 @@
|
||||
<span id="indicator_daily_mined_sats"></span>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Monthly Mined (Net):</strong>
|
||||
<strong>Projected Monthly (Net):</strong>
|
||||
<span id="monthly_mined_sats" class="metric-value yellow">
|
||||
{% if metrics and metrics.monthly_mined_sats %}
|
||||
{{ metrics.monthly_mined_sats|commafy }} SATS
|
||||
|
Loading…
Reference in New Issue
Block a user