-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add modal logic for dynamic data display for blocks and fee rates in …
…footer
- Loading branch information
1 parent
8cab27b
commit 82e5aef
Showing
7 changed files
with
348 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,182 @@ | ||
// Function to establish WebSocket connection and listen for fee rate updates | ||
function connectToMempoolAPI() { | ||
const ws = new WebSocket('wss://mempool.space/api/v1/ws'); | ||
|
||
ws.onopen = () => { | ||
console.log('WebSocket connection established'); | ||
// Subscribe to 'stats' and 'blocks' channels to receive mempool statistics and block info | ||
ws.send(JSON.stringify({ | ||
"action": "init", | ||
"channels": ["stats", "blocks"] | ||
})); | ||
ws.send(JSON.stringify({ "action": "init", "channels": ["stats", "blocks"] })); | ||
}; | ||
|
||
ws.onmessage = (event) => { | ||
const data = JSON.parse(event.data); | ||
|
||
// Log the received data to check its structure | ||
console.log('Received data:', data); | ||
window.latestMempoolData = data; // Store the latest data globally | ||
|
||
// Extract the half-hour fee rate from the 'fees' object | ||
if (data.fees && data.fees.halfHourFee) { | ||
const feeRate = data.fees.halfHourFee; | ||
document.getElementById('fee-rate').textContent = feeRate + ' sat/vB'; | ||
} else { | ||
console.log('Fee rate data not available in the received payload.'); | ||
} | ||
console.log('Received data:', data); | ||
|
||
// Extract the last block height from the 'blocks' object | ||
if (data.blocks && data.blocks.length > 0) { | ||
const lastBlockHeight = data.blocks[7].height; | ||
document.getElementById('block-height').textContent = '' + lastBlockHeight; | ||
} else { | ||
console.log('Block height data not available in the received payload.'); | ||
} | ||
updateFooterDisplay(data); | ||
}; | ||
|
||
ws.onerror = (error) => { | ||
console.error('WebSocket error:', error); | ||
}; | ||
|
||
ws.onclose = () => { | ||
console.log('WebSocket connection closed'); | ||
// Attempt to reconnect after a 15-second delay | ||
setTimeout(connectToMempoolAPI, 60000); | ||
setTimeout(connectToMempoolAPI, 30000); | ||
}; | ||
} | ||
|
||
// Call the function to establish connection on page load | ||
connectToMempoolAPI(); | ||
|
||
// Function to open the fee rate modal | ||
function openFeeRateModal() { | ||
// Logic to open the modal window displaying more fee rate information | ||
// Global variables to track current state | ||
let currentBlockIndex = 7; // Start with the latest block | ||
let dataType = ''; // To track whether we clicked 'fee rate' or 'block height' | ||
|
||
// Function to update footer display | ||
function updateFooterDisplay(data) { | ||
if (data.blocks && data.blocks.length > 7) { | ||
const lastBlockHeight = data.blocks[7].height; | ||
document.getElementById('block-height').textContent = '' + lastBlockHeight; | ||
} else { | ||
console.log('Block height data not available in the received payload.'); | ||
} | ||
|
||
if (data.fees && data.fees.halfHourFee) { | ||
const feeRate = data.fees.halfHourFee; | ||
document.getElementById('fee-rate').textContent = feeRate + ' sat/vB'; | ||
} else { | ||
console.log('Fee rate data not available in the received payload.'); | ||
} | ||
} | ||
|
||
// Function to open the Mempool Data Modal with dynamic content | ||
function openMempoolDataModal(type, event) { | ||
event.stopPropagation(); | ||
const mempoolModal = document.getElementById('mempoolTinyDataModal'); | ||
if (mempoolModal) { | ||
closeAllModals(); | ||
dataType = type; | ||
clearModalContent(); | ||
|
||
if (dataType === 'block') { | ||
updateBlockHeightModalData(currentBlockIndex); | ||
} else if (dataType === 'fee') { | ||
updateFeeRateModalData(); | ||
} | ||
|
||
mempoolModal.classList.add('active'); | ||
document.body.classList.add('modal-open'); | ||
} else { | ||
console.error('Mempool Tiny Data Modal not found!'); | ||
} | ||
} | ||
} | ||
|
||
// Function to clear modal content before loading new data | ||
function clearModalContent() { | ||
const elementsToClear = [ | ||
'modal-title', 'avg-fee-rate', 'fee-range', 'total-fees-btc', | ||
'total-fees-sats', 'tx-count', 'time-passed', 'mined-by', 'fee-info', | ||
'economy-fee', 'fastest-fee', 'half-hour-fee', 'hour-fee', 'minimum-fee' | ||
]; | ||
elementsToClear.forEach(className => { | ||
const element = document.querySelector(`#mempoolTinyDataModal .${className}`); | ||
if (element) element.textContent = ''; | ||
}); | ||
} | ||
|
||
// Function to update the modal content based on the block index | ||
function updateBlockHeightModalData(blockIndex) { | ||
const data = window.latestMempoolData; | ||
|
||
if (!data || !data.blocks || data.blocks.length <= blockIndex) { | ||
console.log('No data available for the specified block index.'); | ||
return; | ||
} | ||
|
||
const blockData = data.blocks[blockIndex]; | ||
|
||
if (!blockData || !blockData.extras) { | ||
console.log('Block data or extras not available.'); | ||
return; | ||
} | ||
|
||
// Populate modal content for block data | ||
document.querySelector('#mempoolTinyDataModal .modal-title').textContent = `${blockData.height}`; | ||
document.querySelector('#mempoolTinyDataModal .avg-fee-rate').textContent = `Avg Fee: ~ ${blockData.extras.avgFeeRate} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .fee-range').textContent = `Fee Range: ${Math.round(blockData.extras.feeRange[0])} - ${Math.round(blockData.extras.feeRange[6])} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .total-fees-btc').textContent = `Total Fees: ${(blockData.extras.totalFees / 1e8).toFixed(3)} BTC`; | ||
document.querySelector('#mempoolTinyDataModal .total-fees-sats').textContent = `Total Fees (Sats): ${blockData.extras.totalFees} sats`; | ||
document.querySelector('#mempoolTinyDataModal .tx-count').textContent = `Transaction Count: ${blockData.tx_count.toLocaleString()}`; | ||
|
||
// Calculate time passed since block was mined | ||
const timePassed = Math.round((Date.now() / 1000 - blockData.timestamp) / 60); | ||
document.querySelector('#mempoolTinyDataModal .time-passed').textContent = `Time Passed: ${timePassed} minutes ago`; | ||
|
||
document.querySelector('#mempoolTinyDataModal .mined-by').textContent = `Mined by: ${blockData.extras.pool.name}`; | ||
|
||
// Show elements specific to block data | ||
toggleModalSections('block'); | ||
} | ||
|
||
// Function to update the modal content for fee rate | ||
function updateFeeRateModalData() { | ||
const data = window.latestMempoolData; | ||
|
||
if (!data || !data.fees) { | ||
console.log('Fee rate data not available.'); | ||
return; | ||
} | ||
|
||
const { fastestFee, halfHourFee, hourFee, economyFee, minimumFee } = data.fees; | ||
|
||
// Populate modal content for fee data | ||
document.querySelector('#mempoolTinyDataModal .modal-title').textContent = `Fee Rates`; | ||
document.querySelector('#mempoolTinyDataModal .fee-info').textContent = `Half-Hour Fee: ${halfHourFee} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .economy-fee').textContent = `Economy Fee: ${economyFee} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .fastest-fee').textContent = `Fastest Fee: ${fastestFee} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .hour-fee').textContent = `Hour Fee: ${hourFee} sat/vB`; | ||
document.querySelector('#mempoolTinyDataModal .minimum-fee').textContent = `Minimum Fee: ${minimumFee} sat/vB`; | ||
|
||
// Show elements specific to fee data | ||
toggleModalSections('fee'); | ||
} | ||
|
||
// Helper function to toggle modal sections visibility | ||
function toggleModalSections(type) { | ||
const showBlockData = type === 'block'; | ||
document.querySelectorAll('#mempoolTinyDataModal .block-data').forEach(el => el.style.display = showBlockData ? 'block' : 'none'); | ||
document.querySelectorAll('#mempoolTinyDataModal .fee-data').forEach(el => el.style.display = showBlockData ? 'none' : 'block'); | ||
} | ||
|
||
// Event listener for left arrow click to navigate blocks | ||
document.querySelector('#mempoolTinyDataModal .left-arrow').addEventListener('click', function () { | ||
if (dataType === 'block' && currentBlockIndex > 0) { | ||
currentBlockIndex--; | ||
updateBlockHeightModalData(currentBlockIndex); | ||
} | ||
}); | ||
|
||
// Event listener for right arrow click to navigate blocks | ||
document.querySelector('#mempoolTinyDataModal .right-arrow').addEventListener('click', function () { | ||
if (dataType === 'block' && currentBlockIndex < 7) { | ||
currentBlockIndex++; | ||
updateBlockHeightModalData(currentBlockIndex); | ||
} | ||
}); | ||
|
||
function closeAllModals() { | ||
document.querySelectorAll('.description-modal.active').forEach(function (modal) { | ||
modal.classList.remove('active'); | ||
}); | ||
document.body.classList.remove('modal-open'); | ||
} | ||
|
||
// Attach event listeners for footer elements | ||
document.getElementById('block-height').addEventListener('click', function (event) { | ||
openMempoolDataModal('block', event); | ||
}); | ||
|
||
document.getElementById('fee-rate').addEventListener('click', function (event) { | ||
openMempoolDataModal('fee', event); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.