diff --git a/static/js/blocks.js b/static/js/blocks.js
index 556d6c9..f4b8ae0 100644
--- a/static/js/blocks.js
+++ b/static/js/blocks.js
@@ -155,6 +155,211 @@ function showToast(message) {
}, 100);
}
+// Pool color mapping function - add this after your existing helper functions
+function getPoolColor(poolName) {
+ // Normalize the pool name (lowercase and remove special characters)
+ const normalizedName = poolName.toLowerCase().replace(/[^a-z0-9]/g, '');
+
+ // Define color mappings for common mining pools with Ocean pool featured prominently
+ const poolColors = {
+ // OCEAN pool with a distinctive bright cyan color for prominence
+ 'ocean': '#00ffff', // Bright Cyan for Ocean
+ 'oceanpool': '#00ffff', // Bright Cyan for Ocean
+ 'oceanxyz': '#00ffff', // Bright Cyan for Ocean
+ 'ocean.xyz': '#00ffff', // Bright Cyan for Ocean
+
+ // Other common mining pools with more muted colors
+ 'f2pool': '#1a9eff', // Blue
+ 'antpool': '#ff7e33', // Orange
+ 'binancepool': '#f3ba2f', // Binance gold
+ 'foundryusa': '#b150e2', // Purple
+ 'viabtc': '#ff5c5c', // Red
+ 'luxor': '#2bae2b', // Green
+ 'slushpool': '#3355ff', // Bright blue
+ 'btccom': '#ff3355', // Pink
+ 'poolin': '#ffaa22', // Amber
+ 'sbicrypto': '#cc9933', // Bronze
+ 'mara': '#8844cc', // Violet
+ 'ultimuspool': '#09c7be', // Teal
+ 'unknown': '#999999' // Grey for unknown pools
+ };
+
+ // Check for partial matches in pool names (for variations like "F2Pool" vs "F2pool.com")
+ for (const [key, color] of Object.entries(poolColors)) {
+ if (normalizedName.includes(key)) {
+ return color;
+ }
+ }
+
+ // If no match is found, generate a consistent color based on the pool name
+ let hash = 0;
+ for (let i = 0; i < poolName.length; i++) {
+ hash = poolName.charCodeAt(i) + ((hash << 5) - hash);
+ }
+
+ // Generate HSL color with fixed saturation and lightness for readability
+ // Use the hash to vary the hue only (0-360)
+ const hue = Math.abs(hash % 360);
+ return `hsl(${hue}, 70%, 60%)`;
+}
+
+// Function to create a block card
+function createBlockCard(block) {
+ const timestamp = formatTimestamp(block.timestamp);
+ const formattedSize = formatFileSize(block.size);
+ const formattedTxCount = numberWithCommas(block.tx_count);
+
+ // Get the pool name or "Unknown"
+ const poolName = block.extras && block.extras.pool ? block.extras.pool.name : "Unknown";
+
+ // Get pool color
+ const poolColor = getPoolColor(poolName);
+
+ // Check if this is an Ocean pool block for special styling
+ const isOceanPool = poolName.toLowerCase().includes('ocean');
+
+ // Calculate total fees in BTC
+ const totalFees = block.extras ? (block.extras.totalFees / 100000000).toFixed(8) : "N/A";
+
+ // Create the block card
+ const blockCard = $("
", {
+ class: "block-card",
+ "data-height": block.height,
+ "data-hash": block.id
+ });
+
+ // Apply pool color border - with special emphasis for Ocean pool
+ if (isOceanPool) {
+ // Give Ocean pool blocks a more prominent styling
+ blockCard.css({
+ "border": `2px solid ${poolColor}`,
+ "box-shadow": `0 0 10px ${poolColor}`,
+ "background": `linear-gradient(to bottom, rgba(0, 255, 255, 0.1), rgba(0, 0, 0, 0))`
+ });
+ } else {
+ // Standard styling for other pools
+ blockCard.css({
+ "border-left": `4px solid ${poolColor}`,
+ "border-top": `1px solid ${poolColor}30`,
+ "border-right": `1px solid ${poolColor}30`,
+ "border-bottom": `1px solid ${poolColor}30`
+ });
+ }
+
+ // Create the block header
+ const blockHeader = $("
", {
+ class: "block-header"
+ });
+
+ blockHeader.append($("
", {
+ class: "block-height",
+ text: "#" + block.height
+ }));
+
+ blockHeader.append($("
", {
+ class: "block-time",
+ text: timestamp
+ }));
+
+ blockCard.append(blockHeader);
+
+ // Create the block info section
+ const blockInfo = $("
", {
+ class: "block-info"
+ });
+
+ // Add transaction count with conditional coloring based on count
+ const txCountItem = $("
", {
+ class: "block-info-item"
+ });
+ txCountItem.append($("
", {
+ class: "block-info-label",
+ text: "Transactions"
+ }));
+
+ // Determine transaction count color based on thresholds
+ let txCountClass = "green"; // Default for high transaction counts (2000+)
+ if (block.tx_count < 500) {
+ txCountClass = "red"; // Less than 500 transactions
+ } else if (block.tx_count < 2000) {
+ txCountClass = "yellow"; // Between 500 and 1999 transactions
+ }
+
+ txCountItem.append($("
", {
+ class: `block-info-value ${txCountClass}`,
+ text: formattedTxCount
+ }));
+ blockInfo.append(txCountItem);
+
+ // Add size
+ const sizeItem = $("
", {
+ class: "block-info-item"
+ });
+ sizeItem.append($("
", {
+ class: "block-info-label",
+ text: "Size"
+ }));
+ sizeItem.append($("
", {
+ class: "block-info-value white",
+ text: formattedSize
+ }));
+ blockInfo.append(sizeItem);
+
+ // Add miner/pool with custom color
+ const minerItem = $("
", {
+ class: "block-info-item"
+ });
+ minerItem.append($("
", {
+ class: "block-info-label",
+ text: "Miner"
+ }));
+
+ // Apply the custom pool color with special styling for Ocean pool
+ const minerValue = $("
", {
+ class: "block-info-value",
+ text: poolName,
+ css: {
+ color: poolColor,
+ textShadow: isOceanPool ? `0 0 8px ${poolColor}` : `0 0 6px ${poolColor}80`,
+ fontWeight: isOceanPool ? "bold" : "normal"
+ }
+ });
+
+ // Add a special indicator icon for Ocean pool
+ if (isOceanPool) {
+ minerValue.prepend($("
", {
+ html: "★ ",
+ css: { color: poolColor }
+ }));
+ }
+
+ minerItem.append(minerValue);
+ blockInfo.append(minerItem);
+
+ // Add Avg Fee Rate
+ const feesItem = $("", {
+ class: "block-info-item"
+ });
+ feesItem.append($("
", {
+ class: "block-info-label",
+ text: "Avg Fee Rate"
+ }));
+ feesItem.append($("
", {
+ class: "block-info-value yellow",
+ text: block.extras && block.extras.avgFeeRate ? block.extras.avgFeeRate + " sat/vB" : "N/A"
+ }));
+ blockInfo.append(feesItem);
+
+ blockCard.append(blockInfo);
+
+ // Add event listener for clicking on the block card
+ blockCard.on("click", function () {
+ showBlockDetails(block);
+ });
+
+ return blockCard;
+}
+
// Function to load blocks from a specific height
function loadBlocksFromHeight(height) {
if (isLoading) return;
@@ -587,7 +792,6 @@ function showBlockDetails(block) {
blockDetails.append(headerSection);
- // Rest of the function remains unchanged
// Create the mining section
const miningSection = $("
", {
class: "block-detail-section"
@@ -598,7 +802,7 @@ function showBlockDetails(block) {
text: "Mining Details"
}));
- // Add miner/pool
+ // Add miner/pool with matching color
const minerItem = $("
", {
class: "block-detail-item"
});
@@ -607,12 +811,42 @@ function showBlockDetails(block) {
text: "Miner"
}));
const poolName = block.extras && block.extras.pool ? block.extras.pool.name : "Unknown";
- minerItem.append($("
", {
+ const poolColor = getPoolColor(poolName);
+ const isOceanPool = poolName.toLowerCase().includes('ocean');
+
+ // Apply special styling for Ocean pool in the modal
+ const minerValue = $("
", {
class: "block-detail-value",
- text: poolName
- }));
+ text: poolName,
+ css: {
+ color: poolColor,
+ textShadow: isOceanPool ? `0 0 8px ${poolColor}` : `0 0 6px ${poolColor}80`,
+ fontWeight: isOceanPool ? "bold" : "normal"
+ }
+ });
+
+ // Add a special indicator icon for Ocean pool
+ if (isOceanPool) {
+ minerValue.prepend($("
", {
+ html: "★ ",
+ css: { color: poolColor }
+ }));
+
+ // Add a note for Ocean pool
+ minerValue.append($("", {
+ text: "(Your Mining Pool)",
+ css: {
+ fontSize: "0.8em",
+ marginTop: "3px",
+ color: "#ffffffbb"
+ }
+ }));
+ }
+
+ minerItem.append(minerValue);
miningSection.append(minerItem);
+ // Rest of the function remains unchanged
// Add difficulty
const difficultyItem = $("
", {
class: "block-detail-item"